mirror of
https://github.com/umap-project/umap.git
synced 2025-05-05 22:11:50 +02:00
Improve the DRF API
This commit is contained in:
parent
6e9e46dbbd
commit
e97cee9b69
4 changed files with 48 additions and 28 deletions
|
@ -1,4 +1,6 @@
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
from rest_framework import generics, status
|
from rest_framework import generics, status
|
||||||
|
from rest_framework.permissions import BasePermission
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from .models import Map
|
from .models import Map
|
||||||
|
@ -16,23 +18,6 @@ class MapList(generics.ListCreateAPIView):
|
||||||
else:
|
else:
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
def get_map_permissions(self, map_):
|
|
||||||
permissions = {}
|
|
||||||
permissions["edit_status"] = map_.edit_status
|
|
||||||
permissions["share_status"] = map_.share_status
|
|
||||||
if map_.owner:
|
|
||||||
permissions["owner"] = {
|
|
||||||
"id": map_.owner.pk,
|
|
||||||
"name": str(map_.owner),
|
|
||||||
"url": map_.owner.get_url(),
|
|
||||||
}
|
|
||||||
permissions["editors"] = [
|
|
||||||
{"id": editor.pk, "name": str(editor)} for editor in map_.editors.all()
|
|
||||||
]
|
|
||||||
if not map_.owner and map_.is_anonymous_owner(self.request):
|
|
||||||
permissions["anonymous_edit_url"] = map_.get_anonymous_edit_url()
|
|
||||||
return permissions
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
serializer = self.get_serializer(data=request.data)
|
serializer = self.get_serializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
@ -40,11 +25,9 @@ class MapList(generics.ListCreateAPIView):
|
||||||
map_ = serializer.instance
|
map_ = serializer.instance
|
||||||
headers = self.get_success_headers(serializer.data)
|
headers = self.get_success_headers(serializer.data)
|
||||||
data = serializer.data
|
data = serializer.data
|
||||||
permissions = self.get_map_permissions(map_)
|
|
||||||
if not map_.owner:
|
if not map_.owner:
|
||||||
anonymous_url = map_.get_anonymous_edit_url()
|
anonymous_url = map_.get_anonymous_edit_url()
|
||||||
permissions["anonymous_edit_url"] = anonymous_url
|
data["permissions"]["anonymous_edit_url"] = anonymous_url
|
||||||
data["permissions"] = permissions
|
|
||||||
response = Response(data, status=status.HTTP_201_CREATED, headers=headers)
|
response = Response(data, status=status.HTTP_201_CREATED, headers=headers)
|
||||||
if not self.request.user.is_authenticated:
|
if not self.request.user.is_authenticated:
|
||||||
key, value = map_.signed_cookie_elements
|
key, value = map_.signed_cookie_elements
|
||||||
|
@ -54,6 +37,27 @@ class MapList(generics.ListCreateAPIView):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class MapPermission(BasePermission):
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
map_inst = get_object_or_404(Map, pk=view.kwargs.get("pk"))
|
||||||
|
if request.method == "PUT":
|
||||||
|
return map_inst.can_edit(user=request.user, request=request)
|
||||||
|
if request.method == "GET":
|
||||||
|
return map_inst.can_view(request)
|
||||||
|
|
||||||
|
|
||||||
class MapDetail(generics.RetrieveUpdateDestroyAPIView):
|
class MapDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||||
queryset = Map.public.all().order_by("-modified_at")
|
queryset = Map.public.all().order_by("-modified_at")
|
||||||
serializer_class = MapSerializer
|
serializer_class = MapSerializer
|
||||||
|
|
||||||
|
permission_classes = [MapPermission]
|
||||||
|
|
||||||
|
def retrieve(self, request, *args, **kwargs):
|
||||||
|
instance = self.get_object()
|
||||||
|
serializer = self.get_serializer(instance)
|
||||||
|
data = serializer.data
|
||||||
|
if not instance.owner and instance.is_anonymous_owner(request):
|
||||||
|
data["permissions"][
|
||||||
|
"anonymous_edit_url"
|
||||||
|
] = instance.get_anonymous_edit_url()
|
||||||
|
return Response(data)
|
||||||
|
|
|
@ -33,7 +33,7 @@ def can_edit_map(view_func):
|
||||||
|
|
||||||
@wraps(view_func)
|
@wraps(view_func)
|
||||||
def wrapper(request, *args, **kwargs):
|
def wrapper(request, *args, **kwargs):
|
||||||
map_inst = get_object_or_404(Map, pk=kwargs.get("map_id", kwargs.get("pk")))
|
map_inst = get_object_or_404(Map, pk=kwargs["map_id"])
|
||||||
user = request.user
|
user = request.user
|
||||||
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
|
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
|
||||||
if map_inst.edit_status >= map_inst.EDITORS:
|
if map_inst.edit_status >= map_inst.EDITORS:
|
||||||
|
@ -54,7 +54,7 @@ def can_view_map(view_func):
|
||||||
|
|
||||||
@wraps(view_func)
|
@wraps(view_func)
|
||||||
def wrapper(request, *args, **kwargs):
|
def wrapper(request, *args, **kwargs):
|
||||||
map_inst = get_object_or_404(Map, pk=kwargs.get("map_id", kwargs.get("pk")))
|
map_inst = get_object_or_404(Map, pk=kwargs["map_id"])
|
||||||
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
|
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
|
||||||
if not map_inst.can_view(request):
|
if not map_inst.can_view(request):
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
|
|
@ -16,10 +16,26 @@ DEFAULT_CENTER = Point(DEFAULT_LONGITUDE, DEFAULT_LATITUDE)
|
||||||
|
|
||||||
class MapSerializer(serializers.HyperlinkedModelSerializer):
|
class MapSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
slug = serializers.CharField(required=False)
|
slug = serializers.CharField(required=False)
|
||||||
|
permissions = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Map
|
model = Map
|
||||||
fields = ["id", "name", "slug", "center", "settings"]
|
fields = ["id", "name", "slug", "center", "settings", "permissions"]
|
||||||
|
|
||||||
|
def get_permissions(self, obj):
|
||||||
|
permissions = {}
|
||||||
|
permissions["edit_status"] = obj.edit_status
|
||||||
|
permissions["share_status"] = obj.share_status
|
||||||
|
if obj.owner:
|
||||||
|
permissions["owner"] = {
|
||||||
|
"id": obj.owner.pk,
|
||||||
|
"name": str(obj.owner),
|
||||||
|
"url": obj.owner.get_url(),
|
||||||
|
}
|
||||||
|
permissions["editors"] = [
|
||||||
|
{"id": editor.pk, "name": str(editor)} for editor in obj.editors.all()
|
||||||
|
]
|
||||||
|
return permissions
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
slug = data.get("slug")
|
slug = data.get("slug")
|
||||||
|
|
10
umap/urls.py
10
umap/urls.py
|
@ -63,6 +63,11 @@ i18n_urls = [
|
||||||
views.PictogramJSONList.as_view(),
|
views.PictogramJSONList.as_view(),
|
||||||
name="pictogram_list_json",
|
name="pictogram_list_json",
|
||||||
),
|
),
|
||||||
|
re_path(
|
||||||
|
r"^api/map/(?P<pk>[\d]+)/$",
|
||||||
|
api_views.MapDetail.as_view(),
|
||||||
|
name="map_detail",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
i18n_urls += decorated_patterns(
|
i18n_urls += decorated_patterns(
|
||||||
[can_view_map, cache_control(must_revalidate=True)],
|
[can_view_map, cache_control(must_revalidate=True)],
|
||||||
|
@ -115,11 +120,6 @@ i18n_urls += decorated_patterns(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
map_urls = [
|
map_urls = [
|
||||||
re_path(
|
|
||||||
r"^api/map/(?P<pk>[\d]+)/$",
|
|
||||||
api_views.MapDetail.as_view(),
|
|
||||||
name="map_detail",
|
|
||||||
),
|
|
||||||
re_path(
|
re_path(
|
||||||
r"^map/(?P<map_id>[\d]+)/update/permissions/$",
|
r"^map/(?P<map_id>[\d]+)/update/permissions/$",
|
||||||
views.UpdateMapPermissions.as_view(),
|
views.UpdateMapPermissions.as_view(),
|
||||||
|
|
Loading…
Reference in a new issue