mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-03-18 09:10:49 +00:00
- Django's request.get_host() use X_FORWARDED_HOST when appropriate and falls back to HTTP_HOST. In case of FreedomBox due to 'ProxyPreserveHost On' in Apache configuration, both the values are the same. So, it makes no difference. - Also document the need for 'ProxyPreserveHost On' in another validation. Tests: - Log the value of request_host, request.META['HTTP_HOST'], and request.META['X_FORWARDED_HOST'] in DiscoverIDPView:get(). All the values are same when accessing with IP address value not starting with 127.0.0.1. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
72 lines
2.7 KiB
Python
72 lines
2.7 KiB
Python
# 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:
|
|
<callback-url>?iss=[${issuer}|${domain}|${e-mail-style-account-name}]
|
|
[parameters][&login_hint=<login-hint>][&scopes=<scopes>]
|
|
[&auth_request_params=<params>]
|
|
|
|
where the <iss> 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=<url>&x_csrf=<x_csrf>&method=<method>&scopes=<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.get_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}')
|