1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

adds additional parameters for token provision api #12870

This commit is contained in:
Abhimanyu Saharan
2023-08-31 01:18:18 +05:30
committed by Jeremy Stretch
parent 296166da95
commit 7848beedce
2 changed files with 49 additions and 27 deletions

View File

@ -1,11 +1,12 @@
from django.conf import settings from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from rest_framework import serializers from rest_framework import serializers
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import AuthenticationFailed, PermissionDenied
from netbox.api.fields import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField from netbox.api.fields import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer from netbox.api.serializers import ValidatedModelSerializer
@ -107,9 +108,42 @@ class TokenSerializer(ValidatedModelSerializer):
return super().validate(data) return super().validate(data)
class TokenProvisionSerializer(serializers.Serializer): class TokenProvisionSerializer(TokenSerializer):
username = serializers.CharField() user = NestedUserSerializer(
password = serializers.CharField() read_only=True
)
username = serializers.CharField(
write_only=True
)
password = serializers.CharField(
write_only=True
)
last_used = serializers.DateTimeField(
read_only=True
)
key = serializers.CharField(
read_only=True
)
class Meta:
model = Token
fields = (
'id', 'url', 'display', 'user', 'created', 'expires', 'last_used', 'key', 'write_enabled', 'description',
'allowed_ips', 'username', 'password',
)
def validate(self, data):
# Validate the username and password
username = data.pop('username')
password = data.pop('password')
user = authenticate(request=self.context.get('request'), username=username, password=password)
if user is None:
raise AuthenticationFailed("Invalid username/password")
# Inject the user into the validated data
data['user'] = user
return data
class ObjectPermissionSerializer(ValidatedModelSerializer): class ObjectPermissionSerializer(ValidatedModelSerializer):

View File

@ -1,3 +1,4 @@
import logging
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
@ -63,34 +64,21 @@ class TokenProvisionView(APIView):
@extend_schema( @extend_schema(
request=serializers.TokenProvisionSerializer, request=serializers.TokenProvisionSerializer,
responses={ responses={
201: serializers.TokenSerializer, 201: serializers.TokenProvisionSerializer,
401: OpenApiTypes.OBJECT, 401: OpenApiTypes.OBJECT,
} }
) )
def post(self, request): def post(self, request):
serializer = serializers.TokenProvisionSerializer(data=request.data) serializer = serializers.TokenProvisionSerializer(data=request.data, context={'request': request})
serializer.is_valid() serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response(serializer.data, status=HTTP_201_CREATED)
# Authenticate the user account based on the provided credentials def perform_create(self, serializer):
username = serializer.data.get('username') model = serializer.Meta.model
password = serializer.data.get('password') logger = logging.getLogger(f'netbox.api.views.TokenProvisionView')
if not username or not password: logger.info(f"Creating new {model._meta.verbose_name}")
raise AuthenticationFailed("Username and password must be provided to provision a token.") serializer.save()
user = authenticate(request=request, username=username, password=password)
if user is None:
raise AuthenticationFailed("Invalid username/password")
# Create a new Token for the User
token = Token(user=user)
token.save()
data = serializers.TokenSerializer(token, context={'request': request}).data
# Manually append the token key, which is normally write-only
data['key'] = token.key
return Response(data, status=HTTP_201_CREATED)
def get_serializer_class(self):
return serializers.TokenSerializer
# #