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.permissions import BasePermission
|
||||
from rest_framework.response import Response
|
||||
|
||||
from .models import Map
|
||||
|
@ -16,23 +18,6 @@ class MapList(generics.ListCreateAPIView):
|
|||
else:
|
||||
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):
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
@ -40,11 +25,9 @@ class MapList(generics.ListCreateAPIView):
|
|||
map_ = serializer.instance
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
data = serializer.data
|
||||
permissions = self.get_map_permissions(map_)
|
||||
if not map_.owner:
|
||||
anonymous_url = map_.get_anonymous_edit_url()
|
||||
permissions["anonymous_edit_url"] = anonymous_url
|
||||
data["permissions"] = permissions
|
||||
data["permissions"]["anonymous_edit_url"] = anonymous_url
|
||||
response = Response(data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
if not self.request.user.is_authenticated:
|
||||
key, value = map_.signed_cookie_elements
|
||||
|
@ -54,6 +37,27 @@ class MapList(generics.ListCreateAPIView):
|
|||
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):
|
||||
queryset = Map.public.all().order_by("-modified_at")
|
||||
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)
|
||||
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
|
||||
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
|
||||
if map_inst.edit_status >= map_inst.EDITORS:
|
||||
|
@ -54,7 +54,7 @@ def can_view_map(view_func):
|
|||
|
||||
@wraps(view_func)
|
||||
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
|
||||
if not map_inst.can_view(request):
|
||||
return HttpResponseForbidden()
|
||||
|
|
|
@ -16,10 +16,26 @@ DEFAULT_CENTER = Point(DEFAULT_LONGITUDE, DEFAULT_LATITUDE)
|
|||
|
||||
class MapSerializer(serializers.HyperlinkedModelSerializer):
|
||||
slug = serializers.CharField(required=False)
|
||||
permissions = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
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):
|
||||
slug = data.get("slug")
|
||||
|
|
10
umap/urls.py
10
umap/urls.py
|
@ -63,6 +63,11 @@ i18n_urls = [
|
|||
views.PictogramJSONList.as_view(),
|
||||
name="pictogram_list_json",
|
||||
),
|
||||
re_path(
|
||||
r"^api/map/(?P<pk>[\d]+)/$",
|
||||
api_views.MapDetail.as_view(),
|
||||
name="map_detail",
|
||||
),
|
||||
]
|
||||
i18n_urls += decorated_patterns(
|
||||
[can_view_map, cache_control(must_revalidate=True)],
|
||||
|
@ -115,11 +120,6 @@ i18n_urls += decorated_patterns(
|
|||
),
|
||||
)
|
||||
map_urls = [
|
||||
re_path(
|
||||
r"^api/map/(?P<pk>[\d]+)/$",
|
||||
api_views.MapDetail.as_view(),
|
||||
name="map_detail",
|
||||
),
|
||||
re_path(
|
||||
r"^map/(?P<map_id>[\d]+)/update/permissions/$",
|
||||
views.UpdateMapPermissions.as_view(),
|
||||
|
|
Loading…
Reference in a new issue