# SPDX-License-Identifier: AGPL-3.0-or-later """Views for the Apache app.""" from urllib.parse import urlencode, urlparse from django.http import (HttpResponseBadRequest, HttpResponseRedirect, HttpResponseServerError) from django.views import View from . import setup_oidc_client, validate_host # By default 'openid' scope already included by mod_auth_openidc OIDC_SCOPES = 'email freedombox_groups' class DiscoverIDPView(View): """A view called by auth_openidc Apache module to find the IDP. According to documentation for auth_openidc: an Issuer selection can be passed back to the callback URL as in: ?iss=[${issuer}|${domain}|${e-mail-style-account-name}] [parameters][&login_hint=][&scopes=] [&auth_request_params=] where the parameter contains the URL-encoded issuer value of the selected Provider (or...), [parameters] contains the additional parameters that were passed in on the discovery request (e.g. target_link_uri=&x_csrf=&method=&scopes=) """ def get(self, request): """Redirect back to auth_openidc module after selecting a IDP.""" target_link_uri = request.GET.get('target_link_uri', '') method = request.GET.get('method', 'get') x_csrf = request.GET.get('x_csrf', '') oidc_callback = request.GET.get('oidc_callback') if method != 'get': return HttpResponseBadRequest(f'Cannot handle "{method}" method') oidc_callback_parts = urlparse(oidc_callback) request_host = request.META['HTTP_HOST'] if request_host != oidc_callback_parts.netloc: return HttpResponseBadRequest( f'Cannot redirect from {request_host} to a different host ' f'{oidc_callback_parts.netloc}') try: validate_host(oidc_callback_parts.hostname) except ValueError: return HttpResponseBadRequest( f'Accessed using unknown domain {request_host}. Please add ' 'the domain to list of configured domains.') try: setup_oidc_client(oidc_callback_parts.netloc, oidc_callback_parts.hostname) except ValueError: return HttpResponseServerError( f'Server not configured to called as {request_host}') url = '/apache/oidc/callback' params = { 'iss': f'https://{request_host}/freedombox/o', 'target_link_uri': target_link_uri, 'method': method, 'x_csrf': x_csrf, 'scopes': OIDC_SCOPES, } params = urlencode(params) return HttpResponseRedirect(f'{url}?{params}')