Просмотр исходного кода

#4919: Allow adding/changing assigned permissions within group and user admin views

Jeremy Stretch 5 лет назад
Родитель
Сommit
55ee3db5bc
3 измененных файлов с 56 добавлено и 36 удалено
  1. 4 0
      docs/release-notes/version-2.9.md
  2. 49 30
      netbox/users/admin.py
  3. 3 6
      netbox/users/models.py

+ 4 - 0
docs/release-notes/version-2.9.md

@@ -2,6 +2,10 @@
 
 ## v2.9.0 (FUTURE)
 
+### Enhancements
+
+* [#4919](https://github.com/netbox-community/netbox/issues/4919) - Allow adding/changing assigned permissions within group and user admin views
+
 ### Bug Fixes
 
 * [#4905](https://github.com/netbox-community/netbox/issues/4905) - Fix front port count on device type view

+ 49 - 30
netbox/users/admin.py

@@ -10,23 +10,39 @@ from .models import AdminGroup, AdminUser, ObjectPermission, Token, UserConfig
 
 
 #
-# Users & groups
+# Inline models
 #
 
-# Unregister the built-in GroupAdmin and UserAdmin classes so that we can use our custom admin classes below
-admin.site.unregister(Group)
-admin.site.unregister(User)
+class ObjectPermissionInline(admin.TabularInline):
+    exclude = None
+    extra = 3
+    readonly_fields = ['object_types', 'actions', 'constraints']
+    verbose_name = 'Permission'
+    verbose_name_plural = 'Permissions'
 
+    def get_queryset(self, request):
+        return super().get_queryset(request).prefetch_related('objectpermission__object_types')
 
-@admin.register(AdminGroup)
-class GroupAdmin(admin.ModelAdmin):
-    fields = ('name',)
-    list_display = ('name', 'user_count')
-    ordering = ('name',)
-    search_fields = ('name',)
+    @staticmethod
+    def object_types(instance):
+        # Don't call .values_list() here because we want to reference the pre-fetched object_types
+        return ', '.join([ot.name for ot in instance.objectpermission.object_types.all()])
+
+    @staticmethod
+    def actions(instance):
+        return ', '.join(instance.objectpermission.actions)
+
+    @staticmethod
+    def constraints(instance):
+        return instance.objectpermission.constraints
+
+
+class GroupObjectPermissionInline(ObjectPermissionInline):
+    model = AdminGroup.object_permissions.through
 
-    def user_count(self, obj):
-        return obj.user_set.count()
+
+class UserObjectPermissionInline(ObjectPermissionInline):
+    model = AdminUser.object_permissions.through
 
 
 class UserConfigInline(admin.TabularInline):
@@ -36,26 +52,26 @@ class UserConfigInline(admin.TabularInline):
     verbose_name = 'Preferences'
 
 
-class ObjectPermissionInline(admin.TabularInline):
-    model = AdminUser.object_permissions.through
-    fields = ['object_types', 'actions', 'constraints']
-    readonly_fields = fields
-    extra = 0
-    verbose_name = 'Permission'
-    verbose_name_plural = 'Permissions'
+#
+# Users & groups
+#
 
-    def object_types(self, instance):
-        return ', '.join(instance.objectpermission.object_types.values_list('model', flat=True))
+# Unregister the built-in GroupAdmin and UserAdmin classes so that we can use our custom admin classes below
+admin.site.unregister(Group)
+admin.site.unregister(User)
 
-    def actions(self, instance):
-        return ', '.join(instance.objectpermission.actions)
 
-    def constraints(self, instance):
-        return instance.objectpermission.constraints
+@admin.register(AdminGroup)
+class GroupAdmin(admin.ModelAdmin):
+    fields = ('name',)
+    list_display = ('name', 'user_count')
+    ordering = ('name',)
+    search_fields = ('name',)
+    inlines = [GroupObjectPermissionInline]
 
-    def has_add_permission(self, request, obj):
-        # Don't allow the creation of new ObjectPermission assignments via this form
-        return False
+    @staticmethod
+    def user_count(obj):
+        return obj.user_set.count()
 
 
 @admin.register(AdminUser)
@@ -71,7 +87,7 @@ class UserAdmin(UserAdmin_):
         }),
         ('Important dates', {'fields': ('last_login', 'date_joined')}),
     )
-    inlines = [ObjectPermissionInline, UserConfigInline]
+    inlines = [UserObjectPermissionInline, UserConfigInline]
     filter_horizontal = ('groups',)
 
 
@@ -241,7 +257,10 @@ class ObjectPermissionAdmin(admin.ModelAdmin):
         return super().get_queryset(request).prefetch_related('object_types', 'users', 'groups')
 
     def get_name(self, obj):
-        return obj.name or f'Permission #{obj.pk}'
+        return '{}: {}'.format(
+            ', '.join([ot.name for ot in obj.object_types.all()]),
+            ', '.join(obj.actions)
+        )
     get_name.short_description = 'Name'
 
     def list_models(self, obj):

+ 3 - 6
netbox/users/models.py

@@ -16,6 +16,8 @@ from utilities.utils import flatten_dict
 
 
 __all__ = (
+    'AdminGroup',
+    'AdminUser',
     'ObjectPermission',
     'Token',
     'UserConfig',
@@ -278,9 +280,4 @@ class ObjectPermission(models.Model):
         verbose_name = "permission"
 
     def __str__(self):
-        if self.name:
-            return self.name
-        return '{}: {}'.format(
-            ', '.join(self.object_types.values_list('model', flat=True)),
-            ', '.join(self.actions)
-        )
+        return self.name or f'Permission #{self.pk}'