Repository: django-cms/django-filer

Issue:
Issues with permissions in Django filer
1. Issue with adding folder permission when selecting all files crashing due to gettext_lazy
2. Perms should checked for non-root users in the unsorted upload to verify if they should access the file
3. Add additional check in template that you are only able to see your own files and also the change buttons as well.


Discussion:

Resolving patch:
diff --git a/filer/admin/folderadmin.py b/filer/admin/folderadmin.py
--- a/filer/admin/folderadmin.py
+++ b/filer/admin/folderadmin.py
@@ -243,7 +243,9 @@ def directory_listing(self, request, folder_id=None, viewtype=None):
         if viewtype == 'images_with_missing_data':
             folder = ImagesWithMissingData()
         elif viewtype == 'unfiled_images':
-            folder = UnsortedImages()
+            # pass user in the class invocation, so that we can get
+            # access to the current user instance in the class
+            folder = UnsortedImages(user=request.user)
         elif viewtype == 'last':
             last_folder_id = request.session.get('filer_last_folder_id')
             try:
diff --git a/filer/models/foldermodels.py b/filer/models/foldermodels.py
--- a/filer/models/foldermodels.py
+++ b/filer/models/foldermodels.py
@@ -6,7 +6,7 @@
 from django.urls import reverse
 from django.utils.functional import cached_property
 from django.utils.html import format_html, format_html_join
-from django.utils.translation import gettext_lazy as _
+from django.utils.translation import gettext as _
 
 from .. import settings as filer_settings
 from . import mixins
diff --git a/filer/models/virtualitems.py b/filer/models/virtualitems.py
--- a/filer/models/virtualitems.py
+++ b/filer/models/virtualitems.py
@@ -48,8 +48,20 @@ class UnsortedImages(DummyFolder):
     is_unsorted_uploads = True
     _icon = "unfiled_folder"
 
+    def __init__(self, user=None):
+        super().__init__()
+        self.user = user
+
     def _files(self):
-        return File.objects.filter(folder__isnull=True)
+        """
+        If the current user is not a superuser, we don't them to see/edit/change
+        file in the unsorted uploads folder that they don't own.
+        """
+        if self.user.is_superuser or not filer_settings.FILER_ENABLE_PERMISSIONS:
+            return File.objects.filter(folder__isnull=True)
+        else:
+            return File.objects.filter(folder__isnull=True, owner=self.user)
+
     files = property(_files)
 
     def get_admin_directory_listing_url_path(self):


Test patch:
diff --git a/tests/test_admin.py b/tests/test_admin.py
--- a/tests/test_admin.py
+++ b/tests/test_admin.py
@@ -8,16 +8,16 @@
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Permission
 from django.forms.models import model_to_dict as model_to_dict_django
-from django.http import HttpResponseForbidden, HttpRequest
-from django.test import TestCase, RequestFactory
+from django.http import HttpRequest, HttpResponseForbidden
+from django.test import RequestFactory, TestCase
 from django.urls import reverse
 
 from easy_thumbnails.files import get_thumbnailer
 from easy_thumbnails.options import ThumbnailOptions
 
 from filer import settings as filer_settings
-from filer.admin.folderadmin import FolderAdmin
 from filer.admin import tools
+from filer.admin.folderadmin import FolderAdmin
 from filer.models.filemodels import File
 from filer.models.foldermodels import Folder, FolderPermission
 from filer.models.virtualitems import FolderRoot
diff --git a/tests/test_form_fields.py b/tests/test_form_fields.py
--- a/tests/test_form_fields.py
+++ b/tests/test_form_fields.py
@@ -4,7 +4,6 @@
 
 from filer.fields.file import AdminFileWidget
 from filer.models import File
-
 from tests.helpers import create_image
 
 
diff --git a/tests/test_permissions.py b/tests/test_permissions.py
--- a/tests/test_permissions.py
+++ b/tests/test_permissions.py
@@ -4,6 +4,7 @@
 from django.contrib.auth.models import Group, Permission
 from django.core.files import File as DjangoFile
 from django.test.testcases import TestCase
+from django.urls import reverse
 
 from filer import settings as filer_settings
 from filer.models.clipboardmodels import Clipboard
@@ -34,7 +35,10 @@ def setUp(self):
         self.owner = User.objects.create(username='owner')
 
         perms = Permission.objects.filter(codename="change_folder")
-        self.test_user1 = User.objects.create(username='test1', password='secret')
+        perms |= Permission.objects.filter(codename="can_use_directory_listing")
+        self.test_user1 = User.objects.create(username='test1', password='secret', is_staff=True)
+        self.test_user1.set_password("secret")
+        self.test_user1.save()
         self.test_user2 = User.objects.create(username='test2', password='secret')
         self.test_user1.user_permissions.add(*perms)
         self.test_user2.user_permissions.add(*perms)
@@ -63,6 +67,7 @@ def setUp(self):
         self.folder_perm = Folder.objects.create(name='test_folder2')
 
     def tearDown(self):
+        self.file.close()
         self.image.delete()
 
     def test_folder_all(self):
@@ -88,6 +93,22 @@ def test_unlogged_user_has_no_rights(self):
         finally:
             filer_settings.FILER_ENABLE_PERMISSIONS = old_setting
 
+    def test_user_cannot_see_other_users_files(self):
+        old_setting = filer_settings.FILER_ENABLE_PERMISSIONS
+        try:
+            filer_settings.FILER_ENABLE_PERMISSIONS = True
+
+            url = reverse("admin:filer-directory_listing-unfiled_images")
+            response = self.client.get(url)
+            self.assertContains(response, self.image_name)
+            loginok = self.client.login(username=self.test_user1.username, password="secret")
+            self.assertTrue(loginok, "Could not login 'test_user1'")
+            response = self.client.get(url)
+            self.assertNotContains(response, self.image_name)
+
+        finally:
+            filer_settings.FILER_ENABLE_PERMISSIONS = old_setting
+
     def test_unlogged_user_has_rights_when_permissions_disabled(self):
         request = Mock()
         setattr(request, 'user', self.unauth_user)