121 lines
6.1 KiB
Python
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)
|