61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
|
|
from django.core.exceptions import ValidationError as DjangoValidationError
|
||
|
|
from rest_framework.permissions import BasePermission
|
||
|
|
|
||
|
|
from farm_hub.models import FarmHub
|
||
|
|
|
||
|
|
from .services import is_feature_enabled_for_farm
|
||
|
|
|
||
|
|
|
||
|
|
class FeatureAccessPermission(BasePermission):
|
||
|
|
message = "You do not have access to this API."
|
||
|
|
|
||
|
|
def has_permission(self, request, view):
|
||
|
|
feature_code = getattr(view, "required_feature_code", None)
|
||
|
|
if not feature_code:
|
||
|
|
return True
|
||
|
|
|
||
|
|
farm_uuid = self._extract_farm_uuid(request, view)
|
||
|
|
if not farm_uuid:
|
||
|
|
return True
|
||
|
|
|
||
|
|
farm = self._resolve_owned_farm(request, farm_uuid)
|
||
|
|
if farm is None:
|
||
|
|
return True
|
||
|
|
|
||
|
|
if is_feature_enabled_for_farm(farm, feature_code):
|
||
|
|
return True
|
||
|
|
|
||
|
|
self.message = f"Access to feature `{feature_code}` is denied."
|
||
|
|
return False
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def _extract_farm_uuid(request, view):
|
||
|
|
for key in ("farm_uuid", "farmUuid"):
|
||
|
|
farm_uuid = view.kwargs.get(key)
|
||
|
|
if farm_uuid:
|
||
|
|
return str(farm_uuid)
|
||
|
|
|
||
|
|
for key in ("farm_uuid", "farmUuid"):
|
||
|
|
farm_uuid = request.query_params.get(key)
|
||
|
|
if farm_uuid:
|
||
|
|
return farm_uuid
|
||
|
|
|
||
|
|
if isinstance(request.data, dict):
|
||
|
|
for key in ("farm_uuid", "farmUuid"):
|
||
|
|
farm_uuid = request.data.get(key)
|
||
|
|
if farm_uuid:
|
||
|
|
return farm_uuid
|
||
|
|
return None
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def _resolve_owned_farm(request, farm_uuid):
|
||
|
|
try:
|
||
|
|
return (
|
||
|
|
FarmHub.objects.select_related("access_profile")
|
||
|
|
.prefetch_related("products", "sensors")
|
||
|
|
.filter(farm_uuid=farm_uuid, owner=request.user)
|
||
|
|
.first()
|
||
|
|
)
|
||
|
|
except (ValueError, TypeError, DjangoValidationError):
|
||
|
|
return None
|