Closes #20936: Add a REST API endpoint to validate authentication credentials

This commit is contained in:
Jeremy Stretch 2025-12-07 13:59:37 -05:00
parent 7eefb07554
commit ca43adf692
3 changed files with 28 additions and 1 deletions

View File

@ -5,6 +5,7 @@ from django.conf import settings
from django_rq.queues import get_connection from django_rq.queues import get_connection
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import extend_schema
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from rest_framework.views import APIView from rest_framework.views import APIView
@ -12,6 +13,7 @@ from rq.worker import Worker
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
from netbox.plugins.utils import get_installed_plugins from netbox.plugins.utils import get_installed_plugins
from users.api.serializers import UserSerializer
from utilities.apps import get_installed_apps from utilities.apps import get_installed_apps
@ -62,3 +64,15 @@ class StatusView(APIView):
'python-version': platform.python_version(), 'python-version': platform.python_version(),
'rq-workers-running': Worker.count(get_connection('default')), 'rq-workers-running': Worker.count(get_connection('default')),
}) })
class AuthenticationCheckView(APIView):
"""
Return the user making the request, if authenticated successfully.
"""
permission_classes = [IsAuthenticated]
@extend_schema(responses={200: OpenApiTypes.OBJECT})
def get(self, request):
serializer = UserSerializer(request.user, context={'request': request})
return Response(serializer.data)

View File

@ -32,6 +32,18 @@ class AppTest(APITestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_authentication_check(self):
url = reverse('api-authentication-check')
# Test an unauthenticated request
response = self.client.get(f'{url}')
self.assertEqual(response.status_code, 403)
# Test an authenticated request
response = self.client.get(f'{url}', **self.header)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['id'], self.user.pk)
class OptionalLimitOffsetPaginationTest(TestCase): class OptionalLimitOffsetPaginationTest(TestCase):

View File

@ -5,7 +5,7 @@ from django.views.decorators.cache import cache_page
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
from account.views import LoginView, LogoutView from account.views import LoginView, LogoutView
from netbox.api.views import APIRootView, StatusView from netbox.api.views import APIRootView, AuthenticationCheckView, StatusView
from netbox.graphql.schema import schema from netbox.graphql.schema import schema
from netbox.graphql.views import NetBoxGraphQLView from netbox.graphql.views import NetBoxGraphQLView
from netbox.plugins.urls import plugin_patterns, plugin_api_patterns from netbox.plugins.urls import plugin_patterns, plugin_api_patterns
@ -53,6 +53,7 @@ _patterns = [
path('api/vpn/', include('vpn.api.urls')), path('api/vpn/', include('vpn.api.urls')),
path('api/wireless/', include('wireless.api.urls')), path('api/wireless/', include('wireless.api.urls')),
path('api/status/', StatusView.as_view(), name='api-status'), path('api/status/', StatusView.as_view(), name='api-status'),
path('api/authentication-check/', AuthenticationCheckView.as_view(), name='api-authentication-check'),
# REST API schema # REST API schema
path( path(