Skip to content

Commit

Permalink
Restrict Admin from unlinking users from other district (#1157)
Browse files Browse the repository at this point in the history
* prevent unlink for other district

* use id for comparision

* Update care/users/api/viewsets/users.py

Co-authored-by: Aakash Singh <mail@singhaakash.dev>

* add tests

* fix lint

* fix tests and restrict in clear_home_Facility function

* add unlink facility tests

* assert error message in tests

* Update care/users/api/viewsets/users.py

Co-authored-by: Aakash Singh <mail@singhaakash.dev>

* check if user is district admin and above

---------

Co-authored-by: Aakash Singh <mail@singhaakash.dev>
  • Loading branch information
Pranshu1902 and sainak authored Dec 7, 2023
1 parent 940e0e7 commit 7663481
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
84 changes: 84 additions & 0 deletions care/facility/tests/test_unlink_district_admins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from django.conf import settings
from rest_framework import status
from rest_framework.test import APITestCase

from care.utils.tests.test_utils import TestUtils


class UnlinkDistrictAdmin(TestUtils, APITestCase):
def setUp(self):
settings.DISABLE_RATELIMIT = True
self.state = self.create_state()

self.district1 = self.create_district(self.state)
self.admin1 = self.create_user("user12345678", self.district1, user_type=30)

self.district2 = self.create_district(self.state)
self.admin2 = self.create_user("user12345679", self.district2, user_type=30)

self.local_body1 = self.create_local_body(self.district1)
self.local_body2 = self.create_local_body(self.district2)

self.facility1 = self.create_facility(
district=self.district1, user=self.admin1, local_body=self.local_body1
)
self.facility2 = self.create_facility(
district=self.district2, user=self.admin2, local_body=self.local_body2
)

self.staff1 = self.create_user(
"staff1234", self.district1, home_facility=self.facility1
)
self.staff2 = self.create_user(
"staff1235", self.district2, home_facility=self.facility2
)

def test_unlink_home_facility_admin_same_district(self):
self.client.force_login(self.admin1)

username = self.staff1.username
response = self.client.delete(
"/api/v1/users/" + username + "/clear_home_facility/"
)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

def test_unlink_home_facility_admin_different_district(self):
self.client.force_login(self.admin1)

username = self.staff2.username
response = self.client.delete(
"/api/v1/users/" + username + "/clear_home_facility/"
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response.json()["facility"],
"Cannot unlink User's Home Facility from other district",
)

def test_unlink_faciltity_admin_same_district(self):
self.client.force_login(self.admin1)

username = self.staff1.username

# clear from home facility to linked facility
response = self.client.delete(
"/api/v1/users/" + username + "/clear_home_facility/"
)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

response = self.client.delete(
"/api/v1/users/" + username + "/delete_facility/",
{"facility": self.facility1.external_id},
)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

def test_unlink_faciltity_admin_different_district(self):
self.client.force_login(self.admin1)

username = self.staff2.username
response = self.client.delete(
"/api/v1/users/" + username + "/delete_facility/",
{"facility": self.facility2.external_id},
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json()["facility"], "Facility Access not Present")
9 changes: 9 additions & 0 deletions care/users/api/viewsets/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,15 @@ def clear_home_facility(self, request, *args, **kwargs):
if not self.has_user_type_permission_elevation(requesting_user, user):
raise ValidationError({"home_facility": "Cannot Access Higher Level User"})

# ensure that district admin only able to delete in the same district
if (
requesting_user.user_type <= User.TYPE_VALUE_MAP["DistrictAdmin"]
and user.district_id != requesting_user.district_id
):
raise ValidationError(
{"facility": "Cannot unlink User's Home Facility from other district"}
)

user.home_facility = None
user.save(update_fields=["home_facility"])
return Response(status=status.HTTP_204_NO_CONTENT)
Expand Down

0 comments on commit 7663481

Please sign in to comment.