-
Notifications
You must be signed in to change notification settings - Fork 398
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
763 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
20241114T1954 | ||
20241127T2054 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Copyright The IETF Trust 2024, All Rights Reserved | ||
# | ||
from rest_framework import authentication | ||
from django.contrib.auth.models import AnonymousUser | ||
|
||
|
||
class ApiKeyAuthentication(authentication.BaseAuthentication): | ||
"""API-Key header authentication""" | ||
|
||
def authenticate(self, request): | ||
"""Extract the authentication token, if present | ||
This does not validate the token, it just arranges for it to be available in request.auth. | ||
It's up to a Permissions class to validate it for the appropriate endpoint. | ||
""" | ||
token = request.META.get("HTTP_X_API_KEY", None) | ||
if token is None: | ||
return None | ||
return AnonymousUser(), token # available as request.user and request.auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright The IETF Trust 2024, All Rights Reserved | ||
# | ||
from rest_framework import permissions | ||
from ietf.api.ietf_utils import is_valid_token | ||
|
||
|
||
class HasApiKey(permissions.BasePermission): | ||
"""Permissions class that validates a token using is_valid_token | ||
The view class must indicate the relevant endpoint by setting `api_key_endpoint`. | ||
Must be used with an Authentication class that puts a token in request.auth. | ||
""" | ||
def has_permission(self, request, view): | ||
endpoint = getattr(view, "api_key_endpoint", None) | ||
auth_token = getattr(request, "auth", None) | ||
if endpoint is not None and auth_token is not None: | ||
return is_valid_token(endpoint, auth_token) | ||
return False | ||
|
||
|
||
class IsOwnPerson(permissions.BasePermission): | ||
"""Permission to access own Person object""" | ||
def has_object_permission(self, request, view, obj): | ||
if not (request.user.is_authenticated and hasattr(request.user, "person")): | ||
return False | ||
return obj == request.user.person | ||
|
||
|
||
class BelongsToOwnPerson(permissions.BasePermission): | ||
"""Permission to access objects associated with own Person | ||
Requires that the object have a "person" field that indicates ownership. | ||
""" | ||
def has_object_permission(self, request, view, obj): | ||
if not (request.user.is_authenticated and hasattr(request.user, "person")): | ||
return False | ||
return ( | ||
hasattr(obj, "person") and obj.person == request.user.person | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright The IETF Trust 2024, All Rights Reserved | ||
"""Custom django-rest-framework routers""" | ||
from django.core.exceptions import ImproperlyConfigured | ||
from rest_framework import routers | ||
|
||
class PrefixedSimpleRouter(routers.SimpleRouter): | ||
"""SimpleRouter that adds a dot-separated prefix to its basename""" | ||
def __init__(self, name_prefix="", *args, **kwargs): | ||
self.name_prefix = name_prefix | ||
if len(self.name_prefix) == 0 or self.name_prefix[-1] == ".": | ||
raise ImproperlyConfigured("Cannot use a name_prefix that is empty or ends with '.'") | ||
super().__init__(*args, **kwargs) | ||
|
||
def get_default_basename(self, viewset): | ||
basename = super().get_default_basename(viewset) | ||
return f"{self.name_prefix}.{basename}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Copyright The IETF Trust 2024, All Rights Reserved | ||
# | ||
from drf_spectacular.extensions import OpenApiAuthenticationExtension | ||
|
||
|
||
class ApiKeyAuthenticationScheme(OpenApiAuthenticationExtension): | ||
"""Authentication scheme extension for the ApiKeyAuthentication | ||
Used by drf-spectacular when rendering the OpenAPI schema | ||
""" | ||
target_class = "ietf.api.authentication.ApiKeyAuthentication" | ||
name = "apiKeyAuth" | ||
|
||
def get_security_definition(self, auto_schema): | ||
return { | ||
"type": "apiKey", | ||
"description": "Shared secret in the X-Api-Key header", | ||
"name": "X-Api-Key", | ||
"in": "header", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.