-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): integrated restframework_api_keys
- Loading branch information
1 parent
40cb328
commit cccd414
Showing
29 changed files
with
209 additions
and
132 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
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,55 @@ | ||
from django.forms import ValidationError | ||
from rest_framework.permissions import BasePermission | ||
|
||
from django_napse.core.models import NapseSpace | ||
from django_napse.utils.constants import PERMISSION_TYPES | ||
from django_napse.utils.errors import APIError | ||
|
||
|
||
def check_for_space(request): | ||
if "space" not in request.query_params: | ||
raise APIError.MissingSpace() | ||
try: | ||
return NapseSpace.objects.get(uuid=request.query_params["space"]) | ||
except NapseSpace.DoesNotExist as e: | ||
raise APIError.MissingSpace() from e | ||
except ValidationError as e: | ||
raise APIError.MissingSpace() from e | ||
|
||
|
||
class HasAdminPermission(BasePermission): | ||
def has_permission(self, request, view): | ||
space = check_for_space(request) | ||
|
||
api_key = view.get_api_key(request) | ||
if any(permission.permission_type == PERMISSION_TYPES.ADMIN for permission in api_key.permissions.filter(space=space)): | ||
return True | ||
raise APIError.InvalidPermissions() | ||
|
||
|
||
class HasFullAccessPermission(BasePermission): | ||
def has_permission(self, request, view): | ||
space = check_for_space(request) | ||
|
||
api_key = view.get_api_key(request) | ||
for permission in api_key.permissions.filter(space=space): | ||
if permission.permission_type in [PERMISSION_TYPES.ADMIN, PERMISSION_TYPES.FULL_ACCESS]: | ||
return True | ||
raise APIError.InvalidPermissions() | ||
|
||
|
||
class HasReadPermission(BasePermission): | ||
def has_permission(self, request, view): | ||
space = check_for_space(request) | ||
|
||
api_key = view.get_api_key(request) | ||
for permission in api_key.permissions.filter(space=space): | ||
if permission.permission_type in [PERMISSION_TYPES.ADMIN, PERMISSION_TYPES.FULL_ACCESS, PERMISSION_TYPES.READ_ONLY]: | ||
return True | ||
raise APIError.InvalidPermissions() | ||
|
||
|
||
class HasSpace(BasePermission): | ||
def has_permission(self, request, view): | ||
check_for_space(request) | ||
return True |
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,12 @@ | ||
from rest_framework.viewsets import GenericViewSet | ||
from rest_framework_api_key.models import APIKey | ||
|
||
from django_napse.core.models import NapseSpace | ||
|
||
|
||
class CustomViewSet(GenericViewSet): | ||
def get_api_key(self, request): | ||
return APIKey.objects.get_from_key(request.META["HTTP_AUTHORIZATION"].split()[1]) | ||
|
||
def space(self, request): | ||
return NapseSpace.objects.get(uuid=request.query_params["space"]) |
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 +0,0 @@ | ||
from .key import NapseAPIKeySerializer | ||
This file was deleted.
Oops, something went wrong.
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,20 +1,14 @@ | ||
from django.db import IntegrityError | ||
from rest_framework import status | ||
from rest_framework.response import Response | ||
from rest_framework.viewsets import GenericViewSet | ||
|
||
from django_napse.api.keys.serializers import NapseAPIKeySerializer | ||
from django_napse.auth.models import NapseAPIKey | ||
from rest_framework_api_key.models import APIKey | ||
|
||
|
||
class Key(GenericViewSet): | ||
permission_classes = [] | ||
|
||
def create(self, request): | ||
if "name" not in request.data: | ||
if "username" not in request.data: | ||
return Response({"error": "Missing name"}, status=status.HTTP_400_BAD_REQUEST) | ||
if "description" not in request.data: | ||
return Response({"error": "Missing description"}, status=status.HTTP_400_BAD_REQUEST) | ||
try: | ||
new_key = NapseAPIKey.objects.create(name=request.data["name"], description=request.data["description"]) | ||
except IntegrityError: | ||
return Response({"error": f"Napse API Key (name={request.data['name']}) already exists."}, status=status.HTTP_400_BAD_REQUEST) | ||
return Response(data=NapseAPIKeySerializer(new_key).data, status=status.HTTP_200_OK) | ||
_, key = APIKey.objects.create_key(name=request.data["username"]) | ||
return Response({"key": key}, status=status.HTTP_201_CREATED) |
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,2 @@ | ||
from .admin import AdminPermission | ||
from .create import Permission |
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 @@ | ||
from rest_framework import status | ||
from rest_framework.response import Response | ||
|
||
from django_napse.api.custom_viewset import CustomViewSet | ||
from django_napse.api.permissions.serializers import PermissionSerializer | ||
from django_napse.auth.models import KeyPermission | ||
|
||
|
||
class AdminPermission(CustomViewSet): | ||
def list(self, request): | ||
space = self.space(request) | ||
pending_approvals = KeyPermission.objects.filter(space=space, approved=False) | ||
serializer = PermissionSerializer(data=pending_approvals, many=True) | ||
serializer.is_valid() | ||
|
||
return Response(data=serializer.data, status=status.HTTP_204_NO_CONTENT) |
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,26 +1,31 @@ | ||
from django.db import IntegrityError | ||
from rest_framework import status | ||
from rest_framework.response import Response | ||
from rest_framework.viewsets import GenericViewSet | ||
from rest_framework_api_key.permissions import HasAPIKey | ||
|
||
from django_napse.auth.models import KeyPermission, NapseAPIKey | ||
from django_napse.core.models import NapseSpace | ||
from django_napse.api.custom_permissions import HasSpace | ||
from django_napse.api.custom_viewset import CustomViewSet | ||
from django_napse.auth.models import KeyPermission | ||
from django_napse.utils.constants import PERMISSION_TYPES | ||
|
||
|
||
class Permission(GenericViewSet): | ||
class Permission(CustomViewSet): | ||
permission_classes = [HasAPIKey, HasSpace] | ||
|
||
def create(self, request): | ||
if "space_uuid" not in request.data: | ||
return Response({"error": "Missing space_uuid"}, status=status.HTTP_400_BAD_REQUEST) | ||
if "api_key" not in request.data: | ||
return Response({"error": "Missing api_key"}, status=status.HTTP_400_BAD_REQUEST) | ||
try: | ||
key = NapseAPIKey.objects.get(napse_API_key=request.data["api_key"]) | ||
except NapseAPIKey.DoesNotExist: | ||
return Response({"error": f"Napse API Key (name={request.data['api_key']}) does not exist."}, status=status.HTTP_400_BAD_REQUEST) | ||
space = self.space(request) | ||
|
||
if "permission_type" not in request.data: | ||
return Response({"error": "Missing permission_type"}, status=status.HTTP_400_BAD_REQUEST) | ||
|
||
if request.data["permission_type"] not in PERMISSION_TYPES: | ||
return Response({"error": f"Permission type ({request.data['permission_type']}) does not exist."}, status=status.HTTP_400_BAD_REQUEST) | ||
|
||
try: | ||
space = NapseSpace.objects.get(uuid=request.data["space_uuid"]) | ||
except NapseSpace.DoesNotExist: | ||
return Response({"error": f"Napse Space (uuid={request.data['space_uuid']}) does not exist."}, status=status.HTTP_400_BAD_REQUEST) | ||
permission_type = PERMISSION_TYPES.FULL_ACCESS | ||
KeyPermission.objects.create(key=key, space=space, permission_type=permission_type) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
KeyPermission.objects.create(key=self.get_api_key(request), space=space, permission_type=request.data["permission_type"]) | ||
except IntegrityError: | ||
return Response( | ||
{"error": f"Permission {request.data['permission_type']} already exists for this key and space."}, | ||
status=status.HTTP_400_BAD_REQUEST, | ||
) | ||
return Response(status=status.HTTP_201_CREATED) |
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,16 @@ | ||
# Generated by Django 4.2.5 on 2023-10-02 15:29 | ||
|
||
from django.db import migrations | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("django_napse_auth", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.DeleteModel( | ||
name="NapseAPIKey", | ||
), | ||
] |
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,2 +1 @@ | ||
from .key import * | ||
from .permission import * |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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.