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:
committed by
Jeremy Stretch
parent
296166da95
commit
7848beedce
@ -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):
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
Reference in New Issue
Block a user