api: add token authentication

This commit is contained in:
Jens Langhammer 2020-07-05 23:15:07 +02:00
parent d5a3e09a98
commit 2e2c9f5287
5 changed files with 57 additions and 11 deletions

View File

@ -56,10 +56,11 @@ class GroupUpdateView(
success_message = _("Successfully updated Group") success_message = _("Successfully updated Group")
class GroupDeleteView(LoginRequiredMixin, DeleteMessageView): class GroupDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteMessageView):
"""Delete group""" """Delete group"""
model = Group model = Group
permission_required = "passbook_flows.delete_group"
template_name = "generic/delete.html" template_name = "generic/delete.html"
success_url = reverse_lazy("passbook_admin:groups") success_url = reverse_lazy("passbook_admin:groups")

43
passbook/api/auth.py Normal file
View File

@ -0,0 +1,43 @@
"""API Authentication"""
from base64 import b64decode
from typing import Any, Tuple, Union
from django.utils.translation import gettext as _
from rest_framework import HTTP_HEADER_ENCODING, exceptions
from rest_framework.authentication import BaseAuthentication, get_authorization_header
from rest_framework.request import Request
from passbook.core.models import Token, TokenIntents, User
class PassbookTokenAuthentication(BaseAuthentication):
"""Token-based authentication using HTTP Basic authentication"""
def authenticate(self, request: Request) -> Union[Tuple[User, Any], None]:
"""Token-based authentication using HTTP Basic authentication"""
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != b"basic":
return None
if len(auth) == 1:
msg = _("Invalid basic header. No credentials provided.")
raise exceptions.AuthenticationFailed(msg)
if len(auth) > 2:
msg = _(
"Invalid basic header. Credentials string should not contain spaces."
)
raise exceptions.AuthenticationFailed(msg)
header_data = b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(":")
tokens = Token.filter_not_expired(
token_uuid=header_data[2], intent=TokenIntents.INTENT_API
)
if not tokens.exists():
raise exceptions.AuthenticationFailed(_("Invalid token."))
return (tokens.first().user, None)
def authenticate_header(self, request: Request) -> str:
return 'Basic realm="passbook"'

View File

@ -6,5 +6,5 @@ from passbook.api.v2.urls import urlpatterns as v2_urls
urlpatterns = [ urlpatterns = [
path("v1/", include(v1_urls)), path("v1/", include(v1_urls)),
path("v2/", include(v2_urls)), path("v2beta/", include(v2_urls)),
] ]

View File

@ -118,6 +118,9 @@ GUARDIAN_MONKEY_PATCH = False
SWAGGER_SETTINGS = { SWAGGER_SETTINGS = {
"DEFAULT_INFO": "passbook.api.v2.urls.info", "DEFAULT_INFO": "passbook.api.v2.urls.info",
"SECURITY_DEFINITIONS": {
"token": {"type": "apiKey", "name": "Authorization", "in": "header"}
},
} }
REST_FRAMEWORK = { REST_FRAMEWORK = {
@ -128,13 +131,10 @@ REST_FRAMEWORK = {
"rest_framework.filters.OrderingFilter", "rest_framework.filters.OrderingFilter",
"rest_framework.filters.SearchFilter", "rest_framework.filters.SearchFilter",
], ],
"DEFAULT_PERMISSION_CLASSES": ( "DEFAULT_PERMISSION_CLASSES": ("passbook.api.permissions.CustomObjectPermissions"),
# 'rest_framework.permissions.IsAuthenticated',
"passbook.api.permissions.CustomObjectPermissions",
),
"DEFAULT_AUTHENTICATION_CLASSES": ( "DEFAULT_AUTHENTICATION_CLASSES": (
"passbook.api.auth.PassbookTokenAuthentication",
"rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.SessionAuthentication",
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
), ),
} }

View File

@ -6,16 +6,18 @@ info:
license: license:
name: MIT License name: MIT License
version: v2 version: v2
basePath: /api/v2 basePath: /api/v2beta
consumes: consumes:
- application/json - application/json
produces: produces:
- application/json - application/json
securityDefinitions: securityDefinitions:
Basic: token:
type: basic type: apiKey
name: Authorization
in: header
security: security:
- Basic: [] - token: []
paths: paths:
/audit/events/: /audit/events/:
get: get: