Skip to content

Commit f818595

Browse files
Jaapisclaude
andauthored
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 [email protected] 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * remove unused import --------- Co-authored-by: Claude <[email protected]>
1 parent 335a4bb commit f818595

File tree

5 files changed

+49
-7
lines changed

5 files changed

+49
-7
lines changed

awx/api/schema.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import warnings
22

3+
from rest_framework.permissions import IsAuthenticated
34
from drf_spectacular.openapi import AutoSchema
45
from drf_spectacular.views import (
56
SpectacularAPIView,
@@ -46,11 +47,29 @@ def is_deprecated(self):
4647
return getattr(self.view, 'deprecated', False)
4748

4849

50+
class AuthenticatedSpectacularAPIView(SpectacularAPIView):
51+
"""SpectacularAPIView that requires authentication."""
52+
53+
permission_classes = [IsAuthenticated]
54+
55+
56+
class AuthenticatedSpectacularSwaggerView(SpectacularSwaggerView):
57+
"""SpectacularSwaggerView that requires authentication."""
58+
59+
permission_classes = [IsAuthenticated]
60+
61+
62+
class AuthenticatedSpectacularRedocView(SpectacularRedocView):
63+
"""SpectacularRedocView that requires authentication."""
64+
65+
permission_classes = [IsAuthenticated]
66+
67+
4968
# Schema view (returns OpenAPI schema JSON/YAML)
50-
schema_view = SpectacularAPIView.as_view()
69+
schema_view = AuthenticatedSpectacularAPIView.as_view()
5170

5271
# Swagger UI view
53-
swagger_ui_view = SpectacularSwaggerView.as_view(url_name='api:schema-json')
72+
swagger_ui_view = AuthenticatedSpectacularSwaggerView.as_view(url_name='api:schema-json')
5473

5574
# ReDoc UI view
56-
redoc_view = SpectacularRedocView.as_view(url_name='api:schema-json')
75+
redoc_view = AuthenticatedSpectacularRedocView.as_view(url_name='api:schema-json')

awx/api/urls/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158
re_path(r'^logout/$', LoggedLogoutView.as_view(next_page='/api/', redirect_field_name='next'), name='logout'),
159159
# Schema endpoints (available in all modes for API documentation and testing)
160160
re_path(r'^schema/$', schema_view, name='schema-json'),
161-
re_path(r'^swagger/$', swagger_ui_view, name='schema-swagger-ui'),
161+
re_path(r'^docs/$', swagger_ui_view, name='schema-swagger-ui'),
162162
re_path(r'^redoc/$', redoc_view, name='schema-redoc'),
163163
]
164164

awx/api/views/root.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def get(self, request, format=None):
5959
data['custom_login_info'] = settings.CUSTOM_LOGIN_INFO
6060
data['login_redirect_override'] = settings.LOGIN_REDIRECT_OVERRIDE
6161
if MODE == 'development':
62-
data['swagger'] = drf_reverse('api:schema-swagger-ui')
62+
data['docs'] = drf_reverse('api:schema-swagger-ui')
6363
return Response(data)
6464

6565

awx/main/tests/unit/api/test_schema.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import warnings
22
from unittest.mock import Mock, patch
33

4-
from awx.api.schema import CustomAutoSchema
4+
from rest_framework.permissions import IsAuthenticated
5+
6+
from awx.api.schema import (
7+
CustomAutoSchema,
8+
AuthenticatedSpectacularAPIView,
9+
AuthenticatedSpectacularSwaggerView,
10+
AuthenticatedSpectacularRedocView,
11+
)
512

613

714
class TestCustomAutoSchema:
@@ -248,3 +255,19 @@ def test_get_tags_priority_order(self):
248255
tags = schema.get_tags()
249256
# swagger_topic should take priority
250257
assert tags == ['Priority_Topic']
258+
259+
260+
class TestAuthenticatedSchemaViews:
261+
"""Unit tests for authenticated schema view classes."""
262+
263+
def test_authenticated_spectacular_api_view_requires_authentication(self):
264+
"""Test that AuthenticatedSpectacularAPIView requires authentication."""
265+
assert IsAuthenticated in AuthenticatedSpectacularAPIView.permission_classes
266+
267+
def test_authenticated_spectacular_swagger_view_requires_authentication(self):
268+
"""Test that AuthenticatedSpectacularSwaggerView requires authentication."""
269+
assert IsAuthenticated in AuthenticatedSpectacularSwaggerView.permission_classes
270+
271+
def test_authenticated_spectacular_redoc_view_requires_authentication(self):
272+
"""Test that AuthenticatedSpectacularRedocView requires authentication."""
273+
assert IsAuthenticated in AuthenticatedSpectacularRedocView.permission_classes

awx/settings/defaults.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@
10431043
'SCHEMA_PATH_PREFIX': r'/api/v[0-9]',
10441044
'DEFAULT_GENERATOR_CLASS': 'drf_spectacular.generators.SchemaGenerator',
10451045
'SCHEMA_COERCE_PATH_PK_SUFFIX': True,
1046-
'CONTACT': {'email': '[email protected]'},
1046+
'CONTACT': {'email': '[email protected]'},
10471047
'LICENSE': {'name': 'Apache License'},
10481048
'TERMS_OF_SERVICE': 'https://www.google.com/policies/terms/',
10491049
# Use our custom schema class that handles swagger_topic and deprecated views

0 commit comments

Comments
 (0)