diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 01dab140d..7ead5429f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -6,6 +6,7 @@ Changelog * Fix: The `wagtailuserbar` template tag now gracefully handles situations where the `request` object is not in the template context (Matt Westcott) * Fix: Meta classes on StreamField blocks now handle multiple inheritance correctly (Tim Heap) + * Fix: Now user can upload images / documents only into permitted collection from choosers 1.4.3 (04.04.2016) diff --git a/docs/releases/1.4.4.rst b/docs/releases/1.4.4.rst index ed942b102..0bb1de2f0 100644 --- a/docs/releases/1.4.4.rst +++ b/docs/releases/1.4.4.rst @@ -15,3 +15,4 @@ Bug fixes * The ``wagtailuserbar`` template tag now gracefully handles situations where the ``request`` object is not in the template context (Matt Westcott) * Meta classes on StreamField blocks now handle multiple inheritance correctly (Tim Heap) + * Now user can upload images / documents only into permitted collection from choosers diff --git a/wagtail/wagtaildocs/tests.py b/wagtail/wagtaildocs/tests.py index b86fb6132..bb0ec7dfc 100644 --- a/wagtail/wagtaildocs/tests.py +++ b/wagtail/wagtaildocs/tests.py @@ -731,6 +731,78 @@ class TestDocumentChooserUploadView(TestCase, WagtailTestUtils): self.assertTrue(models.Document.objects.filter(title="Test document").exists()) +class TestDocumentChooserUploadViewWithLimitedPermissions(TestCase, WagtailTestUtils): + def setUp(self): + add_doc_permission = Permission.objects.get( + content_type__app_label='wagtaildocs', codename='add_document' + ) + admin_permission = Permission.objects.get( + content_type__app_label='wagtailadmin', codename='access_admin' + ) + + root_collection = Collection.get_first_root_node() + self.evil_plans_collection = root_collection.add_child(name="Evil plans") + + conspirators_group = Group.objects.create(name="Evil conspirators") + conspirators_group.permissions.add(admin_permission) + GroupCollectionPermission.objects.create( + group=conspirators_group, + collection=self.evil_plans_collection, + permission=add_doc_permission + ) + + user = get_user_model().objects.create_user( + username='moriarty', + email='moriarty@example.com', + password='password' + ) + user.groups.add(conspirators_group) + + self.client.login(username='moriarty', password='password') + + def test_simple(self): + response = self.client.get(reverse('wagtaildocs:chooser_upload')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.js') + + # user only has access to one collection -> should not see the collections field + self.assertNotContains(response, 'id_collection') + + def test_chooser_view(self): + # The main chooser view also includes the form, so need to test there too + response = self.client.get(reverse('wagtaildocs:chooser')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.js') + + # user only has access to one collection -> should not see the collections field + self.assertNotContains(response, 'id_collection') + + def test_post(self): + # Build a fake file + fake_file = ContentFile(b("A boring example document")) + fake_file.name = 'test.txt' + + # Submit + post_data = { + 'title': "Test document", + 'file': fake_file, + } + response = self.client.post(reverse('wagtaildocs:chooser_upload'), post_data) + + # Check that the response is a javascript file saying the document was chosen + self.assertTemplateUsed(response, 'wagtaildocs/chooser/document_chosen.js') + self.assertContains(response, "modal.respond('documentChosen'") + + # Document should be created + doc = models.Document.objects.filter(title="Test document") + self.assertTrue(doc.exists()) + + # Document should be in the 'evil plans' collection + self.assertEqual(doc.get().collection, self.evil_plans_collection) + + class TestDocumentFilenameProperties(TestCase): def setUp(self): self.document = models.Document(title="Test document") diff --git a/wagtail/wagtaildocs/views/chooser.py b/wagtail/wagtaildocs/views/chooser.py index 55c9a8004..7e110a98d 100644 --- a/wagtail/wagtaildocs/views/chooser.py +++ b/wagtail/wagtaildocs/views/chooser.py @@ -36,7 +36,7 @@ def chooser(request): if permission_policy.user_has_permission(request.user, 'add'): DocumentForm = get_document_form(Document) - uploadform = DocumentForm() + uploadform = DocumentForm(user=request.user) else: uploadform = None @@ -104,7 +104,7 @@ def chooser_upload(request): if request.POST: document = Document(uploaded_by_user=request.user) - form = DocumentForm(request.POST, request.FILES, instance=document) + form = DocumentForm(request.POST, request.FILES, instance=document, user=request.user) if form.is_valid(): form.save() @@ -118,7 +118,7 @@ def chooser_upload(request): {'document_json': get_document_json(document)} ) else: - form = DocumentForm() + form = DocumentForm(user=request.user) documents = Document.objects.order_by('title') diff --git a/wagtail/wagtailimages/tests/test_admin_views.py b/wagtail/wagtailimages/tests/test_admin_views.py index 08f05a56e..9aa3e5fbf 100644 --- a/wagtail/wagtailimages/tests/test_admin_views.py +++ b/wagtail/wagtailimages/tests/test_admin_views.py @@ -500,6 +500,75 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils): self.assertTrue(Image.objects.filter(title="Test image").exists()) +class TestImageChooserUploadViewWithLimitedPermissions(TestCase, WagtailTestUtils): + def setUp(self): + add_image_permission = Permission.objects.get( + content_type__app_label='wagtailimages', codename='add_image' + ) + admin_permission = Permission.objects.get( + content_type__app_label='wagtailadmin', codename='access_admin' + ) + + root_collection = Collection.get_first_root_node() + self.evil_plans_collection = root_collection.add_child(name="Evil plans") + + conspirators_group = Group.objects.create(name="Evil conspirators") + conspirators_group.permissions.add(admin_permission) + GroupCollectionPermission.objects.create( + group=conspirators_group, + collection=self.evil_plans_collection, + permission=add_image_permission + ) + + user = get_user_model().objects.create_user( + username='moriarty', + email='moriarty@example.com', + password='password' + ) + user.groups.add(conspirators_group) + + self.client.login(username='moriarty', password='password') + + def test_get(self): + response = self.client.get(reverse('wagtailimages:chooser_upload')) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/chooser/chooser.html') + + # user only has access to one collection, so no 'Collection' option + # is displayed on the form + self.assertNotContains(response, '