From 9149e4cbd378ec73c82a28312c2e0641e9e4c680 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 23 Dec 2024 10:45:08 +0100 Subject: [PATCH] # Propagation improvement * fixes documentation and variable names on oauth token revocation * introduces private key for propagation * changes key usage in decryption of propagated user data from oauth_client_id to private propagation key --- .env.sample | 1 + api/models/token.py | 13 ++++++++----- konova/sub_settings/sso_settings.py | 2 ++ konova/views/oauth.py | 8 ++++---- user/views/propagate.py | 4 ++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.env.sample b/.env.sample index 4960a541..3e4c29ed 100644 --- a/.env.sample +++ b/.env.sample @@ -37,6 +37,7 @@ SSO_SERVER_BASE_URL=https://login.naturschutz.rlp.de OAUTH_CODE_VERIFIER=CHANGE_ME OAUTH_CLIENT_ID=CHANGE_ME OAUTH_CLIENT_SECRET=CHANGE_ME +PROPAGATION_SECRET=CHANGE_ME # RabbitMQ ## For connections to EGON diff --git a/api/models/token.py b/api/models/token.py index 698202ed..84c56496 100644 --- a/api/models/token.py +++ b/api/models/token.py @@ -155,15 +155,18 @@ class OAuthToken(UuidModel): return user - def revoke(self) -> (int, int): - """ Revokes the tokens of the user + def revoke(self) -> int: + """ Revokes the OAuth2 token of the user + + (/o/revoke_token/ indeed removes the corresponding access token on provider side and invalidates the + submitted refresh token in one step) Returns: - revocation_status_codes (tuple): HTTP status code for revocation of access_token and refresh_token + revocation_status_code (int): HTTP status code for revocation of refresh_token """ revoke_url = f"{SSO_SERVER_BASE}o/revoke_token/" token = self.refresh_token - revocation_status_codes = requests.post( + revocation_status_code = requests.post( revoke_url, data={ 'token': token, @@ -172,5 +175,5 @@ class OAuthToken(UuidModel): auth=(OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET), ).status_code - return revocation_status_codes + return revocation_status_code diff --git a/konova/sub_settings/sso_settings.py b/konova/sub_settings/sso_settings.py index 7ff66777..2a50e60c 100644 --- a/konova/sub_settings/sso_settings.py +++ b/konova/sub_settings/sso_settings.py @@ -16,3 +16,5 @@ OAUTH_CODE_VERIFIER = env("OAUTH_CODE_VERIFIER") OAUTH_CLIENT_ID = env("OAUTH_CLIENT_ID") OAUTH_CLIENT_SECRET = env("OAUTH_CLIENT_SECRET") + +PROPAGATION_SECRET = env("PROPAGATION_SECRET") diff --git a/konova/views/oauth.py b/konova/views/oauth.py index 5748d482..8649e164 100644 --- a/konova/views/oauth.py +++ b/konova/views/oauth.py @@ -115,10 +115,10 @@ class OAuthCallbackView(View): if status_code_invalid: raise RuntimeError(f"OAuth access token could not be fetched: {access_code_response.text}") - oauth_access_token = OAuthToken.from_access_token_response(access_code_response_body, received_on) - oauth_access_token.save() - user = oauth_access_token.update_and_get_user() - user.oauth_replace_token(oauth_access_token) + oauth_token = OAuthToken.from_access_token_response(access_code_response_body, received_on) + oauth_token.save() + user = oauth_token.update_and_get_user() + user.oauth_replace_token(oauth_token) login(request, user) return redirect("home") diff --git a/user/views/propagate.py b/user/views/propagate.py index e6a0e5c9..3afb6fcf 100644 --- a/user/views/propagate.py +++ b/user/views/propagate.py @@ -16,7 +16,7 @@ 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 konova.sub_settings.sso_settings import PROPAGATION_SECRET from user.models import User @@ -36,7 +36,7 @@ class PropagateUserView(View): # Decrypt encrypted_body = request.body _hash = hashlib.md5() - _hash.update(OAUTH_CLIENT_ID.encode("utf-8")) + _hash.update(PROPAGATION_SECRET.encode("utf-8")) key = base64.urlsafe_b64encode(_hash.hexdigest().encode("utf-8")) fernet = Fernet(key) body = fernet.decrypt(encrypted_body).decode("utf-8")