From 7fc9ca36b8b53c83eb8b1054c9096af872088e5d Mon Sep 17 00:00:00 2001 From: Jacobjohnjeevan Date: Mon, 11 Nov 2024 15:37:42 +0530 Subject: [PATCH] Added get user route - Added get user route - For fetching details of other users - Added additional permissions check for change password - Allowing district admins and above to change password - Enable username search for FacilityUsers --- care/facility/api/viewsets/facility_users.py | 1 + care/users/api/viewsets/change_password.py | 29 +++++++++++++++++++- care/users/api/viewsets/users.py | 25 +++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/care/facility/api/viewsets/facility_users.py b/care/facility/api/viewsets/facility_users.py index fb2cf25916..ce4cf71c91 100644 --- a/care/facility/api/viewsets/facility_users.py +++ b/care/facility/api/viewsets/facility_users.py @@ -16,6 +16,7 @@ class UserFilter(filters.FilterSet): choices=[(key, key) for key in User.TYPE_VALUE_MAP], coerce=lambda role: User.TYPE_VALUE_MAP[role], ) + username = filters.CharFilter(field_name="username", lookup_expr="icontains") class Meta: model = User diff --git a/care/users/api/viewsets/change_password.py b/care/users/api/viewsets/change_password.py index 805bebddd9..f5fc473fd2 100644 --- a/care/users/api/viewsets/change_password.py +++ b/care/users/api/viewsets/change_password.py @@ -29,7 +29,26 @@ class ChangePasswordView(UpdateAPIView): model = User def update(self, request, *args, **kwargs): - self.object = self.request.user + username = request.data.get("username") + if not username: + return Response( + {"message": ["Username is required"]}, + status=status.HTTP_400_BAD_REQUEST, + ) + self.object = User.objects.get(username=username) + if not self.object: + return Response( + {"message": ["User not found"]}, status=status.HTTP_404_NOT_FOUND + ) + if not self.has_permission(request, self.object): + return Response( + { + "message": [ + "User does not have elevated permissions to change password" + ] + }, + status=status.HTTP_403_FORBIDDEN, + ) serializer = self.get_serializer(data=request.data) if serializer.is_valid(): @@ -48,3 +67,11 @@ def update(self, request, *args, **kwargs): return Response({"message": "Password updated successfully"}) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def has_permission(self, request, user): + authuser = request.user + return ( + authuser == user + or authuser.is_superuser + or authuser.user_type >= User.TYPE_VALUE_MAP["DistrictAdmin"] + ) diff --git a/care/users/api/viewsets/users.py b/care/users/api/viewsets/users.py index a70241c855..913c76abe3 100644 --- a/care/users/api/viewsets/users.py +++ b/care/users/api/viewsets/users.py @@ -203,6 +203,31 @@ def destroy(self, request, *args, **kwargs): user.save(update_fields=["is_active"]) return Response(status=status.HTTP_204_NO_CONTENT) + @extend_schema(tags=["users"]) + @action(detail=False, methods=["GET"]) + def get_user(self, request): + username = request.query_params.get("username") + if not username: + raise ValidationError({"username": "This field is required"}) + user = User.objects.filter(username=username).first() + if not user: + raise Http404({"user": "User not found"}) + if not self.has_permission(user): + raise ValidationError({"user": "Cannot Access Higher Level User"}) + return Response( + status=status.HTTP_200_OK, + data=UserSerializer(user, context={"request": request}).data, + ) + + def has_permission(self, user): + requesting_user = self.request.user + return ( + requesting_user == user + or requesting_user.is_superuser + or requesting_user.user_type >= User.TYPE_VALUE_MAP["DistrictAdmin"] + or requesting_user.user_type >= user.user_type + ) + @extend_schema(tags=["users"]) @action(detail=False, methods=["POST"]) def add_user(self, request, *args, **kwargs):