Core: add jwt auth

This commit is contained in:
Omma 2024-08-21 16:38:37 +03:30
parent 1e0ffd9b2d
commit 495312b060
12 changed files with 234 additions and 17 deletions

View file

@ -39,8 +39,10 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'rest_framework', 'rest_framework',
'rest_framework_simplejwt',
'proxy', 'proxy',
'jwtauth',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -125,3 +127,60 @@ STATIC_URL = 'static/'
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
#JWT
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
from datetime import timedelta
...
# Configure Simple JWT
SIMPLE_JWT = {
"AUTH_HEADER_TYPES": ("Bearer",),
}
'''
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
"ROTATE_REFRESH_TOKENS": False,
"BLACKLIST_AFTER_ROTATION": False,
"UPDATE_LAST_LOGIN": False,
"ALGORITHM": "HS256",
#"SIGNING_KEY": settings.SECRET_KEY,
"VERIFYING_KEY": "",
"AUDIENCE": None,
"ISSUER": None,
"JSON_ENCODER": None,
"JWK_URL": None,
"LEEWAY": 0,
# This is nessecary!
"AUTH_HEADER_TYPES": ("Bearer",),
"AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
"USER_ID_FIELD": "id",
"USER_ID_CLAIM": "user_id",
"USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",
"AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
"TOKEN_TYPE_CLAIM": "token_type",
"TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",
"JTI_CLAIM": "jti",
"SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
"SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
"SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
"TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
"TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
"TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
"TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
"SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
"SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}
'''

View file

@ -17,7 +17,14 @@ Including another URLconf
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView,
)
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('proxy/wells/', include('proxy.urls')), path('wells/', include('proxy.urls')),
path('token/', include('jwtauth.urls')),
] ]

0
jwtauth/__init__.py Normal file
View file

3
jwtauth/admin.py Normal file
View file

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
jwtauth/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class JwtauthConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'jwtauth'

View file

@ -0,0 +1,22 @@
# Generated by Django 5.0.7 on 2024-08-19 12:06
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='OkService',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('province', models.CharField(max_length=30)),
],
),
]

View file

7
jwtauth/models.py Normal file
View file

@ -0,0 +1,7 @@
from django.db import models
# Create your models here.
class OkService(models.Model):
name = models.CharField(max_length=30)
province = models.CharField(max_length=30)

3
jwtauth/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

20
jwtauth/urls.py Normal file
View file

@ -0,0 +1,20 @@
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView,
)
from .views import *
urlpatterns = [
#to do: costumize this!
path('register/', register_service, name='register_service'),
#post username and password, get access and refresh token
path('', TokenObtainPairView.as_view(), name='token_obtain_pair'),
#post refresh token to this url to get a new access token
path('refresh/', TokenRefreshView.as_view(), name='token_refresh'),
#validates the access token
path('verify/', TokenVerifyView.as_view(), name='token_verify'),
]

43
jwtauth/views.py Normal file
View file

@ -0,0 +1,43 @@
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.exceptions import InvalidToken
from rest_framework_simplejwt.tokens import UntypedToken
import json
from .models import OkService
@api_view(['POST'])
def register_service(request):
try:
data = dict(json.loads(request.body.decode('utf-8')))
print(data, type(data))
if "shared_key" in dict(data).keys:
if first_step_check():
...
services = OkService.objects.all()
except Exception as ex:
print(ex)
def first_step_check(shared_key):
service_id = 1
return service_id
def generate_tokens(service_id):
refresh = RefreshToken.for_user(service_id)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
def validate_token(token):
try:
UntypedToken(token)
return True
except InvalidToken:
return False

View file

@ -7,7 +7,9 @@ from django.core import serializers
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rest_framework.decorators import api_view from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
import json import json
import requests import requests
@ -15,12 +17,46 @@ from .models import Well
from .serializers import WellSerializer from .serializers import WellSerializer
#To optain the jwt Token for the first time from other services
'''
import requests
url = 'http://<well_service_url>/token/'
credentials = {
"username": "your_username",
"password": "your_password"
}
response = requests.post(url, data=credentials)
token = response.json().get('access')
'''
# Store this token to use in future requests
'''
headers = {
'Authorization': f'Bearer {token}',
}
response = requests.post('http://<well_service_url>/<...>/', headers=headers, json=data_to_send)
'''
#error_list
'''
{
"200_created": ({"data": "<serializer.data>", "message": "<costume message>"}, status=status.HTTP_200_OK),
"200_updated": ({"data": "<serializer.data>", "message": f"<Successfully updated {instance.license_code}>"}, status=status.HTTP_200_OK),
"400":({"message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST),
"404": ({"message": "<Not Found>"}, status=status.HTTP_404_NOT_FOUND),
"409": ({"message":f'<{data["license_code"]} already exists>'}, status=status.HTTP_409_CONFLICT),
"500": ({"message": "<Internal Server Error>"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR),
}
'''
@api_view(['POST']) @api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_well(request): def create_well(request):
try: try:
data = json.loads(request.body.decode('utf-8')) data = json.loads(request.body.decode('utf-8'))
instance = Well.objects.get( instance = Well.objects.filter(
license_code=data["license_code"]) license_code=data["license_code"], log_type = 0)
if instance: if instance:
return Response( return Response(
{"message":f'{data["license_code"]} already exists'}, {"message":f'{data["license_code"]} already exists'},
@ -29,33 +65,38 @@ def create_well(request):
serializer = WellSerializer(data=data) serializer = WellSerializer(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
dd
return Response( return Response(
serializer.data, {"data":serializer.data},
status=status.HTTP_201_CREATED status=status.HTTP_201_CREATED
) )
else: else:
return Response( return Response(
serializer.errors, {"message":serializer.errors},
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
) )
except Exception as e: except Exception as e:
print(e) print(e)
return Response({"error": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"message": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@api_view(['GET']) @api_view(['GET'])
@permission_classes([IsAuthenticated])
def send_well_by_well_id(request, obj_id): def send_well_by_well_id(request, obj_id):
try: try:
well = Well.objects.filter(id=obj_id).first() well = Well.objects.filter(id=obj_id).first()
if well is None: if well is None:
return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND) return Response({"message": "Not Found"}, status=status.HTTP_404_NOT_FOUND)
serializer = WellSerializer(well) serializer = WellSerializer(well)
return Response(serializer.data, status=status.HTTP_200_OK) return Response({"data":serializer.data}, status=status.HTTP_200_OK)
except Exception as ex: except Exception as ex:
print(ex) print(ex)
return Response({"error": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"message": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@api_view(['GET']) @api_view(['GET'])
@permission_classes([IsAuthenticated])
def send_wells(request): def send_wells(request):
#permission_classes = [IsAuthenticated]
try: try:
# to do: add owner # to do: add owner
# to do: add filter # to do: add filter
@ -63,24 +104,28 @@ def send_wells(request):
# to do: add no return data # to do: add no return data
wells = Well.objects.all() wells = Well.objects.all()
serializer = WellSerializer(wells, many=True) serializer = WellSerializer(wells, many=True)
return Response(serializer.data, status=status.HTTP_200_OK) return Response({"data":serializer.data}, status=status.HTTP_200_OK)
except Exception as ex: except Exception as ex:
print(ex) print(ex)
return Response({"error": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"message": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@permission_classes([IsAuthenticated])
@api_view(['DELETE']) @api_view(['DELETE'])
def delete_well_by_well_id(request, obj_id): def delete_well_by_well_id(request, obj_id):
try: try:
instance = Well.objects.get(id=obj_id, log_type=0) instance = Well.objects.get(id=obj_id, log_type=0)
instance.log_type = 1 instance.log_type = 1
instance.save() instance.save()
return Response({"detail": f"Successfully updated log type for well {instance.license_code}"}, status=status.HTTP_200_OK) return Response({"message": f"Successfully removed log type for well {instance.license_code}"}, status=status.HTTP_200_OK)
except Well.DoesNotExist: except Well.DoesNotExist:
return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND) return Response({"message": "Not Found"}, status=status.HTTP_404_NOT_FOUND)
except Exception as e: except Exception as e:
print(e) print(e)
return Response({"error": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"message": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@permission_classes([IsAuthenticated])
@api_view(['PUT']) @api_view(['PUT'])
def update_well_by_well_id(request, obj_id): def update_well_by_well_id(request, obj_id):
try: try:
@ -94,13 +139,15 @@ def update_well_by_well_id(request, obj_id):
serializer.save() serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
else: else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response({"message":serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
except Well.DoesNotExist: except Well.DoesNotExist:
return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND) return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND)
except Exception as e: except Exception as e:
print(e) print(e)
return Response({"error": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"error": "Internal Server Error"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@permission_classes([IsAuthenticated])
@api_view(['PUT']) @api_view(['PUT'])
def edit_well_by_well_id(request, obj_id): def edit_well_by_well_id(request, obj_id):
try: try: