some more stuff for the editor API
This commit is contained in:
parent
ae46b178c2
commit
671d138d03
5 changed files with 66 additions and 36 deletions
|
@ -9,6 +9,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ViewSet
|
from rest_framework.viewsets import ViewSet
|
||||||
|
|
||||||
from c3nav.api.models import Token
|
from c3nav.api.models import Token
|
||||||
|
from c3nav.api.utils import get_api_post_data
|
||||||
|
|
||||||
|
|
||||||
class SessionViewSet(ViewSet):
|
class SessionViewSet(ViewSet):
|
||||||
|
@ -34,10 +35,7 @@ class SessionViewSet(ViewSet):
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
raise ParseError(_('Log out first.'))
|
raise ParseError(_('Log out first.'))
|
||||||
|
|
||||||
try:
|
data = get_api_post_data(request)
|
||||||
data = request.json_body
|
|
||||||
except AttributeError:
|
|
||||||
data = request.POST
|
|
||||||
|
|
||||||
if 'token' in data:
|
if 'token' in data:
|
||||||
try:
|
try:
|
||||||
|
@ -65,10 +63,7 @@ class SessionViewSet(ViewSet):
|
||||||
# django-rest-framework doesn't do this for logged out requests
|
# django-rest-framework doesn't do this for logged out requests
|
||||||
SessionAuthentication().enforce_csrf(request)
|
SessionAuthentication().enforce_csrf(request)
|
||||||
|
|
||||||
try:
|
data = get_api_post_data(request)
|
||||||
data = request.json_body
|
|
||||||
except AttributeError:
|
|
||||||
data = request.POST
|
|
||||||
|
|
||||||
form = AuthenticationForm(request, data=data)
|
form = AuthenticationForm(request, data=data)
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
from django.http import HttpResponseBadRequest
|
|
||||||
|
|
||||||
|
|
||||||
class JsonRequestBodyMiddleware:
|
|
||||||
"""
|
|
||||||
Enables posting JSON requests.
|
|
||||||
"""
|
|
||||||
def __init__(self, get_response):
|
|
||||||
self.get_response = get_response
|
|
||||||
|
|
||||||
def __call__(self, request):
|
|
||||||
is_json = request.META.get('CONTENT_TYPE').lower() == 'application/json'
|
|
||||||
if is_json:
|
|
||||||
try:
|
|
||||||
data = json.loads(request.body)
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
raise HttpResponseBadRequest
|
|
||||||
request.json_body = data
|
|
||||||
return self.get_response(request)
|
|
16
src/c3nav/api/utils.py
Normal file
16
src/c3nav/api/utils.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from rest_framework.exceptions import ParseError
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_post_data(request):
|
||||||
|
is_json = request.META.get('CONTENT_TYPE').lower() == 'application/json'
|
||||||
|
if is_json:
|
||||||
|
try:
|
||||||
|
data = json.loads(request.body)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
raise ParseError('Invalid JSON.')
|
||||||
|
else:
|
||||||
|
request.json_body = data
|
||||||
|
return data
|
||||||
|
return request.POST
|
|
@ -12,6 +12,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
||||||
from shapely.ops import cascaded_union
|
from shapely.ops import cascaded_union
|
||||||
|
|
||||||
|
from c3nav.api.utils import get_api_post_data
|
||||||
from c3nav.editor.models import ChangeSet
|
from c3nav.editor.models import ChangeSet
|
||||||
from c3nav.editor.views.base import etag_func
|
from c3nav.editor.views.base import etag_func
|
||||||
from c3nav.mapdata.api import api_etag
|
from c3nav.mapdata.api import api_etag
|
||||||
|
@ -262,7 +263,7 @@ class EditorViewSet(ViewSet):
|
||||||
@api_etag(etag_func=etag_func, cache_parameters={})
|
@api_etag(etag_func=etag_func, cache_parameters={})
|
||||||
def bounds(self, request, *args, **kwargs):
|
def bounds(self, request, *args, **kwargs):
|
||||||
if not can_access_editor(request):
|
if not can_access_editor(request):
|
||||||
return PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
return Response({
|
return Response({
|
||||||
'bounds': Source.max_bounds(),
|
'bounds': Source.max_bounds(),
|
||||||
|
@ -310,7 +311,7 @@ class EditorViewSet(ViewSet):
|
||||||
|
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
if not can_access_editor(request):
|
if not can_access_editor(request):
|
||||||
return PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
resolved = self.resolved
|
resolved = self.resolved
|
||||||
if not resolved:
|
if not resolved:
|
||||||
|
@ -319,6 +320,8 @@ class EditorViewSet(ViewSet):
|
||||||
if not getattr(resolved.func, 'api_hybrid', False):
|
if not getattr(resolved.func, 'api_hybrid', False):
|
||||||
raise NotFound(_('Matching editor view point does not provide an API.'))
|
raise NotFound(_('Matching editor view point does not provide an API.'))
|
||||||
|
|
||||||
|
get_api_post_data(request)
|
||||||
|
|
||||||
response = resolved.func(request, api=True, *resolved.args, **resolved.kwargs)
|
response = resolved.func(request, api=True, *resolved.args, **resolved.kwargs)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -327,6 +330,9 @@ class ChangeSetViewSet(ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
List change sets
|
List change sets
|
||||||
/current/ returns the current changeset.
|
/current/ returns the current changeset.
|
||||||
|
/direct_editing/ POST to activate direct editing (if available).
|
||||||
|
/deactive/ POST to deactivate current changeset or deactivate direct editing
|
||||||
|
/{id}/changes/ returns the changes of a given changeset.
|
||||||
"""
|
"""
|
||||||
queryset = ChangeSet.objects.all()
|
queryset = ChangeSet.objects.all()
|
||||||
|
|
||||||
|
@ -335,28 +341,63 @@ class ChangeSetViewSet(ReadOnlyModelViewSet):
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
if not can_access_editor(request):
|
if not can_access_editor(request):
|
||||||
return PermissionDenied
|
raise PermissionDenied
|
||||||
return Response([obj.serialize() for obj in self.get_queryset().order_by('id')])
|
return Response([obj.serialize() for obj in self.get_queryset().order_by('id')])
|
||||||
|
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
if not can_access_editor(request):
|
if not can_access_editor(request):
|
||||||
return PermissionDenied
|
raise PermissionDenied
|
||||||
return Response(self.get_object().serialize())
|
return Response(self.get_object().serialize())
|
||||||
|
|
||||||
@action(detail=False, methods=['get'])
|
@action(detail=False, methods=['get'])
|
||||||
def current(self, request, *args, **kwargs):
|
def current(self, request, *args, **kwargs):
|
||||||
if not can_access_editor(request):
|
if not can_access_editor(request):
|
||||||
return PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
changeset = ChangeSet.get_for_request(request)
|
changeset = ChangeSet.get_for_request(request)
|
||||||
return Response({
|
return Response({
|
||||||
'direct_editing': changeset.direct_editing,
|
'direct_editing': changeset.direct_editing,
|
||||||
'changeset': changeset.serialize() if changeset.pk else None,
|
'changeset': changeset.serialize() if changeset.pk else None,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def direct_editing(self, request, *args, **kwargs):
|
||||||
|
if not can_access_editor(request):
|
||||||
|
raise PermissionDenied
|
||||||
|
# django-rest-framework doesn't automatically do this for logged out requests
|
||||||
|
SessionAuthentication().enforce_csrf(request)
|
||||||
|
|
||||||
|
if not ChangeSet.can_direct_edit(request):
|
||||||
|
raise PermissionDenied(_('You don\'t have the permission to activate direct editing.'))
|
||||||
|
|
||||||
|
changeset = ChangeSet.get_for_request(request)
|
||||||
|
if changeset.pk is not None:
|
||||||
|
raise PermissionDenied(_('You cannot activate direct editing if you have an active changeset.'))
|
||||||
|
|
||||||
|
request.session['direct_editing'] = True
|
||||||
|
|
||||||
|
return Response({
|
||||||
|
'success': True,
|
||||||
|
})
|
||||||
|
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def deactivate(self, request, *args, **kwargs):
|
||||||
|
if not can_access_editor(request):
|
||||||
|
raise PermissionDenied
|
||||||
|
# django-rest-framework doesn't automatically do this for logged out requests
|
||||||
|
SessionAuthentication().enforce_csrf(request)
|
||||||
|
|
||||||
|
request.session.pop('changeset', None)
|
||||||
|
request.session['direct_editing'] = False
|
||||||
|
|
||||||
|
return Response({
|
||||||
|
'success': True,
|
||||||
|
})
|
||||||
|
|
||||||
@action(detail=True, methods=['get'])
|
@action(detail=True, methods=['get'])
|
||||||
def changes(self, request, *args, **kwargs):
|
def changes(self, request, *args, **kwargs):
|
||||||
if not can_access_editor(request):
|
if not can_access_editor(request):
|
||||||
return PermissionDenied
|
raise PermissionDenied
|
||||||
changeset = self.get_object()
|
changeset = self.get_object()
|
||||||
changeset.fill_changes_cache()
|
changeset.fill_changes_cache()
|
||||||
return Response([obj.serialize() for obj in changeset.iter_changed_objects()])
|
return Response([obj.serialize() for obj in changeset.iter_changed_objects()])
|
||||||
|
|
|
@ -227,7 +227,6 @@ MIDDLEWARE = [
|
||||||
'c3nav.mapdata.middleware.UserDataMiddleware',
|
'c3nav.mapdata.middleware.UserDataMiddleware',
|
||||||
'c3nav.site.middleware.MobileclientMiddleware',
|
'c3nav.site.middleware.MobileclientMiddleware',
|
||||||
'c3nav.control.middleware.UserPermissionsMiddleware',
|
'c3nav.control.middleware.UserPermissionsMiddleware',
|
||||||
'c3nav.api.middleware.JsonRequestBodyMiddleware',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
with suppress(ImportError):
|
with suppress(ImportError):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue