This commit is contained in:
j3d1 2026-08-31 14:41:52 +02:00
parent 4671860fa4
commit 18a3e40435
7 changed files with 43 additions and 11 deletions

View file

@ -28,8 +28,8 @@ def _accessible_files(request):
# friends-or-self with whatever references it (item, profile picture), a member of the group
# that owns the item it's attached to, or it's their own staged photo.
return File.objects.filter(
Q(connected_items__owner__in=request.user.friends_or_self()) |
Q(connected_items__owner_group__in=request.user.member_of_groups.all()) |
Q(connected_items__owner__in=request.user.friends_or_self(), connected_items__is_deleted=False) |
Q(connected_items__owner_group__in=request.user.member_of_groups.all(), connected_items__is_deleted=False) |
Q(profile_picture_users__in=request.user.friends_or_self()) |
Q(staged_by_workflows__owner__in=request.user.user.all())
).distinct()

View file

@ -187,6 +187,16 @@ class MediaUrlTestCase(FilesTestMixin, UserTestMixin, InventoryTestMixin, Toolsh
self.assertEqual(reply.status_code, 404)
self.assertTrue('X-Accel-Redirect' not in reply.headers)
def test_file_url_only_connected_via_deleted_item(self):
# test_file2 is only reachable through item1; soft-deleting it doesn't sever the files
# M2M row, so this would regress to serving test_file2 as if item1 were still live if
# _accessible_files ever stops excluding soft-deleted items again.
self.f['item1'].delete()
reply = client.get(
f"/media/{self.f['hash2'][:2]}/{self.f['hash2'][2:4]}/{self.f['hash2'][4:6]}/{self.f['hash2'][6:]}",
self.f['local_user1'])
self.assertEqual(reply.status_code, 404)
@override_settings(SERVE_X_ACCEL_REDIRECT=True)
def test_profile_picture_url(self):
self.f['local_user1'].profile_picture = self.f['test_file3']