Skip to content
Snippets Groups Projects
Commit 40cb62a9 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Merge branch '553-oauth-allow-apps-to-generate-claims-for-their-own-scopes' into 'master'

Resolve "[OAuth] Allow apps to generate claims for their own scopes"

Closes #553

See merge request !799
parents cfdaf432 6670cb81
No related branches found
No related tags found
1 merge request!799Resolve "[OAuth] Allow apps to generate claims for their own scopes"
Pipeline #43251 passed with warnings
Pipeline: AlekSIS

#43256

    ......@@ -9,6 +9,11 @@ and this project adheres to `Semantic Versioning`_.
    Unreleased
    ----------
    Added
    ~~~~~
    * [OAuth] Allow apps to fill in their own claim data matching their scopes
    `2.2.1_ – 2021-12-02
    --------------------
    ......
    ......@@ -9,6 +9,7 @@ from django.utils.translation import gettext as _
    from dynamic_preferences.registries import preference_models
    from health_check.plugins import plugin_dir
    from oauthlib.common import Request as OauthlibRequest
    from .registries import (
    group_preferences_registry,
    ......@@ -156,3 +157,49 @@ class CoreConfig(AppConfig):
    "groups": _("Groups"),
    }
    return scopes
    @classmethod
    def get_additional_claims(cls, scopes: list[str], request: OauthlibRequest) -> dict[str, Any]:
    django_request = HttpRequest()
    django_request.META = request.headers
    claims = {
    "preferred_username": request.user.username,
    }
    if "profile" in scopes:
    if has_person(request.user):
    claims["given_name"] = request.user.person.first_name
    claims["family_name"] = request.user.person.last_name
    claims["profile"] = django_request.build_absolute_uri(
    request.user.person.get_absolute_url()
    )
    if request.user.person.photo:
    claims["picture"] = django_request.build_absolute_uri(
    request.user.person.photo.url
    )
    else:
    claims["given_name"] = request.user.first_name
    claims["family_name"] = request.user.last_name
    if "email" in scopes:
    if has_person(request.user):
    claims["email"] = request.user.person.email
    else:
    claims["email"] = request.user.email
    if "address" in scopes and has_person(request.user):
    claims["address"] = {
    "street_address": request.user.person.street
    + " "
    + request.user.person.housenumber,
    "locality": request.user.person.place,
    "postal_code": request.user.person.postal_code,
    }
    if "groups" in scopes and has_person(request.user):
    claims["groups"] = list(
    request.user.person.member_of.values_list("name", flat=True).all()
    )
    return claims
    ......@@ -8,6 +8,7 @@ from django.http import HttpRequest
    from dynamic_preferences.signals import preference_updated
    from license_expression import Licensing
    from oauthlib.common import Request as OauthlibRequest
    from spdx_license_list import LICENSES
    from .core_helpers import copyright_years
    ......@@ -244,6 +245,11 @@ class AppConfig(django.apps.AppConfig):
    """Return a list of all OAuth scopes to always include for this request and application."""
    return []
    @classmethod
    def get_additional_claims(cls, scopes: list[str], request: OauthlibRequest) -> dict[str, Any]:
    """Get claim data for requested scopes."""
    return {}
    def _maintain_default_data(self):
    from django.contrib.auth.models import Permission
    from django.contrib.contenttypes.models import ContentType
    ......
    """Helpers/overrides for django-allauth."""
    from typing import Optional
    from typing import Any, Optional
    from django.conf import settings
    from django.http import HttpRequest
    ......@@ -16,7 +16,6 @@ from oauth2_provider.views.mixins import (
    from oauthlib.common import Request as OauthlibRequest
    from .apps import AppConfig
    from .core_helpers import get_site_preferences, has_person
    class OurSocialAccountAdapter(DefaultSocialAccountAdapter):
    ......@@ -43,52 +42,16 @@ class OurAccountAdapter(DefaultAccountAdapter):
    class CustomOAuth2Validator(OAuth2Validator):
    def get_additional_claims(self, request):
    django_request = HttpRequest()
    django_request.META = request.headers
    def get_additional_claims(self, request: OauthlibRequest) -> dict[str, Any]:
    # Pull together scopes from request and from access token
    scopes = request.scopes.copy()
    if request.access_token:
    scopes += request.access_token.scope.split(" ")
    claims = {
    "preferred_username": request.user.username,
    }
    if "profile" in scopes:
    if has_person(request.user):
    claims["given_name"] = request.user.person.first_name
    claims["family_name"] = request.user.person.last_name
    claims["profile"] = django_request.build_absolute_uri(
    request.user.person.get_absolute_url()
    )
    if request.user.person.photo:
    claims["picture"] = django_request.build_absolute_uri(
    request.user.person.photo.url
    )
    else:
    claims["given_name"] = request.user.first_name
    claims["family_name"] = request.user.last_name
    if "email" in scopes:
    if has_person(request.user):
    claims["email"] = request.user.person.email
    else:
    claims["email"] = request.user.email
    if "address" in scopes and has_person(request.user):
    claims["address"] = {
    "street_address": request.user.person.street
    + " "
    + request.user.person.housenumber,
    "locality": request.user.person.place,
    "postal_code": request.user.person.postal_code,
    }
    if "groups" in scopes and has_person(request.user):
    claims["groups"] = list(
    request.user.person.member_of.values_list("name", flat=True).all()
    )
    claims = {}
    # Pull together claim data from all apps
    for app in AppConfig.__subclasses__():
    claims.update(app.get_additional_claims(scopes, request))
    return claims
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment