serializers.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from django.conf import settings
  2. from django.contrib.auth.models import Group, User
  3. from django.contrib.contenttypes.models import ContentType
  4. from rest_framework import serializers
  5. from netbox.api.fields import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField
  6. from netbox.api.serializers import ValidatedModelSerializer
  7. from users.models import ObjectPermission, Token
  8. from .nested_serializers import *
  9. __all__ = (
  10. 'GroupSerializer',
  11. 'ObjectPermissionSerializer',
  12. 'TokenSerializer',
  13. 'UserSerializer',
  14. )
  15. class UserSerializer(ValidatedModelSerializer):
  16. url = serializers.HyperlinkedIdentityField(view_name='users-api:user-detail')
  17. groups = SerializedPKRelatedField(
  18. queryset=Group.objects.all(),
  19. serializer=NestedGroupSerializer,
  20. required=False,
  21. many=True
  22. )
  23. class Meta:
  24. model = User
  25. fields = (
  26. 'id', 'url', 'display', 'username', 'password', 'first_name', 'last_name', 'email', 'is_staff', 'is_active',
  27. 'date_joined', 'groups',
  28. )
  29. extra_kwargs = {
  30. 'password': {'write_only': True}
  31. }
  32. def create(self, validated_data):
  33. """
  34. Extract the password from validated data and set it separately to ensure proper hash generation.
  35. """
  36. password = validated_data.pop('password')
  37. user = super().create(validated_data)
  38. user.set_password(password)
  39. user.save()
  40. return user
  41. def get_display(self, obj):
  42. if full_name := obj.get_full_name():
  43. return f"{obj.username} ({full_name})"
  44. return obj.username
  45. class GroupSerializer(ValidatedModelSerializer):
  46. url = serializers.HyperlinkedIdentityField(view_name='users-api:group-detail')
  47. user_count = serializers.IntegerField(read_only=True)
  48. class Meta:
  49. model = Group
  50. fields = ('id', 'url', 'display', 'name', 'user_count')
  51. class TokenSerializer(ValidatedModelSerializer):
  52. url = serializers.HyperlinkedIdentityField(view_name='users-api:token-detail')
  53. key = serializers.CharField(
  54. min_length=40,
  55. max_length=40,
  56. allow_blank=True,
  57. required=False,
  58. write_only=not settings.ALLOW_TOKEN_RETRIEVAL
  59. )
  60. user = NestedUserSerializer()
  61. allowed_ips = serializers.ListField(
  62. child=IPNetworkSerializer(),
  63. required=False,
  64. allow_empty=True,
  65. default=[]
  66. )
  67. class Meta:
  68. model = Token
  69. fields = (
  70. 'id', 'url', 'display', 'user', 'created', 'expires', 'last_used', 'key', 'write_enabled', 'description',
  71. 'allowed_ips',
  72. )
  73. def to_internal_value(self, data):
  74. if 'key' not in data:
  75. data['key'] = Token.generate_key()
  76. return super().to_internal_value(data)
  77. class TokenProvisionSerializer(serializers.Serializer):
  78. username = serializers.CharField()
  79. password = serializers.CharField()
  80. class ObjectPermissionSerializer(ValidatedModelSerializer):
  81. url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail')
  82. object_types = ContentTypeField(
  83. queryset=ContentType.objects.all(),
  84. many=True
  85. )
  86. groups = SerializedPKRelatedField(
  87. queryset=Group.objects.all(),
  88. serializer=NestedGroupSerializer,
  89. required=False,
  90. many=True
  91. )
  92. users = SerializedPKRelatedField(
  93. queryset=User.objects.all(),
  94. serializer=NestedUserSerializer,
  95. required=False,
  96. many=True
  97. )
  98. class Meta:
  99. model = ObjectPermission
  100. fields = (
  101. 'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'groups', 'users', 'actions',
  102. 'constraints',
  103. )