mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-17 10:07:04 +02:00
working permissions
This commit is contained in:
parent
ebb95a7d67
commit
777be646a4
10 changed files with 69 additions and 120 deletions
|
@ -654,7 +654,6 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
|
||||||
"user_permissions",
|
"user_permissions",
|
||||||
"portfolio",
|
"portfolio",
|
||||||
"portfolio_roles",
|
"portfolio_roles",
|
||||||
"portfolio_permissions",
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -685,7 +684,6 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
|
||||||
"groups",
|
"groups",
|
||||||
"portfolio",
|
"portfolio",
|
||||||
"portfolio_roles",
|
"portfolio_roles",
|
||||||
"portfolio_permissions",
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -717,7 +715,6 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
|
||||||
"date_joined",
|
"date_joined",
|
||||||
"portfolio",
|
"portfolio",
|
||||||
"portfolio_roles",
|
"portfolio_roles",
|
||||||
"portfolio_permissions",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
list_filter = (
|
list_filter = (
|
||||||
|
|
|
@ -240,6 +240,7 @@ TEMPLATES = [
|
||||||
"registrar.context_processors.canonical_path",
|
"registrar.context_processors.canonical_path",
|
||||||
"registrar.context_processors.is_demo_site",
|
"registrar.context_processors.is_demo_site",
|
||||||
"registrar.context_processors.is_production",
|
"registrar.context_processors.is_production",
|
||||||
|
"registrar.context_processors.portfolio_permissions",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,18 +40,10 @@ def is_production(request):
|
||||||
return {"IS_PRODUCTION": settings.IS_PRODUCTION}
|
return {"IS_PRODUCTION": settings.IS_PRODUCTION}
|
||||||
|
|
||||||
|
|
||||||
def has_base_portfolio_permission(request):
|
def portfolio_permissions(request):
|
||||||
""""""
|
""""""
|
||||||
return {"has_base_portfolio_permission": request.user.has_portfolio_permissions(User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO)}
|
return {
|
||||||
|
"has_base_portfolio_permission": request.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO),
|
||||||
def has_domains_portfolio_permission(request):
|
"has_domains_portfolio_permission": request.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_DOMAINS),
|
||||||
""""""
|
"has_domain_requests_portfolio_permission": request.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_REQUESTS)
|
||||||
return {"has_domains_portfolio_permission": request.user.has_portfolio_permissions(User.UserPortfolioPermissionChoices.VIEW_DOMAINS)}
|
}
|
||||||
|
|
||||||
def has_requests_portfolio_permission(request):
|
|
||||||
""""""
|
|
||||||
return {"has_requests_portfolio_permission": request.user.has_portfolio_permissions(User.UserPortfolioPermissionChoices.VIEW_REQUESTS)}
|
|
||||||
|
|
||||||
def has_organization_portfolio_permission(request):
|
|
||||||
""""""
|
|
||||||
return {"has_organization_portfolio_permission": request.user.has_portfolio_permissions(User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO)}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 4.2.10 on 2024-07-15 22:07
|
# Generated by Django 4.2.10 on 2024-07-17 17:12
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import django.contrib.postgres.fields
|
import django.contrib.postgres.fields
|
||||||
|
@ -24,29 +24,6 @@ class Migration(migrations.Migration):
|
||||||
to="registrar.portfolio",
|
to="registrar.portfolio",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
|
||||||
model_name="user",
|
|
||||||
name="portfolio_permissions",
|
|
||||||
field=django.contrib.postgres.fields.ArrayField(
|
|
||||||
base_field=models.CharField(
|
|
||||||
choices=[
|
|
||||||
("view_domains", "View all domains and domain reports"),
|
|
||||||
("edit_domains", "User is a manager on a domain"),
|
|
||||||
("view_member", "View members"),
|
|
||||||
("edit_member", "Create and edit members"),
|
|
||||||
("view_requests", "View requests"),
|
|
||||||
("edit_requests", "Create and edit requests"),
|
|
||||||
("view_portfolio", "View organization"),
|
|
||||||
("edit_portfolio", "Edit organization"),
|
|
||||||
],
|
|
||||||
max_length=50,
|
|
||||||
),
|
|
||||||
blank=True,
|
|
||||||
help_text="Select one or more permissions.",
|
|
||||||
null=True,
|
|
||||||
size=None,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name="user",
|
model_name="user",
|
||||||
name="portfolio_roles",
|
name="portfolio_roles",
|
|
@ -63,6 +63,7 @@ class User(AbstractUser):
|
||||||
|
|
||||||
class UserPortfolioRoleChoices(models.TextChoices):
|
class UserPortfolioRoleChoices(models.TextChoices):
|
||||||
"""
|
"""
|
||||||
|
Roles make it easier for admins to look at
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ORGANIZATION_ADMIN = "organization_admin", "Admin"
|
ORGANIZATION_ADMIN = "organization_admin", "Admin"
|
||||||
|
@ -149,15 +150,15 @@ class User(AbstractUser):
|
||||||
help_text="Select one or more roles.",
|
help_text="Select one or more roles.",
|
||||||
)
|
)
|
||||||
|
|
||||||
portfolio_permissions = ArrayField(
|
# portfolio_permissions = ArrayField(
|
||||||
models.CharField(
|
# models.CharField(
|
||||||
max_length=50,
|
# max_length=50,
|
||||||
choices=UserPortfolioPermissionChoices.choices,
|
# choices=UserPortfolioPermissionChoices.choices,
|
||||||
),
|
# ),
|
||||||
null=True,
|
# null=True,
|
||||||
blank=True,
|
# blank=True,
|
||||||
help_text="Select one or more permissions.",
|
# help_text="Select one or more permissions.",
|
||||||
)
|
# )
|
||||||
|
|
||||||
phone = PhoneNumberField(
|
phone = PhoneNumberField(
|
||||||
null=True,
|
null=True,
|
||||||
|
@ -252,30 +253,30 @@ class User(AbstractUser):
|
||||||
"""Do not rely on roles when testing for perms in views"""
|
"""Do not rely on roles when testing for perms in views"""
|
||||||
return role in self.portfolio_roles if self.portfolio_roles else False
|
return role in self.portfolio_roles if self.portfolio_roles else False
|
||||||
|
|
||||||
def has_portfolio_permissions(self, portfolio_permission):
|
def has_portfolio_permission(self, portfolio_permission):
|
||||||
"""The views should only call this guy when testing for perms and not rely on roles"""
|
"""The views should only call this guy when testing for perms and not rely on roles"""
|
||||||
|
|
||||||
# TODO: this does not seem to be working
|
# TODO: this does not seem to be working
|
||||||
if portfolio_permission == self.UserPortfolioPermissionChoices.EDIT_DOMAINS and self.domains.exists():
|
# if portfolio_permission == self.UserPortfolioPermissionChoices.EDIT_DOMAINS and self.domains.exists():
|
||||||
print(f'portfolio_permission {portfolio_permission}')
|
# return True
|
||||||
return True
|
|
||||||
|
|
||||||
print(f'portfolio_permission {portfolio_permission}')
|
if not self.portfolio:
|
||||||
|
return False
|
||||||
|
|
||||||
return portfolio_permission in self.portfolio_permissions if self.portfolio_permissions else False
|
portfolio_permissions = self.get_portfolio_permissions()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
return portfolio_permission in portfolio_permissions
|
||||||
self.update_permissions_from_roles()
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
def update_permissions_from_roles(self):
|
def get_portfolio_permissions(self):
|
||||||
print('update permissions when saving')
|
"""
|
||||||
new_portfolio_permissions = set(self.portfolio_permissions or [])
|
Retrieve the permissions for the user's portfolio roles.
|
||||||
print(f'new_portfolio_permissions {new_portfolio_permissions}')
|
"""
|
||||||
for role in self.portfolio_roles or []:
|
portfolio_permissions = set() # Use a set to avoid duplicate permissions
|
||||||
print(f'role {role}')
|
|
||||||
new_portfolio_permissions.update(self.PORTFOLIO_ROLE_PERMISSIONS.get(role, []))
|
for role in self.portfolio_roles:
|
||||||
self.portfolio_permissions = list(new_portfolio_permissions)
|
if role in self.PORTFOLIO_ROLE_PERMISSIONS:
|
||||||
|
portfolio_permissions.update(self.PORTFOLIO_ROLE_PERMISSIONS[role])
|
||||||
|
return list(portfolio_permissions) # Convert back to list if necessary
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def needs_identity_verification(cls, email, uuid):
|
def needs_identity_verification(cls, email, uuid):
|
||||||
|
|
|
@ -6,7 +6,7 @@ import logging
|
||||||
from urllib.parse import parse_qs
|
from urllib.parse import parse_qs
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from registrar.context_processors import has_base_portfolio_permission, has_domains_portfolio_permission, has_requests_portfolio_permission
|
from registrar.context_processors import portfolio_permissions
|
||||||
from registrar.models.user import User
|
from registrar.models.user import User
|
||||||
from waffle.decorators import flag_is_active
|
from waffle.decorators import flag_is_active
|
||||||
|
|
||||||
|
@ -148,19 +148,21 @@ class CheckPortfolioMiddleware:
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
# user_portfolios = Portfolio.objects.filter(creator=request.user)
|
# user_portfolios = Portfolio.objects.filter(creator=request.user)
|
||||||
|
|
||||||
if has_base_portfolio_permission(request):
|
permission_dict = portfolio_permissions(request)
|
||||||
# print('user has portfolio')
|
has_portfolio_base_permission = permission_dict['has_base_portfolio_permission']
|
||||||
|
|
||||||
|
if has_portfolio_base_permission:
|
||||||
portfolio = request.user.portfolio
|
portfolio = request.user.portfolio
|
||||||
|
|
||||||
if has_domains_portfolio_permission(request):
|
permission_dict = portfolio_permissions(request)
|
||||||
|
has_portfolio_domains_permission = permission_dict['has_domains_portfolio_permission']
|
||||||
|
|
||||||
|
if has_portfolio_domains_permission:
|
||||||
portfolio_redirect = reverse("portfolio-domains", kwargs={"portfolio_id": portfolio.id})
|
portfolio_redirect = reverse("portfolio-domains", kwargs={"portfolio_id": portfolio.id})
|
||||||
elif has_requests_portfolio_permission(request):
|
|
||||||
portfolio_redirect = reverse("portfolio-requests", kwargs={"portfolio_id": portfolio.id})
|
|
||||||
else:
|
else:
|
||||||
# View organization is the lowest access
|
# View organization is the lowest access
|
||||||
portfolio_redirect = reverse("portfolio-organization", kwargs={"portfolio_id": portfolio.id})
|
portfolio_redirect = reverse("portfolio-organization", kwargs={"portfolio_id": portfolio.id})
|
||||||
|
|
||||||
return HttpResponseRedirect(portfolio_redirect)
|
return HttpResponseRedirect(portfolio_redirect)
|
||||||
|
|
||||||
# print('user does not have a portfolio')
|
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -12,7 +12,15 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if has_requests_portfolio_permission %}
|
|
||||||
|
<li class="usa-sidenav__item">
|
||||||
|
{% url 'portfolio-organization' portfolio.id as url %}
|
||||||
|
<a href="{{ url }}" {% if request.path == url %}class="usa-current"{% endif %}>
|
||||||
|
Organization
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{% if has_domain_requests_portfolio_permission %}
|
||||||
<li class="usa-sidenav__item">
|
<li class="usa-sidenav__item">
|
||||||
{% url 'portfolio-domain-requests' portfolio.id as url %}
|
{% url 'portfolio-domain-requests' portfolio.id as url %}
|
||||||
<a href="{{ url }}" {% if request.path == url %}class="usa-current"{% endif %}>
|
<a href="{{ url }}" {% if request.path == url %}class="usa-current"{% endif %}>
|
||||||
|
@ -26,12 +34,7 @@
|
||||||
Members
|
Members
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="usa-sidenav__item">
|
|
||||||
{% url 'portfolio-organization' portfolio.id as url %}
|
|
||||||
<a href="{{ url }}" {% if request.path == url %}class="usa-current"{% endif %}>
|
|
||||||
Organization
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="usa-sidenav__item">
|
<li class="usa-sidenav__item">
|
||||||
<a href="#">
|
<a href="#">
|
||||||
Senior official
|
Senior official
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from registrar.models.portfolio import Portfolio
|
from registrar.models.portfolio import Portfolio
|
||||||
from registrar.views.utility.permission_views import PortfolioDomainRequestsPermissionView, PortfolioDomainsPermissionView, PortfolioOrganizationssPermissionView
|
from registrar.views.utility.permission_views import PortfolioDomainRequestsPermissionView, PortfolioDomainsPermissionView, PortfolioBasePermissionView
|
||||||
from waffle.decorators import flag_is_active
|
from waffle.decorators import flag_is_active
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class PortfolioDomainRequestsView(PortfolioDomainRequestsPermissionView, View):
|
||||||
|
|
||||||
return render(request, "portfolio_requests.html", context)
|
return render(request, "portfolio_requests.html", context)
|
||||||
|
|
||||||
class PortfolioOrganizationView(PortfolioOrganizationssPermissionView, View):
|
class PortfolioOrganizationView(PortfolioBasePermissionView, View):
|
||||||
|
|
||||||
template_name = "portfolio_organization.html"
|
template_name = "portfolio_organization.html"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
|
|
||||||
from registrar.context_processors import has_base_portfolio_permission, has_domains_portfolio_permission, has_organization_portfolio_permission, has_requests_portfolio_permission
|
from registrar.context_processors import portfolio_permissions
|
||||||
from registrar.models import (
|
from registrar.models import (
|
||||||
Domain,
|
Domain,
|
||||||
DomainRequest,
|
DomainRequest,
|
||||||
|
@ -402,7 +402,7 @@ class UserProfilePermission(PermissionsLoginMixin):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class PortfolioPermission(PermissionsLoginMixin):
|
class PortfolioBasePermission(PermissionsLoginMixin):
|
||||||
"""Permission mixin that redirects to portfolio pages if user
|
"""Permission mixin that redirects to portfolio pages if user
|
||||||
has access, otherwise 403"""
|
has access, otherwise 403"""
|
||||||
|
|
||||||
|
@ -415,15 +415,15 @@ class PortfolioPermission(PermissionsLoginMixin):
|
||||||
if not self.request.user.is_authenticated:
|
if not self.request.user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# portfolio_id = self.kwargs["pk"]
|
permission_dict = portfolio_permissions(self.request)
|
||||||
# portfolio = Portfolio.objects.get(pk=portfolio_id)
|
has_permission = permission_dict['has_base_portfolio_permission']
|
||||||
|
|
||||||
if not has_base_portfolio_permission(self.request):
|
if not has_permission:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class PortfolioDomainsPermission(PortfolioPermission):
|
class PortfolioDomainsPermission(PortfolioBasePermission):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -431,18 +431,16 @@ class PortfolioDomainsPermission(PortfolioPermission):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_dict = has_domains_portfolio_permission(self.request)
|
permission_dict = portfolio_permissions(self.request)
|
||||||
has_permission = permission_dict['has_domains_portfolio_permission']
|
has_permission = permission_dict['has_domains_portfolio_permission']
|
||||||
|
|
||||||
if not has_permission:
|
if not has_permission:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print('return true')
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class PortfolioDomainRequestsPermission(PortfolioPermission):
|
class PortfolioDomainRequestsPermission(PortfolioBasePermission):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -450,24 +448,8 @@ class PortfolioDomainRequestsPermission(PortfolioPermission):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_dict = has_requests_portfolio_permission(self.request)
|
permission_dict = portfolio_permissions(self.request)
|
||||||
has_permission = permission_dict['has_requests_portfolio_permission']
|
has_permission = permission_dict['has_domain_requests_portfolio_permission']
|
||||||
|
|
||||||
if not has_permission:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
class PortfolioOrganizationssPermission(PortfolioPermission):
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
|
|
||||||
permission_dict = has_organization_portfolio_permission(self.request)
|
|
||||||
has_permission = permission_dict['has_organization_portfolio_permission']
|
|
||||||
|
|
||||||
if not has_permission:
|
if not has_permission:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -15,10 +15,9 @@ from .mixins import (
|
||||||
DomainRequestWizardPermission,
|
DomainRequestWizardPermission,
|
||||||
PortfolioDomainRequestsPermission,
|
PortfolioDomainRequestsPermission,
|
||||||
PortfolioDomainsPermission,
|
PortfolioDomainsPermission,
|
||||||
PortfolioOrganizationssPermission,
|
|
||||||
UserDeleteDomainRolePermission,
|
UserDeleteDomainRolePermission,
|
||||||
UserProfilePermission,
|
UserProfilePermission,
|
||||||
PortfolioPermission,
|
PortfolioBasePermission,
|
||||||
)
|
)
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -169,7 +168,7 @@ class UserProfilePermissionView(UserProfilePermission, DetailView, abc.ABC):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class PortfolioBasePermissionView(PortfolioPermission, DetailView, abc.ABC):
|
class PortfolioBasePermissionView(PortfolioBasePermission, DetailView, abc.ABC):
|
||||||
"""Abstract base view for portfolio views that enforces permissions.
|
"""Abstract base view for portfolio views that enforces permissions.
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
This abstract view cannot be instantiated. Actual views must specify
|
||||||
|
@ -196,8 +195,3 @@ class PortfolioDomainsPermissionView(PortfolioDomainsPermission, PortfolioBasePe
|
||||||
class PortfolioDomainRequestsPermissionView(PortfolioDomainRequestsPermission, PortfolioBasePermissionView, abc.ABC):
|
class PortfolioDomainRequestsPermissionView(PortfolioDomainRequestsPermission, PortfolioBasePermissionView, abc.ABC):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class PortfolioOrganizationssPermissionView(PortfolioOrganizationssPermission, PortfolioBasePermissionView, abc.ABC):
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue