diff --git a/README.md b/README.md index 42820fb..060cdb7 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ $ appknox reports create 4 3 $ appknox reports download summary-csv 3 -Organization ID,Project ID,Application Name,Application Namespace,Platform,Version,Version Code,File ID,Test Case,Scan Type,Severity,Risk Override,CVSS Score,Findings,Description,Noncompliant Code Example,Compliant Solution,Business Implication,OWASP,CWE,MSTG,OWASP MASVS (v2),ASVS,PCI-DSS,GDPR,Created On +Organization ID,Project ID,Application Name,Application Namespace,Platform,Version,Version Code,File ID,Test Case,Scan Type,Severity,Risk Override,CVSS Score,Findings,Description,Noncompliant Code Example,Compliant Solution,Business Implication,OWASP,CWE,MSTG,OWASP MASVS (v2),ASVS,PCI-DSS,GDPR,NIST SP 800-53,NIST SP 800-171,Created On 1,1,MFVA,com.appknox.mfva,Android,1.1,1605631525,51,Broken SSL Trust Manager,Static,High,,6.9,"BluK8lNUoeHkNxZ3GVrKN9BP2 NVWmfbtHDiJBOTbOEpCnsbMhc6T31t...(Truncated) diff --git a/appknox/client.py b/appknox/client.py index acc889f..ce6d955 100644 --- a/appknox/client.py +++ b/appknox/client.py @@ -30,6 +30,7 @@ from appknox.mapper import Organization from appknox.mapper import OWASP from appknox.mapper import PCIDSS +from appknox.mapper import NISTSP80053,NISTSP800171 from appknox.mapper import PersonalToken from appknox.mapper import ProfileReportPreference from appknox.mapper import Project @@ -436,6 +437,46 @@ def get_pcidss(self, pcidss_id: str) -> PCIDSS: pcidss = self.drf_api["v2/pcidsses"](pcidss_id).get() return mapper_drf_api(PCIDSS, pcidss) + @lru_cache(maxsize=1) + def get_nistsp80053es(self) -> List[NISTSP80053]: + nistsp80053_raw = self.drf_api["v2/nistsp80053s"]().get() + nistsp80053 = self.paginated_drf_data(nistsp80053_raw, NISTSP80053) + return nistsp80053 + + def get_nistsp80053(self, nistsp80053_id: str) -> NISTSP80053: + """ + Fetch nistsp80053 by ID + + :param nistsp80053_id: nistsp80053 ID + """ + nistsp80053es = self.get_nistsp80053es() + nistsp80053 = next((x for x in nistsp80053es if x.id == nistsp80053_id), None) + if nistsp80053: + return nistsp80053 + + nistsp80053 = self.drf_api["v2/nistsp80053s"](nistsp80053_id).get() + return mapper_drf_api(NISTSP80053, nistsp80053) + + @lru_cache(maxsize=1) + def get_nistsp800171es(self) -> List[NISTSP800171]: + nistsp800171_raw = self.drf_api["v2/nistsp800171s"]().get() + nistsp800171 = self.paginated_drf_data(nistsp800171_raw, NISTSP800171) + return nistsp800171 + + def get_nistsp800171(self, nistsp800171_id: str) -> NISTSP800171: + """ + Fetch nistsp800171 by ID + + :param nistsp800171_id: nistsp800171 ID + """ + nistsp800171es = self.get_nistsp800171es() + nistsp800171 = next((x for x in nistsp800171es if x.id == nistsp800171_id), None) + if nistsp800171: + return nistsp800171 + + nistsp800171 = self.drf_api["v2/nistsp800171s"](nistsp800171_id).get() + return mapper_drf_api(NISTSP80053, nistsp800171) + def upload_file(self, file_data: str) -> int: """ Upload and scan a package and returns the file_id @@ -542,6 +583,8 @@ def get_unselected_report_preference(self, file_id: int) -> list: unselected_report_pref.append(ReportPreferenceMapper["show_hipaa"]) if not profile_report_preference.show_pcidss.value: unselected_report_pref.append(ReportPreferenceMapper["show_pcidss"]) + if not profile_report_preference.show_nist.value: + unselected_report_pref.append(ReportPreferenceMapper["show_nist"]) return unselected_report_pref def list_reports(self, file_id: int) -> typing.List["Report"]: diff --git a/appknox/mapper.py b/appknox/mapper.py index d38f413..4a3742c 100644 --- a/appknox/mapper.py +++ b/appknox/mapper.py @@ -69,6 +69,8 @@ def mapper_drf_api(model: type, resource: dict) -> object: "masvs", "asvs", "gdpr", + "nistsp80053", + "nistsp800171", "computed_risk", "overridden_risk", ], @@ -93,12 +95,17 @@ def mapper_drf_api(model: type, resource: dict) -> object: PCIDSS = namedtuple("PCIDSS", ["id", "code", "title", "description"]) +NISTSP80053 = namedtuple("NISTSP80053", ["id", "code", "title"]) + +NISTSP800171 = namedtuple("NISTSP800171", ["id", "code", "title"]) + PersonalToken = namedtuple("AccessToken", ["name", "key"]) ReportPreferenceMapper = { "show_pcidss": "pcidss", "show_hipaa": "hipaa", "show_gdpr": "gdpr", + "show_nist": "nist", } @@ -112,6 +119,7 @@ class ProfileReportPreference: show_gdpr: ProfileReportPreferenceConfig show_hipaa: ProfileReportPreferenceConfig show_pcidss: ProfileReportPreferenceConfig + show_nist: ProfileReportPreferenceConfig @classmethod def from_json(cls, data): @@ -121,6 +129,7 @@ def from_json(cls, data): show_pcidss=ProfileReportPreferenceConfig( value=data["show_pcidss"]["value"] ), + show_nist=ProfileReportPreferenceConfig(value=data["show_nist"]["value"]), ) @@ -146,6 +155,7 @@ class ReportPreference: "show_ignored_analyses", "show_hipaa", "show_pcidss", + "show_nist", ] show_api_scan: bool @@ -166,6 +176,7 @@ def from_json(cls, data: typing.Dict[str, typing.Any]) -> "ReportPreference": show_ignored_analyses=data["show_ignored_analyses"], show_hipaa=InheritedPreference.from_json(data["show_hipaa"]), show_pcidss=InheritedPreference.from_json(data["show_pcidss"]), + show_nist=InheritedPreference.from_json(data["show_nist"]), ) diff --git a/appknox/tests/test_client.py b/appknox/tests/test_client.py index 69be466..31a217c 100644 --- a/appknox/tests/test_client.py +++ b/appknox/tests/test_client.py @@ -25,6 +25,7 @@ def setUp(self): "show_ignored_analyses": True, "show_hipaa": {"value": True, "is_inherited": True}, "show_pcidss": {"value": True, "is_inherited": True}, + "show_nist": {"value": False, "is_inherited": True}, } with mock.patch.object(Appknox, "get_organizations", self.get_org_list): self.ap_client = Appknox( diff --git a/docs/.doctrees/client.doctree b/docs/.doctrees/client.doctree index 041626d..a016231 100644 Binary files a/docs/.doctrees/client.doctree and b/docs/.doctrees/client.doctree differ diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index d61d0d0..fbb97f8 100644 Binary files a/docs/.doctrees/environment.pickle and b/docs/.doctrees/environment.pickle differ diff --git a/docs/.doctrees/index.doctree b/docs/.doctrees/index.doctree index 9a04860..5807e07 100644 Binary files a/docs/.doctrees/index.doctree and b/docs/.doctrees/index.doctree differ diff --git a/docs/.doctrees/mapper.doctree b/docs/.doctrees/mapper.doctree index e982863..2c0abe1 100644 Binary files a/docs/.doctrees/mapper.doctree and b/docs/.doctrees/mapper.doctree differ diff --git a/docs/_modules/appknox/client.html b/docs/_modules/appknox/client.html index 87e06fd..70abe9b 100644 --- a/docs/_modules/appknox/client.html +++ b/docs/_modules/appknox/client.html @@ -16,8 +16,9 @@ + + -
@@ -62,6 +63,7 @@
from appknox.mapper import Organization
from appknox.mapper import OWASP
from appknox.mapper import PCIDSS
+from appknox.mapper import NISTSP80053,NISTSP800171
from appknox.mapper import PersonalToken
from appknox.mapper import ProfileReportPreference
from appknox.mapper import Project
@@ -84,6 +86,7 @@ Source code for appknox.client
[docs]class Appknox(object):
"""
+ Client to interact with API server
"""
def __init__(
@@ -292,9 +295,7 @@ Source code for appknox.client
whoami = self.drf_api.me().get()
return mapper_drf_api(Whoami, whoami)
-[docs] def paginated_data(self, response, mapper_class):
- """
- """
+ def paginated_data(self, response, mapper_class):
initial_data = [
mapper_json_api(mapper_class, dict(data=value))
for value in response["data"]
@@ -313,11 +314,9 @@ Source code for appknox.client
for value in resp["data"]
]
- return initial_data
+ return initial_data
-[docs] def paginated_drf_data(self, response, mapper_class):
- """
- """
+ def paginated_drf_data(self, response, mapper_class):
initial_data = [
mapper_drf_api(mapper_class, value) for value in response["results"]
]
@@ -331,7 +330,7 @@ Source code for appknox.client
initial_data += [
mapper_drf_api(mapper_class, value) for value in resp["results"]
]
- return initial_data
+ return initial_data
[docs] def get_organizations(self) -> List[Organization]:
"""
@@ -404,10 +403,8 @@ Source code for appknox.client
analyses = self.drf_api["v2/files/{}/analyses".format(file_id)]().get()
return self.paginated_drf_data(analyses, Analysis)
-[docs] @lru_cache(maxsize=1)
+ @lru_cache(maxsize=1)
def get_vulnerabilities(self) -> List[Vulnerability]:
- """
- """
total_vulnerabilities = self.drf_api["v2/vulnerabilities"]().get(limit=1)[
"count"
] # limit is 1 just to get total count
@@ -415,7 +412,7 @@ Source code for appknox.client
limit=total_vulnerabilities + 1
)
vulnerabilities = self.paginated_drf_data(vulnerabilities_raw, Vulnerability)
- return vulnerabilities
+ return vulnerabilities
[docs] def get_vulnerability(self, vulnerability_id: int) -> Vulnerability:
"""
@@ -433,13 +430,11 @@ Source code for appknox.client
vulnerability = self.drf_api["v2/vulnerabilities"](vulnerability_id).get()
return mapper_drf_api(Vulnerability, vulnerability)
-[docs] @lru_cache(maxsize=1)
+ @lru_cache(maxsize=1)
def get_owasps(self) -> List[OWASP]:
- """
- """
owasps_raw = self.drf_api["v2/owasps"]().get()
owasps = self.paginated_drf_data(owasps_raw, OWASP)
- return owasps
+ return owasps
[docs] def get_owasp(self, owasp_id: str) -> OWASP:
"""
@@ -455,13 +450,11 @@ Source code for appknox.client
owasp = self.drf_api["v2/owasps"](owasp_id).get()
return mapper_drf_api(OWASP, owasp)
-[docs] @lru_cache(maxsize=1)
+ @lru_cache(maxsize=1)
def get_pcidsses(self) -> List[PCIDSS]:
- """
- """
pcidsss_raw = self.drf_api["v2/pcidsses"]().get()
pcidsss = self.paginated_drf_data(pcidsss_raw, PCIDSS)
- return pcidsss
+ return pcidsss
[docs] def get_pcidss(self, pcidss_id: str) -> PCIDSS:
"""
@@ -477,6 +470,46 @@ Source code for appknox.client
pcidss = self.drf_api["v2/pcidsses"](pcidss_id).get()
return mapper_drf_api(PCIDSS, pcidss)
+ @lru_cache(maxsize=1)
+ def get_nistsp80053es(self) -> List[NISTSP80053]:
+ nistsp80053_raw = self.drf_api["v2/nistsp80053s"]().get()
+ nistsp80053 = self.paginated_drf_data(nistsp80053_raw, NISTSP80053)
+ return nistsp80053
+
+[docs] def get_nistsp80053(self, nistsp80053_id: str) -> NISTSP80053:
+ """
+ Fetch nistsp80053 by ID
+
+ :param nistsp80053_id: nistsp80053 ID
+ """
+ nistsp80053es = self.get_nistsp80053es()
+ nistsp80053 = next((x for x in nistsp80053es if x.id == nistsp80053_id), None)
+ if nistsp80053:
+ return nistsp80053
+
+ nistsp80053 = self.drf_api["v2/nistsp80053s"](nistsp80053_id).get()
+ return mapper_drf_api(NISTSP80053, nistsp80053)
+
+ @lru_cache(maxsize=1)
+ def get_nistsp800171es(self) -> List[NISTSP800171]:
+ nistsp800171_raw = self.drf_api["v2/nistsp800171s"]().get()
+ nistsp800171 = self.paginated_drf_data(nistsp800171_raw, NISTSP800171)
+ return nistsp800171
+
+[docs] def get_nistsp800171(self, nistsp800171_id: str) -> NISTSP800171:
+ """
+ Fetch nistsp800171 by ID
+
+ :param nistsp800171_id: nistsp800171 ID
+ """
+ nistsp800171es = self.get_nistsp800171es()
+ nistsp800171 = next((x for x in nistsp800171es if x.id == nistsp800171_id), None)
+ if nistsp800171:
+ return nistsp800171
+
+ nistsp800171 = self.drf_api["v2/nistsp800171s"](nistsp800171_id).get()
+ return mapper_drf_api(NISTSP80053, nistsp800171)
+
[docs] def upload_file(self, file_data: str) -> int:
"""
Upload and scan a package and returns the file_id
@@ -583,6 +616,8 @@ Source code for appknox.client
unselected_report_pref.append(ReportPreferenceMapper["show_hipaa"])
if not profile_report_preference.show_pcidss.value:
unselected_report_pref.append(ReportPreferenceMapper["show_pcidss"])
+ if not profile_report_preference.show_nist.value:
+ unselected_report_pref.append(ReportPreferenceMapper["show_nist"])
return unselected_report_pref
[docs] def list_reports(self, file_id: int) -> typing.List["Report"]:
@@ -670,9 +705,6 @@ Source code for appknox.client
headers: object = None,
auth: Dict[str, str] = None,
):
- """
- Initialise APIResource object
- """
self.host = host
self.headers = {**headers}
self.headers["User-Agent"] = f"appknox-python/{__version__}"
@@ -682,37 +714,27 @@ Source code for appknox.client
self.endpoint = urljoin(host, API_BASE)
def __getitem__(self, resource):
- """
- """
return partial(self.set_endpoint, resource)
def __getattr__(self, resource):
- """
- """
return partial(self.set_endpoint, resource)
-[docs] def set_endpoint(self, resource, resource_id=None):
- """
- """
+ def set_endpoint(self, resource, resource_id=None):
self.endpoint = "{}/{}".format(urljoin(self.host, API_BASE), resource)
if resource_id:
self.endpoint += "/{}".format(str(resource_id))
- return self
+ return self
-[docs] def get(self, **kwargs):
- """
- """
+ def get(self, **kwargs):
resp = self.request_session.get(
self.endpoint,
headers=self.headers,
auth=self.auth,
params=kwargs,
)
- return resp.json()
+ return resp.json()
-[docs] def post(self, data, content_type=None, **kwargs):
- """
- """
+ def post(self, data, content_type=None, **kwargs):
resp = self.request_session.post(
self.endpoint,
headers=self.headers,
@@ -720,18 +742,16 @@ Source code for appknox.client
params=kwargs,
data=data,
)
- return resp.json()
+ return resp.json()
-[docs] def direct_get(self, url, **kwargs):
- """
- """
+ def direct_get(self, url, **kwargs):
resp = self.request_session.get(
url,
headers=self.headers,
auth=self.auth,
params=kwargs,
)
- return resp.json()
+ return resp.json()
[docs] def direct_get_http_response(self, url: str, **kwargs) -> "Response":
"""
@@ -754,7 +774,7 @@ Source code for appknox.client
Source code for appknox.mapper
"masvs",
"asvs",
"gdpr",
+ "nistsp80053",
+ "nistsp800171",
"computed_risk",
"overridden_risk",
],
@@ -125,12 +128,17 @@ Source code for appknox.mapper
PCIDSS = namedtuple("PCIDSS", ["id", "code", "title", "description"])
+NISTSP80053 = namedtuple("NISTSP80053", ["id", "code", "title"])
+
+NISTSP800171 = namedtuple("NISTSP800171", ["id", "code", "title"])
+
PersonalToken = namedtuple("AccessToken", ["name", "key"])
ReportPreferenceMapper = {
"show_pcidss": "pcidss",
"show_hipaa": "hipaa",
"show_gdpr": "gdpr",
+ "show_nist": "nist",
}
@@ -144,6 +152,7 @@ Source code for appknox.mapper
show_gdpr: ProfileReportPreferenceConfig
show_hipaa: ProfileReportPreferenceConfig
show_pcidss: ProfileReportPreferenceConfig
+ show_nist: ProfileReportPreferenceConfig
@classmethod
def from_json(cls, data):
@@ -153,6 +162,7 @@ Source code for appknox.mapper
show_pcidss=ProfileReportPreferenceConfig(
value=data["show_pcidss"]["value"]
),
+ show_nist=ProfileReportPreferenceConfig(value=data["show_nist"]["value"]),
)
@@ -178,6 +188,7 @@ Source code for appknox.mapper
"show_ignored_analyses",
"show_hipaa",
"show_pcidss",
+ "show_nist",
]
show_api_scan: bool
@@ -198,6 +209,7 @@ Source code for appknox.mapper
show_ignored_analyses=data["show_ignored_analyses"],
show_hipaa=InheritedPreference.from_json(data["show_hipaa"]),
show_pcidss=InheritedPreference.from_json(data["show_pcidss"]),
+ show_nist=InheritedPreference.from_json(data["show_nist"]),
)
@@ -239,7 +251,7 @@ Source code for appknox.mapper
All modules for which code is available
diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt
index 86e1cbf..06d15ad 100644
--- a/docs/_sources/index.rst.txt
+++ b/docs/_sources/index.rst.txt
@@ -165,92 +165,47 @@ Get the analyses for this new file:
.. code-block:: python
- >>> client.get_analyses(273)[:3]
- [Analysis(id = 22248, risk = 2, status = 3, cvss_base = 6.6, cvss_vector = 'CVSS:3.0/AV:A/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H', cvss_version = 3, cvss_metrics_humanized = [{
- 'key': 'Attack Vector',
- 'value': 'Adjacent'
- }, {
- 'key': 'Attack Complexity',
- 'value': 'Low'
- }, {
- 'key': 'Privileges Required',
- 'value': 'High'
- }, {
- 'key': 'User Interaction',
- 'value': 'Required'
- }, {
- 'key': 'Scope',
- 'value': 'Unchanged'
- }, {
- 'key': 'Confidentiality Impact',
- 'value': 'High'
- }, {
- 'key': 'Integrity Impact',
- 'value': 'High'
- }, {
- 'key': 'Availability Impact',
- 'value': 'High'
- }],
- findings = [{
- 'title': 'ssLA5o60a398i7TM5RkofIA1J',
- 'description': 'MfmnwBwK2HsWqnZMOJoDvWnhIFdVMn'
- }, {
- 'title': 'p9TPfBKLqtlExLklJYnifHO72',
- 'description': '0rppCThV5ybdROVlizmG5ryoWd7S7r'
- }, {
- 'title': 'DpqNGv4q8ZhrYgyobSpEuqiq7',
- 'description': 'BmQkMywysefELpWcG1OGYN9N98PdSi'
- }, {
- 'title': 'pcqd88I0ZLpRqKYD7lTrbGEEY',
- 'description': '7PYqk3Gg9J3Zr7nu8PKhv1tHH1NhdA'
- }, {
- 'title': 'TGdwRQOaFBQ9J046BRB2DJXn4',
- 'description': 'skEJq90yDVC5y0zmSD09f1rQyK8KNZ'
- }],
- updated_on = '2023-09-13T06:08:18.384903Z', vulnerability = 1, owasp = ['M1_2016'], pcidss = ['3_2', '3_3', '3_4'], hipaa = ['164_312_a_1'], cwe = ['CWE_926'], mstg = ['MSTG_6_3', 'MSTG_6_4'], masvs = ['MASVS_6_1'], asvs = [], gdpr = ['gdpr_25', 'gdpr_32'], computed_risk = 2, overridden_risk = None),
- Analysis(id = 22247, risk = 2, status = 3, cvss_base = 5.7, cvss_vector = 'CVSS:3.0/AV:P/AC:L/PR:H/UI:N/S:C/C:L/I:H/A:N', cvss_version = 3, cvss_metrics_humanized = [{
- 'key': 'Attack Vector',
- 'value': 'Physical'
- }, {
- 'key': 'Attack Complexity',
- 'value': 'Low'
- }, {
- 'key': 'Privileges Required',
- 'value': 'High'
- }, {
- 'key': 'User Interaction',
- 'value': 'Not Required'
- }, {
- 'key': 'Scope',
- 'value': 'Changed'
- }, {
- 'key': 'Confidentiality Impact',
- 'value': 'Low'
- }, {
- 'key': 'Integrity Impact',
- 'value': 'High'
- }, {
- 'key': 'Availability Impact',
- 'value': 'None'
- }],
- findings = [{
- 'title': 'y4iutu3KCWb7shg6BsZqu867Y',
- 'description': 'cqB9EcXpGrvQbsrGNMProR3J1cbmxw'
- }, {
- 'title': 'kPLH7e9juz1wq2JCBJrVR9fnb',
- 'description': '2rSLRxGXZbeSZ437l5bzKTTwwSB7il'
- }, {
- 'title': 'qUObDBfoIvOSbVgyhQwxBWOY6',
- 'description': 'iHdHrlq0dCA1gxjWyo4wnGZ3flmr70'
- }, {
- 'title': 'l1i4LxUXU3PaMv1wsYaN7zzLu',
- 'description': '5g4ml46nrfndL7M4V43ZbkEXVX0bVn'
- }, {
- 'title': 'OgZY2lNjHTPqvNl75bupA3tNH',
- 'description': 'IiwQX1xQDjX5t4W6Y9KyWIrMdeREtw'
- }],
- updated_on = '2023-09-13T06:08:21.540225Z', vulnerability = 2, owasp = ['M1_2016'], pcidss = ['3_2', '3_3', '3_4'], hipaa = ['164_312_a_1'], cwe = ['CWE_926'], mstg = ['MSTG_6_1'], masvs = ['MASVS_6_1'], asvs = [], gdpr = ['gdpr_25', 'gdpr_32'], computed_risk = 2, overridden_risk = None), ]
-
+>>> client.get_analyses(1405)[:2]
+[
+ Analysis(
+ id=115449,
+ risk=3,
+ status=3,
+ cvss_base=7.3,
+ cvss_vector="CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L",
+ cvss_version=3,
+ cvss_metrics_humanized=[
+ {"key": "Attack Vector", "value": "Local"},
+ {"key": "Attack Complexity", "value": "Low"},
+ {"key": "Privileges Required", "value": "Low"},
+ {"key": "User Interaction", "value": "Not Required"},
+ {"key": "Scope", "value": "Unchanged"},
+ {"key": "Confidentiality Impact", "value": "High"},
+ {"key": "Integrity Impact", "value": "High"},
+ {"key": "Availability Impact", "value": "Low"},
+ ],
+ findings=[
+ {
+ "title": ' ',
+ "description": "pathPrefix=/",
+ }
+ ],
+ updated_on="2024-01-08T08:39:23.575462Z",
+ vulnerability=2,
+ owasp=["M1_2016"],
+ pcidss=["3_2", "3_3", "3_4"],
+ hipaa=["164_312_a_1"],
+ cwe=["CWE_926"],
+ mstg=["MSTG_6_1"],
+ masvs=["MASVS_6_1"],
+ asvs=[],
+ gdpr=["gdpr_25", "gdpr_32"],
+ nistsp80053=["RA_2", "RA_9", "AC_6", "SC_28", "AC_4", "AC_5", "PS_6", "AC_3"],
+ nistsp800171=["3_1_1", "3_1_5", "3_13_16", "3_4_2"],
+ computed_risk=3,
+ overridden_risk=None,
+ ),
+]
Note the ``vulnerability_id`` for ``Analysis(id=235)``. To get details about this vulnerability:
@@ -432,7 +387,7 @@ __
Download Report Data from URL
------------------------------
-Returns full HTTP response body from a given absolute URL
+Returns full HTTP response body from a given absolute URL
.. code-block:: python
@@ -459,7 +414,7 @@ Complete Reference
:maxdepth: 2
client
-
+
mapper
--
diff --git a/docs/_static/alabaster.css b/docs/_static/alabaster.css
index 6476cd5..c46b859 100644
--- a/docs/_static/alabaster.css
+++ b/docs/_static/alabaster.css
@@ -69,6 +69,11 @@ div.relations {
}
+div.sphinxsidebar {
+ max-height: 100%;
+ overflow-y: auto;
+}
+
div.sphinxsidebar a {
color: #444;
text-decoration: none;
@@ -155,6 +160,14 @@ div.sphinxsidebar input {
font-size: 1em;
}
+div.sphinxsidebar #searchbox input[type="text"] {
+ width: 160px;
+}
+
+div.sphinxsidebar .search > div {
+ display: table-cell;
+}
+
div.sphinxsidebar hr {
border: none;
height: 1px;
@@ -638,15 +651,7 @@ a:hover tt, a:hover code {
display: none!important;
}
-/* Make nested-list/multi-paragraph items look better in Releases changelog
- * pages. Without this, docutils' magical list fuckery causes inconsistent
- * formatting between different release sub-lists.
- */
-div#changelog > div.section > ul > li > p:only-child {
- margin-bottom: 0;
-}
-
-/* Hide fugly table cell borders in ..bibliography:: directive output */
+/* Hide ugly table cell borders in ..bibliography:: directive output */
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
border: none;
/* Below needed in some edge cases; if not applied, bottom shadows appear */
diff --git a/docs/_static/basic.css b/docs/_static/basic.css
index 7577acb..2d467bf 100644
--- a/docs/_static/basic.css
+++ b/docs/_static/basic.css
@@ -222,7 +222,7 @@ table.modindextable td {
/* -- general body styles --------------------------------------------------- */
div.body {
- min-width: 360px;
+ min-width: inherit;
max-width: 800px;
}
diff --git a/docs/client.html b/docs/client.html
index 551956e..6797ecc 100644
--- a/docs/client.html
+++ b/docs/client.html
@@ -19,8 +19,9 @@
+
+
-
@@ -112,6 +113,28 @@
+
diff --git a/docs/_modules/index.html b/docs/_modules/index.html
index f42964a..3dbb979 100644
--- a/docs/_modules/index.html
+++ b/docs/_modules/index.html
@@ -16,8 +16,9 @@
+
+
-
@@ -42,7 +43,7 @@
+-
+get_nistsp800171(nistsp800171_id: str) NISTSP800171 [source]¶
+Fetch nistsp800171 by ID
+
+- Parameters:
+nistsp800171_id – nistsp800171 ID
+
+
+
+
+
+-
+get_nistsp80053(nistsp80053_id: str) NISTSP80053 [source]¶
+Fetch nistsp80053 by ID
+
+- Parameters:
+nistsp80053_id – nistsp80053 ID
+
+
+
+
diff --git a/docs/_modules/appknox/mapper.html b/docs/_modules/appknox/mapper.html
index a85c6fa..0830f39 100644
--- a/docs/_modules/appknox/mapper.html
+++ b/docs/_modules/appknox/mapper.html
@@ -16,8 +16,9 @@
+
+
-
@@ -101,6 +102,8 @@