From dcb467c060014516710a3838cd862301e5193855 Mon Sep 17 00:00:00 2001 From: Sandeep Chauhan <sandeepsajan0@gmail.com> Date: Tue, 18 Apr 2023 14:12:15 +0530 Subject: [PATCH] Fix Permissions for Project access(detail view) (#3220) Fixes #3205 Fixes #3216 1. Staff can access the project in every status. 2. Contracting can access projects only in `WAITING_FOR_APPROVAL` and `CONTRACTING` statuses. 3. Finance can access projects only in the `WAITING_FOR_APPROVAL` and `IN_PROGRESS` statuses. 4. Applicant(only project user) can access the project in every status to keep track. 5. Unauthorised users and any other role can not access the project. --- hypha/apply/projects/permissions.py | 20 ++++++++++++++++++++ hypha/apply/projects/tests/test_views.py | 5 +++-- hypha/apply/projects/views/project.py | 8 ++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/hypha/apply/projects/permissions.py b/hypha/apply/projects/permissions.py index 400cb9781..ad5e6973b 100644 --- a/hypha/apply/projects/permissions.py +++ b/hypha/apply/projects/permissions.py @@ -153,6 +153,25 @@ def can_view_report(user, report, **kwargs): return False, 'Forbidden Error' +def can_access_project(user, project): + if not user.is_authenticated: + return False, 'Login Required' + + if user.is_contracting and project.status in [CONTRACTING, WAITING_FOR_APPROVAL]: + return True, 'Contracting can view project only in Waiting for approval and contracting status' + + if user.is_finance and project.status in [WAITING_FOR_APPROVAL, IN_PROGRESS]: + return True, 'Finance can view project only in Waiting for approval and in progress status' + + if user.is_apply_staff: + return True, 'Staff can view project in all statuses' + + if user.is_applicant and user == project.user: + return True, 'Applicant(project user) can view project in all statuses' + + return False, 'Forbidden Error' + + permissions_map = { 'contract_approve': can_approve_contract, 'contract_upload': can_upload_contract, @@ -163,4 +182,5 @@ permissions_map = { 'report_config_update': can_update_report_config, 'report_view': can_view_report, 'submit_contract_documents': can_submit_contract_documents, + 'project_access': can_access_project, } diff --git a/hypha/apply/projects/tests/test_views.py b/hypha/apply/projects/tests/test_views.py index c011290ca..373397909 100644 --- a/hypha/apply/projects/tests/test_views.py +++ b/hypha/apply/projects/tests/test_views.py @@ -231,12 +231,13 @@ class TestFinanceProjectDetailView(BaseProjectDetailTestCase): user_factory = FinanceFactory def test_has_access(self): - project = ProjectFactory() + project = ProjectFactory(status=WAITING_FOR_APPROVAL) response = self.get_page(project) self.assertEqual(response.status_code, 200) + def test_lab_project_renders(self): - project = ProjectFactory(submission=LabSubmissionFactory()) + project = ProjectFactory(submission=LabSubmissionFactory(), status=WAITING_FOR_APPROVAL) response = self.get_page(project) self.assertEqual(response.status_code, 200) diff --git a/hypha/apply/projects/views/project.py b/hypha/apply/projects/views/project.py index 9fa762881..9cdace426 100644 --- a/hypha/apply/projects/views/project.py +++ b/hypha/apply/projects/views/project.py @@ -670,6 +670,11 @@ class AdminProjectDetailView( model = Project template_name_suffix = '_admin_detail' + def dispatch(self, *args, **kwargs): + project = self.get_object() + permission, _ = has_permission('project_access', self.request.user, object=project, raise_exception=True) + return super().dispatch(*args, **kwargs) + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) project_settings = ProjectSettings.for_request(self.request) @@ -716,8 +721,7 @@ class ApplicantProjectDetailView( def dispatch(self, request, *args, **kwargs): project = self.get_object() - if project.user != request.user: - raise PermissionDenied + permission, _ = has_permission('project_access', request.user, object=project, raise_exception=True) return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): -- GitLab