diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py index 58d8145522..50e61b63bc 100644 --- a/hypha/apply/funds/models/submissions.py +++ b/hypha/apply/funds/models/submissions.py @@ -5,6 +5,7 @@ from django.apps import apps from django.conf import settings from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group from django.contrib.contenttypes.fields import GenericRelation from django.contrib.postgres.indexes import GinIndex from django.contrib.postgres.search import SearchVector, SearchVectorField @@ -44,6 +45,7 @@ from hypha.apply.review.options import AGREE from hypha.apply.stream_forms.files import StreamFieldDataEncoder from hypha.apply.stream_forms.models import BaseStreamForm +from hypha.apply.users.groups import APPLICANT_GROUP_NAME from ..blocks import NAMED_BLOCKS, ApplicationCustomFormFieldsBlock from ..workflow import ( @@ -507,6 +509,11 @@ def ensure_user_has_account(self): if self.user and self.user.is_authenticated: self.form_data['email'] = self.user.email self.form_data['full_name'] = self.user.get_full_name() + # Ensure applying user should have applicant role + if not self.user.is_applicant: + applicant_group = Group.objects.get(name=APPLICANT_GROUP_NAME) + self.user.groups.add(applicant_group) + self.user.save() else: # Rely on the form having the following must include fields (see blocks.py) email = self.form_data.get('email') @@ -519,6 +526,11 @@ def ensure_user_has_account(self): email=email, defaults={'full_name': full_name} ) + # Ensure applying user should have applicant role + if not self.user.is_applicant: + applicant_group = Group.objects.get(name=APPLICANT_GROUP_NAME) + self.user.groups.add(applicant_group) + self.user.save() else: self.user, _ = User.objects.get_or_create_and_notify( email=email, diff --git a/hypha/apply/projects/views/project.py b/hypha/apply/projects/views/project.py index 807b4f939f..3a82b2b879 100644 --- a/hypha/apply/projects/views/project.py +++ b/hypha/apply/projects/views/project.py @@ -208,7 +208,7 @@ class RemoveContractDocumentView(DelegatedViewMixin, FormView): model = Project def dispatch(self, request, *args, **kwargs): - if not request.user.is_applicant: + if not request.user.is_applicant or request.user != self.get_object().user: raise PermissionDenied return super().dispatch(request, *args, **kwargs) @@ -228,6 +228,7 @@ def form_valid(self, form): @method_decorator(login_required, name='dispatch') class SelectDocumentView(DelegatedViewMixin, CreateView): + # todo: (no role issue) not getting used anywhere form_class = SelectDocumentForm context_name = 'select_document_form' model = PacketFile @@ -472,6 +473,11 @@ class UploadContractDocumentView(DelegatedViewMixin, CreateView): model = Project context_name = 'contract_document_form' + def dispatch(self, request, *args, **kwargs): + if request.user != self.get_object().user or not request.user.is_applicant: + raise PermissionDenied + return super().dispatch(request, *args, **kwargs) + def form_valid(self, form): project = self.kwargs['object'] form.instance.project = project diff --git a/hypha/apply/projects/views/project_partials.py b/hypha/apply/projects/views/project_partials.py index 72e24dc8c7..d0d2b12989 100644 --- a/hypha/apply/projects/views/project_partials.py +++ b/hypha/apply/projects/views/project_partials.py @@ -7,12 +7,14 @@ ) from ..models.project import Project +from ..permissions import has_permission @login_required @require_GET def partial_project_activities(request, pk): project = get_object_or_404(Project, pk=pk) + has_permission('project_access', request.user, object=project, raise_exception=True) ctx = { 'actions': get_related_actions_for_user(project, request.user) } diff --git a/hypha/apply/utils/views.py b/hypha/apply/utils/views.py index 351d1b560f..9f76f0fb12 100644 --- a/hypha/apply/utils/views.py +++ b/hypha/apply/utils/views.py @@ -50,8 +50,11 @@ def finance_check(self, request): def contracting_check(self, request): return request.user.is_contracting + def applicant_check(self, request): + return request.user.is_applicant + def dispatch(self, request, *args, **kwargs): - view = self.applicant_view + view = None if self.admin_check(request): view = self.admin_view @@ -65,6 +68,8 @@ def dispatch(self, request, *args, **kwargs): view = self.finance_view elif self.contracting_check(request): view = self.contracting_view + elif self.applicant_check(request): + view = self.applicant_view if view: return view.as_view()(request, *args, **kwargs)