Reputation: 425
I have to set some permission to a model in Django because I have some operations in DRF and I need to know whether the user has permission to do it or not. My models :
class Device(models.Model):
type = models.ForeignKey(Type, on_delete=models.CASCADE)
name = models.fields.CharField(max_length=36)
ip = models.CharField(max_length=64, blank=True)
password = models.CharField(max_length=62, blank=True)
mac = models.CharField(max_length=17, blank=True)
description = models.fields.TextField(max_length=600, blank=True)
users = models.ManyToManyField(User,'users_device',through="UserMeta")
status = models.BooleanField(default=False)
def __str__(self):
return self.name
class UsersMeta(models.Model):
type_choices = [
("owner",'owner'),
('user','user'),
('admin','admin')
]
user = models.ForeignKey(User,on_delete=models.DO_NOTHING,related_name='UserMeta_devices')
device = models.ForeignKey(Device,models.CASCADE,related_name='UserMeta_device')
type = models.CharField(max_length=8,choices=type_choices)
token = models.UUIDField(default=uuid4,
editable=False,
unique=True)
join_time = models.DateTimeField(auto_now_add=True)
last_activate = models.DateTimeField(null=True,blank=True)
I need specific permission access to the Device model depending on the User model in the UserMeta model. in the UserMeta, I have some choices permissions like: owner,admin,user, so I need to say if this User has permission OWNER, or anything else can do it or not.
I don't is correct or not, if do you know pls say to me
update :
class Device(ViewSet):
permission_classes = [permissions.IsAuthenticated]
########################################################
# Device #
########################################################
@extend_schema(
summary="Get All Devices of User",
request={
200: Serializer_Device,
},
responses={
200: Serializer_Device(many=True),
400: None,
},
)
def list(self, request) -> Response:
device = get_list_or_404(Device_Model, user=request.user)
serializer = Serializer_Device(device, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
@extend_schema(
summary="Retrive a special device with the UUID token",
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
allow_blank=False,
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def retrieve(self, request, pk) -> Union[Response, Http404]:
user = request.user
device = get_object_or_404(Device_Model, token=pk, user=user)
serializer = Serializer_Device(device)
return Response(serializer.data, status=Status.HTTP_200_OK)
@extend_schema(
summary="Full Update a Device",
request=Serializer_Device,
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
allow_blank=False,
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def update(self, request, pk) -> Response:
device = get_object_or_404(Device_Model, token=pk, user=request.user)
serializer = Serializer_Device(
instance=device, data=request.data, context={"request": request}
)
if serializer.is_valid(raise_exception_validitor):
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
@extend_schema(
summary="Create a new device",
request=Serializer_Device,
responses={201: Serializer_Device, 400: dict},
)
def create(self, request) -> Union[Response, Http404]:
data = request.data
serializer = Serializer_Device(data=request.data, context={"request": request})
if serializer.is_valid(raise_exception_validitor):
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
@extend_schema(
summary="Delete Device with Token",
responses={
200: Serializer_Device,
204: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def destroy(self, request, pk) -> Union[Response, None]:
device = get_object_or_404(Device_Model, token=pk, user=request.user)
device.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@extend_schema(
summary="Filter Device With Tyep ",
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="type",
description="type of Device",
type=OpenApiTypes.STR,
location=OpenApiParameter.PATH,
)
],
)
@action(
detail=False,
methods=["GET"],
url_path=r"filter/(?P<type>\w+)",
url_name="filter_type",
)
def filter(self, request, type) -> Union[Response, Http404]:
user = request.user
device = get_list_or_404(Device_Model, type=type, user=user)
serializer = Serializer_Device(device, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
########################################################
# Data #
########################################################
@extend_schema(
summary="get logs of the device",
responses={
200: Serializer_Device_Data,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
@action(detail=True, methods=["GET"], url_name="data")
def data(self, request, pk) -> Union[Response, Http404]:
user = request.user
token = pk
device = get_object_or_404(Device_Model, user=user, token=token)
data_instance = get_list_or_404(Data_Model, device=device)
serializer = Serializer_Device_Data(data_instance, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
########################################################
# Command #
########################################################
@extend_schema(
summary="Get the last command",
responses={
200: Serializer_Command,
404: OpenApiTypes.OBJECT,
},
parameters=[
OpenApiParameter(
"id",
OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
description="Toekn Device",
)
],
)
@action(detail=True, methods=["GET"], url_name="command")
def command(self, request, pk) -> Union[Response, Http404]: # Retrieve Command
data = request.data
status = get_object_or_404(Command_Model, device=pk)
serializer = Serializer_Command(status)
return Response(serializer.data, status=Status.HTTP_200_OK)
Upvotes: 1
Views: 2138
Reputation: 10106
You can define your custom permission in DRF like this:
permissions.py:
from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
"""
Allows access only to owners
"""
def has_permission(self, request, view):
pk = request.GET.get('pk')
user_meta = UsersMeta.objects.filter(user=request.user, token=pk).first()
return True if user_meta and user_meta.type == "owner" else False
Usage:
from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import IsOwner
class YourView(APIView):
permission_classes = (IsOwner,)
def get(self, request, format=None):
content = {
'status': 'owner users'
}
return Response(content)
Upvotes: 2