103 lines
3.7 KiB
Python
103 lines
3.7 KiB
Python
from rest_framework.permissions import BasePermission
|
|
from django.conf import settings
|
|
from .models.user_constants import DJ
|
|
|
|
REQUEST_PERMISSION_TYPE_MAP = {
|
|
'GET': 'view',
|
|
'HEAD': 'view',
|
|
'OPTIONS': 'view',
|
|
'POST': 'change',
|
|
'PUT': 'change',
|
|
'DELETE': 'delete',
|
|
'PATCH': 'change',
|
|
}
|
|
|
|
def get_own_obj(request, view):
|
|
user = request.user
|
|
if user is None or user.type != DJ:
|
|
return ''
|
|
if request.method == 'GET':
|
|
return ''
|
|
qs = view.queryset.all()
|
|
try:
|
|
model_owners = []
|
|
for model in qs:
|
|
owner = model.get_owner()
|
|
if owner not in model_owners:
|
|
model_owners.append(owner)
|
|
if len(model_owners) == 1 and user in model_owners:
|
|
return 'own_'
|
|
except AttributeError:
|
|
return ''
|
|
return ''
|
|
|
|
def get_permission_for_view(request, view):
|
|
try:
|
|
permission_type = REQUEST_PERMISSION_TYPE_MAP[request.method]
|
|
if view.__class__.__name__ == 'APIRootView':
|
|
return '{}_apiroot'.format(permission_type)
|
|
model = view.model_permission_name
|
|
own_obj = get_own_obj(request, view)
|
|
return '{permission_type}_{own_obj}{model}'.format(permission_type=permission_type,
|
|
own_obj=own_obj,
|
|
model=model)
|
|
except AttributeError:
|
|
return None
|
|
|
|
def check_authorization_header(request):
|
|
auth_header = request.META.get('Authorization')
|
|
if not auth_header:
|
|
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
|
|
|
|
if auth_header.startswith('Api-Key'):
|
|
token = auth_header.split()[1]
|
|
if token == settings.CONFIG.get('general', 'api_key'):
|
|
return True
|
|
return False
|
|
|
|
|
|
class IsAdminOrOwnUser(BasePermission):
|
|
"""
|
|
Implements Django Rest Framework permissions. This is separate from
|
|
Django's standard permission system. For details see
|
|
https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions
|
|
"""
|
|
def has_permission(self, request, view):
|
|
if request.user.is_superuser():
|
|
return True
|
|
return False
|
|
|
|
def has_object_permission(self, request, view, obj):
|
|
if request.user.is_superuser():
|
|
return True
|
|
return obj.username == request.user
|
|
|
|
|
|
class IsSystemTokenOrUser(BasePermission):
|
|
"""
|
|
Implements Django Rest Framework permissions. This is separate from
|
|
Django's standard permission system. For details see
|
|
https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions
|
|
|
|
This permission allows services (liquidsoap, 3rd-party, etc) to connect with
|
|
an API-Key header. All standard-users (i.e. not using the API-Key) have their
|
|
permissions checked against Django's standard permission system.
|
|
"""
|
|
def has_permission(self, request, view):
|
|
if request.user and request.user.is_authenticated:
|
|
perm = get_permission_for_view(request, view)
|
|
# Required as view_apiroot is a permission not linked to a specific
|
|
# model. This use-case allows users to view the base of the API
|
|
# explorer. Their assigned group permissions determine further access
|
|
# into the explorer.
|
|
if perm == 'view_apiroot':
|
|
return True
|
|
return request.user.has_perm(perm)
|
|
return check_authorization_header(request)
|
|
|
|
def has_object_permission(self, request, view, obj):
|
|
if request.user and request.user.is_authenticated:
|
|
perm = get_permission_for_view(request, view)
|
|
return request.user.has_perm(perm, obj)
|
|
return check_authorization_header(request)
|