GooDrive/backend/drive/test_granular_permissions.py
Louis Mazin 90004d4540 nickel
2026-10-14 17:27:37 +02:00

113 lines
7.1 KiB
Python

"""Run: USE_SQLITE=true python manage.py test drive.test_granular_permissions"""
import tempfile
import uuid
from pathlib import Path
from django.contrib.auth import get_user_model
from django.test import TestCase, override_settings
from django.core.files.uploadedfile import SimpleUploadedFile
from rest_framework.test import APIClient
from .models import DriveItem, DriveSpace, SpaceGrant, ItemGrant
from .spaces import ensure_space, ensure_private_space
from .quotas import quota_state, occupancy
class GranularPermissionTests(TestCase):
def setUp(self):
tmp=tempfile.TemporaryDirectory()
self.addCleanup(tmp.cleanup)
self.dir=Path(tmp.name)
settings=override_settings(DRIVE_STORAGE_ROOT=self.dir, FILE_UPLOAD_TEMP_DIR=str(self.dir/'.uploads'))
settings.enable();self.addCleanup(settings.disable)
User=get_user_model()
self.admin=User.objects.create_superuser('test-admin','admin@localhost','ComplexPassword123!')
self.member=User.objects.create_user('test-member',password='ComplexPassword123!')
self.guest=User.objects.create_user('test-guest',password='ComplexPassword123!')
self.root=ensure_space(self.admin)
self.private=ensure_private_space(self.member)
self.client=APIClient()
self.client.force_authenticate(self.admin)
def test_delegation_and_independent_rights(self):
rights=['view','download','manage_access']
SpaceGrant.objects.create(user=self.member,space=self.root,permissions=rights,can_invite=True)
self.client.force_authenticate(self.member)
self.assertEqual(self.client.post('/api/drive/folders/',{'space':self.root.pk,'name':'NO'},format='json').status_code,403)
created=self.client.post('/api/drive/invitations/',{
'parent_space':self.root.pk,'permissions':['view','download']},format='json')
self.assertEqual(created.status_code,201,created.data)
escalation=self.client.post('/api/drive/invitations/',{
'parent_space':self.root.pk,'permissions':['view','modify']},format='json')
self.assertEqual(escalation.status_code,403)
no_create=self.client.post('/api/drive/spaces/create/',{
'parent_space':self.root.pk,'display_name':'Impossible','quota_bytes':None},format='json')
self.assertEqual(no_create.status_code,403)
self.client.force_authenticate(self.admin)
grant=self.client.post('/api/drive/spaces/users/',{
'parent_space':self.root.pk,'user_id':self.guest.pk,
'permissions':['view','add']},format='json',QUERY_STRING=f'parent_space={self.root.pk}')
self.assertEqual(grant.status_code,201,grant.data)
self.client.force_authenticate(self.guest)
self.assertEqual(self.client.post('/api/drive/folders/',{'space':self.root.pk,'name':'OK'},format='json').status_code,201)
self.assertEqual(self.client.post('/api/drive/invitations/',{'parent_space':self.root.pk},format='json').status_code,403)
def test_granular_folder_share_and_anonymous_preview(self):
folder=DriveItem.objects.create(owner=self.member,space=self.private,name='Photos',is_folder=True)
image=DriveItem.objects.create(owner=self.member,space=self.private,parent=folder,name='photo.png',
storage_key=str(uuid.uuid4()),storage_location=f'{self.private.relative_path}/Photos/photo.png',size=8,mime_type='image/png')
filename=self.dir/image.storage_location
filename.parent.mkdir(parents=True,exist_ok=True)
filename.write_bytes(b'PNGDATA!')
self.client.force_authenticate(self.member)
share=self.client.post(f'/api/drive/items/{folder.pk}/shares/',{
'user_id':self.guest.pk,'permissions':['view','download','add']},format='json')
self.assertEqual(share.status_code,201,share.data)
self.client.force_authenticate(self.guest)
self.assertEqual(self.client.post('/api/drive/folders/',{
'name':'Nouveau','parent':str(folder.pk),'space':self.private.pk},format='json').status_code,201)
self.assertEqual(self.client.post(f'/api/drive/items/{image.pk}/trash/').status_code,403)
self.client.force_authenticate(self.member)
result=self.client.post(f'/api/drive/items/{image.pk}/public-links/',{},format='json')
self.assertEqual(result.status_code,201,result.data)
anonymous=APIClient()
token=result.data['token']
inline=anonymous.get(f'/api/public/{token}/files/{image.pk}/?inline=1')
self.assertEqual(inline.status_code,200)
self.assertEqual(inline['Content-Type'],'image/png')
self.assertEqual(b''.join(inline.streaming_content),b'PNGDATA!')
partial=anonymous.get(f'/api/public/{token}/files/{image.pk}/?inline=1',HTTP_RANGE='bytes=0-2')
self.assertEqual(partial.status_code,206)
self.assertEqual(b''.join(partial.streaming_content),b'PNG')
self.client.force_authenticate(self.member)
self.assertEqual(self.client.patch(f'/api/drive/items/{folder.pk}/shares/{share.data["id"]}/permissions/',{
'permissions':['view']},format='json').status_code,200)
self.client.force_authenticate(self.guest)
self.assertEqual(self.client.post('/api/drive/folders/',{
'name':'Interdit','parent':str(folder.pk),'space':self.private.pk},format='json').status_code,403)
self.assertEqual(self.client.post(f'/api/drive/items/{image.pk}/link/',{'inline':False},format='json').status_code,403)
self.assertEqual(self.client.post(f'/api/drive/items/{image.pk}/link/',{'inline':True},format='json').status_code,200)
def test_unreserved_child_quota_parent_usage_reduces_child_capacity(self):
gib=1024**3
self.root.quota_bytes=50*gib
self.root.save(update_fields=['quota_bytes'])
self.client.force_authenticate(self.admin)
res=self.client.post('/api/drive/spaces/create/',{
'parent_space':self.root.pk,'display_name':'Sous espace','quota_bytes':30*gib},format='json')
self.assertEqual(res.status_code,201,res.data)
child=DriveSpace.objects.get(pk=res.data['id'])
self.assertEqual(child.parent_id,self.root.pk)
DriveItem.objects.create(space=self.root,owner=self.admin,name='parent.bin',size=20*gib,
storage_key=str(uuid.uuid4()),storage_location='unused')
self.assertEqual(quota_state(self.root)['used_bytes'],20*gib)
self.assertEqual(quota_state(child)['used_bytes'],0)
DriveItem.objects.filter(space=self.root).update(size=30*gib)
self.assertEqual(quota_state(self.root)['used_bytes'],30*gib)
self.assertEqual(quota_state(child)['used_bytes'],10*gib)
self.assertEqual(quota_state(child)['available_bytes'],20*gib)
DriveItem.objects.create(space=child,owner=self.admin,name='child.bin',size=10*gib,
storage_key=str(uuid.uuid4()),storage_location='unused2')
self.assertGreaterEqual(quota_state(self.root)['used_bytes'],10*gib)
self.assertEqual(quota_state(self.root)['used_bytes'],40*gib)
self.assertEqual(quota_state(child)['used_bytes'],20*gib)
self.assertEqual(occupancy(child)[0],10*gib)