mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-05 00:17:42 +00:00
🔒️(backend) prevent accessing files if they are not ready
With the addition of the ANALYSING state files could be accessed in the short time they were in that state. We now require files to be in ready. Also adds missing frontend types (no impact).
This commit is contained in:
@@ -20,6 +20,7 @@ and this project adheres to
|
||||
### Fixed
|
||||
|
||||
- 🔇(summary) make ffmpeg quiet #1404
|
||||
- 🔒️(backend) prevent accessing files if they are not ready #1395
|
||||
|
||||
## [1.18.0] - 2026-06-03
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ class FileAdmin(admin.ModelAdmin):
|
||||
"hard_deleted_at",
|
||||
"description",
|
||||
"malware_detection_info",
|
||||
"is_pending_upload",
|
||||
"is_ready",
|
||||
"preview_url",
|
||||
"extension",
|
||||
"key_base",
|
||||
@@ -226,7 +226,7 @@ class FileAdmin(admin.ModelAdmin):
|
||||
_("Derived info"),
|
||||
{
|
||||
"fields": (
|
||||
"is_pending_upload",
|
||||
"is_ready",
|
||||
"extension",
|
||||
"key_base",
|
||||
"file_key",
|
||||
@@ -240,7 +240,7 @@ class FileAdmin(admin.ModelAdmin):
|
||||
@admin.display(description=_("File preview"))
|
||||
def preview_url(self, obj):
|
||||
"""Return a clickable preview URL for the file."""
|
||||
if obj.is_pending_upload:
|
||||
if not obj.is_ready:
|
||||
return "-"
|
||||
url = generate_download_file_url(obj, expires_in=60 * 60)
|
||||
|
||||
|
||||
@@ -456,7 +456,7 @@ class ListFileSerializer(serializers.ModelSerializer):
|
||||
|
||||
def get_url(self, obj):
|
||||
"""Return the URL of the file."""
|
||||
if obj.is_pending_upload:
|
||||
if not obj.is_ready:
|
||||
return None
|
||||
|
||||
return f"{settings.MEDIA_BASE_URL}{settings.MEDIA_URL}{quote(obj.file_key)}"
|
||||
|
||||
@@ -1417,7 +1417,7 @@ class FileViewSet(
|
||||
request, MEDIA_STORAGE_URL_PATTERN
|
||||
)
|
||||
|
||||
if file.is_pending_upload:
|
||||
if not file.is_ready:
|
||||
logger.warning("File '%s' is not ready", file.id)
|
||||
raise drf_exceptions.PermissionDenied()
|
||||
|
||||
|
||||
@@ -925,9 +925,9 @@ class File(BaseModel):
|
||||
return super().delete(using, keep_parents)
|
||||
|
||||
@property
|
||||
def is_pending_upload(self):
|
||||
"""Return whether the file is in a pending upload state"""
|
||||
return self.upload_state == FileUploadStateChoices.PENDING
|
||||
def is_ready(self):
|
||||
"""Return whether the file is in a ready upload state"""
|
||||
return self.upload_state == FileUploadStateChoices.READY
|
||||
|
||||
@property
|
||||
def extension(self):
|
||||
|
||||
@@ -86,7 +86,11 @@ def test_api_files_media_get_own():
|
||||
assert response.content.decode("utf-8") == "my prose"
|
||||
|
||||
|
||||
def test_api_files_media_auth_file_pending():
|
||||
@pytest.mark.parametrize(
|
||||
"rejecting_status",
|
||||
[models.FileUploadStateChoices.PENDING, models.FileUploadStateChoices.ANALYZING],
|
||||
)
|
||||
def test_api_files_media_auth_rejects(rejecting_status):
|
||||
"""
|
||||
Users who have a specific access to an file, whatever the role, should not be able to
|
||||
retrieve related attachments if the file is not ready.
|
||||
@@ -97,7 +101,7 @@ def test_api_files_media_auth_file_pending():
|
||||
|
||||
file = factories.FileFactory(
|
||||
type=models.FileTypeChoices.BACKGROUND_IMAGE,
|
||||
upload_state=models.FileUploadStateChoices.PENDING,
|
||||
upload_state=rejecting_status,
|
||||
creator=user,
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ export type ApiFileCreator = {
|
||||
}
|
||||
|
||||
export type ApiFileType = 'background_image'
|
||||
export type ApiFileUploadState = 'pending' | 'ready'
|
||||
export type ApiFileUploadState = 'pending' | 'analyzing' | 'ready'
|
||||
|
||||
export type ApiFileItem = {
|
||||
id: string // UUID
|
||||
|
||||
Reference in New Issue
Block a user