from rest_framework.permissions import BasePermission, SAFE_METHODS class IsOwnerOrUnclaimed(BasePermission): """ Permission for resources with an optional `user` FK. - POST (create): open to anyone — viewset sets user=None for anonymous callers. - GET list: viewset filters to own records (or returns empty for anonymous). - GET detail: open to anyone with the ID. - PATCH/PUT/DELETE: * unclaimed (user=None) → anyone may mutate. * claimed (user set) → owner only. NOTE: The global DRF default is IsAuthenticated; this class must be explicitly declared on every viewset in the tools app. """ def has_permission(self, request, view): return True # object-level and queryset filtering handle the rest def has_object_permission(self, request, view, obj): if request.method in SAFE_METHODS: return True if obj.user is None: return True return request.user.is_authenticated and obj.user == request.user