mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 20:18:38 +02:00
wip
This commit is contained in:
parent
9aa3504426
commit
2ecbab459b
8 changed files with 91 additions and 4 deletions
|
@ -81,6 +81,11 @@ urlpatterns = [
|
||||||
views.PortfolioMembersView.as_view(),
|
views.PortfolioMembersView.as_view(),
|
||||||
name="members",
|
name="members",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"member/<int:pk>",
|
||||||
|
views.PortfolioMemberView.as_view(),
|
||||||
|
name="member",
|
||||||
|
),
|
||||||
# path(
|
# path(
|
||||||
# "no-organization-members/",
|
# "no-organization-members/",
|
||||||
# views.PortfolioNoMembersView.as_view(),
|
# views.PortfolioNoMembersView.as_view(),
|
||||||
|
|
|
@ -7,7 +7,7 @@ from registrar.fixtures.fixtures_users import UserFixture
|
||||||
from registrar.models import User
|
from registrar.models import User
|
||||||
from registrar.models.portfolio import Portfolio
|
from registrar.models.portfolio import Portfolio
|
||||||
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
||||||
from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
|
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
||||||
|
|
||||||
fake = Faker()
|
fake = Faker()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -58,6 +58,7 @@ class UserPortfolioPermissionFixture:
|
||||||
user=user,
|
user=user,
|
||||||
portfolio=portfolio,
|
portfolio=portfolio,
|
||||||
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
||||||
|
additional_permissions=[UserPortfolioPermissionChoices.EDIT_MEMBERS],
|
||||||
)
|
)
|
||||||
user_portfolio_permissions_to_create.append(user_portfolio_permission)
|
user_portfolio_permissions_to_create.append(user_portfolio_permission)
|
||||||
else:
|
else:
|
||||||
|
|
32
src/registrar/templates/portfolio_member.html
Normal file
32
src/registrar/templates/portfolio_member.html
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{% extends 'portfolio_base.html' %}
|
||||||
|
{% load static field_helpers%}
|
||||||
|
|
||||||
|
{% block title %}Organization member {% endblock %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block portfolio_content %}
|
||||||
|
<div class="grid-row grid-gap">
|
||||||
|
<div class="tablet:grid-col-3">
|
||||||
|
<p class="font-body-md margin-top-0 margin-bottom-2
|
||||||
|
text-primary-darker text-semibold"
|
||||||
|
>
|
||||||
|
<span class="usa-sr-only"> Portfolio name:</span> {{ portfolio }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tablet:grid-col-9" id="main-content">
|
||||||
|
|
||||||
|
{% block messages %}
|
||||||
|
{% include "includes/form_messages.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<h1>Member</h1>
|
||||||
|
|
||||||
|
<p>The name of your organization will be publicly listed as the domain registrant.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -68,6 +68,11 @@ class GetPortfolioMembersJsonTest(TestWithUser, WebTest):
|
||||||
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def tearDownClass(cls):
|
||||||
|
UserPortfolioPermission.objects.all().delete()
|
||||||
|
Portfolio.objects.all().delete()
|
||||||
|
User.objects.all().delete()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.app.set_user(self.user.username)
|
self.app.set_user(self.user.username)
|
||||||
|
|
|
@ -2,6 +2,7 @@ from django.http import JsonResponse
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from registrar.models.portfolio_invitation import PortfolioInvitation
|
from registrar.models.portfolio_invitation import PortfolioInvitation
|
||||||
from registrar.models.user import User
|
from registrar.models.user import User
|
||||||
|
@ -118,7 +119,7 @@ def serialize_members(request, portfolio, member, user, admin_ids, portfolio_inv
|
||||||
"email": member.email,
|
"email": member.email,
|
||||||
"is_admin": is_admin,
|
"is_admin": is_admin,
|
||||||
"last_active": last_active,
|
"last_active": last_active,
|
||||||
"action_url": "#", # reverse("members", kwargs={"pk": member.id}), # TODO: Future ticket?
|
"action_url": reverse("member", kwargs={"pk": member.id}), # TODO: Future ticket?
|
||||||
"action_label": ("View" if view_only else "Manage"),
|
"action_label": ("View" if view_only else "Manage"),
|
||||||
"svg_icon": ("visibility" if view_only else "settings"),
|
"svg_icon": ("visibility" if view_only else "settings"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ from registrar.views.utility.permission_views import (
|
||||||
PortfolioDomainsPermissionView,
|
PortfolioDomainsPermissionView,
|
||||||
PortfolioBasePermissionView,
|
PortfolioBasePermissionView,
|
||||||
NoPortfolioDomainsPermissionView,
|
NoPortfolioDomainsPermissionView,
|
||||||
|
PortfolioMemberPermissionView,
|
||||||
PortfolioMembersPermissionView,
|
PortfolioMembersPermissionView,
|
||||||
)
|
)
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
@ -51,6 +52,18 @@ class PortfolioMembersView(PortfolioMembersPermissionView, View):
|
||||||
return render(request, "portfolio_members.html")
|
return render(request, "portfolio_members.html")
|
||||||
|
|
||||||
|
|
||||||
|
class PortfolioMemberView(PortfolioMemberPermissionView, View):
|
||||||
|
|
||||||
|
template_name = "portfolio_member.html"
|
||||||
|
model = User
|
||||||
|
|
||||||
|
# def get(self, request):
|
||||||
|
# """Add additional context data to the template."""
|
||||||
|
# return render(request, self.template_name, context=self.get_context_data())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioNoDomainsView(NoPortfolioDomainsPermissionView, View):
|
class PortfolioNoDomainsView(NoPortfolioDomainsPermissionView, View):
|
||||||
"""Some users have access to the underlying portfolio, but not any domains.
|
"""Some users have access to the underlying portfolio, but not any domains.
|
||||||
This is a custom view which explains that to the user - and denotes who to contact.
|
This is a custom view which explains that to the user - and denotes who to contact.
|
||||||
|
|
|
@ -490,7 +490,28 @@ class PortfolioMembersPermission(PortfolioBasePermission):
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]"""
|
up from the portfolio's primary key in self.kwargs["pk"]"""
|
||||||
|
|
||||||
portfolio = self.request.session.get("portfolio")
|
portfolio = self.request.session.get("portfolio")
|
||||||
if not self.request.user.has_view_members_portfolio_permission(portfolio):
|
if not self.request.user.has_view_members_portfolio_permission(
|
||||||
|
portfolio
|
||||||
|
) and not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return super().has_permission()
|
||||||
|
|
||||||
|
|
||||||
|
class PortfolioMemberPermission(PortfolioBasePermission):
|
||||||
|
"""Permission mixin that allows access to portfolio member pages if user
|
||||||
|
has access, otherwise 403"""
|
||||||
|
|
||||||
|
def has_permission(self):
|
||||||
|
"""Check if this user has access to members for this portfolio.
|
||||||
|
|
||||||
|
The user is in self.request.user and the portfolio can be looked
|
||||||
|
up from the portfolio's primary key in self.kwargs["pk"]"""
|
||||||
|
|
||||||
|
portfolio = self.request.session.get("portfolio")
|
||||||
|
if not self.request.user.has_view_members_portfolio_permission(
|
||||||
|
portfolio
|
||||||
|
) and not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return super().has_permission()
|
return super().has_permission()
|
||||||
|
|
|
@ -19,6 +19,7 @@ from .mixins import (
|
||||||
UserProfilePermission,
|
UserProfilePermission,
|
||||||
PortfolioBasePermission,
|
PortfolioBasePermission,
|
||||||
PortfolioMembersPermission,
|
PortfolioMembersPermission,
|
||||||
|
PortfolioMemberPermission,
|
||||||
DomainRequestPortfolioViewonlyPermission,
|
DomainRequestPortfolioViewonlyPermission,
|
||||||
)
|
)
|
||||||
import logging
|
import logging
|
||||||
|
@ -253,7 +254,15 @@ class PortfolioDomainRequestsPermissionView(PortfolioDomainRequestsPermission, P
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMembersPermissionView(PortfolioMembersPermission, PortfolioBasePermissionView, abc.ABC):
|
class PortfolioMembersPermissionView(PortfolioMembersPermission, PortfolioBasePermissionView, abc.ABC):
|
||||||
"""Abstract base view for portfolio domain request views that enforces permissions.
|
"""Abstract base view for portfolio members views that enforces permissions.
|
||||||
|
|
||||||
|
This abstract view cannot be instantiated. Actual views must specify
|
||||||
|
`template_name`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class PortfolioMemberPermissionView(PortfolioMemberPermission, PortfolioBasePermissionView, abc.ABC):
|
||||||
|
"""Abstract base view for portfolio member views that enforces permissions.
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
This abstract view cannot be instantiated. Actual views must specify
|
||||||
`template_name`.
|
`template_name`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue