diff --git a/README.md b/README.md index 26ced30c..98fe3713 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # NoteKfet 2020 [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.txt) -[![pipeline status](https://gitlab.crans.org/bde/nk20/badges/master/pipeline.svg)](https://gitlab.crans.org/bde/nk20/commits/master) -[![coverage report](https://gitlab.crans.org/bde/nk20/badges/master/coverage.svg)](https://gitlab.crans.org/bde/nk20/commits/master) +[![pipeline status](https://gitlab.crans.org/bde/nk20/badges/main/pipeline.svg)](https://gitlab.crans.org/bde/nk20/commits/main) +[![coverage report](https://gitlab.crans.org/bde/nk20/badges/main/coverage.svg)](https://gitlab.crans.org/bde/nk20/commits/main) ## Table des matières diff --git a/ansible/base.yml b/ansible/base.yml index 83b20cbb..05e63b1c 100755 --- a/ansible/base.yml +++ b/ansible/base.yml @@ -7,7 +7,7 @@ prompt: "Password of the database (leave it blank to skip database init)" private: yes vars: - mirror: mirror.crans.org + mirror: eclats.crans.org roles: - 1-apt-basic - 2-nk20 diff --git a/ansible/host_vars/bde-note.adh.crans.org.yml b/ansible/host_vars/bde-note.adh.crans.org.yml index 9c8ec1ed..6b97e084 100644 --- a/ansible/host_vars/bde-note.adh.crans.org.yml +++ b/ansible/host_vars/bde-note.adh.crans.org.yml @@ -1,7 +1,7 @@ --- note: server_name: note.crans.org - git_branch: master + git_branch: main serve_static: true cron_enabled: true email: notekfet2020@lists.crans.org diff --git a/ansible/roles/1-apt-basic/tasks/main.yml b/ansible/roles/1-apt-basic/tasks/main.yml index 7c57646f..bbef195a 100644 --- a/ansible/roles/1-apt-basic/tasks/main.yml +++ b/ansible/roles/1-apt-basic/tasks/main.yml @@ -1,14 +1,15 @@ --- -- name: Add buster-backports to apt sources +- name: Add buster-backports to apt sources if needed apt_repository: repo: deb http://{{ mirror }}/debian buster-backports main state: present - when: ansible_facts['distribution'] == "Debian" + when: + - ansible_distribution == "Debian" + - ansible_distribution_major_version | int == 10 - name: Install note_kfet APT dependencies apt: update_cache: true - default_release: "{{ 'buster-backports' if ansible_facts['distribution'] == 'Debian' }}" install_recommends: false name: # Common tools diff --git a/apps/api/serializers.py b/apps/api/serializers.py index f91132d5..d6403dd1 100644 --- a/apps/api/serializers.py +++ b/apps/api/serializers.py @@ -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 diff --git a/apps/member/models.py b/apps/member/models.py index 9cb0cbde..89be7a3a 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -264,10 +264,12 @@ class Club(models.Model): today = datetime.date.today() if (today - self.membership_start).days >= 365: - self.membership_start = datetime.date(self.membership_start.year + 1, - self.membership_start.month, self.membership_start.day) - self.membership_end = datetime.date(self.membership_end.year + 1, - self.membership_end.month, self.membership_end.day) + if self.membership_start: + self.membership_start = datetime.date(self.membership_start.year + 1, + self.membership_start.month, self.membership_start.day) + if self.membership_end: + self.membership_end = datetime.date(self.membership_end.year + 1, + self.membership_end.month, self.membership_end.day) self._force_save = True self.save(force_update=True) diff --git a/apps/permission/scopes.py b/apps/permission/scopes.py index bf74cb81..65242804 100644 --- a/apps/permission/scopes.py +++ b/apps/permission/scopes.py @@ -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 diff --git a/apps/permission/templates/permission/scopes.html b/apps/permission/templates/permission/scopes.html index 31a4395e..bebc0898 100644 --- a/apps/permission/templates/permission/scopes.html +++ b/apps/permission/templates/permission/scopes.html @@ -11,25 +11,25 @@
+
{{ request.scheme }}://{{ request.get_host }}{% url 'oauth2_provider:authorize' %}?client_id={{ app.client_id }}&response_type=code @@ -51,11 +51,10 @@ {% block extrajavascript %}