1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-21 09:58:23 +02:00

Merge branch 'optional-scopes' into 'beta'

Implement optional scopes : clients can request scopes, but they are not guaranteed to get them

See merge request bde/nk20!192
This commit is contained in:
2022-02-12 13:57:19 +01:00
4 changed files with 78 additions and 4 deletions

View File

@ -7,8 +7,11 @@ from django.contrib.auth.models import User
from django.utils import timezone
from rest_framework import serializers
from member.api.serializers import ProfileSerializer, MembershipSerializer
from member.models import Membership
from note.api.serializers import NoteSerializer
from note.models import Alias
from note_kfet.middlewares import get_current_request
from permission.backends import PermissionBackend
class UserSerializer(serializers.ModelSerializer):
@ -45,18 +48,30 @@ class OAuthSerializer(serializers.ModelSerializer):
"""
normalized_name = serializers.SerializerMethodField()
profile = ProfileSerializer()
profile = serializers.SerializerMethodField()
note = NoteSerializer()
note = serializers.SerializerMethodField()
memberships = serializers.SerializerMethodField()
def get_normalized_name(self, obj):
return Alias.normalize(obj.username)
def get_profile(self, obj):
# Display the profile of the user only if we have rights to see it.
return ProfileSerializer().to_representation(obj.profile) \
if PermissionBackend.has_perm(get_current_request(), obj.profile, 'view') else None
def get_note(self, obj):
# Display the note of the user only if we have rights to see it.
return NoteSerializer().to_representation(obj.note) \
if PermissionBackend.has_perm(get_current_request(), obj.note, 'view') else None
def get_memberships(self, obj):
# Display only memberships that we are allowed to see.
return serializers.ListSerializer(child=MembershipSerializer()).to_representation(
obj.memberships.filter(date_start__lte=timezone.now(), date_end__gte=timezone.now()))
obj.memberships.filter(date_start__lte=timezone.now(), date_end__gte=timezone.now())
.filter(PermissionBackend.filter_queryset(get_current_request(), Membership, 'view')))
class Meta:
model = User

View File

@ -1,6 +1,6 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from oauth2_provider.oauth2_validators import OAuth2Validator
from oauth2_provider.scopes import BaseScopes
from member.models import Club
from note_kfet.middlewares import get_current_request
@ -32,3 +32,26 @@ class PermissionScopes(BaseScopes):
return []
return [f"{p.id}_{p.membership.club.id}"
for p in PermissionBackend.get_raw_permissions(get_current_request(), 'view')]
class PermissionOAuth2Validator(OAuth2Validator):
def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs):
"""
User can request as many scope as he wants, including invalid scopes,
but it will have only the permissions he has.
This allows clients to request more permission to get finally a
subset of permissions.
"""
valid_scopes = set()
for t in Permission.PERMISSION_TYPES:
for p in PermissionBackend.get_raw_permissions(get_current_request(), t[0]):
scope = f"{p.id}_{p.membership.club.id}"
if scope in scopes:
valid_scopes.add(scope)
request.scopes = valid_scopes
return valid_scopes