Merge branch 'main' into rjm/3318-remove-from-domains-if-removed-from-portfolio

This commit is contained in:
Rachid Mrad 2025-02-03 18:25:30 -05:00 committed by GitHub
commit 3867910d05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 59 additions and 6 deletions

View file

@ -29,7 +29,7 @@
font-weight: 400 !important; font-weight: 400 !important;
} }
.domains__table { .domains__table, .usa-table {
/* /*
Trick tooltips in the domains table to do 2 things... Trick tooltips in the domains table to do 2 things...
1 - Shrink itself to a padded viewport window 1 - Shrink itself to a padded viewport window

View file

@ -5,17 +5,20 @@ from django.views import View
from django.shortcuts import render from django.shortcuts import render
from django.contrib import admin from django.contrib import admin
from django.db.models import Avg, F from django.db.models import Avg, F
from registrar.views.utility.mixins import DomainAndRequestsReportsPermission, PortfolioReportsPermission
from .. import models from .. import models
import datetime import datetime
from django.utils import timezone from django.utils import timezone
from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator
from registrar.utility import csv_export from registrar.utility import csv_export
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@method_decorator(staff_member_required, name="dispatch")
class AnalyticsView(View): class AnalyticsView(View):
def get(self, request): def get(self, request):
thirty_days_ago = datetime.datetime.today() - datetime.timedelta(days=30) thirty_days_ago = datetime.datetime.today() - datetime.timedelta(days=30)
@ -149,6 +152,7 @@ class AnalyticsView(View):
return render(request, "admin/analytics.html", context) return render(request, "admin/analytics.html", context)
@method_decorator(staff_member_required, name="dispatch")
class ExportDataType(View): class ExportDataType(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# match the CSV example with all the fields # match the CSV example with all the fields
@ -158,7 +162,7 @@ class ExportDataType(View):
return response return response
class ExportDataTypeUser(View): class ExportDataTypeUser(DomainAndRequestsReportsPermission, View):
"""Returns a domain report for a given user on the request""" """Returns a domain report for a given user on the request"""
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -169,7 +173,7 @@ class ExportDataTypeUser(View):
return response return response
class ExportMembersPortfolio(View): class ExportMembersPortfolio(PortfolioReportsPermission, View):
"""Returns a members report for a given portfolio""" """Returns a members report for a given portfolio"""
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -197,7 +201,7 @@ class ExportMembersPortfolio(View):
return response return response
class ExportDataTypeRequests(View): class ExportDataTypeRequests(DomainAndRequestsReportsPermission, View):
"""Returns a domain requests report for a given user on the request""" """Returns a domain requests report for a given user on the request"""
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -208,6 +212,7 @@ class ExportDataTypeRequests(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDataFull(View): class ExportDataFull(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Smaller export based on 1 # Smaller export based on 1
@ -217,6 +222,7 @@ class ExportDataFull(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDataFederal(View): class ExportDataFederal(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Federal only # Federal only
@ -226,6 +232,7 @@ class ExportDataFederal(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDomainRequestDataFull(View): class ExportDomainRequestDataFull(View):
"""Generates a downloaded report containing all Domain Requests (except started)""" """Generates a downloaded report containing all Domain Requests (except started)"""
@ -237,6 +244,7 @@ class ExportDomainRequestDataFull(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDataDomainsGrowth(View): class ExportDataDomainsGrowth(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
start_date = request.GET.get("start_date", "") start_date = request.GET.get("start_date", "")
@ -249,6 +257,7 @@ class ExportDataDomainsGrowth(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDataRequestsGrowth(View): class ExportDataRequestsGrowth(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
start_date = request.GET.get("start_date", "") start_date = request.GET.get("start_date", "")
@ -261,6 +270,7 @@ class ExportDataRequestsGrowth(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDataManagedDomains(View): class ExportDataManagedDomains(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
start_date = request.GET.get("start_date", "") start_date = request.GET.get("start_date", "")
@ -272,6 +282,7 @@ class ExportDataManagedDomains(View):
return response return response
@method_decorator(staff_member_required, name="dispatch")
class ExportDataUnmanagedDomains(View): class ExportDataUnmanagedDomains(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
start_date = request.GET.get("start_date", "") start_date = request.GET.get("start_date", "")

View file

@ -153,6 +153,48 @@ class PermissionsLoginMixin(PermissionRequiredMixin):
return super().handle_no_permission() return super().handle_no_permission()
class DomainAndRequestsReportsPermission(PermissionsLoginMixin):
"""Permission mixin for domain and requests csv downloads"""
def has_permission(self):
"""Check if this user has access to this domain.
The user is in self.request.user and the domain needs to be looked
up from the domain's primary key in self.kwargs["pk"]
"""
if not self.request.user.is_authenticated:
return False
if self.request.user.is_restricted():
return False
return True
class PortfolioReportsPermission(PermissionsLoginMixin):
"""Permission mixin for portfolio csv downloads"""
def has_permission(self):
"""Check if this user has access to this domain.
The user is in self.request.user and the domain needs to be looked
up from the domain's primary key in self.kwargs["pk"]
"""
if not self.request.user.is_authenticated:
return False
if self.request.user.is_restricted():
return False
portfolio = self.request.session.get("portfolio")
if not self.request.user.has_view_members_portfolio_permission(portfolio):
return False
return self.request.user.is_org_user(self.request)
class DomainPermission(PermissionsLoginMixin): class DomainPermission(PermissionsLoginMixin):
"""Permission mixin that redirects to domain if user has access, """Permission mixin that redirects to domain if user has access,
otherwise 403""" otherwise 403"""