mirror of
https://github.com/ansible/awx.git
synced 2026-01-09 15:02:07 -03:30
Change Swagger UI endpoint from /api/swagger/ to /api/docs/ (#16172)
* Change Swagger UI endpoint from /api/swagger/ to /api/docs/ - Update URL pattern to use /docs/ instead of /swagger/ - Update API root response to show 'docs' key instead of 'swagger' - Add authentication requirement for schema documentation endpoints - Update contact email to controller-eng@redhat.com The schema endpoints (/api/docs/, /api/schema/, /api/redoc/) now require authentication to prevent unauthorized access to API documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Require authentication for all schema endpoints including /api/schema/ Create custom view classes that enforce authentication for all schema endpoints to prevent inconsistent access control where UI views required authentication but the raw schema endpoint remained publicly accessible. This ensures all schema endpoints (/api/schema/, /api/docs/, /api/redoc/) consistently require authentication. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add unit tests for authenticated schema view classes Add test coverage for the new AuthenticatedSpectacular* view classes to ensure they properly require authentication. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * remove unused import --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
335a4bbbc6
commit
f81859510c
@ -1,5 +1,6 @@
|
||||
import warnings
|
||||
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from drf_spectacular.openapi import AutoSchema
|
||||
from drf_spectacular.views import (
|
||||
SpectacularAPIView,
|
||||
@ -46,11 +47,29 @@ class CustomAutoSchema(AutoSchema):
|
||||
return getattr(self.view, 'deprecated', False)
|
||||
|
||||
|
||||
class AuthenticatedSpectacularAPIView(SpectacularAPIView):
|
||||
"""SpectacularAPIView that requires authentication."""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
|
||||
class AuthenticatedSpectacularSwaggerView(SpectacularSwaggerView):
|
||||
"""SpectacularSwaggerView that requires authentication."""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
|
||||
class AuthenticatedSpectacularRedocView(SpectacularRedocView):
|
||||
"""SpectacularRedocView that requires authentication."""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
|
||||
# Schema view (returns OpenAPI schema JSON/YAML)
|
||||
schema_view = SpectacularAPIView.as_view()
|
||||
schema_view = AuthenticatedSpectacularAPIView.as_view()
|
||||
|
||||
# Swagger UI view
|
||||
swagger_ui_view = SpectacularSwaggerView.as_view(url_name='api:schema-json')
|
||||
swagger_ui_view = AuthenticatedSpectacularSwaggerView.as_view(url_name='api:schema-json')
|
||||
|
||||
# ReDoc UI view
|
||||
redoc_view = SpectacularRedocView.as_view(url_name='api:schema-json')
|
||||
redoc_view = AuthenticatedSpectacularRedocView.as_view(url_name='api:schema-json')
|
||||
|
||||
@ -158,7 +158,7 @@ urlpatterns = [
|
||||
re_path(r'^logout/$', LoggedLogoutView.as_view(next_page='/api/', redirect_field_name='next'), name='logout'),
|
||||
# Schema endpoints (available in all modes for API documentation and testing)
|
||||
re_path(r'^schema/$', schema_view, name='schema-json'),
|
||||
re_path(r'^swagger/$', swagger_ui_view, name='schema-swagger-ui'),
|
||||
re_path(r'^docs/$', swagger_ui_view, name='schema-swagger-ui'),
|
||||
re_path(r'^redoc/$', redoc_view, name='schema-redoc'),
|
||||
]
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ class ApiRootView(APIView):
|
||||
data['custom_login_info'] = settings.CUSTOM_LOGIN_INFO
|
||||
data['login_redirect_override'] = settings.LOGIN_REDIRECT_OVERRIDE
|
||||
if MODE == 'development':
|
||||
data['swagger'] = drf_reverse('api:schema-swagger-ui')
|
||||
data['docs'] = drf_reverse('api:schema-swagger-ui')
|
||||
return Response(data)
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
import warnings
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from awx.api.schema import CustomAutoSchema
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from awx.api.schema import (
|
||||
CustomAutoSchema,
|
||||
AuthenticatedSpectacularAPIView,
|
||||
AuthenticatedSpectacularSwaggerView,
|
||||
AuthenticatedSpectacularRedocView,
|
||||
)
|
||||
|
||||
|
||||
class TestCustomAutoSchema:
|
||||
@ -248,3 +255,19 @@ class TestCustomAutoSchema:
|
||||
tags = schema.get_tags()
|
||||
# swagger_topic should take priority
|
||||
assert tags == ['Priority_Topic']
|
||||
|
||||
|
||||
class TestAuthenticatedSchemaViews:
|
||||
"""Unit tests for authenticated schema view classes."""
|
||||
|
||||
def test_authenticated_spectacular_api_view_requires_authentication(self):
|
||||
"""Test that AuthenticatedSpectacularAPIView requires authentication."""
|
||||
assert IsAuthenticated in AuthenticatedSpectacularAPIView.permission_classes
|
||||
|
||||
def test_authenticated_spectacular_swagger_view_requires_authentication(self):
|
||||
"""Test that AuthenticatedSpectacularSwaggerView requires authentication."""
|
||||
assert IsAuthenticated in AuthenticatedSpectacularSwaggerView.permission_classes
|
||||
|
||||
def test_authenticated_spectacular_redoc_view_requires_authentication(self):
|
||||
"""Test that AuthenticatedSpectacularRedocView requires authentication."""
|
||||
assert IsAuthenticated in AuthenticatedSpectacularRedocView.permission_classes
|
||||
|
||||
@ -1043,7 +1043,7 @@ SPECTACULAR_SETTINGS = {
|
||||
'SCHEMA_PATH_PREFIX': r'/api/v[0-9]',
|
||||
'DEFAULT_GENERATOR_CLASS': 'drf_spectacular.generators.SchemaGenerator',
|
||||
'SCHEMA_COERCE_PATH_PK_SUFFIX': True,
|
||||
'CONTACT': {'email': 'contact@snippets.local'},
|
||||
'CONTACT': {'email': 'controller-eng@redhat.com'},
|
||||
'LICENSE': {'name': 'Apache License'},
|
||||
'TERMS_OF_SERVICE': 'https://www.google.com/policies/terms/',
|
||||
# Use our custom schema class that handles swagger_topic and deprecated views
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user