From f135008447aad128ba5d12a2e83b3b1fe8bb49e8 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 29 Apr 2024 12:27:07 +0200 Subject: [PATCH] # OAuth refactoring code * refactors code --- konova/sub_settings/sso_settings.py | 4 +- konova/views/oauth.py | 119 +++++++++++++++------------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/konova/sub_settings/sso_settings.py b/konova/sub_settings/sso_settings.py index 01592cc3..d1b9ee80 100644 --- a/konova/sub_settings/sso_settings.py +++ b/konova/sub_settings/sso_settings.py @@ -19,4 +19,6 @@ OAUTH_CODE_VERIFIER = ''.join( random.choice( string.ascii_uppercase + string.digits ) for _ in range(random.randint(43, 128)) -) \ No newline at end of file +) +OAUTH_CLIENT_ID = "CHANGE_ME" +OAUTH_CLIENT_SECRET = "CHANGE_ME" \ No newline at end of file diff --git a/konova/views/oauth.py b/konova/views/oauth.py index fc2735f4..43e888f4 100644 --- a/konova/views/oauth.py +++ b/konova/views/oauth.py @@ -17,17 +17,78 @@ from django.shortcuts import redirect from django.urls import reverse from django.views import View -from konova.sub_settings.sso_settings import SSO_SERVER_BASE, OAUTH_CODE_VERIFIER +from konova.sub_settings.sso_settings import SSO_SERVER_BASE, OAUTH_CODE_VERIFIER, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET from user.models import User -OAUTH_CLIENT_ID = "CHANGE_ME" -OAUTH_CLIENT_SECRET = "CHANGE_ME" + +class OAuthLoginView(View): + """ + Starts OAuth Login procedure + -> AnonymousUser is redirected to SSO component using specific parameters + -> After successful login (in SSO component), user will be redirected to a specific callback url (OAuthCallbackView) + -> Callback view uses retrieved authorization token to get a proper access token from SSO component + -> SSO component answers with access token + -> OAuthCallbackView uses token in Authorization header to access user data of logged-in user in SSO component + -> OAuthCallbackView creates/updates user + -> OAuthCallbackView logs in user and redirects to default home view + + """ + + def __create_code_challenge(self): + """ + Creates a code verifier and code challenge for extra security. + See https://django-oauth-toolkit.readthedocs.io/en/latest/getting_started.html#authorization-code for further + information + + Returns: + + """ + code_verifier = OAUTH_CODE_VERIFIER + + code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8').replace('=', '') + return code_verifier, code_challenge + + def get(self, request: HttpRequest, *args, **kwargs): + """ + Redirects user to OAuth SSO webservice for credential based login there + + Args: + request (): + *args (): + **kwargs (): + + Returns: + + """ + oauth_authentication_code_url = f"{SSO_SERVER_BASE}o/authorize/" + code_verifier, code_challenge = self.__create_code_challenge() + + urlencode_params = urlencode( + { + "response_type": "code", + "code_challenge": code_challenge, + "code_challenge_method": "S256", + "client_id": OAUTH_CLIENT_ID, + "redirect_uri": request.build_absolute_uri( + reverse( + "oauth-callback" + ) + ), + } + ) + url = f"{oauth_authentication_code_url}?{urlencode_params}" + return redirect(url) class OAuthCallbackView(View): """ - Callback view for a OAuth2.0 authentication token. - Authentication tokens need to be exchanged for the access token. + Callback view for OAuth2.0 authentication token. + Authentication tokens will be exchanged for access token. + Access Token will be used for fetching user data from SSO component. + User data will be used for creating/updating user data inside this app. + User will be logged-in and redirected to default home view. + """ def get(self, request: HttpRequest, *args, **kwargs): @@ -67,51 +128,3 @@ class OAuthCallbackView(View): login(request, user) return redirect("home") - -class OAuthLoginView(View): - - def __create_code_challenge(self): - """ - Creates a code verifier and code challenge for extra security. - See https://django-oauth-toolkit.readthedocs.io/en/latest/getting_started.html#authorization-code for further - information - - Returns: - - """ - code_verifier = OAUTH_CODE_VERIFIER - - code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8').replace('=', '') - return code_verifier, code_challenge - - def get(self, request: HttpRequest, *args, **kwargs): - """ Redirects user to OAuth SSO webservice - - Args: - request (): - *args (): - **kwargs (): - - Returns: - - """ - oauth_authentication_code_url = f"{SSO_SERVER_BASE}o/authorize/" - code_verifier, code_challenge = self.__create_code_challenge() - print(code_verifier) - - urlencode_params = urlencode( - { - "response_type": "code", - "code_challenge": code_challenge, - "code_challenge_method": "S256", - "client_id": OAUTH_CLIENT_ID, - "redirect_uri": request.build_absolute_uri( - reverse( - "oauth-callback" - ) - ), - } - ) - url = f"{oauth_authentication_code_url}?{urlencode_params}" - return redirect(url)