69 lines
3 KiB
Python
69 lines
3 KiB
Python
from django.urls import path
|
|
from rest_framework.decorators import api_view, authentication_classes, permission_classes
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
from rest_framework.viewsets import ViewSetMixin
|
|
|
|
from authentication.models import KnownIdentity, ToolshedUser, Group
|
|
from authentication.signature_auth import SignatureAuthentication
|
|
from toolshed.models import InventoryItem, StorageLocation
|
|
from toolshed.serializers import FriendSerializer, GroupIdMapSerializer
|
|
|
|
|
|
class IdMap(APIView, ViewSetMixin):
|
|
authentication_classes = [SignatureAuthentication]
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def get(self, request, format=None): # /api/idmap/
|
|
identity = request.user
|
|
identities = identity.friends.all() | KnownIdentity.objects.filter(pk=identity.pk)
|
|
groups = identity.member_of_groups.all()
|
|
return Response({
|
|
'identities': FriendSerializer(identities, many=True).data,
|
|
'groups': GroupIdMapSerializer(groups, many=True).data,
|
|
})
|
|
|
|
|
|
@api_view(['GET'])
|
|
@authentication_classes([SignatureAuthentication])
|
|
@permission_classes([IsAuthenticated])
|
|
def resolve_short_id(request, kind, owner_id, local_id):
|
|
"""Resolves a short id's (kind, owner_id, local_id) against this backend's own numbering. See docs/implementation.md#domain-qualified-short-id-resolution."""
|
|
if kind in ('item', 'storage_location'):
|
|
try:
|
|
owner = KnownIdentity.objects.get(pk=owner_id).user.get()
|
|
except (KnownIdentity.DoesNotExist, ToolshedUser.DoesNotExist):
|
|
return Response(status=404)
|
|
if owner not in request.user.friends_or_self():
|
|
return Response(status=403)
|
|
model = InventoryItem if kind == 'item' else StorageLocation
|
|
try:
|
|
obj = model.objects.get(owner=owner, id=local_id)
|
|
except model.DoesNotExist:
|
|
return Response(status=404)
|
|
is_owner = request.user.user.filter(pk=owner.pk).exists()
|
|
if getattr(obj, 'availability_policy', 'share') == 'private' and not is_owner:
|
|
return Response(status=403)
|
|
return Response({'handle': f'{owner.username}@{owner.domain}', 'id': obj.id})
|
|
if kind in ('group_item', 'group_storage_location'):
|
|
try:
|
|
group = Group.objects.get(pk=owner_id)
|
|
except Group.DoesNotExist:
|
|
return Response(status=404)
|
|
if not group.is_member(request.user):
|
|
return Response(status=403)
|
|
model = InventoryItem if kind == 'group_item' else StorageLocation
|
|
try:
|
|
obj = model.objects.get(owner_group=group, id=local_id)
|
|
except model.DoesNotExist:
|
|
return Response(status=404)
|
|
return Response({'handle': str(group), 'id': obj.id})
|
|
return Response(status=400)
|
|
|
|
|
|
urlpatterns = [
|
|
path('idmap/', IdMap.as_view(), name='idmap'),
|
|
path('resolve_short_id/<str:kind>/<int:owner_id>/<int:local_id>/', resolve_short_id,
|
|
name='resolve_short_id'),
|
|
]
|