import json from django.conf import settings from django.contrib.auth.views import redirect_to_login from django.http import HttpResponseNotFound from django.shortcuts import resolve_url from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from oauth2_provider import views as oauth_views class OidcProviderEnabledMixin: def dispatch(self, request, *args, **kwargs): if not settings.OIDC_PROVIDER_ENABLED: return HttpResponseNotFound() return super().dispatch(request, *args, **kwargs) class CorporateConnectDiscoveryView(oauth_views.ConnectDiscoveryInfoView): def get(self, request, *args, **kwargs): response = super().get(request, *args, **kwargs) if response.status_code == 200 and settings.OIDC_BACKCHANNEL_LOGOUT_ENABLED: data = json.loads(response.content) data["backchannel_logout_supported"] = True # Subject-wide logout is supported; per-device sid tracking is not. data["backchannel_logout_session_supported"] = False response.content = json.dumps(data).encode("utf-8") return response class CorporateAuthorizationView( OidcProviderEnabledMixin, oauth_views.AuthorizationView, ): """Send unauthenticated authorization requests through the portal login.""" def get_login_url(self): return settings.OIDC_PORTAL_LOGIN_URL def handle_no_permission(self): # Keep the return target relative. This remains safe behind a reverse proxy # even if Django receives an internal host name and the SPA is public. return redirect_to_login( self.request.get_full_path(), resolve_url(self.get_login_url()), self.get_redirect_field_name(), ) def handle_prompt_login(self): query = self.request.GET.copy() query.pop("prompt", None) return_path = self.request.path if query: return_path = f"{return_path}?{query.urlencode()}" return redirect_to_login( return_path, resolve_url(self.get_login_url()), self.get_redirect_field_name(), ) @method_decorator(csrf_exempt, name="dispatch") class CorporateTokenView(OidcProviderEnabledMixin, oauth_views.TokenView): pass @method_decorator(csrf_exempt, name="dispatch") class CorporateRevokeTokenView( OidcProviderEnabledMixin, oauth_views.RevokeTokenView, ): pass @method_decorator(csrf_exempt, name="dispatch") class CorporateIntrospectTokenView( OidcProviderEnabledMixin, oauth_views.IntrospectTokenView, ): pass