diff --git a/pyracf/common/security_admin.py b/pyracf/common/security_admin.py index e026e4ee..cbf69349 100644 --- a/pyracf/common/security_admin.py +++ b/pyracf/common/security_admin.py @@ -53,6 +53,16 @@ class SecurityAdmin: "base:generic": "racf:generic", } + __template_map = { + "base:warning": "base:warn_on_insufficient_access", + "base:erase": "base:erase_data_sets_on_delete", + "base:notify": "base:notify_userid", + "cdtinfo:security_labels_required": "cdtinfo:security_label_required", + "cfdef:maxlength": "cfdef:max_field_length", + "kerb:key_encryption_type": "kerb:encryption_algorithms", + "kerb:check_addresses": "kerb:validate_addresses", + } + _valid_segment_traits = {} _extracted_key_value_pair_segment_traits_map = {} _case_sensitive_extracted_values = [] @@ -235,7 +245,7 @@ def _validate_access_levels( ) raise ValueError(value_error_text) - def _build_traits_from_audit_rules(self, audit_rules: dict) -> dict: + def _build_traits_from_audit_rules(self, audit_rules: dict = {}) -> dict: traits = {} if "success" in audit_rules: traits[f"base:audit_{audit_rules['success']}"] = "success" @@ -524,13 +534,17 @@ def _build_template( if self._generate_requests_only: # Allows this function to work with "self._generate_requests_only" mode. return profile - template = {} + audit_rules = profile["base"].get("auditing", {}) + template = self._build_traits_from_audit_rules(audit_rules) for segment in profile.keys(): for trait in profile[segment].keys(): if ( f"{segment}:{self.__camel_case_to_snake_case(trait)}" not in self._valid_segment_traits[segment] ): + template = self.__map_extract_to_template( + template, segment, trait, profile[segment][trait] + ) continue template[f"{segment}:{self.__camel_case_to_snake_case(trait)}"] = ( profile[segment][trait] @@ -539,7 +553,14 @@ def _build_template( template[f"{segment}:{self.__camel_case_to_snake_case(trait)}"] = ( re.sub(r"20([0-9][0-9])", r"\1", profile[segment][trait]) ) - print(template) + return template + + def __map_extract_to_template( + self, template: dict, segment: str, trait: str, value: Union[str, List, int] + ): + key = f"{segment}:{self.__camel_case_to_snake_case(trait)}" + if key in self.__template_map: + template[self.__template_map[key]] = value return template def _get_field( diff --git a/tests/data_set/test_data_set_constants.py b/tests/data_set/test_data_set_constants.py index beaabcdb..61ffee91 100644 --- a/tests/data_set/test_data_set_constants.py +++ b/tests/data_set/test_data_set_constants.py @@ -103,14 +103,23 @@ def get_sample(sample_file: str) -> Union[str, bytes]: TEST_EXTRACT_DATA_SET_REQUEST_BASE_TRAITS = { "datasetname": "ESWIFT.TEST.T1136242.P3020470" } -# Extract Data Set TEST_EXTRACT_DATA_SET_REQUEST_GENRIC_BASE_XML = get_sample( "extract_data_set_request_generic_base.xml" ) TEST_EXTRACT_DATA_SET_REQUEST_GENERIC_BASE_TRAITS = { "datasetname": "ESWIFT.TEST.T1136242.*" } -TEST_EXTRACT_DATA_SET_BASE_ONLY_TEMPLATE_TRAITS = {} +TEST_EXTRACT_DATA_SET_BASE_ONLY_TEMPLATE_TRAITS = { + "base:audit_read": "failure", + "base:level": 0, + "base:owner": "eswift", + "base:universal_access": "read", + "base:warn_on_insufficient_access": None, + "base:erase_data_sets_on_delete": None, + "base:notify_userid": None, + "base:volumes": ["usrat2"], + "base:installation_data": None, +} # Delete Data Set TEST_DELETE_DATA_SET_REQUEST_XML = get_sample("delete_data_set_request.xml") diff --git a/tests/data_set/test_data_set_result_parser.py b/tests/data_set/test_data_set_result_parser.py index 811ff600..db05d08a 100644 --- a/tests/data_set/test_data_set_result_parser.py +++ b/tests/data_set/test_data_set_result_parser.py @@ -292,14 +292,16 @@ def test_data_set_admin_can_parse_delete_data_set_error_xml( # Build Template Data Set Profile # ============================================================================ - # def test_data_set_admin_can_build_template_data_set_base_success_xml( - # self, - # call_racf_mock: Mock, - # ): - # call_racf_mock.return_value = ( - # TestDataSetConstants.TEST_EXTRACT_DATA_SET_RESULT_BASE_ONLY_SUCCESS_XML - # ) - # self.assertEqual( - # self.data_set_admin.extract("ESWIFT.TEST.T1136242.P3020470",data_set_template = True), - # TestDataSetConstants.TEST_EXTRACT_DATA_SET_BASE_ONLY_TEMPLATE_TRAITS, - # ) + def test_data_set_admin_can_build_template_data_set_base_success_xml( + self, + call_racf_mock: Mock, + ): + call_racf_mock.return_value = ( + TestDataSetConstants.TEST_EXTRACT_DATA_SET_RESULT_BASE_ONLY_SUCCESS_XML + ) + self.assertEqual( + self.data_set_admin.extract( + "ESWIFT.TEST.T1136242.P3020470", data_set_template=True + ), + TestDataSetConstants.TEST_EXTRACT_DATA_SET_BASE_ONLY_TEMPLATE_TRAITS, + ) diff --git a/tests/resource/resource_result_samples/extract_resource_result_base_and_subfunctions_success.xml b/tests/resource/resource_result_samples/extract_resource_result_base_and_subfunctions_success.xml new file mode 100644 index 00000000..4638911a --- /dev/null +++ b/tests/resource/resource_result_samples/extract_resource_result_base_and_subfunctions_success.xml @@ -0,0 +1,95 @@ + + + + + 0 + 0 + 0 + RLIST STARTED (TSTTSKEL) STDATA + CLASS NAME + ----- ---- + STARTED TSTTSKEL + + LEVEL OWNER UNIVERSAL ACCESS YOUR ACCESS WARNING + ----- -------- ---------------- ----------- ------- + 00 ESWIFT NONE NONE NO + + INSTALLATION DATA + ----------------- + NONE + + APPLICATION DATA + ---------------- + NONE + + AUDITING + -------- + FAILURES(READ) + + NOTIFY + ------ + NO USER TO BE NOTIFIED + + STDATA INFORMATION + ------------------ + USER= + GROUP= + TRUSTED= YES + PRIVILEGED= NO + TRACE= NO + + CDTINFO INFORMATION + ------------------- + CASE = UPPER + DEFAULTRC = 008 + DEFAULTUACC = NONE + FIRST = ALPHA + GENLIST = DISALLOWED + GENERIC = ALLOWED + GROUP = + KEYQUALIFIERS = 0000000000 + MACPROCESSING = NORMAL + MAXLENGTH = 246 + MAXLENX = 0000000246 + MEMBER = + OPERATIONS = NO + OTHER = ALPHA NUMERIC + POSIT = 0000000200 + PROFILESALLOWED = YES + RACLIST = ALLOWED + SECLABELSREQUIRED = NO + SIGNAL = NO + + CFDEF INFORMATION + ----------------- + TYPE = CHAR + MAXLENGTH = NONE + MAXVALUE = NONE + MINVALUE = NONE + FIRST = ALPHA + OTHER = ALPHA + MIXED = NO + HELP = FAVORITE TV SHOW + + KERB INFORMATION + ---------------- + KEY ENCRYPTION TYPE= DES DES3 DESD AES128 AES256 AES128SHA2 AES256SHA2 + CHECK ADDRESSES= NO + + SESSION INFORMATION + ------------------- + SESSION KEY IS E3C5E2E3D2C5E800 + SESSION KEY INTERVAL IS 00005 DAYS + LOCKED + CONVSEC= CONV + + SIGVER INFORMATION + ------------------ + SIGREQUIRED = NO + FAILLOAD = NEVER + SIGAUDIT = SUCCESS + + + 0 + 0 + \ No newline at end of file diff --git a/tests/resource/test_resource_constants.py b/tests/resource/test_resource_constants.py index 8b742026..30164c6a 100644 --- a/tests/resource/test_resource_constants.py +++ b/tests/resource/test_resource_constants.py @@ -61,6 +61,70 @@ def get_sample(sample_file: str) -> Union[str, bytes]: TEST_EXTRACT_RESOURCE_RESULT_BASE_GENERIC_SUCCESS_XML = get_sample( "extract_resource_result_base_generic_success.xml" ) +# Note: It is impractical that one profile would have data in all of these segments, but it does +# have value to test with this larger value. +TEST_EXTRACT_RESOURCE_RESULT_BASE_AND_SUBFUNCTIONS_SUCCESS_XML = get_sample( + "extract_resource_result_base_and_subfunctions_success.xml" +) +TEST_EXTRACT_RESOURCE_BASE_AND_SUBFUNCTIONS_TEMPLATE_TRAITS = { + "base:application_data": None, + "base:audit_read": "failure", + "base:installation_data": None, + "base:level": 0, + "base:notify_userid": None, + "base:owner": "eswift", + "base:universal_access": None, + "base:warn_on_insufficient_access": None, + "cdtinfo:case_allowed": "upper", + "cdtinfo:default_racroute_return_code": 8, + "cdtinfo:default_universal_access": None, + "cdtinfo:generic_profile_checking": "allowed", + "cdtinfo:generic_profile_sharing": "disallowed", + "cdtinfo:grouping_class_name": None, + "cdtinfo:key_qualifiers": 0, + "cdtinfo:manditory_access_control_processing": "normal", + "cdtinfo:max_length": 246, + "cdtinfo:max_length_entityx": 246, + "cdtinfo:member_class_name": None, + "cdtinfo:operations": None, + "cdtinfo:posit_number": 200, + "cdtinfo:profiles_allowed": "yes", + "cdtinfo:raclist_allowed": "allowed", + "cdtinfo:security_label_required": None, + "cdtinfo:send_enf_signal_on_profile_creation": None, + "cdtinfo:valid_first_characters": "alpha", + "cdtinfo:valid_other_characters": ["alpha", "numeric"], + "cfdef:custom_field_data_type": "char", + "cfdef:help_text": ["favorite", "tv", "show"], + "cfdef:max_field_length": None, + "cfdef:max_numeric_value": None, + "cfdef:min_numeric_value": None, + "cfdef:mixed_case_allowed": None, + "cfdef:valid_first_characters": "alpha", + "cfdef:valid_other_characters": "alpha", + "kerb:encryption_algorithms": [ + "des", + "des3", + "desd", + "aes128", + "aes256", + "aes128sha2", + "aes256sha2", + ], + "kerb:validate_addresses": None, + "session:locked": True, + "session:security_checking_level": "conv", + "session:session_key": "e3c5e2e3d2c5e800", + "session:session_key_interval": 5, + "sigver:fail_program_load_condition": "never", + "sigver:log_signature_verification_events": "success", + "sigver:signature_required": None, + "stdata:group": None, + "stdata:privileged": None, + "stdata:trace": None, + "stdata:trusted": "yes", + "stdata:user": None, +} # Delete Resource TEST_DELETE_RESOURCE_RESULT_SUCCESS_XML = get_sample( diff --git a/tests/resource/test_resource_result_parser.py b/tests/resource/test_resource_result_parser.py index 57b0a35a..65c51201 100644 --- a/tests/resource/test_resource_result_parser.py +++ b/tests/resource/test_resource_result_parser.py @@ -404,16 +404,19 @@ def test_resource_admin_delete_can_check_for_unnecessary_refresh_xml( # Build template general resource profile # ============================================================================ - # def test_group_admin_can_build_template_group_base_omvs_tso_revoke_resume_success_xml( - # self, - # call_racf_mock: Mock, - # ): - # call_racf_mock.return_value = ( - # TestGroupConstants.TEST_EXTRACT_GROUP_RESULT_BASE_OMVS_SUCCESS_XML - # ) - # self.assertEqual( - # self.group_admin.extract( - # "testgrp0", segments=["omvs"], group_template=True - # ), - # TestGroupConstants.TEST_EXTRACT_GROUP_BASE_OMVS_TEMPLATE_TRAITS, - # ) + def test_resource_admin_can_build_template_resource_base_xml( + self, + call_racf_mock: Mock, + ): + call_racf_mock.return_value = ( + TestResourceConstants.TEST_EXTRACT_RESOURCE_RESULT_BASE_AND_SUBFUNCTIONS_SUCCESS_XML + ) + self.assertEqual( + self.resource_admin.extract( + "TESTING", + "ELIJTEST", + segments=["cfdef", "cdtinfo", "kerb", "session", "sigver", "stdata"], + resource_template=True, + ), + TestResourceConstants.TEST_EXTRACT_RESOURCE_BASE_AND_SUBFUNCTIONS_TEMPLATE_TRAITS, + )