Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict Admin from unlinking users from other district #1157

Merged
merged 14 commits into from
Dec 7, 2023
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 @@ -253,6 +253,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