Skip to content

Commit

Permalink
Add resource sub-functions as function groups
Browse files Browse the repository at this point in the history
Added Function Groups for:
Custom general resource class admin
Custom Security Database Field admin
APPC Session Admin
Kerberos Realm Admin
Signed Program Admin
Started Task Admin

Unit testing and doc still to come.

Signed-off-by: Elijah Swift <elijah.swift@ibm.com>
  • Loading branch information
ElijahSwiftIBM committed Oct 22, 2023
1 parent d873cda commit 274ce13
Show file tree
Hide file tree
Showing 45 changed files with 808 additions and 42 deletions.
122 changes: 122 additions & 0 deletions pyracf/class/class_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""Custom General Resource Class Administration."""

from typing import List, Union

from pyracf.common.security_admin import SecurityAdmin

from .class_request import ClassRequest


class ClassAdmin(SecurityAdmin):
"""Custom General Resource Class Administration."""

def __init__(
self,
debug: bool = False,
generate_requests_only: bool = False,
update_existing_segment_traits: Union[dict, None] = None,
replace_existing_segment_traits: Union[dict, None] = None,
additional_secret_traits: Union[List[str], None] = None,
) -> None:
self._valid_segment_traits = {
"base": {
"cdtinfo:cdtcase": "case",
"cdtinfo:cdtdftrc": "defaultrc",
"cdtinfo:cdtfirst": "first",
"cdtinfo:cdtgen": "generic",
"cdtinfo:cdtgenl": "genlist",
"cdtinfo:cdtgroup": "grouping",
"cdtinfo:cdtkeyql": "keyqual",
"cdtinfo:cdtmac": "macprocessing",
"cdtinfo:cdtmaxln": "maxlenx",
"cdtinfo:cdtmaxlx": "maxlength",
"cdtinfo:cdtmembr": "member",
"cdtinfo:cdtoper": "operations",
"cdtinfo:cdtother": "other",
"cdtinfo:cdtposit": "posit",
"cdtinfo:cdtprfal": "profilesallowed",
"cdtinfo:cdtracl": "raclist",
"cdtinfo:cdtsigl": "signal",
"cdtinfo:cdtslreq": "seclabelrequired",
"cdtinfo:cdtuacc": "defaultuacc",
},
}
super().__init__(
"class",
debug=debug,
generate_requests_only=generate_requests_only,
update_existing_segment_traits=update_existing_segment_traits,
replace_existing_segment_traits=replace_existing_segment_traits,
additional_secret_traits=additional_secret_traits,
)

# ============================================================================
# Base Functions
# ============================================================================
def add(
self, class_name: str, traits: dict = {}
) -> Union[dict, bytes]:
"""Create a new custom general resource class."""
self._build_segment_dictionaries(traits)
class_request = ClassRequest(class_name, "set")
self._build_xml_segments(class_request)
return self._make_request(class_request)

def alter(
self, class_name: str, traits: dict = {}
) -> Union[dict, bytes]:
"""Alter an existing custom general resource class."""
self._build_segment_dictionaries(traits)
class_request = ClassRequest(class_name, "set")
self._build_xml_segments(class_request, alter=True)
return self._make_request(class_request, irrsmo00_precheck=True)

def extract(
self, class_name: str, segments={}, profile_only: bool = False
) -> Union[dict, bytes]:
"""Extract a general class profile."""
self._build_bool_segment_dictionaries(segments)
class_request = ClassRequest(class_name, "listdata")
self._build_xml_segments(class_request, extract=True)
result = self._extract_and_check_result(class_request)
if profile_only:
return self._get_profile(result)
return result

def delete(self, class_name: str) -> Union[dict, bytes]:
"""Delete a general class profile."""
class_request = ClassRequest(class_name, "del")
return self._make_request(class_request)

# ============================================================================
# Private/Protected Utility Functions
# ============================================================================
def _format_profile(self, result: dict) -> None:
"""Format profile extract data into a dictionary."""
messages = result["securityResult"]["class"]["commands"][0]["messages"]
indexes = [
i
for i in range(len(messages) - 1)
if messages[i] and "CLASS NAME" in messages[i]
]
indexes.append(len(messages))
profiles = []
for i in range(len(indexes) - 1):
profile = self._format_profile_generic(
messages[indexes[i] : indexes[i + 1]]
)
# Post processing
if "(g)" in profile["base"].get("name"):
profile["base"]["generic"] = True
profile["base"]["name"] = self._cast_from_str(
profile["base"].get("name")[0]
)
else:
profile["base"]["generic"] = False

if profile["base"].get("notify") == [None, "user", "to", "be", "notified"]:
profile["base"]["notify"] = None
profiles.append(profile)

del result["securityResult"]["class"]["commands"][0]["messages"]
result["securityResult"]["class"]["commands"][0]["profiles"] = profiles
16 changes: 16 additions & 0 deletions pyracf/class/class_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Custom General Resource Class Administration Request Builder."""

from pyracf.common.security_request import SecurityRequest


class ClassRequest(SecurityRequest):
"""Custom General Resource Class Administration Request Builder."""

def __init__(self, classname: str, operation: str) -> None:
super().__init__()
self._security_definition.tag = "customclass"
self._security_definition.attrib = {
"name": classname,
"operation": operation,
"requestid": "ClassRequest",
}
112 changes: 112 additions & 0 deletions pyracf/custom_field/custom_field_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"""Custom Security Database Field Administration."""

from typing import List, Union

from pyracf.common.security_admin import SecurityAdmin

from .custom_field_request import CustomFieldRequest


class CustomFieldAdmin(SecurityAdmin):
"""Custom Security Database Field Administration."""

def __init__(
self,
debug: bool = False,
generate_requests_only: bool = False,
update_existing_segment_traits: Union[dict, None] = None,
replace_existing_segment_traits: Union[dict, None] = None,
additional_secret_traits: Union[List[str], None] = None,
) -> None:
self._valid_segment_traits = {
"base": {
"cfdef:cffirst": "first",
"cfdef:cfhelp": "help",
"cfdef:cflist": "listhead",
"cfdef:cfmixed": "mixed",
"cfdef:cfmnval": "minvalue",
"cfdef:cfmxlen": "maxlength",
"cfdef:cfmxval": "other",
"cfdef:cfother": "other",
"cfdef:cfvalrx": "racf:cfvalrx",
},
}
super().__init__(
"custom_field",
debug=debug,
generate_requests_only=generate_requests_only,
update_existing_segment_traits=update_existing_segment_traits,
replace_existing_segment_traits=replace_existing_segment_traits,
additional_secret_traits=additional_secret_traits,
)

# ============================================================================
# Base Functions
# ============================================================================
def add(
self, custom_field: str, field_type: str, traits: dict = {}
) -> Union[dict, bytes]:
"""Create a new general custom_field profile."""
self._build_segment_dictionaries(traits)
custom_field_request = CustomFieldRequest(custom_field, field_type, "set")
self._build_xml_segments(custom_field_request)
return self._make_request(custom_field_request)

def alter(
self, custom_field: str, field_type: str, traits: dict = {}
) -> Union[dict, bytes]:
"""Alter an existing general custom_field profile."""
self._build_segment_dictionaries(traits)
custom_field_request = CustomFieldRequest(custom_field, field_type, "set")
self._build_xml_segments(custom_field_request, alter=True)
return self._make_request(custom_field_request, irrsmo00_precheck=True)

def extract(
self, custom_field: str, field_type: str, segments={}, profile_only: bool = False
) -> Union[dict, bytes]:
"""Extract a general custom_field profile."""
self._build_bool_segment_dictionaries(segments)
custom_field_request = CustomFieldRequest(custom_field, field_type, "listdata")
self._build_xml_segments(custom_field_request, extract=True)
result = self._extract_and_check_result(custom_field_request)
if profile_only:
return self._get_profile(result)
return result

def delete(self, custom_field: str, field_type: str) -> Union[dict, bytes]:
"""Delete a general custom_field profile."""
custom_field_request = CustomFieldRequest(custom_field, field_type, "del")
return self._make_request(custom_field_request)

# ============================================================================
# Private/Protected Utility Functions
# ============================================================================
def _format_profile(self, result: dict) -> None:
"""Format profile extract data into a dictionary."""
messages = result["securityResult"]["custom_field"]["commands"][0]["messages"]
indexes = [
i
for i in range(len(messages) - 1)
if messages[i] and "CLASS NAME" in messages[i]
]
indexes.append(len(messages))
profiles = []
for i in range(len(indexes) - 1):
profile = self._format_profile_generic(
messages[indexes[i] : indexes[i + 1]]
)
# Post processing
if "(g)" in profile["base"].get("name"):
profile["base"]["generic"] = True
profile["base"]["name"] = self._cast_from_str(
profile["base"].get("name")[0]
)
else:
profile["base"]["generic"] = False

if profile["base"].get("notify") == [None, "user", "to", "be", "notified"]:
profile["base"]["notify"] = None
profiles.append(profile)

del result["securityResult"]["custom_field"]["commands"][0]["messages"]
result["securityResult"]["custom_field"]["commands"][0]["profiles"] = profiles
17 changes: 17 additions & 0 deletions pyracf/custom_field/custom_field_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Custom Security Database Field Administration Request Builder."""

from pyracf.common.security_request import SecurityRequest


class CustomFieldRequest(SecurityRequest):
"""Custom Security Database Field Administration Request Builder."""

def __init__(self, custom_field_name: str, custom_field_type: str, operation: str) -> None:
super().__init__()
self._security_definition.tag = "customfield"
self._security_definition.attrib = {
"name": custom_field_name,
"type": custom_field_type,
"operation": operation,
"requestid": "CustomFieldRequest",
}
2 changes: 1 addition & 1 deletion pyracf/data_set/data_set_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(
"operation": operation,
"generic": generic,
"volume": volume,
"requestid": "DatasetRequest",
"requestid": "DataSetRequest",
}
)
if volume == "":
Expand Down
107 changes: 107 additions & 0 deletions pyracf/program/program_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""Signed Program Administration."""

from typing import List, Union

from pyracf.common.security_admin import SecurityAdmin

from .program_request import ProgramRequest


class ProgramAdmin(SecurityAdmin):
"""Signed Program Administration."""

def __init__(
self,
debug: bool = False,
generate_requests_only: bool = False,
update_existing_segment_traits: Union[dict, None] = None,
replace_existing_segment_traits: Union[dict, None] = None,
additional_secret_traits: Union[List[str], None] = None,
) -> None:
self._valid_segment_traits = {
"base": {
"sigver:failload": "failload",
"sigver:sigaudit": "sigaudit",
"sigver:sigreqd": "sigrequired",
"sigver:library": "library",
},
}
super().__init__(
"program",
debug=debug,
generate_requests_only=generate_requests_only,
update_existing_segment_traits=update_existing_segment_traits,
replace_existing_segment_traits=replace_existing_segment_traits,
additional_secret_traits=additional_secret_traits,
)

# ============================================================================
# Base Functions
# ============================================================================
def add(
self, program_name: str, traits: dict = {}
) -> Union[dict, bytes]:
"""Create a new general program profile."""
self._build_segment_dictionaries(traits)
program_request = ProgramRequest(program_name, "set")
self._build_xml_segments(program_request)
return self._make_request(program_request)

def alter(
self, program_name: str, traits: dict = {}
) -> Union[dict, bytes]:
"""Alter an existing general program profile."""
self._build_segment_dictionaries(traits)
program_request = ProgramRequest(program_name, "set")
self._build_xml_segments(program_request, alter=True)
return self._make_request(program_request, irrsmo00_precheck=True)

def extract(
self, program_name: str, segments={}, profile_only: bool = False
) -> Union[dict, bytes]:
"""Extract a general program profile."""
self._build_bool_segment_dictionaries(segments)
program_request = ProgramRequest(program_name, "listdata")
self._build_xml_segments(program_request, extract=True)
result = self._extract_and_check_result(program_request)
if profile_only:
return self._get_profile(result)
return result

def delete(self, program_name: str) -> Union[dict, bytes]:
"""Delete a general program profile."""
program_request = ProgramRequest(program_name, "del")
return self._make_request(program_request)

# ============================================================================
# Private/Protected Utility Functions
# ============================================================================
def _format_profile(self, result: dict) -> None:
"""Format profile extract data into a dictionary."""
messages = result["securityResult"]["program"]["commands"][0]["messages"]
indexes = [
i
for i in range(len(messages) - 1)
if messages[i] and "CLASS NAME" in messages[i]
]
indexes.append(len(messages))
profiles = []
for i in range(len(indexes) - 1):
profile = self._format_profile_generic(
messages[indexes[i] : indexes[i + 1]]
)
# Post processing
if "(g)" in profile["base"].get("name"):
profile["base"]["generic"] = True
profile["base"]["name"] = self._cast_from_str(
profile["base"].get("name")[0]
)
else:
profile["base"]["generic"] = False

if profile["base"].get("notify") == [None, "user", "to", "be", "notified"]:
profile["base"]["notify"] = None
profiles.append(profile)

del result["securityResult"]["program"]["commands"][0]["messages"]
result["securityResult"]["program"]["commands"][0]["profiles"] = profiles
Loading

0 comments on commit 274ce13

Please sign in to comment.