GooDrive/backend/drive/test_quota_allocation_protection.py
Louis Mazin 9834626cf4 nice
2026-10-14 17:57:24 +02:00

121 lines
6.1 KiB
Python

"""Regressions: an invitee cannot enlarge their assigned storage allocation.
Run with: USE_SQLITE=true python manage.py test drive.test_quota_allocation_protection
"""
import tempfile
from pathlib import Path
from django.contrib.auth import get_user_model
from django.test import TestCase, override_settings
from rest_framework.test import APIClient
from .models import SpaceGrant
from .spaces import _make_numbered_space, ensure_space, space_info
class AllocatedQuotaProtectionTests(TestCase):
def setUp(self):
directory = tempfile.TemporaryDirectory()
self.addCleanup(directory.cleanup)
settings = override_settings(DRIVE_STORAGE_ROOT=Path(directory.name),
FILE_UPLOAD_TEMP_DIR=str(Path(directory.name) / '.uploads'))
settings.enable()
self.addCleanup(settings.disable)
User = get_user_model()
self.admin = User.objects.create_superuser('quota-admin', 'admin@example.com', 'TestPassword123!')
self.member = User.objects.create_user('quota-member', password='TestPassword123!')
self.client = APIClient()
self.root = ensure_space(self.admin)
self.root.quota_bytes = 100 * 1024**3
self.root.save(update_fields=['quota_bytes'])
self.allocated = _make_numbered_space(
self.root, managed_by=self.admin, display_name='Espace attribué', quota_bytes=50 * 1024**3)
SpaceGrant.objects.create(
user=self.member, space=self.allocated,
permissions=['view', 'download', 'manage_space', 'manage_access', 'create_spaces'])
self.child_by_admin = _make_numbered_space(
self.allocated, managed_by=self.admin, display_name='Sous-espace administrateur',
quota_bytes=20 * 1024**3)
self.child_by_member = _make_numbered_space(
self.allocated, managed_by=self.member, display_name='Sous-espace personnel',
quota_bytes=20 * 1024**3)
self.client.force_authenticate(self.member)
def test_member_cannot_change_allocation_through_quota_endpoint(self):
response = self.client.patch(
f'/api/drive/spaces/{self.allocated.pk}/quota/',
{'quota_bytes': 80 * 1024**3}, format='json')
self.assertEqual(response.status_code, 403, response.data)
self.allocated.refresh_from_db()
self.assertEqual(self.allocated.quota_bytes, 50 * 1024**3)
def test_member_can_rename_allocated_space_but_not_change_quota(self):
response = self.client.patch(
f'/api/drive/spaces/{self.allocated.pk}/',
{'display_name': 'Nom autorisé'}, format='json')
self.assertEqual(response.status_code, 200, response.data)
forbidden = self.client.patch(
f'/api/drive/spaces/{self.allocated.pk}/',
{'display_name': 'Nom non enregistré', 'quota_bytes': None}, format='json')
self.assertEqual(forbidden.status_code, 403, forbidden.data)
self.allocated.refresh_from_db()
self.assertEqual(self.allocated.display_name, 'Nom autorisé')
self.assertEqual(self.allocated.quota_bytes, 50 * 1024**3)
self.assertFalse(space_info(self.allocated, self.member)['can_edit_quota'])
def test_member_cannot_change_other_users_allocations_using_manage_access(self):
response = self.client.patch(
f'/api/drive/spaces/members/{self.child_by_admin.pk}/',
{'quota_bytes': 40 * 1024**3}, format='json')
self.assertEqual(response.status_code, 403, response.data)
self.child_by_admin.refresh_from_db()
self.assertEqual(self.child_by_admin.quota_bytes, 20 * 1024**3)
def test_member_can_adjust_the_subspace_they_created(self):
self.assertTrue(space_info(self.child_by_member, self.member)['can_edit_quota'])
response = self.client.patch(
f'/api/drive/spaces/{self.child_by_member.pk}/',
{'quota_bytes': 30 * 1024**3}, format='json')
self.assertEqual(response.status_code, 200, response.data)
self.child_by_member.refresh_from_db()
self.assertEqual(self.child_by_member.quota_bytes, 30 * 1024**3)
def test_admin_still_controls_allocated_quota(self):
self.client.force_authenticate(self.admin)
response = self.client.patch(
f'/api/drive/spaces/{self.allocated.pk}/quota/',
{'quota_bytes': 75 * 1024**3}, format='json')
self.assertEqual(response.status_code, 200, response.data)
self.allocated.refresh_from_db()
self.assertEqual(self.allocated.quota_bytes, 75 * 1024**3)
self.assertTrue(space_info(self.allocated, self.admin)['can_edit_quota'])
def test_legacy_assigned_owner_must_not_enlarge_allocation(self):
User = get_user_model()
legacy = User.objects.create_user('quota-legacy', password='TestPassword123!')
allocated = _make_numbered_space(
self.root, user=legacy, display_name='Ancien espace attribué',
quota_bytes=40 * 1024**3)
self.client.force_authenticate(legacy)
response = self.client.patch(
f'/api/drive/spaces/{allocated.pk}/',
{'quota_bytes': 70 * 1024**3}, format='json')
self.assertEqual(response.status_code, 403, response.data)
allocated.refresh_from_db()
self.assertEqual(allocated.quota_bytes, 40 * 1024**3)
def test_grant_makes_a_created_space_an_assigned_space_not_resizable(self):
# Even a creator loses quota control if this space has become their
# assigned access point through an explicit share grant.
SpaceGrant.objects.create(
user=self.member, space=self.child_by_member,
permissions=['view', 'download', 'manage_space'])
self.assertFalse(space_info(self.child_by_member, self.member)['can_edit_quota'])
response = self.client.patch(
f'/api/drive/spaces/{self.child_by_member.pk}/',
{'quota_bytes': 45 * 1024**3}, format='json')
self.assertEqual(response.status_code, 403, response.data)
self.child_by_member.refresh_from_db()
self.assertEqual(self.child_by_member.quota_bytes, 20 * 1024**3)