api: add filter backend for secret key to allow access to tenants and certificates
closes #4182 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
89a3f7d004
commit
f0e121c064
|
@ -1,9 +1,15 @@
|
||||||
"""API Authorization"""
|
"""API Authorization"""
|
||||||
|
from django.conf import settings
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from rest_framework.authentication import get_authorization_header
|
||||||
from rest_framework.filters import BaseFilterBackend
|
from rest_framework.filters import BaseFilterBackend
|
||||||
from rest_framework.permissions import BasePermission
|
from rest_framework.permissions import BasePermission
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
|
from rest_framework_guardian.filters import ObjectPermissionsFilter
|
||||||
|
|
||||||
|
from authentik.api.authentication import validate_auth
|
||||||
|
|
||||||
|
|
||||||
class OwnerFilter(BaseFilterBackend):
|
class OwnerFilter(BaseFilterBackend):
|
||||||
|
@ -17,6 +23,20 @@ class OwnerFilter(BaseFilterBackend):
|
||||||
return queryset.filter(**{self.owner_key: request.user})
|
return queryset.filter(**{self.owner_key: request.user})
|
||||||
|
|
||||||
|
|
||||||
|
class SecretKeyFilter(DjangoFilterBackend):
|
||||||
|
"""Allow access to all objects when authenticated with secret key as token.
|
||||||
|
|
||||||
|
Replaces both DjangoFilterBackend and ObjectPermissionsFilter"""
|
||||||
|
|
||||||
|
def filter_queryset(self, request: Request, queryset: QuerySet, view) -> QuerySet:
|
||||||
|
auth_header = get_authorization_header(request)
|
||||||
|
token = validate_auth(auth_header)
|
||||||
|
if token and token == settings.SECRET_KEY:
|
||||||
|
return queryset
|
||||||
|
queryset = ObjectPermissionsFilter().filter_queryset(request, queryset, view)
|
||||||
|
return super().filter_queryset(request, queryset, view)
|
||||||
|
|
||||||
|
|
||||||
class OwnerPermissions(BasePermission):
|
class OwnerPermissions(BasePermission):
|
||||||
"""Authorize requests by an object's owner matching the requesting user"""
|
"""Authorize requests by an object's owner matching the requesting user"""
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,14 @@ from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_sche
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError
|
||||||
from rest_framework.fields import CharField, DateTimeField, IntegerField, SerializerMethodField
|
from rest_framework.fields import CharField, DateTimeField, IntegerField, SerializerMethodField
|
||||||
|
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
|
from authentik.api.authorization import SecretKeyFilter
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
|
@ -203,6 +205,7 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
|
||||||
filterset_class = CertificateKeyPairFilter
|
filterset_class = CertificateKeyPairFilter
|
||||||
ordering = ["name"]
|
ordering = ["name"]
|
||||||
search_fields = ["name"]
|
search_fields = ["name"]
|
||||||
|
filter_backends = [SecretKeyFilter, OrderingFilter, SearchFilter]
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
parameters=[
|
parameters=[
|
||||||
|
|
|
@ -5,12 +5,14 @@ from drf_spectacular.utils import extend_schema
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError
|
||||||
from rest_framework.fields import CharField, ListField
|
from rest_framework.fields import CharField, ListField
|
||||||
|
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.api.authorization import SecretKeyFilter
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
|
@ -109,6 +111,8 @@ class TenantViewSet(UsedByMixin, ModelViewSet):
|
||||||
]
|
]
|
||||||
ordering = ["domain"]
|
ordering = ["domain"]
|
||||||
|
|
||||||
|
filter_backends = [SecretKeyFilter, OrderingFilter, SearchFilter]
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
responses=CurrentTenantSerializer(many=False),
|
responses=CurrentTenantSerializer(many=False),
|
||||||
)
|
)
|
||||||
|
|
Reference in a new issue