diff --git a/konova/sub_settings/sso_settings.py b/konova/sub_settings/sso_settings.py index d1b9ee80..dbb6b2b8 100644 --- a/konova/sub_settings/sso_settings.py +++ b/konova/sub_settings/sso_settings.py @@ -8,17 +8,18 @@ Created on: 31.01.22 import random import string -# SSO settings +# Django-simple-SSO settings SSO_SERVER_BASE = "http://127.0.0.1:8000/" SSO_SERVER = f"{SSO_SERVER_BASE}sso/" SSO_PRIVATE_KEY = "CHANGE_ME" SSO_PUBLIC_KEY = "CHANGE_ME" -# OAuth +# OAuth settings OAUTH_CODE_VERIFIER = ''.join( random.choice( string.ascii_uppercase + string.digits ) for _ in range(random.randint(43, 128)) ) + OAUTH_CLIENT_ID = "CHANGE_ME" OAUTH_CLIENT_SECRET = "CHANGE_ME" \ No newline at end of file diff --git a/konova/tests/test_views.py b/konova/tests/test_views.py index 860b3616..95fb8367 100644 --- a/konova/tests/test_views.py +++ b/konova/tests/test_views.py @@ -509,7 +509,7 @@ class BaseViewTestCase(BaseTestCase): def setUp(self) -> None: super().setUp() - self.login_url = reverse("simple-sso-login") + self.login_url = reverse("oauth-login") def assert_url_success(self, client: Client, urls: list): """ Assert for all given urls a direct 200 response diff --git a/user/urls.py b/user/urls.py index ed975488..cb6e20b0 100644 --- a/user/urls.py +++ b/user/urls.py @@ -9,11 +9,13 @@ from django.urls import path from user.autocomplete.share import ShareUserAutocomplete, ShareTeamAutocomplete from user.autocomplete.team import TeamAdminAutocomplete -from user.views import * +from user.views.propagate import PropagateUserView +from user.views.views import * app_name = "user" urlpatterns = [ path("", index_view, name="index"), + path("propagate/", PropagateUserView.as_view(), name="propagate"), path("notifications/", notifications_view, name="notifications"), path("token/api", api_token_view, name="api-token"), path("contact/", contact_view, name="contact"), diff --git a/user/views/__init__.py b/user/views/__init__.py new file mode 100644 index 00000000..1f81b60d --- /dev/null +++ b/user/views/__init__.py @@ -0,0 +1,7 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 10.05.24 + +""" diff --git a/user/views/propagate.py b/user/views/propagate.py new file mode 100644 index 00000000..b285dcf0 --- /dev/null +++ b/user/views/propagate.py @@ -0,0 +1,69 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 10.05.24 + +""" +import base64 +import hashlib +import json + +from cryptography.fernet import Fernet +from django.core.exceptions import ObjectDoesNotExist +from django.http import HttpRequest, JsonResponse +from django.utils.decorators import method_decorator +from django.views import View +from django.views.decorators.csrf import csrf_exempt + +from konova.sub_settings.sso_settings import OAUTH_CLIENT_ID +from user.models import User + + +class PropagateUserView(View): + """ Receives user data to be stored in db + + Used if new user gets access to application and needs to be created in application before first login (e.g. + proper rights management) + + """ + + @method_decorator(csrf_exempt) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + def post(self, request: HttpRequest, *args, **kwargs): + # Decrypt + encrypted_body = request.body + hash = hashlib.md5() + hash.update(OAUTH_CLIENT_ID.encode("utf-8")) + key = base64.urlsafe_b64encode(hash.hexdigest().encode("utf-8")) + fernet = Fernet(key) + body = fernet.decrypt(encrypted_body).decode("utf-8") + body = json.loads(body) + + try: + status = "updated" + user = User.objects.get(username=body.get('username')) + # Update user data, excluding some changes + skipable_attrs = { + "username", + "is_staff", + "is_superuser", + } + for _attr, _val in body.items(): + if _attr in skipable_attrs: + continue + setattr(user, _attr, _val) + except ObjectDoesNotExist: + user = User(**body) + status = "created" + user.set_unusable_password() + user.save() + + data = { + "success": True, + "status": status + } + + return JsonResponse(data) diff --git a/user/views.py b/user/views/views.py similarity index 100% rename from user/views.py rename to user/views/views.py