petcare-api / api /permissions.py
Sameer669
Initial PawCare Django backend with JWT auth, RBAC, audit logging, and HF storage
4f01198
"""
Custom RBAC Permission Classes
Admin β†’ full access to everything
Caregiver β†’ read own profile, manage own bookings
User β†’ manage own pets/bookings, read caregivers
"""
from rest_framework.permissions import BasePermission, SAFE_METHODS
from api.models import Role
class IsAdmin(BasePermission):
"""Only platform admins (role=admin OR is_staff)."""
message = 'Admin access required.'
def has_permission(self, request, view):
return (
request.user
and request.user.is_authenticated
and (request.user.role == Role.ADMIN or request.user.is_staff)
)
class IsCaregiver(BasePermission):
"""Only caregivers."""
message = 'Caregiver account required.'
def has_permission(self, request, view):
return (
request.user
and request.user.is_authenticated
and request.user.role == Role.CAREGIVER
)
class IsAdminOrReadOnly(BasePermission):
"""
GET/HEAD/OPTIONS β†’ any authenticated user.
Mutations (POST/PUT/PATCH/DELETE) β†’ admin only.
Used on /caregivers/ endpoint.
"""
message = 'Write access requires admin privileges.'
def has_permission(self, request, view):
if not request.user or not request.user.is_authenticated:
return False
if request.method in SAFE_METHODS:
return True
return request.user.role == Role.ADMIN or request.user.is_staff
class IsOwnerOrAdmin(BasePermission):
"""
Object-level: owner or admin can access.
Works for Pet, Booking, Conversation objects.
"""
message = 'You do not have permission to access this resource.'
def has_object_permission(self, request, view, obj):
if request.user.role == Role.ADMIN or request.user.is_staff:
return True
# Support objects with either .user or .owner attribute
owner = getattr(obj, 'user', None) or getattr(obj, 'owner', None)
return owner == request.user
class IsParticipantOrAdmin(BasePermission):
"""For Conversation / Message objects."""
message = 'You are not a participant in this conversation.'
def has_object_permission(self, request, view, obj):
if request.user.role == Role.ADMIN or request.user.is_staff:
return True
# obj is a Conversation
conversation = getattr(obj, 'conversation', obj)
return request.user in conversation.participants.all()
class IsCaregiverOwnerOrAdmin(BasePermission):
"""Caregiver can update their own profile; admin can update any."""
message = 'You can only manage your own caregiver profile.'
def has_object_permission(self, request, view, obj):
if request.user.role == Role.ADMIN or request.user.is_staff:
return True
if request.method in SAFE_METHODS:
return True
return obj.user == request.user