Skip to content

Commit 2dcbcfe

Browse files
authored
Fix can_view_submission ignoring ReviewerSettings configured in wagtail admin (#4899)
Fixed a permission bug that ignored the [ReviewerSettings](https://github.com/HyphaApp/hypha/blob/6b3aa1f72d6b30efa66641f968cff9813873e878/hypha/apply/funds/models/reviewer_role.py#L42) that were set in Wagtail admin. By default (no settings configured) a reviewer should have access to all submissions. But in Wagtail, setting can be configured to scope a reviewer's specific access to things like assigned applications, specific application outcomes, etc. This was not being considered by `can_view_submission`, which would give reviewers access to things like attachments on applications they wouldn't otherwise have access to. The logic for ReviewerSettings was implemented on the `ReviewerSubmissionDetailView` alone so the detail view would account for these settings but not the `can_view_submission` function itself. Thank you to https://github.com/Santoshkumarpuppala for discovering and responsibly disclosing this bug! ## Test Steps <!-- If step does not require manual testing, skip/remove this section. Give a brief overview of the steps required for a user/dev to test this contribution. Important things to include: - Required user roles for where necessary (ie. "As a Staff Admin...") - Clear & validatable expected results (ie. "Confirm the submit button is now not clickable") - Language that can be understood by non-technical testers if being tested by users --> - [ ] Ensure that with no ReviewerSettings configured/enabled in Wagtail admin, reviewers are able to access all submissions (both in detail view and see them displayed in the All Submissions view) - [ ] Ensure that with ReviewSettings configured, all permissions act as expected (ie. if a submission cannot be viewed, confirmed associated files also return a 403)
1 parent 0014829 commit 2dcbcfe

4 files changed

Lines changed: 52 additions & 15 deletions

File tree

hypha/apply/funds/permissions.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
from django.apps import apps
12
from django.conf import settings
23
from django.core.exceptions import PermissionDenied
34
from django.utils.translation import gettext as _
45
from rolepermissions.permissions import register_object_checker
56

67
from hypha.apply.funds.models.co_applicants import CoApplicant, CoApplicantRole
8+
from hypha.apply.funds.models.reviewer_role import ReviewerSettings
79
from hypha.apply.funds.models.submissions import DRAFT_STATE
10+
from hypha.home.models import ApplyHomePage
811

912
from ..users.roles import STAFF_GROUP_NAME, SUPERADMIN, TEAMADMIN_GROUP_NAME, StaffAdmin
1013

@@ -213,11 +216,22 @@ def can_view_submission(user, submission):
213216
if (
214217
user.is_apply_staff
215218
or submission.user == user
216-
or user.is_reviewer
217219
or submission.co_applicants.filter(user=user).exists()
218220
):
219221
return True, ""
220222

223+
# By default, reviewers can see all submissions. This can be configured in Wagtail Admin > Apply > Reviewer Settings
224+
if user.is_reviewer:
225+
site = ApplyHomePage.objects.first().get_site()
226+
reviewer_settings = ReviewerSettings.for_site(site)
227+
ApplicationSubmission = apps.get_model("funds", "ApplicationSubmission")
228+
if reviewer_settings.use_settings:
229+
return ApplicationSubmission.objects.for_reviewer_settings(
230+
user, reviewer_settings
231+
).filter(pk=submission.pk).exists(), ""
232+
else:
233+
return True, ""
234+
221235
if user.is_community_reviewer and submission.community_review:
222236
return True, ""
223237

hypha/apply/funds/tests/test_permissions.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
CoApplicantInviteStatus,
1010
CoApplicantRole,
1111
)
12+
from hypha.apply.funds.models.reviewer_role import ReviewerSettings
1213
from hypha.apply.funds.tests.factories import ApplicationSubmissionFactory
1314
from hypha.apply.funds.workflows import DRAFT_STATE
1415
from hypha.apply.users.tests.factories import (
@@ -18,6 +19,7 @@
1819
StaffFactory,
1920
UserFactory,
2021
)
22+
from hypha.home.factories import ApplySiteFactory
2123

2224
from ..permissions import (
2325
can_access_drafts,
@@ -221,12 +223,45 @@ def test_submission_owner_can_view(self):
221223
result, _ = can_view_submission(applicant, submission)
222224
self.assertTrue(result)
223225

224-
def test_reviewer_can_view(self):
226+
def test_reviewer_can_view_by_default(self):
225227
reviewer = ReviewerFactory()
226228
submission = ApplicationSubmissionFactory()
227229
result, _ = can_view_submission(reviewer, submission)
228230
self.assertTrue(result)
229231

232+
# Basic tests to ensure functionality, more in-depth tests happen in hypha/apply/funds/tests/test_views.py::TestReviewerSubmissionView
233+
def test_reviewer_cannot_view_unassigned_when_configured(self):
234+
reviewer = ReviewerFactory()
235+
apply_site = ApplySiteFactory()
236+
reviewer_settings, _ = ReviewerSettings.objects.get_or_create(
237+
site_id=apply_site.id
238+
)
239+
reviewer_settings.use_settings = True
240+
reviewer_settings.submission = "all"
241+
reviewer_settings.outcome = "all"
242+
reviewer_settings.assigned = True
243+
reviewer_settings.save()
244+
245+
submission = ApplicationSubmissionFactory()
246+
result, _ = can_view_submission(reviewer, submission)
247+
self.assertFalse(result)
248+
249+
def test_reviewer_can_view_assigned_when_configured(self):
250+
reviewer = ReviewerFactory()
251+
apply_site = ApplySiteFactory()
252+
reviewer_settings, _ = ReviewerSettings.objects.get_or_create(
253+
site_id=apply_site.id
254+
)
255+
reviewer_settings.use_settings = True
256+
reviewer_settings.submission = "all"
257+
reviewer_settings.outcome = "all"
258+
reviewer_settings.assigned = True
259+
reviewer_settings.save()
260+
261+
submission = ApplicationSubmissionFactory(reviewers=[reviewer])
262+
result, _ = can_view_submission(reviewer, submission)
263+
self.assertTrue(result)
264+
230265
def test_unrelated_user_cannot_view(self):
231266
user = UserFactory()
232267
submission = ApplicationSubmissionFactory()

hypha/apply/funds/views/all.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,11 @@ def submissions_all(
129129
else:
130130
qs = ApplicationSubmission.objects.current()
131131

132-
# Reviewers also have access to this view but should only see a subset of submissions.
132+
# By default, reviewers can see all submissions. This can be configured in Wagtail Admin > Apply > Reviewer Settings
133133
if request.user.is_reviewer:
134134
reviewer_settings = ReviewerSettings.for_request(request)
135135
if reviewer_settings.use_settings:
136136
qs = qs.for_reviewer_settings(request.user, reviewer_settings)
137-
else:
138-
qs = qs.filter(reviewers=request.user)
139137

140138
if not can_access_drafts or not show_drafts:
141139
qs = qs.exclude_draft()

hypha/apply/funds/views/submission_detail.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
from ..models import (
3535
ApplicationSubmission,
36-
ReviewerSettings,
3736
)
3837
from ..permissions import (
3938
can_alter_archived_submissions,
@@ -142,15 +141,6 @@ def dispatch(self, request, *args, **kwargs):
142141
"submission_view", request.user, object=submission, raise_exception=True
143142
)
144143

145-
reviewer_settings = ReviewerSettings.for_request(request)
146-
if reviewer_settings.use_settings:
147-
queryset = ApplicationSubmission.objects.for_reviewer_settings(
148-
request.user, reviewer_settings
149-
)
150-
# Reviewer can't view submission which is not listed in ReviewerSubmissionsTable
151-
if not queryset.filter(id=submission.id).exists():
152-
raise PermissionDenied
153-
154144
return super().dispatch(request, *args, **kwargs)
155145

156146

0 commit comments

Comments
 (0)