Skip to content

Commit 594f2a3

Browse files
Merge pull request #3766 from rebeccacremona/tweak-folder-check
Tweak how links are filtered when listed by the API
2 parents 6adf5ae + f273ec8 commit 594f2a3

2 files changed

Lines changed: 61 additions & 3 deletions

File tree

perma_web/api/tests/test_link_authorization.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ def get_link_url(self, link):
7474

7575
class LinkAuthorizationTestCase(LinkAuthorizationMixin, ApiResourceTestCase):
7676

77+
def folder_archives_url(self, folder):
78+
return "{0}/folders/{1}/archives".format(self.url_base, folder.pk)
79+
7780
#######
7881
# GET #
7982
#######
@@ -99,6 +102,57 @@ def test_should_reject_logged_out_users_getting_logged_in_list(self):
99102
def test_should_reject_logged_out_users_getting_logged_in_detail(self):
100103
self.rejected_get(self.link_url)
101104

105+
##########################
106+
# Listing folder archives #
107+
##########################
108+
109+
def test_should_allow_user_to_list_archives_in_own_folder(self):
110+
self.successful_get(self.folder_archives_url(self.regular_user.root_folder),
111+
user=self.regular_user)
112+
113+
def test_should_allow_org_user_to_list_archives_in_org_shared_folder(self):
114+
self.successful_get(self.folder_archives_url(self.link.organization.shared_folder),
115+
user=self.org_user)
116+
117+
def test_should_allow_related_org_user_to_list_archives_in_org_shared_folder(self):
118+
self.successful_get(self.folder_archives_url(self.link.organization.shared_folder),
119+
user=self.related_org_user)
120+
121+
def test_should_allow_registrar_user_to_list_archives_in_registrar_org_folder(self):
122+
self.successful_get(self.folder_archives_url(self.link.organization.shared_folder),
123+
user=self.registrar_user)
124+
125+
def test_should_allow_admin_to_list_archives_in_any_folder(self):
126+
self.successful_get(self.folder_archives_url(self.regular_user.root_folder),
127+
user=self.admin_user)
128+
129+
def test_should_reject_listing_archives_in_other_users_folder(self):
130+
self.rejected_get(self.folder_archives_url(self.org_user.root_folder),
131+
user=self.regular_user,
132+
expected_status_code=403)
133+
134+
def test_should_reject_listing_archives_in_unrelated_org_folder(self):
135+
self.rejected_get(self.folder_archives_url(self.link.organization.shared_folder),
136+
user=self.unrelated_org_user,
137+
expected_status_code=403)
138+
139+
def test_should_reject_logged_out_user_listing_folder_archives(self):
140+
self.rejected_get(self.folder_archives_url(self.regular_user.root_folder))
141+
142+
def test_should_return_404_for_nonexistent_folder_archives(self):
143+
url = "{0}/folders/{1}/archives".format(self.url_base, 99999)
144+
self.rejected_get(url, user=self.regular_user, expected_status_code=404)
145+
146+
def test_folder_archives_only_contains_links_from_that_folder(self):
147+
folder = self.regular_user.root_folder
148+
data = self.successful_get(self.folder_archives_url(folder), user=self.regular_user)
149+
returned_guids = {obj['guid'] for obj in data['objects']}
150+
folder_link_guids = set(
151+
folder.links.filter(user_deleted=False).values_list('guid', flat=True)
152+
)
153+
self.assertTrue(returned_guids.issubset(folder_link_guids),
154+
f"Returned links {returned_guids - folder_link_guids} are not in folder {folder.pk}")
155+
102156
###########
103157
# Editing #
104158
###########

perma_web/api/views.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,12 +395,16 @@ def load_links(request):
395395
queryset = Link.objects\
396396
.order_by('-creation_timestamp')\
397397
.select_related('organization', 'organization__registrar', 'organization__shared_folder', 'capture_job', 'created_by')\
398-
.prefetch_related('captures')\
399-
.accessible_to(request.user)
398+
.prefetch_related('captures')
400399

401-
# for /folders/:parent_id/archives, limit to links in folder
402400
if request.parent:
401+
# For /folders/:parent_id/archives, limit to links in folder.
402+
# The code that sets request.parent guarantees that folder is accessible to this user;
403+
# no need for a check here.
403404
queryset = queryset.filter(folders=request.parent)
405+
else:
406+
# Otherwise, get all the links accessible to the user
407+
queryset = queryset.accessible_to(request.user)
404408

405409
return queryset
406410

0 commit comments

Comments
 (0)