diff --git a/services/webapp/code/rosetta/auth.py b/services/webapp/code/rosetta/auth.py index 207ce59c4cf226089700fc753ca67c7aabdff55e..92c25a29b0df5acea050c81f3349ad4eef3ff1d5 100644 --- a/services/webapp/code/rosetta/auth.py +++ b/services/webapp/code/rosetta/auth.py @@ -1,5 +1,7 @@ from mozilla_django_oidc.auth import OIDCAuthenticationBackend +from mozilla_django_oidc.views import OIDCAuthenticationCallbackView from .core_app.utils import finalize_user_creation +from django.http import HttpResponseRedirect # Setup logging import logging @@ -18,9 +20,27 @@ class RosettaOIDCAuthenticationBackend(OIDCAuthenticationBackend): return user - def get_userinfo(self, access_token, id_token, payload): # Payload must contain the "email" key return payload + +class RosettaOIDCAuthenticationCallbackView(OIDCAuthenticationCallbackView): + + def login_success(self): + + # Call parent login_success but do not return + super(RosettaOIDCAuthenticationCallbackView, self).login_success() + + logger.debug('Trying to get cookie-based post login redirect') + post_login_page = self.request.COOKIES.get('post_login_redirect') + if post_login_page: + logger.debug('Got "%s" and redirecting', post_login_page ) + response = HttpResponseRedirect(post_login_page) + response.delete_cookie('post_login_redirect') + return response + else: + logger.debug('No cookie-based post login redirect found, redirecting to "%s"', self.success_url) + return HttpResponseRedirect(self.success_url) + diff --git a/services/webapp/code/rosetta/core_app/decorators.py b/services/webapp/code/rosetta/core_app/decorators.py index dca065534c42d08f8ff82cbdf8a6c39e5e4b6e86..d6e13e0959de0d25dcd37a2047675fc1928a268d 100644 --- a/services/webapp/code/rosetta/core_app/decorators.py +++ b/services/webapp/code/rosetta/core_app/decorators.py @@ -132,5 +132,8 @@ def private_view(wrapped_view): else: log_user_activity("DEBUG", "Redirecting to login since not authenticated", request) - return HttpResponseRedirect('/login') + logger.debug('Setting cookie-based post login redirect to "%s"', request.build_absolute_uri()) + response = HttpResponseRedirect('/login') + response.set_cookie('post_login_redirect', request.build_absolute_uri()) + return response return private_view_wrapper diff --git a/services/webapp/code/rosetta/core_app/views.py b/services/webapp/code/rosetta/core_app/views.py index 08e4a164a07211fbf096af6c3cde96d70f943635..2082ee51a62a528cf5fa03acdc0d1a8ccc93bacc 100644 --- a/services/webapp/code/rosetta/core_app/views.py +++ b/services/webapp/code/rosetta/core_app/views.py @@ -35,10 +35,17 @@ _task_cache = {} def login_view(request): data = {} + + # Set post login page + post_login_page = request.COOKIES.get('post_login_redirect') + if post_login_page is None: + post_login_page = '/main' # If authenticated user reloads the main URL if request.method == 'GET' and request.user.is_authenticated: - return HttpResponseRedirect('/main/') + response = HttpResponseRedirect(post_login_page) + response.delete_cookie('post_login_redirect') + return response else: # If local auth disabled, just render login page # (will be rendered an open id connect url only) @@ -73,7 +80,9 @@ def login_view(request): user = authenticate(username=username, password=password) if user: login(request, user) - return HttpResponseRedirect('/main') + response = HttpResponseRedirect(post_login_page) + response.delete_cookie('post_login_redirect') + return response else: raise ErrorMessage('Check email and password') else: @@ -138,8 +147,9 @@ def login_view(request): loginToken.delete() # Now redirect to site - return HttpResponseRedirect('/main/') - + response = HttpResponseRedirect(post_login_page) + response.delete_cookie('post_login_redirect') + return response # All other cases, render the login page again with no other data than title return render(request, 'login.html', {'data': data}) diff --git a/services/webapp/code/rosetta/settings.py b/services/webapp/code/rosetta/settings.py index 63a0410711cb6f04502aab9a885ea13a53ddfc6e..9f854acf62f1cba237472ebfd4c738bce871e29c 100644 --- a/services/webapp/code/rosetta/settings.py +++ b/services/webapp/code/rosetta/settings.py @@ -264,6 +264,9 @@ if OIDC_RP_CLIENT_ID: # Optional OIDC_USE_NONCE = booleanize(os.environ.get('OIDC_USE_NONCE', False)) OIDC_TOKEN_USE_BASIC_AUTH = booleanize(os.environ.get('OIDC_TOKEN_USE_BASIC_AUTH', False)) + + # Custom callback to enable session-based post-login redirects + OIDC_CALLBACK_CLASS = 'rosetta.auth.RosettaOIDCAuthenticationCallbackView' # Non-customizable stuff LOGIN_REDIRECT_URL = '/' @@ -274,6 +277,8 @@ if OIDC_RP_CLIENT_ID: # Required for the Open ID connect redirects to work properly USE_X_FORWARDED_HOST = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') + +