Skip to content

Commit

Permalink
Add auth extension for django-rest-knox
Browse files Browse the repository at this point in the history
  • Loading branch information
callumgare committed Feb 5, 2024
1 parent 22b78d6 commit 624c9b9
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions drf_spectacular/contrib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
'rest_framework_recursive',
'rest_framework_gis',
'pydantic',
'knox_auth_token',
]
13 changes: 13 additions & 0 deletions drf_spectacular/contrib/knox_auth_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from drf_spectacular.extensions import OpenApiAuthenticationExtension
from drf_spectacular.plumbing import build_bearer_security_scheme_object


class KnoxTokenScheme(OpenApiAuthenticationExtension):
target_class = 'knox.auth.TokenAuthentication'
name = 'knoxApiToken'

def get_security_definition(self, auto_schema):
return build_bearer_security_scheme_object(
header_name='Authorization',
token_prefix=self.target.authenticate_header(""),
)
1 change: 1 addition & 0 deletions requirements/optionals.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ drf-spectacular-sidecar
djangorestframework-dataclasses>=1.0.0; python_version >= '3.7'
djangorestframework-gis>=1.0.0
pydantic>=2,<3; python_version >= '3.7'
django-rest-knox>=4.1
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def pytest_configure(config):
'allauth.account',
'oauth2_provider',
'django_filters',
'knox',
# this is not strictly required and when added django-polymorphic
# currently breaks the whole Django/DRF upstream testing.
# 'polymorphic',
Expand Down
49 changes: 49 additions & 0 deletions tests/contrib/test_knox_auth_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from unittest import mock

import pytest
from rest_framework import mixins, routers, serializers, viewsets

from tests import assert_schema, generate_schema

try:
from knox.auth import TokenAuthentication
except ImportError:
TokenAuthentication = None


class XSerializer(serializers.Serializer):
uuid = serializers.UUIDField()


class XViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = XSerializer
authentication_classes = [TokenAuthentication]
required_scopes = ['x:read', 'x:write']


@pytest.mark.contrib('knox_auth_token')
def test_knox_auth_token(no_warnings):
router = routers.SimpleRouter()
router.register('x', XViewset, basename="x")

urlpatterns = [
*router.urls
]

schema = generate_schema(None, patterns=urlpatterns)

assert_schema(schema, 'tests/contrib/test_knox_auth_token.yml')


@pytest.mark.contrib('knox_auth_token')
@mock.patch('knox.settings.knox_settings.AUTH_HEADER_PREFIX', 'CustomPrefix')
def test_knox_auth_token_non_default_prefix(no_warnings):
schema = generate_schema('/x', XViewset)
assert schema['components']['securitySchemes'] == {
'knoxApiToken': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization',
'description': 'Token-based authentication with required prefix "CustomPrefix"'
},
}
38 changes: 38 additions & 0 deletions tests/contrib/test_knox_auth_token.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
openapi: 3.0.3
info:
title: ''
version: 0.0.0
paths:
/x/:
get:
operationId: x_list
tags:
- x
security:
- knoxApiToken: []
- {}
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/X'
description: ''
components:
schemas:
X:
type: object
properties:
uuid:
type: string
format: uuid
required:
- uuid
securitySchemes:
knoxApiToken:
type: apiKey
in: header
name: Authorization
description: Token-based authentication with required prefix "Token"
4 changes: 4 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ known_third_party =
polymorphic
oauth2_provider
djstripe
knox
multi_line_output = 5
use_parentheses = true
include_trailing_comma = true
Expand Down Expand Up @@ -142,6 +143,9 @@ ignore_missing_imports = True
[mypy-rest_framework_jwt.*]
ignore_missing_imports = True

[mypy-knox.*]
ignore_missing_imports = True

[mypy-uritemplate.*]
ignore_missing_imports = True

Expand Down

0 comments on commit 624c9b9

Please sign in to comment.