Skip to content
Snippets Groups Projects
Select Git revision
  • 3e4ebb72bded8f48b888b5952a5661662b59bbb4
  • master default
  • renovate/django-split-settings-1.x
  • renovate/djangorestframework-3.x
  • main
  • 520-improve-trackmanager
  • 520-fix-scheduling
  • 520-akowner
  • 520-status
  • 520-message-resolved
  • 520-improve-scheduling-2
  • renovate/django-bootstrap5-24.x
  • 520-improve-submission
  • 520-improve-scheduling
  • 520-improve-wall
  • 520-fix-event-wizard-datepicker
  • 520-upgrades
  • renovate/tzdata-2023.x
  • renovate/django-5.x
  • renovate/fontawesomefree-6.x
  • renovate/sphinx-rtd-theme-2.x
  • renovate/sphinxcontrib-apidoc-0.x
22 results

__init__.py

Blame
  • Forked from KIF / AKPlanning
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    auth.py 4.29 KiB
    import logging
    import time
    from django.urls import reverse
    from oic import rndstr
    from oic.oic import Client
    from oic.oic.message import (
        AuthorizationResponse,
        ProviderConfigurationResponse,
        RegistrationResponse,
    )
    from oic.utils.authn.client import CLIENT_AUTHN_METHOD
    from pretix.base.auth import BaseAuthBackend
    from pretix.settings import config
    
    logger = logging.getLogger(__name__)
    
    
    class OIDCAuthBackend(BaseAuthBackend):
        def __init__(self):
            try:
                self.title = config.get(
                    "oidc", "title", fallback="Login with OpenID connect"
                )
    
                op_info = ProviderConfigurationResponse(
                    version="1.0",
                    issuer=config.get("oidc", "issuer"),
                    authorization_endpoint=config.get("oidc", "authorization_endpoint"),
                    token_endpoint=config.get("oidc", "token_endpoint"),
                    userinfo_endpoint=config.get("oidc", "userinfo_endpoint"),
                    end_session_endpoint=config.get("oidc", "end_session_endpoint"),
                    jwks_uri=config.get("oidc", "jwks_uri"),
                )
    
                client_reg = RegistrationResponse(
                    client_id=config.get("oidc", "client_id"),
                    client_secret=config.get("oidc", "client_secret"),
                )
    
                self.client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
                self.client.handle_provider_config(op_info, op_info["issuer"])
                self.client.store_registration_info(client_reg)
                self.client.redirect_uris = [None]
    
                self.scopes = config.get("oidc", "scopes", fallback="openid").split(",")
            except KeyError:
                logger.error(
                    "Please specify issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, end_session_endpoint, jwks_uri, client_id and client_secret "
                    "in [oidc] section in pretix.cfg"
                )
    
        @property
        def identifier(self):
            return "pretix_oidc"
    
        @property
        def verbose_name(self):
            return self.title
    
        def authentication_url(self, request):
            oidc_state = rndstr()
            request.session["oidc_state"] = {
                oidc_state: {
                    "next": request.GET.get("next", None),
                    "generated_on": int(time.time()),
                }
            }
    
            auth_req = self.client.construct_AuthorizationRequest(
                request_args={
                    "client_id": self.client.client_id,
                    "response_type": "code",
                    "scope": self.scopes,
                    "redirect_uri": self.redirect_uri(request),
                    "state": oidc_state,
                }
            )
    
            return auth_req.request(self.client.authorization_endpoint)
    
        def redirect_uri(self, request):
            return request.build_absolute_uri(reverse("plugins:pretix_oidc:oidc_callback"))
    
        def get_next_url(self, request):
            return request.session.pop("oidc_next_url", None)
    
        def process_callback(self, request):
            auth_response = self.client.parse_response(
                AuthorizationResponse,
                info=request.META["QUERY_STRING"],
                sformat="urlencoded",
            )
    
            request.session["oidc_next_url"] = None
            oidc_state = request.session.pop("oidc_state", None)
            response_state = auth_response.get("state", None)
    
            if not oidc_state or not response_state:
                return [None, None]
    
            if response_state not in oidc_state:
                return [None, None]
    
            if oidc_state[response_state]["generated_on"] < time.time() - 5 * 60:
                return [None, None]
    
            request.session["oidc_next_url"] = oidc_state[response_state]["next"]
    
            access_token_response = self.client.do_access_token_request(
                state=auth_response["state"],
                scope=self.scopes,
                request_args={
                    "code": auth_response["code"],
                    "redirect_uri": self.redirect_uri(request),
                },
                authn_method="client_secret_basic",
            )
    
            id_token = access_token_response["id_token"]
            user_data = {
                "uuid": id_token[config.get("oidc", "unique_attribute", fallback="sub")],
                "email": id_token["email"],
                "fullname": id_token["name"],
                "auth_backend": self.identifier,
            }
    
            return [user_data, id_token]