OpenSlides/openslides/utils/rest_api.py
2015-06-29 15:15:33 +02:00

88 lines
2.9 KiB
Python

import re
from urllib.parse import urlparse
from rest_framework.decorators import detail_route # noqa
from rest_framework.decorators import list_route # noqa
from rest_framework.metadata import SimpleMetadata # noqa
from rest_framework.mixins import DestroyModelMixin, UpdateModelMixin # noqa
from rest_framework.response import Response # noqa
from rest_framework.routers import DefaultRouter
from rest_framework.serializers import ( # noqa
CharField,
DictField,
Field,
IntegerField,
ListField,
ListSerializer,
ModelSerializer,
PrimaryKeyRelatedField,
RelatedField,
SerializerMethodField,
ValidationError,
)
from rest_framework.viewsets import ModelViewSet as _ModelViewSet # noqa
from rest_framework.viewsets import ( # noqa
GenericViewSet,
ReadOnlyModelViewSet,
ViewSet,
)
from .exceptions import OpenSlidesError
router = DefaultRouter()
class ModelViewSet(_ModelViewSet):
"""
Viewset for models. Before the method check_permission is called we
check projector requirements. If access for projector client users is
not currently required, check_permission is called, else not.
"""
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs)
# Ensure that the incoming request is permitted
self.perform_authentication(request)
if not self.check_projector_requirements():
self.check_permissions(request)
self.check_throttles(request)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
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
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
match = re.match(r'^/rest/(?P<collection>[-\w]+/[-\w]+)/(?P<id>[-\w]+)/$', path)
if not match:
raise OpenSlidesError('Invalid REST api URL: %s' % url)
return match.group('collection'), match.group('id')