2026-04-03 23:51:00 +03:30
|
|
|
from rest_framework import status
|
|
|
|
|
from rest_framework.permissions import IsAuthenticated
|
|
|
|
|
from rest_framework.response import Response
|
|
|
|
|
from rest_framework.views import APIView
|
2026-04-10 16:12:51 +03:30
|
|
|
from drf_spectacular.utils import OpenApiParameter, OpenApiTypes, extend_schema
|
2026-04-03 23:51:00 +03:30
|
|
|
|
|
|
|
|
from config.swagger import code_response
|
|
|
|
|
from farm_hub.models import FarmHub
|
|
|
|
|
|
2026-04-09 22:48:54 +03:30
|
|
|
from .serializers import FeatureAuthorizationRequestSerializer
|
|
|
|
|
from .services import AccessControlServiceUnavailable, request_opa_batch_authorization
|
2026-04-03 23:51:00 +03:30
|
|
|
|
|
|
|
|
|
2026-04-09 22:48:54 +03:30
|
|
|
class FarmFeatureAuthorizationView(APIView):
|
2026-04-03 23:51:00 +03:30
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
|
|
2026-04-09 22:48:54 +03:30
|
|
|
@extend_schema(
|
|
|
|
|
tags=["Access Control"],
|
2026-04-10 16:12:51 +03:30
|
|
|
parameters=[
|
|
|
|
|
OpenApiParameter(name="farm_uuid", type=OpenApiTypes.UUID, location=OpenApiParameter.PATH, default="11111111-1111-1111-1111-111111111111"),
|
|
|
|
|
],
|
2026-04-09 22:48:54 +03:30
|
|
|
request=FeatureAuthorizationRequestSerializer,
|
|
|
|
|
responses={200: code_response("FarmFeatureAuthorizationResponse")},
|
|
|
|
|
)
|
|
|
|
|
def post(self, request, farm_uuid):
|
|
|
|
|
serializer = FeatureAuthorizationRequestSerializer(data=request.data)
|
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
|
|
2026-04-03 23:51:00 +03:30
|
|
|
try:
|
2026-04-09 22:48:54 +03:30
|
|
|
farm = FarmHub.objects.select_related("subscription_plan", "farm_type").prefetch_related(
|
|
|
|
|
"products",
|
|
|
|
|
"sensors",
|
|
|
|
|
"sensors__sensor_catalog",
|
2026-05-05 01:32:27 +03:30
|
|
|
"sensors__device_catalogs",
|
2026-04-03 23:51:00 +03:30
|
|
|
).get(
|
|
|
|
|
farm_uuid=farm_uuid,
|
|
|
|
|
owner=request.user,
|
|
|
|
|
)
|
|
|
|
|
except FarmHub.DoesNotExist:
|
|
|
|
|
return Response({"code": 404, "msg": "Farm not found."}, status=status.HTTP_404_NOT_FOUND)
|
|
|
|
|
|
2026-04-09 22:48:54 +03:30
|
|
|
try:
|
|
|
|
|
opa_result = request_opa_batch_authorization(
|
|
|
|
|
farm=farm,
|
|
|
|
|
user=request.user,
|
|
|
|
|
features=serializer.validated_data["features"],
|
|
|
|
|
action=serializer.validated_data["action"],
|
2026-04-09 23:43:58 +03:30
|
|
|
route=request.path,
|
2026-04-09 22:48:54 +03:30
|
|
|
)
|
|
|
|
|
except AccessControlServiceUnavailable as exc:
|
|
|
|
|
return Response(
|
|
|
|
|
{"code": 503, "msg": str(exc)},
|
|
|
|
|
status=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return Response(
|
|
|
|
|
{
|
|
|
|
|
"code": 200,
|
|
|
|
|
"msg": "success",
|
|
|
|
|
"data": {
|
|
|
|
|
"farm_uuid": str(farm.farm_uuid),
|
|
|
|
|
"user": {
|
|
|
|
|
"id": request.user.id,
|
|
|
|
|
"username": request.user.username,
|
|
|
|
|
"email": request.user.email,
|
|
|
|
|
"phone_number": getattr(request.user, "phone_number", ""),
|
|
|
|
|
},
|
|
|
|
|
"features": serializer.validated_data["features"],
|
|
|
|
|
"action": serializer.validated_data["action"],
|
|
|
|
|
"decision": opa_result,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
status=status.HTTP_200_OK,
|
|
|
|
|
)
|