Skip to content

Commit 070947c

Browse files
authored
Merge pull request #34 from ambitus/cleanup_after_segment_errors
Clear State before raising errors
2 parents 05903d2 + eca4e7c commit 070947c

File tree

9 files changed

+75
-27
lines changed

9 files changed

+75
-27
lines changed

pyracf/access/access_admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def permit(
6464
) -> Union[dict, bytes]:
6565
"""Create or change a permission"""
6666
traits["base:auth_id"] = auth_id
67-
self._build_segment_dictionaries(traits)
67+
self._build_segment_trait_dictionary(traits)
6868
access_request = AccessRequest(resource, class_name, "set", volume, generic)
6969
self._add_traits_directly_to_request_xml_with_no_segments(
7070
access_request, alter=True
@@ -81,7 +81,7 @@ def delete(
8181
) -> Union[dict, bytes]:
8282
"""Delete a permission."""
8383
traits = {"base:auth_id": auth_id}
84-
self._build_segment_dictionaries(traits)
84+
self._build_segment_trait_dictionary(traits)
8585
access_request = AccessRequest(resource, class_name, "del", volume, generic)
8686
self._add_traits_directly_to_request_xml_with_no_segments(access_request)
8787
return self._make_request(access_request)

pyracf/common/security_admin.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def __validate_and_add_trait(
260260
self._trait_map[trait] = self._valid_segment_traits[segment][trait]
261261
return True
262262

263-
def _build_bool_segment_dictionaries(self, segments: List[str]) -> None:
263+
def _build_segment_dictionary(self, segments: List[str]) -> None:
264264
"""Build segment dictionaries for profile extract."""
265265
bad_segments = []
266266
for segment in segments:
@@ -269,11 +269,12 @@ def _build_bool_segment_dictionaries(self, segments: List[str]) -> None:
269269
else:
270270
bad_segments.append(segment)
271271
if bad_segments:
272+
self.__clear_state(SecurityRequest)
272273
raise SegmentError(bad_segments, self._profile_type)
273274
# preserve segment traits for debug logging.
274275
self.__preserved_segment_traits = self._segment_traits
275276

276-
def _build_segment_dictionaries(self, traits: dict) -> None:
277+
def _build_segment_trait_dictionary(self, traits: dict) -> None:
277278
"""Build segemnt dictionaries for each segment."""
278279
bad_traits = []
279280
for trait in traits:
@@ -287,6 +288,7 @@ def _build_segment_dictionaries(self, traits: dict) -> None:
287288
if not trait_valid:
288289
bad_traits.append(trait)
289290
if bad_traits:
291+
self.__clear_state(SecurityRequest)
290292
raise SegmentTraitError(bad_traits, self._profile_type)
291293

292294
# preserve segment traits for debug logging.

pyracf/connection/connection_admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def take_away_group_access_attribute(
121121
# ============================================================================
122122
def connect(self, userid: str, group: str, traits: dict = {}) -> Union[dict, bytes]:
123123
"""Create or change a group connection."""
124-
self._build_segment_dictionaries(traits)
124+
self._build_segment_trait_dictionary(traits)
125125
connection_request = ConnectionRequest(userid, group, "set")
126126
self._add_traits_directly_to_request_xml_with_no_segments(
127127
connection_request, alter=True

pyracf/data_set/data_set_admin.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def add(
105105
) -> Union[dict, bytes]:
106106
"""Create a new data set profile."""
107107
if self._generate_requests_only:
108-
self._build_segment_dictionaries(traits)
108+
self._build_segment_trait_dictionary(traits)
109109
data_set_request = DataSetRequest(data_set, "set", volume, generic)
110110
self._build_xml_segments(data_set_request)
111111
return self._make_request(data_set_request)
@@ -118,7 +118,7 @@ def add(
118118
except SecurityRequestError as exception:
119119
if not exception.contains_error_message(self._profile_type, "ICH35003I"):
120120
raise exception
121-
self._build_segment_dictionaries(traits)
121+
self._build_segment_trait_dictionary(traits)
122122
data_set_request = DataSetRequest(data_set, "set", volume, generic)
123123
self._build_xml_segments(data_set_request)
124124
return self._make_request(data_set_request)
@@ -132,7 +132,7 @@ def alter(
132132
) -> Union[dict, bytes]:
133133
"""Alter an existing data set profile."""
134134
if self._generate_requests_only:
135-
self._build_segment_dictionaries(traits)
135+
self._build_segment_trait_dictionary(traits)
136136
data_set_request = DataSetRequest(data_set, "set", volume, generic)
137137
self._build_xml_segments(data_set_request, alter=True)
138138
return self._make_request(data_set_request, irrsmo00_precheck=True)
@@ -144,7 +144,7 @@ def alter(
144144
raise AlterOperationError(data_set, self._profile_type)
145145
if not self._get_field(profile, "base", "name") == data_set.lower():
146146
raise AlterOperationError(data_set, self._profile_type)
147-
self._build_segment_dictionaries(traits)
147+
self._build_segment_trait_dictionary(traits)
148148
data_set_request = DataSetRequest(data_set, "set", volume, generic)
149149
self._build_xml_segments(data_set_request, alter=True)
150150
return self._make_request(data_set_request, irrsmo00_precheck=True)
@@ -158,7 +158,7 @@ def extract(
158158
profile_only: bool = False,
159159
) -> Union[dict, bytes]:
160160
"""Extract a data set profile."""
161-
self._build_bool_segment_dictionaries(segments)
161+
self._build_segment_dictionary(segments)
162162
data_set_request = DataSetRequest(data_set, "listdata", volume, generic)
163163
self._build_xml_segments(data_set_request, extract=True)
164164
result = self._extract_and_check_result(data_set_request)

pyracf/group/group_admin.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def set_ovm_gid(self, group: str, gid: int) -> Union[dict, bytes]:
123123
def add(self, group: str, traits: dict = {}) -> Union[dict, bytes]:
124124
"""Create a new group."""
125125
if self._generate_requests_only:
126-
self._build_segment_dictionaries(traits)
126+
self._build_segment_trait_dictionary(traits)
127127
group_request = GroupRequest(group, "set")
128128
self._build_xml_segments(group_request)
129129
return self._make_request(group_request)
@@ -132,7 +132,7 @@ def add(self, group: str, traits: dict = {}) -> Union[dict, bytes]:
132132
except SecurityRequestError as exception:
133133
if not exception.contains_error_message(self._profile_type, "ICH51003I"):
134134
raise exception
135-
self._build_segment_dictionaries(traits)
135+
self._build_segment_trait_dictionary(traits)
136136
group_request = GroupRequest(group, "set")
137137
self._build_xml_segments(group_request)
138138
return self._make_request(group_request)
@@ -141,15 +141,15 @@ def add(self, group: str, traits: dict = {}) -> Union[dict, bytes]:
141141
def alter(self, group: str, traits: dict) -> Union[dict, bytes]:
142142
"""Alter an existing group."""
143143
if self._generate_requests_only:
144-
self._build_segment_dictionaries(traits)
144+
self._build_segment_trait_dictionary(traits)
145145
group_request = GroupRequest(group, "set")
146146
self._build_xml_segments(group_request, alter=True)
147147
return self._make_request(group_request, irrsmo00_precheck=True)
148148
try:
149149
self.extract(group)
150150
except SecurityRequestError:
151151
raise AlterOperationError(group, self._profile_type)
152-
self._build_segment_dictionaries(traits)
152+
self._build_segment_trait_dictionary(traits)
153153
group_request = GroupRequest(group, "set")
154154
self._build_xml_segments(group_request, alter=True)
155155
return self._make_request(group_request, irrsmo00_precheck=True)
@@ -158,7 +158,7 @@ def extract(
158158
self, group: str, segments: List[str] = [], profile_only: bool = False
159159
) -> Union[dict, bytes]:
160160
"""Extract a group's profile."""
161-
self._build_bool_segment_dictionaries(segments)
161+
self._build_segment_dictionary(segments)
162162
group_request = GroupRequest(group, "listdata")
163163
self._build_xml_segments(group_request, extract=True)
164164
result = self._extract_and_check_result(group_request)

pyracf/resource/resource_admin.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ def add(
487487
) -> Union[dict, bytes]:
488488
"""Create a new general resource profile."""
489489
if self._generate_requests_only:
490-
self._build_segment_dictionaries(traits)
490+
self._build_segment_trait_dictionary(traits)
491491
profile_request = ResourceRequest(resource, class_name, "set")
492492
self._build_xml_segments(profile_request)
493493
return self._make_request(profile_request)
@@ -498,15 +498,15 @@ def add(
498498
except SecurityRequestError as exception:
499499
if not exception.contains_error_message(self._profile_type, "ICH13003I"):
500500
raise exception
501-
self._build_segment_dictionaries(traits)
501+
self._build_segment_trait_dictionary(traits)
502502
profile_request = ResourceRequest(resource, class_name, "set")
503503
self._build_xml_segments(profile_request)
504504
return self._make_request(profile_request)
505505

506506
def alter(self, resource: str, class_name: str, traits: dict) -> Union[dict, bytes]:
507507
"""Alter an existing general resource profile."""
508508
if self._generate_requests_only:
509-
self._build_segment_dictionaries(traits)
509+
self._build_segment_trait_dictionary(traits)
510510
profile_request = ResourceRequest(resource, class_name, "set")
511511
self._build_xml_segments(profile_request, alter=True)
512512
return self._make_request(profile_request, irrsmo00_precheck=True)
@@ -516,7 +516,7 @@ def alter(self, resource: str, class_name: str, traits: dict) -> Union[dict, byt
516516
raise AlterOperationError(resource, class_name)
517517
if not self._get_field(profile, "base", "name") == resource.lower():
518518
raise AlterOperationError(resource, class_name)
519-
self._build_segment_dictionaries(traits)
519+
self._build_segment_trait_dictionary(traits)
520520
profile_request = ResourceRequest(resource, class_name, "set")
521521
self._build_xml_segments(profile_request, alter=True)
522522
return self._make_request(profile_request, irrsmo00_precheck=True)
@@ -529,7 +529,7 @@ def extract(
529529
profile_only: bool = False,
530530
) -> Union[dict, bytes]:
531531
"""Extract a general resource profile."""
532-
self._build_bool_segment_dictionaries(segments)
532+
self._build_segment_dictionary(segments)
533533
resource_request = ResourceRequest(resource, class_name, "listdata")
534534
self._build_xml_segments(resource_request, extract=True)
535535
result = self._extract_and_check_result(resource_request)

pyracf/setropts/setropts_admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ def remove_raclist_classes(
313313
# ============================================================================
314314
def list_racf_options(self, options_only: bool = False) -> Union[dict, bytes]:
315315
"""List RACF options."""
316-
self._build_segment_dictionaries({"base:list": True})
316+
self._build_segment_trait_dictionary({"base:list": True})
317317
setropts_request = SetroptsRequest()
318318
self._add_traits_directly_to_request_xml_with_no_segments(setropts_request)
319319
result = self._extract_and_check_result(setropts_request)
@@ -323,7 +323,7 @@ def list_racf_options(self, options_only: bool = False) -> Union[dict, bytes]:
323323

324324
def alter(self, options: dict = {}) -> Union[dict, bytes]:
325325
"""Update RACF options."""
326-
self._build_segment_dictionaries(options)
326+
self._build_segment_trait_dictionary(options)
327327
setropts_request = SetroptsRequest()
328328
self._add_traits_directly_to_request_xml_with_no_segments(
329329
setropts_request, alter=True

pyracf/user/user_admin.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ def set_tso_data_set_allocation_unit(
769769
def add(self, userid: str, traits: dict = {}) -> Union[dict, bytes]:
770770
"""Create a new user."""
771771
if self._generate_requests_only:
772-
self._build_segment_dictionaries(traits)
772+
self._build_segment_trait_dictionary(traits)
773773
user_request = UserRequest(userid, "set")
774774
self._build_xml_segments(user_request)
775775
return self._make_request(user_request)
@@ -778,7 +778,7 @@ def add(self, userid: str, traits: dict = {}) -> Union[dict, bytes]:
778778
except SecurityRequestError as exception:
779779
if not exception.contains_error_message(self._profile_type, "ICH30001I"):
780780
raise exception
781-
self._build_segment_dictionaries(traits)
781+
self._build_segment_trait_dictionary(traits)
782782
user_request = UserRequest(userid, "set")
783783
self._build_xml_segments(user_request)
784784
return self._make_request(user_request)
@@ -787,15 +787,15 @@ def add(self, userid: str, traits: dict = {}) -> Union[dict, bytes]:
787787
def alter(self, userid: str, traits: dict) -> Union[dict, bytes]:
788788
"""Alter an existing user."""
789789
if self._generate_requests_only:
790-
self._build_segment_dictionaries(traits)
790+
self._build_segment_trait_dictionary(traits)
791791
user_request = UserRequest(userid, "set")
792792
self._build_xml_segments(user_request, alter=True)
793793
return self._make_request(user_request, irrsmo00_precheck=True)
794794
try:
795795
self.extract(userid)
796796
except SecurityRequestError:
797797
raise AlterOperationError(userid, self._profile_type)
798-
self._build_segment_dictionaries(traits)
798+
self._build_segment_trait_dictionary(traits)
799799
user_request = UserRequest(userid, "set")
800800
self._build_xml_segments(user_request, alter=True)
801801
return self._make_request(user_request, irrsmo00_precheck=True)
@@ -804,7 +804,7 @@ def extract(
804804
self, userid: str, segments: List[str] = [], profile_only: bool = False
805805
) -> Union[dict, bytes]:
806806
"""Extract a user's profile."""
807-
self._build_bool_segment_dictionaries(segments)
807+
self._build_segment_dictionary(segments)
808808
user_request = UserRequest(userid, "listdata")
809809
self._build_xml_segments(user_request, extract=True)
810810
result = self._extract_and_check_result(user_request)

tests/user/test_user_request_builder.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,33 @@ def test_user_admin_build_add_request_with_bad_segment_traits(self):
140140
+ f"combination for '{self.user_admin._profile_type}'.\n",
141141
)
142142

143+
# Since this test uses generate_requests_only, the "Add" after the AddOperationError is
144+
# returned does not begin with an "Extract" call. This is necessary to recreate the error,
145+
# so an extra extract call was added to simulate this behavior.
146+
def test_user_admin_cleans_up_after_build_add_request_with_bad_segment_traits(self):
147+
bad_trait = "omvs:bad_trait"
148+
user_admin = UserAdmin(
149+
generate_requests_only=True,
150+
)
151+
with self.assertRaises(SegmentTraitError) as exception:
152+
user_admin.add(
153+
"squidwrd", TestUserConstants.TEST_ADD_USER_REQUEST_BAD_TRAITS
154+
)
155+
self.assertEqual(
156+
exception.exception.message,
157+
"Unable to build Security Request.\n\n"
158+
+ f"'{bad_trait}' is not a known segment-trait "
159+
+ f"combination for '{self.user_admin._profile_type}'.\n",
160+
)
161+
result = user_admin.extract("squidwrd", segments=["omvs"])
162+
self.assertEqual(
163+
result, TestUserConstants.TEST_EXTRACT_USER_REQUEST_BASE_OMVS_XML
164+
)
165+
result = self.user_admin.add(
166+
"squidwrd", traits=TestUserConstants.TEST_ADD_USER_REQUEST_TRAITS
167+
)
168+
self.assertEqual(result, TestUserConstants.TEST_ADD_USER_REQUEST_XML)
169+
143170
def test_user_admin_build_extract_request_with_bad_segment_name(self):
144171
bad_segment = "bad_segment"
145172
user_admin = UserAdmin(
@@ -152,3 +179,22 @@ def test_user_admin_build_extract_request_with_bad_segment_name(self):
152179
"Unable to build Security Request.\n\n"
153180
+ f"'{bad_segment}' is not a known segment for '{self.user_admin._profile_type}'.\n",
154181
)
182+
183+
def test_user_admin_cleans_up_after_build_extract_request_with_bad_segment_name(
184+
self,
185+
):
186+
bad_segment = "bad_segment"
187+
user_admin = UserAdmin(
188+
generate_requests_only=True,
189+
)
190+
with self.assertRaises(SegmentError) as exception:
191+
user_admin.extract("squidwrd", segments=["tso", bad_segment])
192+
self.assertEqual(
193+
exception.exception.message,
194+
"Unable to build Security Request.\n\n"
195+
+ f"'{bad_segment}' is not a known segment for '{self.user_admin._profile_type}'.\n",
196+
)
197+
result = user_admin.extract("squidwrd", segments=["omvs"])
198+
self.assertEqual(
199+
result, TestUserConstants.TEST_EXTRACT_USER_REQUEST_BASE_OMVS_XML
200+
)

0 commit comments

Comments
 (0)