diff --git a/ansible_base/django_template/views/api/v1/local_login.py b/ansible_base/django_template/views/api/v1/local_login.py index 179e8780f..211e86e04 100644 --- a/ansible_base/django_template/views/api/v1/local_login.py +++ b/ansible_base/django_template/views/api/v1/local_login.py @@ -4,6 +4,7 @@ from django.contrib.auth import views from django.core.exceptions import PermissionDenied +from django.shortcuts import redirect from django.utils.decorators import method_decorator from django.views.decorators.http import require_http_methods from rest_framework import status @@ -13,7 +14,7 @@ from rest_framework.response import Response #from social_core.exceptions import AuthException TODO This does not work -from ansible_base.lib.utils.requests import get_remote_host +from ansible_base.lib.utils.requests import get_remote_host, is_proxied_request from ansible_base.lib.utils.settings import get_setting logger = logging.getLogger('ansible_base.django_template.views.local_login') @@ -21,6 +22,12 @@ class LoggedLoginView(views.LoginView): def get(self, request, *args, **kwargs): + if is_proxied_request() and get_setting('LOGIN_LOGOUT_FORWARDING', False): + next = request.GET.get('next', "") + if next: + next = f"?next={next}" + return redirect(f"/{next}") + # The django.auth.contrib login form doesn't perform the content # negotiation we've come to expect from DRF; add in code to catch # situations where Accept != text/html (or */*) and reply with @@ -37,6 +44,14 @@ def get(self, request, *args, **kwargs): return super(LoggedLoginView, self).get(request, *args, **kwargs) def post(self, request, *args, **kwargs): + if is_proxied_request() and get_setting('LOGIN_LOGOUT_FORWARDING', False): + # Give a message, saying to login via AAP + return Response( + { + 'detail': _('Please log in via Platform Authentication.'), + }, + status=status.HTTP_401_UNAUTHORIZED, + ) try: ret = super(LoggedLoginView, self).post(request, *args, **kwargs) except ValueError as e: # TODO What exception should be caught? Common denominator between social auth and django auth? @@ -67,6 +82,11 @@ class LoggedLogoutView(views.LogoutView): success_url_allowed_hosts = get_setting('LOGOUT_ALLOWED_HOSTS', []) def dispatch(self, request, *args, **kwargs): + if is_proxied_request and get_setting('LOGIN_LOGOUT_FORWARDING', False): + # 1) We intentionally don't obey ?next= here, just always redirect to platform login + # 2) Hack to prevent rewrites of Location header + qs = "?__gateway_no_rewrite__=1&next=/" + return redirect(f"/api/gateway/v1/logout/{qs}") original_user = getattr(request, 'user', None) ret = super().dispatch(request, *args, **kwargs) current_user = getattr(request, 'user', None) diff --git a/ansible_base/lib/dynamic_config/settings_logic.py b/ansible_base/lib/dynamic_config/settings_logic.py index fd2b2f265..67d1d6dc7 100644 --- a/ansible_base/lib/dynamic_config/settings_logic.py +++ b/ansible_base/lib/dynamic_config/settings_logic.py @@ -235,6 +235,9 @@ def get_dab_settings( # Disable legacy SSO by default dab_data['ENABLE_SERVICE_BACKED_SSO'] = False + # Enable login/logout forwarding by default + dab_data['LOGIN_LOGOUT_FORWARDING'] = True + if 'ansible_base.oauth2_provider' in installed_apps: if 'oauth2_provider' not in installed_apps: dab_data.setdefault('INSTALLED_APPS', copy(installed_apps))