mirror of
https://github.com/suitenumerique/meet.git
synced 2026-09-03 22:25:27 +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
|
### Fixed
|
||||||
|
|
||||||
- 🔇(summary) make ffmpeg quiet #1404
|
- 🔇(summary) make ffmpeg quiet #1404
|
||||||
|
- 🔒️(backend) prevent accessing files if they are not ready #1395
|
||||||
|
|
||||||
## [1.18.0] - 2026-06-03
|
## [1.18.0] - 2026-06-03
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ class FileAdmin(admin.ModelAdmin):
|
|||||||
"hard_deleted_at",
|
"hard_deleted_at",
|
||||||
"description",
|
"description",
|
||||||
"malware_detection_info",
|
"malware_detection_info",
|
||||||
"is_pending_upload",
|
"is_ready",
|
||||||
"preview_url",
|
"preview_url",
|
||||||
"extension",
|
"extension",
|
||||||
"key_base",
|
"key_base",
|
||||||
@@ -226,7 +226,7 @@ class FileAdmin(admin.ModelAdmin):
|
|||||||
_("Derived info"),
|
_("Derived info"),
|
||||||
{
|
{
|
||||||
"fields": (
|
"fields": (
|
||||||
"is_pending_upload",
|
"is_ready",
|
||||||
"extension",
|
"extension",
|
||||||
"key_base",
|
"key_base",
|
||||||
"file_key",
|
"file_key",
|
||||||
@@ -240,7 +240,7 @@ class FileAdmin(admin.ModelAdmin):
|
|||||||
@admin.display(description=_("File preview"))
|
@admin.display(description=_("File preview"))
|
||||||
def preview_url(self, obj):
|
def preview_url(self, obj):
|
||||||
"""Return a clickable preview URL for the file."""
|
"""Return a clickable preview URL for the file."""
|
||||||
if obj.is_pending_upload:
|
if not obj.is_ready:
|
||||||
return "-"
|
return "-"
|
||||||
url = generate_download_file_url(obj, expires_in=60 * 60)
|
url = generate_download_file_url(obj, expires_in=60 * 60)
|
||||||
|
|
||||||
|
|||||||
@@ -456,7 +456,7 @@ class ListFileSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def get_url(self, obj):
|
def get_url(self, obj):
|
||||||
"""Return the URL of the file."""
|
"""Return the URL of the file."""
|
||||||
if obj.is_pending_upload:
|
if not obj.is_ready:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return f"{settings.MEDIA_BASE_URL}{settings.MEDIA_URL}{quote(obj.file_key)}"
|
return f"{settings.MEDIA_BASE_URL}{settings.MEDIA_URL}{quote(obj.file_key)}"
|
||||||
|
|||||||
@@ -1417,7 +1417,7 @@ class FileViewSet(
|
|||||||
request, MEDIA_STORAGE_URL_PATTERN
|
request, MEDIA_STORAGE_URL_PATTERN
|
||||||
)
|
)
|
||||||
|
|
||||||
if file.is_pending_upload:
|
if not file.is_ready:
|
||||||
logger.warning("File '%s' is not ready", file.id)
|
logger.warning("File '%s' is not ready", file.id)
|
||||||
raise drf_exceptions.PermissionDenied()
|
raise drf_exceptions.PermissionDenied()
|
||||||
|
|
||||||
|
|||||||
@@ -925,9 +925,9 @@ class File(BaseModel):
|
|||||||
return super().delete(using, keep_parents)
|
return super().delete(using, keep_parents)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_pending_upload(self):
|
def is_ready(self):
|
||||||
"""Return whether the file is in a pending upload state"""
|
"""Return whether the file is in a ready upload state"""
|
||||||
return self.upload_state == FileUploadStateChoices.PENDING
|
return self.upload_state == FileUploadStateChoices.READY
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extension(self):
|
def extension(self):
|
||||||
|
|||||||
@@ -86,7 +86,11 @@ def test_api_files_media_get_own():
|
|||||||
assert response.content.decode("utf-8") == "my prose"
|
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
|
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.
|
retrieve related attachments if the file is not ready.
|
||||||
@@ -97,7 +101,7 @@ def test_api_files_media_auth_file_pending():
|
|||||||
|
|
||||||
file = factories.FileFactory(
|
file = factories.FileFactory(
|
||||||
type=models.FileTypeChoices.BACKGROUND_IMAGE,
|
type=models.FileTypeChoices.BACKGROUND_IMAGE,
|
||||||
upload_state=models.FileUploadStateChoices.PENDING,
|
upload_state=rejecting_status,
|
||||||
creator=user,
|
creator=user,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export type ApiFileCreator = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ApiFileType = 'background_image'
|
export type ApiFileType = 'background_image'
|
||||||
export type ApiFileUploadState = 'pending' | 'ready'
|
export type ApiFileUploadState = 'pending' | 'analyzing' | 'ready'
|
||||||
|
|
||||||
export type ApiFileItem = {
|
export type ApiFileItem = {
|
||||||
id: string // UUID
|
id: string // UUID
|
||||||
|
|||||||
Reference in New Issue
Block a user