Skip to content

Commit 6089726

Browse files
committed
[_763] Adapt GEN_ADMIN call style for removing remote user.
When calling to GEN_ADMIN to remove a remote user with separate user and zone parameters, the server will not remove the /tempZone/**/user#hello collections. So, we now force PRC to use an integrated user#zone format.
1 parent 17010c9 commit 6089726

File tree

3 files changed

+75
-8
lines changed

3 files changed

+75
-8
lines changed

irods/manager/user_manager.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,38 @@ def remove_quota(self, user_name, resource="total"):
4545
self._get_session, "set-quota", "user", user_name, resource, "0"
4646
)
4747

48+
@staticmethod
49+
def _parse_user_and_zone(user_param, zone_param):
50+
"""
51+
Parse out user and zone components from the arguments given.
52+
53+
Args:
54+
user_param: either a simple user name, or a combination of both
55+
user and zone names joined with "#".
56+
zone_param: a simple zone name,
57+
58+
Returns:
59+
The resulting parsed user and zone.
60+
61+
Raises:
62+
RuntimeError: in the case of formatting errors or conflicting zone names.
63+
"""
64+
if '#' in user_param:
65+
u_parsed_user, u_parsed_zone = user_param.split('#', 1)
66+
if not u_parsed_zone:
67+
raise RuntimeError("The compound user#zone specification may not contain a zero-length zone")
68+
if '#' in u_parsed_zone:
69+
raise RuntimeError(f"{u_parsed_zone = } is wrongly formatted")
70+
if zone_param and (u_parsed_zone != zone_param):
71+
raise RuntimeError(
72+
f"Two nonzero-length zone names ({u_parsed_zone}, {zone_param}) were given, but they do not agree."
73+
)
74+
return u_parsed_user, u_parsed_zone
75+
return user_param, zone_param
76+
4877
def get(self, user_name, user_zone=""):
78+
user_name, user_zone = self._parse_user_and_zone(user_name, user_zone)
79+
4980
if not user_zone:
5081
user_zone = self.sess.zone
5182

@@ -121,15 +152,20 @@ def create(self, user_name, user_type, user_zone="", auth_str=""):
121152
def remove(self, user_name, user_zone="", _object=None):
122153
if _object is None:
123154
_object = self.get(user_name, user_zone)
155+
156+
if _object.type == "rodsgroup": # noqa: SIM108
157+
uz_args = (f"{_object.name}",)
158+
else:
159+
uz_args = (f"{_object.name}#{_object.zone}",)
160+
124161
message_body = GeneralAdminRequest(
125162
"rm",
126163
(
127164
"user"
128165
if (_object.type != "rodsgroup" or self.sess.server_version < (4, 3, 2))
129166
else "group"
130167
),
131-
user_name,
132-
user_zone,
168+
*uz_args,
133169
)
134170
request = iRODSMessage(
135171
"RODS_API_REQ", msg=message_body, int_info=api_number["GENERAL_ADMIN_AN"]

irods/test/admin_test.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
import os
55
import sys
66
import unittest
7-
from irods.models import User, Group
7+
8+
import irods.keywords as kw
9+
from irods.column import Like
810
from irods.exception import (
9-
UserDoesNotExist,
10-
ResourceDoesNotExist,
1111
SYS_NO_API_PRIV,
12+
ResourceDoesNotExist,
13+
UserDoesNotExist,
1214
)
13-
from irods.session import iRODSSession
15+
from irods.models import Collection, Group, User
1416
from irods.resource import iRODSResource
15-
import irods.test.helpers as helpers
16-
import irods.keywords as kw
17+
from irods.session import iRODSSession
18+
from irods.test import helpers
1719

1820

1921
class TestAdmin(unittest.TestCase):
@@ -531,6 +533,34 @@ def test_set_user_info(self):
531533
with self.assertRaises(UserDoesNotExist):
532534
self.sess.users.get(self.new_user_name)
533535

536+
def test_deleting_remote_user_including_home_collection_and_trash_artifact__issue_763(self):
537+
# Test and confirm that, when passing user and zone parameters separately in calls to
538+
# remove remote users, that both /tempZone/home/user#zone and /tempZone/trash/home/user#zone
539+
# are deleted.
540+
remote_zone = remote_user = None
541+
try:
542+
remote_zone = (sess := self.sess).zones.create('other_zone', 'remote')
543+
remote_user = sess.users.create(user_name='myuser', user_type='rodsuser', user_zone=remote_zone.name)
544+
545+
def get_collection_artifacts():
546+
return list(
547+
sess.query(Collection).filter(Like(Collection.name, f'%/{remote_user.name}#{remote_zone.name}'))
548+
)
549+
550+
# Two collection artifacts should be present, with names:
551+
# /<local_zone>/home/remote_user#remote_zone
552+
# /<local_zone>/trash/home/remote_user#remote_zone
553+
self.assertEqual(len(get_collection_artifacts()), 2)
554+
555+
remote_user.remove()
556+
557+
# The above-mentioned artifacts should have been deleted along with the remote user.
558+
self.assertEqual(len(get_collection_artifacts()), 0)
559+
560+
finally:
561+
if remote_zone:
562+
remote_zone.remove()
563+
534564

535565
if __name__ == "__main__":
536566
# let the tests find the parent irods lib

irods/test/user_group_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def generator(p=OLDPASS):
143143
shutil.rmtree(ENV_DIR)
144144
ses.users.remove("alice")
145145

146+
146147
def test_modifying_password_at_various_lengths__issue_328(self):
147148
ses = self.sess
148149
try:

0 commit comments

Comments
 (0)