From 8b76cde13d1b435f697ad1e05811edb953becbc2 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:33:07 -0700 Subject: [PATCH] Start correcting additional perms --- src/registrar/decorators.py | 33 ++++++++++++++++++++++++------- src/registrar/views/portfolios.py | 23 ++++++++++----------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/registrar/decorators.py b/src/registrar/decorators.py index 829011817..aa16e91f5 100644 --- a/src/registrar/decorators.py +++ b/src/registrar/decorators.py @@ -2,6 +2,8 @@ import functools from django.core.exceptions import PermissionDenied from django.utils.decorators import method_decorator from registrar.models import Domain, DomainInformation, DomainInvitation, DomainRequest, UserDomainRole +from registrar.models.portfolio_invitation import PortfolioInvitation +from registrar.models.user_portfolio_permission import UserPortfolioPermission # Constants for clarity ALL = "all" @@ -116,7 +118,9 @@ def _user_has_permission(user, request, rules, **kwargs): ), ( IS_PORTFOLIO_MEMBER_AND_DOMAIN_MANAGER, - lambda: _is_domain_manager(user, **kwargs) and _is_portfolio_member(request), + lambda: _is_domain_manager(user, **kwargs) + and _is_portfolio_member(request) + and _domain_exists_under_portfolio(portfolio, kwargs.get("domain_pk")), ), ( IS_DOMAIN_MANAGER_AND_NOT_PORTFOLIO_MEMBER, @@ -141,6 +145,7 @@ def _user_has_permission(user, request, rules, **kwargs): ( HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT, lambda: _has_portfolio_domain_requests_edit(user, request, kwargs.get("domain_request_pk")) + and _domain_request_exists_under_portfolio(portfolio, kwargs.get("domain_request_pk")), ), ( HAS_PORTFOLIO_MEMBERS_ANY_PERM, @@ -153,12 +158,17 @@ def _user_has_permission(user, request, rules, **kwargs): ( HAS_PORTFOLIO_MEMBERS_EDIT, lambda: user.is_org_user(request) - and user.has_edit_members_portfolio_permission(portfolio), + and user.has_edit_members_portfolio_permission(portfolio) ), ( HAS_PORTFOLIO_MEMBERS_VIEW, lambda: user.is_org_user(request) - and user.has_view_members_portfolio_permission(portfolio), + and user.has_view_members_portfolio_permission(portfolio) + # TODO -- fix this on all related URLS :( + and ( + _member_exists_under_portfolio(portfolio, kwargs.get("member_pk")) + or _member_invitation_exists_under_portfolio(portfolio, kwargs.get("memberinvitation_pk")) + ), ), ] @@ -192,6 +202,19 @@ def _is_domain_manager(user, **kwargs): return DomainInvitation.objects.filter(id=domain_invitation_id, domain__permissions__user=user).exists() return False +def _domain_exists_under_portfolio(portfolio, domain_pk): + """Checks to see if the given domain exists under the provided portfolio""" + return Domain.objects.filter(domain_info__portfolio=portfolio, id=domain_pk).exists() + +def _domain_request_exists_under_portfolio(portfolio, domain_request_pk): + """Checks to see if the given domain request exists under the provided portfolio""" + return DomainRequest.objects.filter(portfolio=portfolio, id=domain_request_pk).exists() + +def _member_exists_under_portfolio(portfolio, member_pk): + return UserPortfolioPermission.objects.filter(portfolio=portfolio, id=member_pk).exists() + +def _member_invitation_exists_under_portfolio(portfolio, memberinvitation_pk): + return PortfolioInvitation.objects.filter(portfolio=portfolio, id=memberinvitation_pk).exists() def _is_domain_request_creator(user, domain_request_pk): """Checks to see if the user is the creator of a domain request @@ -200,10 +223,6 @@ def _is_domain_request_creator(user, domain_request_pk): return DomainRequest.objects.filter(creator=user, id=domain_request_pk).exists() return True -def _domain_request_exists_under_portfolio(portfolio, domain_request_pk): - """Checks to see if the given domain request exists under the provided portfolio""" - return DomainRequest.objects.filter(portfolio=portfolio, id=domain_request_pk).exists() - def _is_portfolio_member(request): """Checks to see if the user in the request is a member of the diff --git a/src/registrar/views/portfolios.py b/src/registrar/views/portfolios.py index 1882cc11b..420ef5acf 100644 --- a/src/registrar/views/portfolios.py +++ b/src/registrar/views/portfolios.py @@ -12,6 +12,7 @@ from registrar.decorators import ( HAS_PORTFOLIO_DOMAINS_ANY_PERM, HAS_PORTFOLIO_MEMBERS_ANY_PERM, HAS_PORTFOLIO_MEMBERS_EDIT, + HAS_PORTFOLIO_MEMBERS_VIEW, IS_PORTFOLIO_MEMBER, grant_access, ) @@ -71,7 +72,7 @@ class PortfolioDomainRequestsView(View): return render(request, "portfolio_requests.html") -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW) class PortfolioMemberView(DetailView, View): model = Portfolio context_object_name = "portfolio" @@ -115,7 +116,7 @@ class PortfolioMemberView(DetailView, View): ) -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW, HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioMemberDeleteView(View): def post(self, request, pk): @@ -217,7 +218,7 @@ class PortfolioMemberDeleteView(View): messages.warning(self.request, "Could not send email notification to existing organization admins.") -@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW, HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioMemberEditView(DetailView, View): model = Portfolio context_object_name = "portfolio" @@ -300,7 +301,7 @@ class PortfolioMemberEditView(DetailView, View): messages.warning(self.request, "Could not send email notification to existing organization admins.") -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW) class PortfolioMemberDomainsView(View): template_name = "portfolio_member_domains.html" @@ -319,7 +320,7 @@ class PortfolioMemberDomainsView(View): ) -@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW, HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioMemberDomainsEditView(DetailView, View): model = Portfolio context_object_name = "portfolio" @@ -431,7 +432,7 @@ class PortfolioMemberDomainsEditView(DetailView, View): UserDomainRole.objects.filter(domain_id__in=removed_domain_ids, user=member).delete() -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW) class PortfolioInvitedMemberView(DetailView, View): model = Portfolio context_object_name = "portfolio" @@ -475,7 +476,7 @@ class PortfolioInvitedMemberView(DetailView, View): ) -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW, HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioInvitedMemberDeleteView(View): def post(self, request, pk): @@ -521,7 +522,7 @@ class PortfolioInvitedMemberDeleteView(View): messages.warning(self.request, "Could not send email notification to existing organization admins.") -@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW, HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioInvitedMemberEditView(DetailView, View): model = Portfolio context_object_name = "portfolio" @@ -592,7 +593,7 @@ class PortfolioInvitedMemberEditView(DetailView, View): messages.warning(self.request, "Could not send email notification to existing organization admins.") -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW) class PortfolioInvitedMemberDomainsView(View): template_name = "portfolio_member_domains.html" @@ -609,7 +610,7 @@ class PortfolioInvitedMemberDomainsView(View): ) -@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT) +@grant_access(HAS_PORTFOLIO_MEMBERS_VIEW, HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioInvitedMemberDomainsEditView(DetailView, View): model = Portfolio @@ -903,7 +904,7 @@ class PortfolioMembersView(View): return render(request, "portfolio_members.html") -@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM) +@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT) class PortfolioAddMemberView(DetailView, FormMixin): template_name = "portfolio_members_add_new.html"