-
Notifications
You must be signed in to change notification settings - Fork 105
Expand file tree
/
Copy pathpermissions.py
More file actions
62 lines (43 loc) · 1.82 KB
/
permissions.py
File metadata and controls
62 lines (43 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import typing
from django.conf import settings
from django.http import HttpRequest
from rest_framework import permissions
from .models import AbstractAPIKey, get_api_key_model
class KeyParser:
keyword = "Api-Key"
def get(self, request: HttpRequest) -> typing.Optional[str]:
custom_header = getattr(settings, "API_KEY_CUSTOM_HEADER", None)
if custom_header is not None:
return self.get_from_header(request, custom_header)
return self.get_from_authorization(request)
def get_from_authorization(self, request: HttpRequest) -> typing.Optional[str]:
authorization = request.META.get("HTTP_AUTHORIZATION")
if not authorization:
return None
try:
_, key = authorization.split("{} ".format(self.keyword))
except ValueError:
key = None
return key
def get_from_header(self, request: HttpRequest, name: str) -> typing.Optional[str]:
return request.META.get(name) or None
class BaseHasAPIKey(permissions.BasePermission):
model: typing.Optional[typing.Type[AbstractAPIKey]] = None
key_parser = KeyParser()
def get_key(self, request: HttpRequest) -> typing.Optional[str]:
return self.key_parser.get(request)
def has_permission(self, request: HttpRequest, view: typing.Any) -> bool:
assert self.model is not None, (
"%s must define `.model` with the API key model to use"
% self.__class__.__name__
)
key = self.get_key(request)
if not key:
return False
return self.model.objects.is_valid(key)
def has_object_permission(
self, request: HttpRequest, view: typing.Any, obj: AbstractAPIKey
) -> bool:
return self.has_permission(request, view)
class HasAPIKey(BaseHasAPIKey):
model = get_api_key_model()