2015-02-04 00:08:38 +01:00
|
|
|
import re
|
|
|
|
from urllib.parse import urlparse
|
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
from rest_framework.decorators import detail_route, list_route # noqa
|
2015-06-17 18:32:05 +02:00
|
|
|
from rest_framework.metadata import SimpleMetadata # noqa
|
2015-06-16 10:37:23 +02:00
|
|
|
from rest_framework.mixins import DestroyModelMixin, UpdateModelMixin # noqa
|
|
|
|
from rest_framework.response import Response # noqa
|
|
|
|
from rest_framework.routers import DefaultRouter
|
2015-02-12 18:48:14 +01:00
|
|
|
from rest_framework.serializers import ( # noqa
|
|
|
|
CharField,
|
2015-06-14 23:26:06 +02:00
|
|
|
DictField,
|
2015-02-18 01:45:39 +01:00
|
|
|
Field,
|
2015-04-30 19:13:28 +02:00
|
|
|
IntegerField,
|
2015-06-14 23:26:06 +02:00
|
|
|
ListField,
|
2015-02-12 18:48:14 +01:00
|
|
|
ListSerializer,
|
|
|
|
ModelSerializer,
|
|
|
|
PrimaryKeyRelatedField,
|
|
|
|
RelatedField,
|
2015-02-12 20:57:05 +01:00
|
|
|
SerializerMethodField,
|
2015-06-16 10:37:23 +02:00
|
|
|
ValidationError,
|
|
|
|
)
|
2015-07-01 23:18:48 +02:00
|
|
|
from rest_framework.viewsets import GenericViewSet as _GenericViewSet # noqa
|
2015-06-16 10:37:23 +02:00
|
|
|
from rest_framework.viewsets import ModelViewSet as _ModelViewSet # noqa
|
2015-07-01 23:18:48 +02:00
|
|
|
from rest_framework.viewsets import \
|
|
|
|
ReadOnlyModelViewSet as _ReadOnlyModelViewSet # noqa
|
|
|
|
from rest_framework.viewsets import ViewSet as _ViewSet # noqa
|
2014-10-11 14:15:42 +02:00
|
|
|
|
2015-02-04 00:08:38 +01:00
|
|
|
from .exceptions import OpenSlidesError
|
|
|
|
|
2015-02-12 18:48:14 +01:00
|
|
|
router = DefaultRouter()
|
2015-01-17 14:01:44 +01:00
|
|
|
|
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
class PermissionMixin:
|
2015-06-12 21:08:57 +02:00
|
|
|
"""
|
2015-07-01 23:18:48 +02:00
|
|
|
Mixin for subclasses of APIView like GenericViewSet and ModelViewSet.
|
|
|
|
|
|
|
|
The methods check_view_permissions or check_projector_requirements are
|
|
|
|
evaluated. If both return False self.permission_denied() is called.
|
|
|
|
Django REST framework's permission system is disabled.
|
2015-06-12 21:08:57 +02:00
|
|
|
"""
|
2015-07-01 23:18:48 +02:00
|
|
|
|
|
|
|
def get_permissions(self):
|
2015-06-12 21:08:57 +02:00
|
|
|
"""
|
2015-07-01 23:18:48 +02:00
|
|
|
Overriden method to check view and projector permissions. Returns an
|
|
|
|
empty interable so Django REST framework won't do any other
|
|
|
|
permission checks by evaluating Django REST framework style permission
|
|
|
|
classes and the request passes.
|
2015-06-12 21:08:57 +02:00
|
|
|
"""
|
2015-07-01 23:18:48 +02:00
|
|
|
if not self.check_view_permissions() and not self.check_projector_requirements():
|
|
|
|
self.permission_denied(self.request)
|
|
|
|
return ()
|
2015-06-12 21:08:57 +02:00
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
def check_view_permissions(self):
|
|
|
|
"""
|
|
|
|
Override this and return True if the requesting user should be able to
|
|
|
|
get access to your view.
|
|
|
|
"""
|
|
|
|
return False
|
2015-06-12 21:08:57 +02:00
|
|
|
|
|
|
|
def check_projector_requirements(self):
|
|
|
|
"""
|
|
|
|
Helper method which returns True if the current request (on this
|
|
|
|
view instance) is required for at least one active projector element.
|
|
|
|
"""
|
|
|
|
from openslides.core.models import Projector
|
|
|
|
|
|
|
|
result = False
|
|
|
|
if self.request.user.has_perm('core.can_see_projector'):
|
|
|
|
for requirement in Projector.get_all_requirements():
|
|
|
|
if requirement.is_currently_required(view_instance=self):
|
|
|
|
result = True
|
|
|
|
break
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
class GenericViewSet(PermissionMixin, _GenericViewSet):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class ModelViewSet(PermissionMixin, _ModelViewSet):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class ReadOnlyModelViewSet(PermissionMixin, _ReadOnlyModelViewSet):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class ViewSet(PermissionMixin, _ViewSet):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2015-02-04 00:08:38 +01:00
|
|
|
def get_collection_and_id_from_url(url):
|
|
|
|
"""
|
|
|
|
Helper function. Returns a tuple containing the collection name and the id
|
|
|
|
extracted out of the given REST api URL.
|
|
|
|
|
|
|
|
For example get_collection_and_id_from_url('http://localhost/api/users/user/3/')
|
|
|
|
returns ('users/user', '3').
|
|
|
|
|
|
|
|
Raises OpenSlidesError if the URL is invalid.
|
|
|
|
"""
|
|
|
|
path = urlparse(url).path
|
2015-01-30 11:58:36 +01:00
|
|
|
match = re.match(r'^/rest/(?P<collection>[-\w]+/[-\w]+)/(?P<id>[-\w]+)/$', path)
|
2015-02-04 00:08:38 +01:00
|
|
|
if not match:
|
|
|
|
raise OpenSlidesError('Invalid REST api URL: %s' % url)
|
2015-01-30 11:58:36 +01:00
|
|
|
return match.group('collection'), match.group('id')
|