mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-16 12:38:17 -06:00
Restore users & groups fields on ObjectPermission serializer
This commit is contained in:
parent
a673015f86
commit
37a003afea
@ -81,8 +81,9 @@ class ValidatedModelSerializer(BaseModelSerializer):
|
|||||||
attrs.pop('custom_fields', None)
|
attrs.pop('custom_fields', None)
|
||||||
|
|
||||||
# Skip ManyToManyFields
|
# Skip ManyToManyFields
|
||||||
|
opts = self.Meta.model._meta
|
||||||
m2m_values = {}
|
m2m_values = {}
|
||||||
for field in self.Meta.model._meta.local_many_to_many:
|
for field in [*opts.local_many_to_many, *opts.related_objects]:
|
||||||
if field.name in attrs:
|
if field.name in attrs:
|
||||||
m2m_values[field.name] = attrs.pop(field.name)
|
m2m_values[field.name] = attrs.pop(field.name)
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from core.models import ObjectType
|
from core.models import ObjectType
|
||||||
from netbox.api.fields import ContentTypeField
|
from netbox.api.fields import ContentTypeField, SerializedPKRelatedField
|
||||||
from netbox.api.serializers import ValidatedModelSerializer
|
from netbox.api.serializers import ValidatedModelSerializer
|
||||||
from users.models import ObjectPermission
|
from users.api.nested_serializers import NestedGroupSerializer, NestedUserSerializer
|
||||||
|
from users.models import Group, ObjectPermission, User
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ObjectPermissionSerializer',
|
'ObjectPermissionSerializer',
|
||||||
@ -16,11 +17,26 @@ class ObjectPermissionSerializer(ValidatedModelSerializer):
|
|||||||
queryset=ObjectType.objects.all(),
|
queryset=ObjectType.objects.all(),
|
||||||
many=True
|
many=True
|
||||||
)
|
)
|
||||||
|
groups = SerializedPKRelatedField(
|
||||||
|
queryset=Group.objects.all(),
|
||||||
|
serializer=NestedGroupSerializer,
|
||||||
|
nested=True,
|
||||||
|
required=False,
|
||||||
|
many=True
|
||||||
|
)
|
||||||
|
users = SerializedPKRelatedField(
|
||||||
|
queryset=User.objects.all(),
|
||||||
|
serializer=NestedUserSerializer,
|
||||||
|
nested=True,
|
||||||
|
required=False,
|
||||||
|
many=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ObjectPermission
|
model = ObjectPermission
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'actions', 'constraints',
|
'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'actions', 'constraints',
|
||||||
|
'groups', 'users',
|
||||||
)
|
)
|
||||||
brief_fields = (
|
brief_fields = (
|
||||||
'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'actions',
|
'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'actions',
|
||||||
|
@ -41,25 +41,25 @@ class UserTest(APIViewTestCases.APIViewTestCase):
|
|||||||
permissions[2].object_types.add(ObjectType.objects.get_by_natural_key('dcim', 'rack'))
|
permissions[2].object_types.add(ObjectType.objects.get_by_natural_key('dcim', 'rack'))
|
||||||
|
|
||||||
users = (
|
users = (
|
||||||
User(username='User_1', password='password1'),
|
User(username='User1', password='password1'),
|
||||||
User(username='User_2', password='password2'),
|
User(username='User2', password='password2'),
|
||||||
User(username='User_3', password='password3'),
|
User(username='User3', password='password3'),
|
||||||
)
|
)
|
||||||
User.objects.bulk_create(users)
|
User.objects.bulk_create(users)
|
||||||
|
|
||||||
cls.create_data = [
|
cls.create_data = [
|
||||||
{
|
{
|
||||||
'username': 'User_4',
|
'username': 'User4',
|
||||||
'password': 'password4',
|
'password': 'password4',
|
||||||
'permissions': [permissions[0].pk],
|
'permissions': [permissions[0].pk],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'username': 'User_5',
|
'username': 'User5',
|
||||||
'password': 'password5',
|
'password': 'password5',
|
||||||
'permissions': [permissions[1].pk],
|
'permissions': [permissions[1].pk],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'username': 'User_6',
|
'username': 'User6',
|
||||||
'password': 'password6',
|
'password': 'password6',
|
||||||
'permissions': [permissions[2].pk],
|
'permissions': [permissions[2].pk],
|
||||||
},
|
},
|
||||||
@ -79,7 +79,7 @@ class UserTest(APIViewTestCases.APIViewTestCase):
|
|||||||
obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model))
|
obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model))
|
||||||
|
|
||||||
user_credentials = {
|
user_credentials = {
|
||||||
'username': 'user1',
|
'username': 'newuser',
|
||||||
'password': 'abc123',
|
'password': 'abc123',
|
||||||
}
|
}
|
||||||
user = User.objects.create_user(**user_credentials)
|
user = User.objects.create_user(**user_credentials)
|
||||||
@ -169,9 +169,9 @@ class TokenTest(
|
|||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
users = (
|
users = (
|
||||||
create_test_user('User 1'),
|
create_test_user('User1'),
|
||||||
create_test_user('User 2'),
|
create_test_user('User2'),
|
||||||
create_test_user('User 3'),
|
create_test_user('User3'),
|
||||||
)
|
)
|
||||||
|
|
||||||
tokens = (
|
tokens = (
|
||||||
@ -280,9 +280,9 @@ class ObjectPermissionTest(
|
|||||||
Group.objects.bulk_create(groups)
|
Group.objects.bulk_create(groups)
|
||||||
|
|
||||||
users = (
|
users = (
|
||||||
User(username='User 1', is_active=True),
|
User(username='User1', is_active=True),
|
||||||
User(username='User 2', is_active=True),
|
User(username='User2', is_active=True),
|
||||||
User(username='User 3', is_active=True),
|
User(username='User3', is_active=True),
|
||||||
)
|
)
|
||||||
User.objects.bulk_create(users)
|
User.objects.bulk_create(users)
|
||||||
|
|
||||||
@ -303,18 +303,24 @@ class ObjectPermissionTest(
|
|||||||
{
|
{
|
||||||
'name': 'Permission 4',
|
'name': 'Permission 4',
|
||||||
'object_types': ['dcim.site'],
|
'object_types': ['dcim.site'],
|
||||||
|
'groups': [groups[0].pk],
|
||||||
|
'users': [users[0].pk],
|
||||||
'actions': ['view', 'add', 'change', 'delete'],
|
'actions': ['view', 'add', 'change', 'delete'],
|
||||||
'constraints': {'name': 'TEST4'},
|
'constraints': {'name': 'TEST4'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Permission 5',
|
'name': 'Permission 5',
|
||||||
'object_types': ['dcim.site'],
|
'object_types': ['dcim.site'],
|
||||||
|
'groups': [groups[1].pk],
|
||||||
|
'users': [users[1].pk],
|
||||||
'actions': ['view', 'add', 'change', 'delete'],
|
'actions': ['view', 'add', 'change', 'delete'],
|
||||||
'constraints': {'name': 'TEST5'},
|
'constraints': {'name': 'TEST5'},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Permission 6',
|
'name': 'Permission 6',
|
||||||
'object_types': ['dcim.site'],
|
'object_types': ['dcim.site'],
|
||||||
|
'groups': [groups[2].pk],
|
||||||
|
'users': [users[2].pk],
|
||||||
'actions': ['view', 'add', 'change', 'delete'],
|
'actions': ['view', 'add', 'change', 'delete'],
|
||||||
'constraints': {'name': 'TEST6'},
|
'constraints': {'name': 'TEST6'},
|
||||||
},
|
},
|
||||||
|
@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.postgres.fields import ArrayField
|
from django.contrib.postgres.fields import ArrayField
|
||||||
from django.core.exceptions import FieldDoesNotExist
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
from django.db.models import ManyToManyField, JSONField
|
from django.db.models import ManyToManyField, ManyToManyRel, JSONField
|
||||||
from django.forms.models import model_to_dict
|
from django.forms.models import model_to_dict
|
||||||
from django.test import Client, TestCase as _TestCase
|
from django.test import Client, TestCase as _TestCase
|
||||||
from netaddr import IPNetwork
|
from netaddr import IPNetwork
|
||||||
@ -111,8 +111,10 @@ class ModelTestCase(TestCase):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Handle ManyToManyFields
|
# Handle ManyToManyFields
|
||||||
if value and type(field) in (ManyToManyField, TaggableManager):
|
if value and type(field) in (ManyToManyField, ManyToManyRel, TaggableManager):
|
||||||
|
# Resolve reverse M2M relationships
|
||||||
|
if isinstance(field, ManyToManyRel):
|
||||||
|
value = getattr(instance, field.related_name).all()
|
||||||
if field.related_model in (ContentType, ObjectType) and api:
|
if field.related_model in (ContentType, ObjectType) and api:
|
||||||
model_dict[key] = sorted([object_type_identifier(ot) for ot in value])
|
model_dict[key] = sorted([object_type_identifier(ot) for ot in value])
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user