mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-25 08:46:10 -06:00
Misc cleanup
This commit is contained in:
parent
b5362f059c
commit
34b8d2a097
@ -41,10 +41,10 @@ class Migration(migrations.Migration):
|
|||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='netboxgroup',
|
name='netboxgroup',
|
||||||
options={'ordering': ['name'], 'verbose_name': 'Group'},
|
options={'ordering': ('name',), 'verbose_name': 'Group'},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='netboxuser',
|
name='netboxuser',
|
||||||
options={'ordering': ['username'], 'verbose_name': 'User'},
|
options={'ordering': ('username',), 'verbose_name': 'User'},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -69,7 +69,7 @@ class NetBoxUser(User):
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'User'
|
verbose_name = 'User'
|
||||||
proxy = True
|
proxy = True
|
||||||
ordering = ['username',]
|
ordering = ('username',)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('users:netboxuser', args=[self.pk])
|
return reverse('users:netboxuser', args=[self.pk])
|
||||||
@ -84,7 +84,7 @@ class NetBoxGroup(Group):
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'Group'
|
verbose_name = 'Group'
|
||||||
proxy = True
|
proxy = True
|
||||||
ordering = ['name',]
|
ordering = ('name',)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('users:netboxgroup', args=[self.pk])
|
return reverse('users:netboxgroup', args=[self.pk])
|
||||||
@ -94,7 +94,6 @@ class NetBoxGroup(Group):
|
|||||||
# User preferences
|
# User preferences
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class UserConfig(models.Model):
|
class UserConfig(models.Model):
|
||||||
"""
|
"""
|
||||||
This model stores arbitrary user-specific preferences in a JSON data structure.
|
This model stores arbitrary user-specific preferences in a JSON data structure.
|
||||||
|
@ -57,8 +57,12 @@ class TokenTable(NetBoxTable):
|
|||||||
|
|
||||||
|
|
||||||
class UserTable(NetBoxTable):
|
class UserTable(NetBoxTable):
|
||||||
username = tables.Column(linkify=True)
|
username = tables.Column(
|
||||||
groups = tables.ManyToManyColumn()
|
linkify=True
|
||||||
|
)
|
||||||
|
groups = columns.ManyToManyColumn(
|
||||||
|
linkify_item=('users:netboxgroup', {'pk': tables.A('pk')})
|
||||||
|
)
|
||||||
is_active = columns.BooleanColumn()
|
is_active = columns.BooleanColumn()
|
||||||
is_staff = columns.BooleanColumn()
|
is_staff = columns.BooleanColumn()
|
||||||
is_superuser = columns.BooleanColumn()
|
is_superuser = columns.BooleanColumn()
|
||||||
@ -100,8 +104,12 @@ class ObjectPermissionTable(NetBoxTable):
|
|||||||
custom_actions = columns.ArrayColumn(
|
custom_actions = columns.ArrayColumn(
|
||||||
accessor=tables.A('actions')
|
accessor=tables.A('actions')
|
||||||
)
|
)
|
||||||
users = tables.ManyToManyColumn()
|
users = columns.ManyToManyColumn(
|
||||||
groups = tables.ManyToManyColumn()
|
linkify_item=('users:netboxuser', {'pk': tables.A('pk')})
|
||||||
|
)
|
||||||
|
groups = columns.ManyToManyColumn(
|
||||||
|
linkify_item=('users:netboxgroup', {'pk': tables.A('pk')})
|
||||||
|
)
|
||||||
actions = columns.ActionsColumn(
|
actions = columns.ActionsColumn(
|
||||||
actions=('edit', 'delete'),
|
actions=('edit', 'delete'),
|
||||||
)
|
)
|
||||||
|
@ -16,18 +16,18 @@ urlpatterns = [
|
|||||||
path('api-tokens/<int:pk>/', include(get_model_urls('users', 'token'))),
|
path('api-tokens/<int:pk>/', include(get_model_urls('users', 'token'))),
|
||||||
|
|
||||||
# Users
|
# Users
|
||||||
path('users/', views.NetBoxUserListView.as_view(), name='netboxuser_list'),
|
path('users/', views.UserListView.as_view(), name='netboxuser_list'),
|
||||||
path('users/add/', views.NetBoxUserEditView.as_view(), name='netboxuser_add'),
|
path('users/add/', views.UserEditView.as_view(), name='netboxuser_add'),
|
||||||
path('users/edit/', views.NetBoxUserBulkEditView.as_view(), name='netboxuser_bulk_edit'),
|
path('users/edit/', views.UserBulkEditView.as_view(), name='netboxuser_bulk_edit'),
|
||||||
path('users/import/', views.NetBoxUserBulkImportView.as_view(), name='netboxuser_import'),
|
path('users/import/', views.UserBulkImportView.as_view(), name='netboxuser_import'),
|
||||||
path('users/delete/', views.NetBoxUserBulkDeleteView.as_view(), name='netboxuser_bulk_delete'),
|
path('users/delete/', views.UserBulkDeleteView.as_view(), name='netboxuser_bulk_delete'),
|
||||||
path('users/<int:pk>/', include(get_model_urls('users', 'netboxuser'))),
|
path('users/<int:pk>/', include(get_model_urls('users', 'netboxuser'))),
|
||||||
|
|
||||||
# Groups
|
# Groups
|
||||||
path('groups/', views.NetBoxGroupListView.as_view(), name='netboxgroup_list'),
|
path('groups/', views.GroupListView.as_view(), name='netboxgroup_list'),
|
||||||
path('groups/add/', views.NetBoxGroupEditView.as_view(), name='netboxgroup_add'),
|
path('groups/add/', views.GroupEditView.as_view(), name='netboxgroup_add'),
|
||||||
path('groups/import/', views.NetBoxGroupBulkImportView.as_view(), name='netboxgroup_import'),
|
path('groups/import/', views.GroupBulkImportView.as_view(), name='netboxgroup_import'),
|
||||||
path('groups/delete/', views.NetBoxGroupBulkDeleteView.as_view(), name='netboxgroup_bulk_delete'),
|
path('groups/delete/', views.GroupBulkDeleteView.as_view(), name='netboxgroup_bulk_delete'),
|
||||||
path('groups/<int:pk>/', include(get_model_urls('users', 'netboxgroup'))),
|
path('groups/<int:pk>/', include(get_model_urls('users', 'netboxgroup'))),
|
||||||
|
|
||||||
# Permissions
|
# Permissions
|
||||||
|
@ -2,11 +2,10 @@ import logging
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
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.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.contrib.auth.signals import user_logged_in
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, redirect, render, resolve_url
|
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.config import get_config
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.forms import ConfirmationForm
|
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 utilities.views import register_model_view
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
from .models import Token, UserConfig, NetBoxGroup, NetBoxUser, ObjectPermission
|
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()
|
queryset = NetBoxUser.objects.all()
|
||||||
filterset = filtersets.UserFilterSet
|
filterset = filtersets.UserFilterSet
|
||||||
filterset_form = forms.UserFilterForm
|
filterset_form = forms.UserFilterForm
|
||||||
@ -370,47 +367,43 @@ class NetBoxUserListView(generic.ObjectListView):
|
|||||||
|
|
||||||
|
|
||||||
@register_model_view(NetBoxUser)
|
@register_model_view(NetBoxUser)
|
||||||
class NetBoxUserView(generic.ObjectView):
|
class UserView(generic.ObjectView):
|
||||||
queryset = NetBoxUser.objects.all()
|
queryset = NetBoxUser.objects.all()
|
||||||
template_name = 'users/user.html'
|
template_name = 'users/user.html'
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
# Compile changelog table
|
changelog = ObjectChange.objects.restrict(request.user, 'view').filter(user=request.user)[:20]
|
||||||
changelog = ObjectChange.objects.restrict(request.user, 'view').filter(user=request.user).prefetch_related(
|
|
||||||
'changed_object_type'
|
|
||||||
)[:20]
|
|
||||||
changelog_table = ObjectChangeTable(changelog)
|
changelog_table = ObjectChangeTable(changelog)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'changelog_table': changelog_table,
|
'changelog_table': changelog_table,
|
||||||
'active_tab': 'user',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(NetBoxUser, 'edit')
|
@register_model_view(NetBoxUser, 'edit')
|
||||||
class NetBoxUserEditView(generic.ObjectEditView):
|
class UserEditView(generic.ObjectEditView):
|
||||||
queryset = NetBoxUser.objects.all()
|
queryset = NetBoxUser.objects.all()
|
||||||
form = forms.UserForm
|
form = forms.UserForm
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(NetBoxUser, 'delete')
|
@register_model_view(NetBoxUser, 'delete')
|
||||||
class NetBoxUserDeleteView(generic.ObjectDeleteView):
|
class UserDeleteView(generic.ObjectDeleteView):
|
||||||
queryset = NetBoxUser.objects.all()
|
queryset = NetBoxUser.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class NetBoxUserBulkEditView(generic.BulkEditView):
|
class UserBulkEditView(generic.BulkEditView):
|
||||||
queryset = NetBoxUser.objects.all()
|
queryset = NetBoxUser.objects.all()
|
||||||
filterset = filtersets.UserFilterSet
|
filterset = filtersets.UserFilterSet
|
||||||
table = tables.UserTable
|
table = tables.UserTable
|
||||||
form = forms.UserBulkEditForm
|
form = forms.UserBulkEditForm
|
||||||
|
|
||||||
|
|
||||||
class NetBoxUserBulkImportView(generic.BulkImportView):
|
class UserBulkImportView(generic.BulkImportView):
|
||||||
queryset = NetBoxUser.objects.all()
|
queryset = NetBoxUser.objects.all()
|
||||||
model_form = forms.UserImportForm
|
model_form = forms.UserImportForm
|
||||||
|
|
||||||
|
|
||||||
class NetBoxUserBulkDeleteView(generic.BulkDeleteView):
|
class UserBulkDeleteView(generic.BulkDeleteView):
|
||||||
queryset = NetBoxUser.objects.all()
|
queryset = NetBoxUser.objects.all()
|
||||||
filterset = filtersets.UserFilterSet
|
filterset = filtersets.UserFilterSet
|
||||||
table = tables.UserTable
|
table = tables.UserTable
|
||||||
@ -421,42 +414,37 @@ class NetBoxUserBulkDeleteView(generic.BulkDeleteView):
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class NetBoxGroupListView(generic.ObjectListView):
|
class GroupListView(generic.ObjectListView):
|
||||||
queryset = NetBoxGroup.objects.all().annotate(users_count=Count('user'))
|
queryset = NetBoxGroup.objects.annotate(users_count=Count('user'))
|
||||||
filterset = filtersets.GroupFilterSet
|
filterset = filtersets.GroupFilterSet
|
||||||
filterset_form = forms.GroupFilterForm
|
filterset_form = forms.GroupFilterForm
|
||||||
table = tables.GroupTable
|
table = tables.GroupTable
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(NetBoxGroup)
|
@register_model_view(NetBoxGroup)
|
||||||
class NetBoxGroupView(generic.ObjectView):
|
class GroupView(generic.ObjectView):
|
||||||
queryset = NetBoxGroup.objects.all()
|
queryset = NetBoxGroup.objects.all()
|
||||||
template_name = 'users/group.html'
|
template_name = 'users/group.html'
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
|
||||||
return {
|
|
||||||
'active_tab': 'group',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(NetBoxGroup, 'edit')
|
@register_model_view(NetBoxGroup, 'edit')
|
||||||
class NetBoxGroupEditView(generic.ObjectEditView):
|
class GroupEditView(generic.ObjectEditView):
|
||||||
queryset = NetBoxGroup.objects.all()
|
queryset = NetBoxGroup.objects.all()
|
||||||
form = forms.GroupForm
|
form = forms.GroupForm
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(NetBoxGroup, 'delete')
|
@register_model_view(NetBoxGroup, 'delete')
|
||||||
class NetBoxGroupDeleteView(generic.ObjectDeleteView):
|
class GroupDeleteView(generic.ObjectDeleteView):
|
||||||
queryset = NetBoxGroup.objects.all()
|
queryset = NetBoxGroup.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class NetBoxGroupBulkImportView(generic.BulkImportView):
|
class GroupBulkImportView(generic.BulkImportView):
|
||||||
queryset = NetBoxGroup.objects.all()
|
queryset = NetBoxGroup.objects.all()
|
||||||
model_form = forms.GroupImportForm
|
model_form = forms.GroupImportForm
|
||||||
|
|
||||||
|
|
||||||
class NetBoxGroupBulkDeleteView(generic.BulkDeleteView):
|
class GroupBulkDeleteView(generic.BulkDeleteView):
|
||||||
queryset = NetBoxGroup.objects.all()
|
queryset = NetBoxGroup.objects.annotate(users_count=Count('user'))
|
||||||
filterset = filtersets.GroupFilterSet
|
filterset = filtersets.GroupFilterSet
|
||||||
table = tables.GroupTable
|
table = tables.GroupTable
|
||||||
|
|
||||||
@ -477,11 +465,6 @@ class ObjectPermissionView(generic.ObjectView):
|
|||||||
queryset = ObjectPermission.objects.all()
|
queryset = ObjectPermission.objects.all()
|
||||||
template_name = 'users/objectpermission.html'
|
template_name = 'users/objectpermission.html'
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
|
||||||
return {
|
|
||||||
'active_tab': 'objectpermission',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(ObjectPermission, 'edit')
|
@register_model_view(ObjectPermission, 'edit')
|
||||||
class ObjectPermissionEditView(generic.ObjectEditView):
|
class ObjectPermissionEditView(generic.ObjectEditView):
|
||||||
|
@ -18,17 +18,10 @@ def get_permission_for_model(model, action):
|
|||||||
:param model: A model or instance
|
:param model: A model or instance
|
||||||
:param action: View, add, change, or delete (string)
|
: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
|
return f'{model._meta.app_label}.{action}_{model._meta.model_name}'
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_permission(name):
|
def resolve_permission(name):
|
||||||
@ -75,17 +68,14 @@ def permission_is_exempt(name):
|
|||||||
|
|
||||||
if action == 'view':
|
if action == 'view':
|
||||||
if (
|
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
|
# This specific model is exempt from view permission enforcement
|
||||||
f'{app_label}.{model_name}' in settings.EXEMPT_VIEW_PERMISSIONS
|
f'{app_label}.{model_name}' in settings.EXEMPT_VIEW_PERMISSIONS
|
||||||
):
|
):
|
||||||
return True
|
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
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
|
||||||
from django.db.models import Prefetch, QuerySet
|
from django.db.models import Prefetch, QuerySet
|
||||||
|
|
||||||
from users.constants import CONSTRAINT_TOKEN_USER
|
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__ = (
|
__all__ = (
|
||||||
'RestrictedPrefetch',
|
'RestrictedPrefetch',
|
||||||
|
@ -5,7 +5,6 @@ from django.urls.exceptions import NoReverseMatch
|
|||||||
|
|
||||||
from netbox.registry import registry
|
from netbox.registry import registry
|
||||||
from .permissions import resolve_permission
|
from .permissions import resolve_permission
|
||||||
from .querysets import RestrictedQuerySet
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ContentTypePermissionRequiredMixin',
|
'ContentTypePermissionRequiredMixin',
|
||||||
|
Loading…
Reference in New Issue
Block a user