"""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)