Add permissions to staff in fixtures by codename not id, make class with for the list header context updater and inherit it from domain, domain application, and contacts (the classes that implement search, filter and sort)

This commit is contained in:
rachidatecs 2023-06-28 16:23:55 -04:00
parent eac616204b
commit de36ca9cf7
No known key found for this signature in database
GPG key ID: 3CEBBFA7325E5525
5 changed files with 83 additions and 43 deletions

View file

@ -14,6 +14,7 @@ Staff
### Additional group permissions ### Additional group permissions
admin | log entry | can view log entry auditlog | log entry | can view log entry
registrar | contact | can view contact registrar | contact | can view contact
registrar | domain application | can change domain application registrar | domain application | can change domain application
registrar | domain | can view domain

View file

@ -24,6 +24,31 @@ class AuditedAdmin(admin.ModelAdmin):
) )
class ListHeaderAdmin(AuditedAdmin):
"""Custom admin to add a descriptive subheader to list views."""
def changelist_view(self, request, extra_context=None):
if extra_context is None:
extra_context = {}
# Get the filtered values
filters = self.get_filters(request)
# Pass the filtered values to the template context
extra_context['filters'] = filters
extra_context['search_query'] = request.GET.get('q', '') # Assuming the search query parameter is 'q'
return super().changelist_view(request, extra_context=extra_context)
def get_filters(self, request):
filters = []
# Retrieve the filter parameters
for param in request.GET.keys():
# Exclude the default search parameter 'q'
if param != 'q' and param != 'o':
# Append the filter parameter and its value to the list
filters.append({'parameter_name': param.replace('__exact','').replace('_type','').replace('__id',' id'), 'parameter_value': request.GET.get(param)})
return filters
class UserContactInline(admin.StackedInline): class UserContactInline(admin.StackedInline):
"""Edit a user's profile on the user page.""" """Edit a user's profile on the user page."""
@ -52,7 +77,7 @@ class MyHostAdmin(AuditedAdmin):
inlines = [HostIPInline] inlines = [HostIPInline]
class DomainAdmin(AuditedAdmin): class DomainAdmin(ListHeaderAdmin):
"""Custom domain admin class to add extra buttons.""" """Custom domain admin class to add extra buttons."""
@ -82,7 +107,7 @@ class DomainAdmin(AuditedAdmin):
return super().response_change(request, obj) return super().response_change(request, obj)
class ContactAdmin(AuditedAdmin): class ContactAdmin(ListHeaderAdmin):
"""Custom contact admin class to add search.""" """Custom contact admin class to add search."""
@ -90,7 +115,7 @@ class ContactAdmin(AuditedAdmin):
search_help_text = "Search by firstname, lastname or email." search_help_text = "Search by firstname, lastname or email."
class DomainApplicationAdmin(AuditedAdmin): class DomainApplicationAdmin(ListHeaderAdmin):
"""Customize the applications listing view.""" """Customize the applications listing view."""
@ -141,26 +166,6 @@ class DomainApplicationAdmin(AuditedAdmin):
# Regular users can only view the specified fields # Regular users can only view the specified fields
return self.readonly_fields return self.readonly_fields
def changelist_view(self, request, extra_context=None):
if extra_context is None:
extra_context = {}
# Get the filtered values
filters = self.get_filters(request)
# Pass the filtered values to the template context
extra_context['filters'] = filters
extra_context['search_query'] = request.GET.get('q', '') # Assuming the search query parameter is 'q'
return super().changelist_view(request, extra_context=extra_context)
def get_filters(self, request):
filters = []
# Retrieve the filter parameters
for param in request.GET.keys():
# Exclude the default search parameter 'q'
if param != 'q' and param != 'o':
# Append the filter parameter and its value to the list
filters.append({'parameter_name': param.replace('__exact','').replace('_type','').replace('__id',' id'), 'parameter_value': request.GET.get(param)})
return filters
admin.site.register(models.User, MyUserAdmin) admin.site.register(models.User, MyUserAdmin)
admin.site.register(models.UserDomainRole, AuditedAdmin) admin.site.register(models.UserDomainRole, AuditedAdmin)

View file

@ -92,6 +92,8 @@ INSTALLED_APPS = [
# the "user" model! *\o/* # the "user" model! *\o/*
"django.contrib.auth", "django.contrib.auth",
# generic interface for Django models # generic interface for Django models
"auditlog",
# library to simplify form templating
"django.contrib.contenttypes", "django.contrib.contenttypes",
# required for CSRF protection and many other things # required for CSRF protection and many other things
"django.contrib.sessions", "django.contrib.sessions",
@ -105,8 +107,6 @@ INSTALLED_APPS = [
# application used for integrating with Login.gov # application used for integrating with Login.gov
"djangooidc", "djangooidc",
# audit logging of changes to models # audit logging of changes to models
"auditlog",
# library to simplify form templating
"widget_tweaks", "widget_tweaks",
# library for Finite State Machine statuses # library for Finite State Machine statuses
"django_fsm", "django_fsm",

View file

@ -11,6 +11,7 @@ from registrar.models import (
) )
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
fake = Faker() fake = Faker()
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -61,9 +62,32 @@ class UserFixture:
}, },
] ]
STAFF_PERMISSIONS = [
{
'app_label': 'auditlog',
'model': 'logentry',
'permissions': ['view_logentry']
},
{
'app_label': 'registrar',
'model': 'contact',
'permissions': ['view_contact']
},
{
'app_label': 'registrar',
'model': 'domainapplication',
'permissions': ['change_domainapplication']
},
{
'app_label': 'registrar',
'model': 'domain',
'permissions': ['view_domain']
},
]
@classmethod @classmethod
def load(cls): def load(cls):
logger.info("Going to load %s users" % str(len(cls.ADMINS))) logger.info("Going to load %s superusers" % str(len(cls.ADMINS)))
for admin in cls.ADMINS: for admin in cls.ADMINS:
try: try:
user, _ = User.objects.get_or_create( user, _ = User.objects.get_or_create(
@ -78,31 +102,41 @@ class UserFixture:
logger.debug("User object created for %s" % admin["first_name"]) logger.debug("User object created for %s" % admin["first_name"])
except Exception as e: except Exception as e:
logger.warning(e) logger.warning(e)
logger.debug("All superusers loaded.")
logger.info("Going to load %s CISA analysts (staff)" % str(len(cls.STAFF)))
for staff in cls.STAFF: for staff in cls.STAFF:
try: try:
user, _ = User.objects.get_or_create( user, _ = User.objects.get_or_create(
username=staff["username"], username=staff["username"],
) )
user.is_superuser = False user.is_superuser = False
user.first_name = admin["first_name"] user.first_name = staff["first_name"]
user.last_name = admin["last_name"] user.last_name = staff["last_name"]
user.is_staff = True user.is_staff = True
user.is_active = True user.is_active = True
# CISA ANALYST permissions
# id 24 = codename view_logentry (auditlog) for permission in cls.STAFF_PERMISSIONS:
# id 32 = codename view_contact app_label = permission['app_label']
# id 38 = codename change_domainapplication model_name = permission['model']
# id 44 = codename view_domain permissions = permission['permissions']
permission_ids = [24, 32, 38, 44] # List of permission IDs to assign
# Retrieve the corresponding permission objects # Retrieve the content type for the app and model
permissions = Permission.objects.filter(id__in=permission_ids) content_type = ContentType.objects.get(app_label=app_label, model=model_name)
# Add the permissions to the user
user.user_permissions.add(*permissions) # Retrieve the permissions based on their codenames
permissions = Permission.objects.filter(content_type=content_type, codename__in=permissions)
# Assign the permissions to the user
user.user_permissions.add(*permissions)
logger.debug(f"{app_label} | {model_name} | {permissions} added for user {staff['first_name']}")
user.save() user.save()
logger.debug("User object created for %s" % admin["first_name"]) logger.debug("User object created for %s" % staff["first_name"])
except Exception as e: except Exception as e:
logger.warning(e) logger.warning(e)
logger.debug("All users loaded.") logger.debug("All CISA analysts (staff) loaded.")
class DomainApplicationFixture: class DomainApplicationFixture: