Misc cleanup

This commit is contained in:
Jeremy Stretch 2023-07-20 14:32:25 -04:00
parent b5362f059c
commit 34b8d2a097
8 changed files with 50 additions and 72 deletions

View File

@ -41,10 +41,10 @@ class Migration(migrations.Migration):
),
migrations.AlterModelOptions(
name='netboxgroup',
options={'ordering': ['name'], 'verbose_name': 'Group'},
options={'ordering': ('name',), 'verbose_name': 'Group'},
),
migrations.AlterModelOptions(
name='netboxuser',
options={'ordering': ['username'], 'verbose_name': 'User'},
options={'ordering': ('username',), 'verbose_name': 'User'},
),
]

View File

@ -69,7 +69,7 @@ class NetBoxUser(User):
class Meta:
verbose_name = 'User'
proxy = True
ordering = ['username',]
ordering = ('username',)
def get_absolute_url(self):
return reverse('users:netboxuser', args=[self.pk])
@ -84,7 +84,7 @@ class NetBoxGroup(Group):
class Meta:
verbose_name = 'Group'
proxy = True
ordering = ['name',]
ordering = ('name',)
def get_absolute_url(self):
return reverse('users:netboxgroup', args=[self.pk])
@ -94,7 +94,6 @@ class NetBoxGroup(Group):
# User preferences
#
class UserConfig(models.Model):
"""
This model stores arbitrary user-specific preferences in a JSON data structure.

View File

@ -57,8 +57,12 @@ class TokenTable(NetBoxTable):
class UserTable(NetBoxTable):
username = tables.Column(linkify=True)
groups = tables.ManyToManyColumn()
username = tables.Column(
linkify=True
)
groups = columns.ManyToManyColumn(
linkify_item=('users:netboxgroup', {'pk': tables.A('pk')})
)
is_active = columns.BooleanColumn()
is_staff = columns.BooleanColumn()
is_superuser = columns.BooleanColumn()
@ -100,8 +104,12 @@ class ObjectPermissionTable(NetBoxTable):
custom_actions = columns.ArrayColumn(
accessor=tables.A('actions')
)
users = tables.ManyToManyColumn()
groups = tables.ManyToManyColumn()
users = columns.ManyToManyColumn(
linkify_item=('users:netboxuser', {'pk': tables.A('pk')})
)
groups = columns.ManyToManyColumn(
linkify_item=('users:netboxgroup', {'pk': tables.A('pk')})
)
actions = columns.ActionsColumn(
actions=('edit', 'delete'),
)

View File

@ -16,18 +16,18 @@ urlpatterns = [
path('api-tokens/<int:pk>/', include(get_model_urls('users', 'token'))),
# Users
path('users/', views.NetBoxUserListView.as_view(), name='netboxuser_list'),
path('users/add/', views.NetBoxUserEditView.as_view(), name='netboxuser_add'),
path('users/edit/', views.NetBoxUserBulkEditView.as_view(), name='netboxuser_bulk_edit'),
path('users/import/', views.NetBoxUserBulkImportView.as_view(), name='netboxuser_import'),
path('users/delete/', views.NetBoxUserBulkDeleteView.as_view(), name='netboxuser_bulk_delete'),
path('users/', views.UserListView.as_view(), name='netboxuser_list'),
path('users/add/', views.UserEditView.as_view(), name='netboxuser_add'),
path('users/edit/', views.UserBulkEditView.as_view(), name='netboxuser_bulk_edit'),
path('users/import/', views.UserBulkImportView.as_view(), name='netboxuser_import'),
path('users/delete/', views.UserBulkDeleteView.as_view(), name='netboxuser_bulk_delete'),
path('users/<int:pk>/', include(get_model_urls('users', 'netboxuser'))),
# Groups
path('groups/', views.NetBoxGroupListView.as_view(), name='netboxgroup_list'),
path('groups/add/', views.NetBoxGroupEditView.as_view(), name='netboxgroup_add'),
path('groups/import/', views.NetBoxGroupBulkImportView.as_view(), name='netboxgroup_import'),
path('groups/delete/', views.NetBoxGroupBulkDeleteView.as_view(), name='netboxgroup_bulk_delete'),
path('groups/', views.GroupListView.as_view(), name='netboxgroup_list'),
path('groups/add/', views.GroupEditView.as_view(), name='netboxgroup_add'),
path('groups/import/', views.GroupBulkImportView.as_view(), name='netboxgroup_import'),
path('groups/delete/', views.GroupBulkDeleteView.as_view(), name='netboxgroup_bulk_delete'),
path('groups/<int:pk>/', include(get_model_urls('users', 'netboxgroup'))),
# Permissions

View File

@ -2,11 +2,10 @@ import logging
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import login as auth_login, logout as auth_logout, update_session_auth_hash, get_user_model
from django.contrib.auth import login as auth_login, logout as auth_logout, update_session_auth_hash
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import Group, User, update_last_login
from django.contrib.auth.models import update_last_login
from django.contrib.auth.signals import user_logged_in
from django.core.exceptions import ImproperlyConfigured
from django.db.models import Count
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render, resolve_url
@ -23,8 +22,6 @@ from netbox.authentication import get_auth_backend_display, get_saml_idps
from netbox.config import get_config
from netbox.views import generic
from utilities.forms import ConfirmationForm
from utilities.permissions import get_permission_for_model
from utilities.querysets import RestrictedQuerySet
from utilities.views import register_model_view
from . import filtersets, forms, tables
from .models import Token, UserConfig, NetBoxGroup, NetBoxUser, ObjectPermission
@ -362,7 +359,7 @@ class TokenDeleteView(LoginRequiredMixin, View):
#
class NetBoxUserListView(generic.ObjectListView):
class UserListView(generic.ObjectListView):
queryset = NetBoxUser.objects.all()
filterset = filtersets.UserFilterSet
filterset_form = forms.UserFilterForm
@ -370,47 +367,43 @@ class NetBoxUserListView(generic.ObjectListView):
@register_model_view(NetBoxUser)
class NetBoxUserView(generic.ObjectView):
class UserView(generic.ObjectView):
queryset = NetBoxUser.objects.all()
template_name = 'users/user.html'
def get_extra_context(self, request, instance):
# Compile changelog table
changelog = ObjectChange.objects.restrict(request.user, 'view').filter(user=request.user).prefetch_related(
'changed_object_type'
)[:20]
changelog = ObjectChange.objects.restrict(request.user, 'view').filter(user=request.user)[:20]
changelog_table = ObjectChangeTable(changelog)
return {
'changelog_table': changelog_table,
'active_tab': 'user',
}
@register_model_view(NetBoxUser, 'edit')
class NetBoxUserEditView(generic.ObjectEditView):
class UserEditView(generic.ObjectEditView):
queryset = NetBoxUser.objects.all()
form = forms.UserForm
@register_model_view(NetBoxUser, 'delete')
class NetBoxUserDeleteView(generic.ObjectDeleteView):
class UserDeleteView(generic.ObjectDeleteView):
queryset = NetBoxUser.objects.all()
class NetBoxUserBulkEditView(generic.BulkEditView):
class UserBulkEditView(generic.BulkEditView):
queryset = NetBoxUser.objects.all()
filterset = filtersets.UserFilterSet
table = tables.UserTable
form = forms.UserBulkEditForm
class NetBoxUserBulkImportView(generic.BulkImportView):
class UserBulkImportView(generic.BulkImportView):
queryset = NetBoxUser.objects.all()
model_form = forms.UserImportForm
class NetBoxUserBulkDeleteView(generic.BulkDeleteView):
class UserBulkDeleteView(generic.BulkDeleteView):
queryset = NetBoxUser.objects.all()
filterset = filtersets.UserFilterSet
table = tables.UserTable
@ -421,42 +414,37 @@ class NetBoxUserBulkDeleteView(generic.BulkDeleteView):
#
class NetBoxGroupListView(generic.ObjectListView):
queryset = NetBoxGroup.objects.all().annotate(users_count=Count('user'))
class GroupListView(generic.ObjectListView):
queryset = NetBoxGroup.objects.annotate(users_count=Count('user'))
filterset = filtersets.GroupFilterSet
filterset_form = forms.GroupFilterForm
table = tables.GroupTable
@register_model_view(NetBoxGroup)
class NetBoxGroupView(generic.ObjectView):
class GroupView(generic.ObjectView):
queryset = NetBoxGroup.objects.all()
template_name = 'users/group.html'
def get_extra_context(self, request, instance):
return {
'active_tab': 'group',
}
@register_model_view(NetBoxGroup, 'edit')
class NetBoxGroupEditView(generic.ObjectEditView):
class GroupEditView(generic.ObjectEditView):
queryset = NetBoxGroup.objects.all()
form = forms.GroupForm
@register_model_view(NetBoxGroup, 'delete')
class NetBoxGroupDeleteView(generic.ObjectDeleteView):
class GroupDeleteView(generic.ObjectDeleteView):
queryset = NetBoxGroup.objects.all()
class NetBoxGroupBulkImportView(generic.BulkImportView):
class GroupBulkImportView(generic.BulkImportView):
queryset = NetBoxGroup.objects.all()
model_form = forms.GroupImportForm
class NetBoxGroupBulkDeleteView(generic.BulkDeleteView):
queryset = NetBoxGroup.objects.all()
class GroupBulkDeleteView(generic.BulkDeleteView):
queryset = NetBoxGroup.objects.annotate(users_count=Count('user'))
filterset = filtersets.GroupFilterSet
table = tables.GroupTable
@ -477,11 +465,6 @@ class ObjectPermissionView(generic.ObjectView):
queryset = ObjectPermission.objects.all()
template_name = 'users/objectpermission.html'
def get_extra_context(self, request, instance):
return {
'active_tab': 'objectpermission',
}
@register_model_view(ObjectPermission, 'edit')
class ObjectPermissionEditView(generic.ObjectEditView):

View File

@ -18,17 +18,10 @@ def get_permission_for_model(model, action):
:param model: A model or instance
:param action: View, add, change, or delete (string)
"""
# Resolve to the "concrete" model (for proxy models)
model = model._meta.concrete_model
# Get non proxied model
concrete_model = model
while concrete_model._meta.proxy_for_model:
concrete_model = concrete_model._meta.proxy_for_model
return '{}.{}_{}'.format(
concrete_model._meta.app_label,
action,
concrete_model._meta.model_name
)
return f'{model._meta.app_label}.{action}_{model._meta.model_name}'
def resolve_permission(name):
@ -75,17 +68,14 @@ def permission_is_exempt(name):
if action == 'view':
if (
# All models (excluding those in EXEMPT_EXCLUDE_MODELS) are exempt from view permission enforcement
'*' in settings.EXEMPT_VIEW_PERMISSIONS and (app_label, model_name) not in settings.EXEMPT_EXCLUDE_MODELS
) or (
# This specific model is exempt from view permission enforcement
f'{app_label}.{model_name}' in settings.EXEMPT_VIEW_PERMISSIONS
):
return True
if (
# All models (excluding those in EXEMPT_EXCLUDE_MODELS) are exempt from view permission enforcement
'*' in settings.EXEMPT_VIEW_PERMISSIONS and ((app_label, model_name) not in settings.EXEMPT_EXCLUDE_MODELS)
):
return True
return False

View File

@ -1,8 +1,7 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import Prefetch, QuerySet
from users.constants import CONSTRAINT_TOKEN_USER
from utilities.permissions import permission_is_exempt, qs_filter_from_constraints, get_permission_for_model
from utilities.permissions import get_permission_for_model, permission_is_exempt, qs_filter_from_constraints
__all__ = (
'RestrictedPrefetch',

View File

@ -5,7 +5,6 @@ from django.urls.exceptions import NoReverseMatch
from netbox.registry import registry
from .permissions import resolve_permission
from .querysets import RestrictedQuerySet
__all__ = (
'ContentTypePermissionRequiredMixin',