Skip to content

Commit 1e343fd

Browse files
committed
[Fixes #11995] Implement endpoint to transfer ownership
1 parent f25e550 commit 1e343fd

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

geonode/people/tests.py

+93
Original file line numberDiff line numberDiff line change
@@ -911,3 +911,96 @@ def test_delete_a_user_with_resource(self):
911911
# bobby cant be deleted
912912
self.assertNotEqual(get_user_model().objects.filter(username="bobby").first(), None)
913913
self.assertTrue("user_has_resources" in response.json()["errors"][0])
914+
915+
def test_transfer_resources_all(self):
916+
"""
917+
user wants to transfer resources to target
918+
"""
919+
bobby = get_user_model().objects.get(username="bobby")
920+
norman = get_user_model().objects.get(username="norman")
921+
# group = GroupProfile.objects.get(slug="bar")
922+
923+
self.assertTrue(self.client.login(username="bobby", password="bob"))
924+
self.assertTrue(bobby.is_authenticated)
925+
# check bobbys resources
926+
prior_bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
927+
self.assertTrue(len(prior_bobby_resources))
928+
# call api
929+
response = self.client.post(
930+
path=f"{reverse('users-list')}/{bobby.pk}/transfer_resources", data={"owner": norman.id}
931+
)
932+
# check that bobby owns the resources no more
933+
later_bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
934+
self.assertFalse(len(later_bobby_resources))
935+
self.assertEqual(response.status_code, 200)
936+
# check that the resources have been transvered to norman
937+
norman_resources = ResourceBase.objects.filter(owner=norman).all()
938+
self.assertTrue(set(prior_bobby_resources).issubset(set(norman_resources)))
939+
940+
def test_transfer_resources_invalid_user(self):
941+
"""
942+
user wants to transfer resources to target
943+
"""
944+
bobby = get_user_model().objects.get(username="bobby")
945+
invalid_user_id = get_user_model().objects.last().id + 1
946+
947+
self.assertTrue(self.client.login(username="bobby", password="bob"))
948+
self.assertTrue(bobby.is_authenticated)
949+
# check bobbys resources
950+
prior_bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
951+
self.assertTrue(len(prior_bobby_resources))
952+
# call api
953+
response = self.client.post(
954+
path=f"{reverse('users-list')}/{bobby}/transfer_resources", data={"owner": invalid_user_id}
955+
)
956+
# response should be 404
957+
self.assertEqual(response.status_code, 404)
958+
# check that bobby still owns the resources
959+
later_bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
960+
self.assertTrue(len(later_bobby_resources))
961+
# and no change has happened to them
962+
self.assertTrue(set(prior_bobby_resources) == set(later_bobby_resources))
963+
self.assertTrue(len(later_bobby_resources))
964+
965+
def test_transfer_resources_default(self):
966+
"""
967+
user wants to transfer resources to target
968+
"""
969+
bobby = get_user_model().objects.get(username="bobby")
970+
admin = get_user_model().objects.get(username="admin")
971+
972+
self.assertTrue(self.client.login(username="bobby", password="bob"))
973+
self.assertTrue(bobby.is_authenticated)
974+
975+
# check bobbys resources
976+
prior_bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
977+
self.assertTrue(len(prior_bobby_resources))
978+
# call api
979+
response = self.client.post(
980+
path=f"{reverse('users-list')}/{bobby.pk}/transfer_resources", data={"owner": "DEFAULT"}
981+
)
982+
self.assertTrue(response.status_code == 200)
983+
# check that bobby owns the resources no more
984+
later_bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
985+
self.assertFalse(len(later_bobby_resources))
986+
# check that the resources have been transfered to admin
987+
admin_resources = ResourceBase.objects.filter(owner=admin).all()
988+
self.assertTrue(set(prior_bobby_resources).issubset(set(admin_resources)))
989+
990+
def test_transfer_resources_nopayload(self):
991+
"""
992+
user wants to transfer resources to target
993+
"""
994+
bobby = get_user_model().objects.get(username="bobby")
995+
self.assertTrue(self.client.login(username="bobby", password="bob"))
996+
self.assertTrue(bobby.is_authenticated)
997+
# check bobbys resources
998+
bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
999+
self.assertTrue(len(bobby_resources))
1000+
# call api
1001+
response = self.client.post(path=f"{reverse('users-list')}/{bobby.pk}/transfer_resources", data={})
1002+
# response should be 404
1003+
self.assertEqual(response.status_code, 404)
1004+
# check that bobby still owns the resources
1005+
bobby_resources = ResourceBase.objects.filter(owner=bobby).all()
1006+
self.assertTrue(len(bobby_resources))

geonode/people/views.py

+22
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,28 @@ def groups(self, request, pk=None):
251251
groups = GroupProfile.objects.filter(id__in=qs_ids)
252252
return Response(GroupProfileSerializer(embed=True, many=True).to_representation(groups))
253253

254+
@action(detail=True, methods=["post"])
255+
def transfer_resources(self, request, pk=None):
256+
user = self.get_object()
257+
admin = (
258+
get_user_model().objects.filter(is_superuser=True, is_staff=True).first()
259+
) # admin=get_object_or_404(get_user_model(),username=admin)
260+
target_user = request.data.get("owner")
261+
# initalize as self
262+
target = user
263+
if target_user == "DEFAULT":
264+
if not admin:
265+
return Response("Principal User not found", status=500)
266+
target = admin
267+
else:
268+
target = get_object_or_404(get_user_model(), id=target_user)
269+
# transfer to target
270+
user_resources = ResourceBase.objects.filter(owner=user).all()
271+
for resource in user_resources:
272+
resource.owner = target
273+
resource.save()
274+
return Response("Resources transfered successfully", status=200)
275+
254276

255277
class ProfileAutocomplete(autocomplete.Select2QuerySetView):
256278
def get_queryset(self):

0 commit comments

Comments
 (0)