This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/passbook/channels/out_oidc/auth.py

65 lines
2.3 KiB
Python
Raw Normal View History

"""OIDC Permission checking"""
from typing import Optional
from django.contrib import messages
from django.db.models.deletion import Collector
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect
from oidc_provider.models import Client
2019-10-01 08:24:10 +00:00
from structlog import get_logger
from passbook.audit.models import Event, EventAction
from passbook.core.models import Application, Outlet, User
2019-10-07 14:33:48 +00:00
from passbook.policies.engine import PolicyEngine
LOGGER = get_logger()
def client_related_provider(client: Client) -> Optional[Outlet]:
"""Lookup related Application from Client"""
# because oidc_provider is also used by app_gw, we can't be
# sure an OpenIDPRovider instance exists. hence we look through all related models
# and choose the one that inherits from Outlet, which is guaranteed to
# have the application property
collector = Collector(using="default")
collector.collect([client])
for _, related in collector.data.items():
related_object = next(iter(related))
if isinstance(related_object, Outlet):
return related_object
return None
def check_permissions(
request: HttpRequest, user: User, client: Client
) -> Optional[HttpResponse]:
"""Check permissions, used for
https://django-oidc-provider.readthedocs.io/en/latest/
sections/settings.html#oidc-after-userlogin-hook"""
provider = client_related_provider(client)
if not provider:
return redirect("passbook_channels_out_oauth:oauth2-permission-denied")
try:
application = provider.application
except Application.DoesNotExist:
return redirect("passbook_channels_out_oauth:oauth2-permission-denied")
2019-12-31 11:51:16 +00:00
LOGGER.debug(
"Checking permissions for application", user=user, application=application
)
policy_engine = PolicyEngine(application.policies.all(), user, request)
policy_engine.build()
# Check permissions
passing, policy_messages = policy_engine.result
if not passing:
for policy_message in policy_messages:
messages.error(request, policy_message)
return redirect("passbook_channels_out_oauth:oauth2-permission-denied")
2019-12-31 11:51:16 +00:00
Event.new(
EventAction.AUTHORIZE_APPLICATION,
authorized_application=application,
2019-12-31 11:51:16 +00:00
skipped_authorization=False,
).from_http(request)
return None