mirror of https://gitlab.crans.org/bde/nk20
Check that permissions are working when accessing to API pages
Signed-off-by: Yohann D'ANELLO <yohann.danello@gmail.com>
This commit is contained in:
parent
5cb4183e9f
commit
f570ff3cd5
|
@ -210,9 +210,24 @@ class TestActivityAPI(TestAPI):
|
|||
|
||||
def test_activity_api(self):
|
||||
"""
|
||||
Load API pages for the activity app and test all filters
|
||||
Load Activity API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(ActivityViewSet, "/api/activity/activity/")
|
||||
|
||||
def test_activity_type_api(self):
|
||||
"""
|
||||
Load ActivityType API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(ActivityTypeViewSet, "/api/activity/type/")
|
||||
|
||||
def test_entry_api(self):
|
||||
"""
|
||||
Load Entry API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(EntryViewSet, "/api/activity/entry/")
|
||||
|
||||
def test_guest_api(self):
|
||||
"""
|
||||
Load Guest API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(GuestViewSet, "/api/activity/guest/")
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from datetime import datetime, date
|
||||
from urllib.parse import quote_plus
|
||||
from warnings import warn
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models.fields.files import ImageFieldFile
|
||||
from django.test import TestCase
|
||||
from django_filters.rest_framework import DjangoFilterBackend, OrderingFilter
|
||||
from member.models import Membership, Club
|
||||
from note.models import NoteClub, NoteUser, Alias, Note
|
||||
from permission.models import PermissionMask, Permission, Role
|
||||
from phonenumbers import PhoneNumber
|
||||
from rest_framework.filters import SearchFilter
|
||||
|
||||
|
@ -103,6 +107,77 @@ class TestAPI(TestCase):
|
|||
f"{model._meta.verbose_name} does not work. "
|
||||
f"Given parameter: {value}")
|
||||
|
||||
self.check_permissions(url, obj)
|
||||
|
||||
def check_permissions(self, url, obj):
|
||||
"""
|
||||
Check that permissions are working
|
||||
"""
|
||||
# Drop rights
|
||||
self.user.is_superuser = False
|
||||
self.user.save()
|
||||
sess = self.client.session
|
||||
sess["permission_mask"] = 0
|
||||
sess.save()
|
||||
|
||||
# Delete user permissions
|
||||
for m in Membership.objects.filter(user=self.user).all():
|
||||
m.roles.clear()
|
||||
m.save()
|
||||
|
||||
# Create a new role, which will have the checking permission
|
||||
role = Role.objects.get_or_create(name="β-tester")[0]
|
||||
role.permissions.clear()
|
||||
role.save()
|
||||
membership = Membership.objects.get_or_create(user=self.user, club=Club.objects.get(name="BDE"))[0]
|
||||
membership.roles.set([role])
|
||||
membership.save()
|
||||
|
||||
# Ensure that the access to the object is forbidden without permission
|
||||
resp = self.client.get(url + f"{obj.pk}/")
|
||||
self.assertEqual(resp.status_code, 404, f"Mysterious access to {url}{obj.pk}/ for {obj}")
|
||||
|
||||
obj.refresh_from_db()
|
||||
|
||||
# There are problems with polymorphism
|
||||
if isinstance(obj, Note) and hasattr(obj, "note_ptr"):
|
||||
obj = obj.note_ptr
|
||||
|
||||
mask = PermissionMask.objects.get(rank=0)
|
||||
|
||||
for field in obj._meta.fields:
|
||||
# Build permission query
|
||||
value = self.get_value(obj, field.name)
|
||||
if isinstance(value, date) or isinstance(value, datetime):
|
||||
value = value.isoformat()
|
||||
elif isinstance(value, ImageFieldFile):
|
||||
value = value.name
|
||||
query = json.dumps({field.name: value})
|
||||
|
||||
# Create sample permission
|
||||
permission = Permission.objects.get_or_create(
|
||||
model=ContentType.objects.get_for_model(obj._meta.model),
|
||||
query=query,
|
||||
mask=mask,
|
||||
type="view",
|
||||
permanent=False,
|
||||
description=f"Can view {obj._meta.verbose_name}",
|
||||
)[0]
|
||||
role.permissions.set([permission])
|
||||
role.save()
|
||||
|
||||
# Check that the access is possible
|
||||
resp = self.client.get(url + f"{obj.pk}/")
|
||||
self.assertEqual(resp.status_code, 200, f"Permission {permission.query} is not working "
|
||||
f"for the model {obj._meta.verbose_name}")
|
||||
|
||||
# Restore rights
|
||||
self.user.is_superuser = True
|
||||
self.user.save()
|
||||
sess = self.client.session
|
||||
sess["permission_mask"] = 42
|
||||
sess.save()
|
||||
|
||||
@staticmethod
|
||||
def get_value(obj, key: str):
|
||||
"""
|
||||
|
|
|
@ -432,10 +432,20 @@ class TestMemberAPI(TestAPI):
|
|||
self.membership.roles.add(Role.objects.get(name="Bureau de club"))
|
||||
self.membership.save()
|
||||
|
||||
def test_member_api(self):
|
||||
def test_club_api(self):
|
||||
"""
|
||||
Load API pages for the member app and test all filters
|
||||
Load Club API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(ClubViewSet, "/api/members/club/")
|
||||
|
||||
def test_profile_api(self):
|
||||
"""
|
||||
Load Profile API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(ProfileViewSet, "/api/members/profile/")
|
||||
|
||||
def test_membership_api(self):
|
||||
"""
|
||||
Load Membership API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(MembershipViewSet, "/api/members/membership/")
|
||||
|
|
|
@ -15,7 +15,7 @@ from permission.backends import PermissionBackend
|
|||
|
||||
from .serializers import NotePolymorphicSerializer, AliasSerializer, ConsumerSerializer,\
|
||||
TemplateCategorySerializer, TransactionTemplateSerializer, TransactionPolymorphicSerializer
|
||||
from ..models.notes import Note, Alias
|
||||
from ..models.notes import Note, Alias, NoteUser, NoteClub, NoteSpecial
|
||||
from ..models.transactions import TransactionTemplate, Transaction, TemplateCategory
|
||||
|
||||
|
||||
|
@ -40,7 +40,12 @@ class NotePolymorphicViewSet(ReadProtectedModelViewSet):
|
|||
Parse query and apply filters.
|
||||
:return: The filtered set of requested notes
|
||||
"""
|
||||
queryset = super().get_queryset().distinct()
|
||||
user = self.request.user
|
||||
get_current_session().setdefault("permission_mask", 42)
|
||||
queryset = self.queryset.filter(PermissionBackend.filter_queryset(user, Note, "view")
|
||||
| PermissionBackend.filter_queryset(user, NoteUser, "view")
|
||||
| PermissionBackend.filter_queryset(user, NoteClub, "view")
|
||||
| PermissionBackend.filter_queryset(user, NoteSpecial, "view")).distinct()
|
||||
|
||||
alias = self.request.query_params.get("alias", ".*")
|
||||
queryset = queryset.filter(
|
||||
|
|
|
@ -399,13 +399,38 @@ class TestNoteAPI(TestAPI):
|
|||
description="Test template",
|
||||
)
|
||||
|
||||
def test_note_api(self):
|
||||
def test_alias_api(self):
|
||||
"""
|
||||
Load API pages for the note app and test all filters
|
||||
Load Alias API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(AliasViewSet, "/api/note/alias/")
|
||||
|
||||
def test_consumer_api(self):
|
||||
"""
|
||||
Load Consumer API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(ConsumerViewSet, "/api/note/consumer/")
|
||||
|
||||
def test_note_api(self):
|
||||
"""
|
||||
Load Note API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(NotePolymorphicViewSet, "/api/note/note/")
|
||||
|
||||
def test_template_category_api(self):
|
||||
"""
|
||||
Load TemplateCategory API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(TemplateCategoryViewSet, "/api/note/transaction/category/")
|
||||
|
||||
def test_transaction_template_api(self):
|
||||
"""
|
||||
Load TemplateTemplate API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(TransactionTemplateViewSet, "/api/note/transaction/template/")
|
||||
|
||||
def test_transaction_api(self):
|
||||
"""
|
||||
Load Transaction API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(TransactionViewSet, "/api/note/transaction/transaction/")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import sys
|
||||
from functools import lru_cache
|
||||
from time import time
|
||||
|
||||
|
@ -38,6 +38,10 @@ def memoize(f):
|
|||
|
||||
nonlocal last_collect
|
||||
|
||||
if "test" in sys.argv:
|
||||
# In a test environment, don't memoize permissions
|
||||
return f(*args, **kwargs)
|
||||
|
||||
if time() - last_collect > 60:
|
||||
# Clear cache
|
||||
collect()
|
||||
|
|
|
@ -453,12 +453,32 @@ class TestTreasuryAPI(TestAPI):
|
|||
self.kfet_membership._soge = True
|
||||
self.kfet_membership.save()
|
||||
|
||||
def test_treasury_api(self):
|
||||
def test_invoice_api(self):
|
||||
"""
|
||||
Load API pages for the treasury app and test all filters
|
||||
Load Invoice API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(InvoiceViewSet, "/api/treasury/invoice/")
|
||||
|
||||
def test_product_api(self):
|
||||
"""
|
||||
Load Product API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(ProductViewSet, "/api/treasury/product/")
|
||||
|
||||
def test_remittance_api(self):
|
||||
"""
|
||||
Load Remittance API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(RemittanceViewSet, "/api/treasury/remittance/")
|
||||
|
||||
def test_remittance_type_api(self):
|
||||
"""
|
||||
Load RemittanceType API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(RemittanceTypeViewSet, "/api/treasury/remittance_type/")
|
||||
|
||||
def test_sogecredit_api(self):
|
||||
"""
|
||||
Load SogeCredit API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(SogeCreditViewSet, "/api/treasury/soge_credit/")
|
||||
|
|
|
@ -527,7 +527,7 @@ class TestWEIRegistration(TestCase):
|
|||
sess["permission_mask"] = 0
|
||||
sess.save()
|
||||
response = self.client.get(reverse("wei:wei_update_registration", kwargs=dict(pk=self.registration.pk)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
sess["permission_mask"] = 42
|
||||
sess.save()
|
||||
|
||||
|
@ -869,13 +869,38 @@ class TestWeiAPI(TestAPI):
|
|||
self.membership.roles.add(WEIRole.objects.last())
|
||||
self.membership.save()
|
||||
|
||||
def test_wei_api(self):
|
||||
def test_weiclub_api(self):
|
||||
"""
|
||||
Load API pages for the treasury app and test all filters
|
||||
Load WEI API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(WEIClubViewSet, "/api/wei/club/")
|
||||
|
||||
def test_wei_bus_api(self):
|
||||
"""
|
||||
Load Bus API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(BusViewSet, "/api/wei/bus/")
|
||||
|
||||
def test_wei_team_api(self):
|
||||
"""
|
||||
Load BusTeam API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(BusTeamViewSet, "/api/wei/team/")
|
||||
|
||||
def test_weirole_api(self):
|
||||
"""
|
||||
Load WEIRole API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(WEIRoleViewSet, "/api/wei/role/")
|
||||
|
||||
def test_weiregistration_api(self):
|
||||
"""
|
||||
Load WEIRegistration API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(WEIRegistrationViewSet, "/api/wei/registration/")
|
||||
|
||||
def test_weimembership_api(self):
|
||||
"""
|
||||
Load WEIMembership API page and test all filters and permissions
|
||||
"""
|
||||
self.check_viewset(WEIMembershipViewSet, "/api/wei/membership/")
|
||||
|
|
Loading…
Reference in New Issue