diff --git a/appknox/mapper.py b/appknox/mapper.py index ea05535..cd20088 100644 --- a/appknox/mapper.py +++ b/appknox/mapper.py @@ -66,6 +66,7 @@ def mapper_drf_api(model: type, resource: dict) -> object: "hipaa", "cwe", "mstg", + "owaspapi2023", "asvs", "gdpr", "computed_risk", diff --git a/docs/.doctrees/client.doctree b/docs/.doctrees/client.doctree index 1f7b393..041626d 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 87262f1..039bae1 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 36a2012..f2dd04c 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 8ec2b8a..05267ea 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..0cfb6a0 100644 --- a/docs/_modules/appknox/client.html +++ b/docs/_modules/appknox/client.html @@ -84,6 +84,7 @@
[docs]class Appknox(object):
"""
+ Client to interact with API server
"""
def __init__(
@@ -292,9 +293,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 +312,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 +328,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 +401,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 +410,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 +428,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 +448,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:
"""
@@ -670,9 +661,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 +670,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 +698,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":
"""
diff --git a/docs/_modules/appknox/mapper.html b/docs/_modules/appknox/mapper.html
index 90dd90a..5eb72d7 100644
--- a/docs/_modules/appknox/mapper.html
+++ b/docs/_modules/appknox/mapper.html
@@ -1,29 +1,16 @@
-
+
-
+
-
-
+
+
appknox.mapper — appknox-python 3.0.0 documentation
-
-
-
-
-
-
-
-
+
+
+
+
+
@@ -32,8 +19,7 @@
-
-
+
@@ -48,23 +34,25 @@ Source code for appknox.mapper
from collections import namedtuple
from dataclasses import dataclass
+import datetime
+import typing
+
[docs]def mapper_json_api(model: type, resource: dict) -> object:
- """
+ """
Returns an obj of type `model` from dictified JSON `resource` for JSON APIs
"""
attr = dict()
for field in model._fields:
- if field == 'id':
- attr[field] = resource['data']['id']
+ if field == "id":
+ attr[field] = resource["data"]["id"]
else:
- attr[field] = resource['data']['attributes'][
- field.replace('_', '-')]
+ attr[field] = resource["data"]["attributes"][field.replace("_", "-")]
return model(**attr)
[docs]def mapper_drf_api(model: type, resource: dict) -> object:
- """
+ """
Returns an obj of type `model` from dictified JSON `resource` for DRF APIs
"""
accepted_params = {k: resource[k] for k in model._fields}
@@ -72,73 +60,85 @@ Source code for appknox.mapper
User = namedtuple(
- 'User',
- ['id', 'email', 'first_name', 'lang', 'last_name', 'username']
+ "User", ["id", "email", "first_name", "lang", "last_name", "username"]
)
-Whoami = namedtuple(
- 'Whoami',
- ['id', 'email', 'username', 'default_organization']
-)
+Whoami = namedtuple("Whoami", ["id", "email", "username", "default_organization"])
-Organization = namedtuple(
- 'Organization',
- ['id', 'name']
-)
+Organization = namedtuple("Organization", ["id", "name"])
Project = namedtuple(
- 'Project',
- ['id', 'created_on', 'file_count', 'package_name', 'platform',
- 'updated_on']
+ "Project",
+ ["id", "created_on", "file_count", "package_name", "platform", "updated_on"],
)
File = namedtuple(
- 'File',
- ['id', 'name', 'version', 'version_code', 'static_scan_progress', 'profile']
+ "File", ["id", "name", "version", "version_code", "static_scan_progress", "profile"]
)
Submission = namedtuple(
- 'Submission',
- ['id', 'status', 'file', 'package_name', 'created_on', 'reason']
+ "Submission", ["id", "status", "file", "package_name", "created_on", "reason"]
)
Analysis = namedtuple(
- 'Analysis',
- ['id', 'risk', 'status', 'cvss_base', 'cvss_vector', 'cvss_version',
- 'cvss_metrics_humanized', 'findings', 'updated_on', 'vulnerability',
- 'owasp', 'pcidss', 'hipaa', 'cwe', 'mstg', 'asvs', 'gdpr', 'computed_risk', 'overridden_risk']
+ "Analysis",
+ [
+ "id",
+ "risk",
+ "status",
+ "cvss_base",
+ "cvss_vector",
+ "cvss_version",
+ "cvss_metrics_humanized",
+ "findings",
+ "updated_on",
+ "vulnerability",
+ "owasp",
+ "pcidss",
+ "hipaa",
+ "cwe",
+ "mstg",
+ "owaspapi2023",
+ "asvs",
+ "gdpr",
+ "computed_risk",
+ "overridden_risk",
+ ],
)
Vulnerability = namedtuple(
- 'Vulnerability',
- ['id', 'name', 'description', 'intro', 'related_to',
- 'business_implication', 'compliant', 'non_compliant', 'types']
+ "Vulnerability",
+ [
+ "id",
+ "name",
+ "description",
+ "intro",
+ "related_to",
+ "business_implication",
+ "compliant",
+ "non_compliant",
+ "types",
+ ],
)
-OWASP = namedtuple(
- 'OWASP',
- ['id', 'code', 'title', 'description', 'year']
-)
+OWASP = namedtuple("OWASP", ["id", "code", "title", "description", "year"])
-PCIDSS = namedtuple(
- 'PCIDSS',
- ['id', 'code', 'title', 'description']
-)
+PCIDSS = namedtuple("PCIDSS", ["id", "code", "title", "description"])
-PersonalToken = namedtuple(
- 'AccessToken',
- ['name', 'key']
-)
+PersonalToken = namedtuple("AccessToken", ["name", "key"])
ReportPreferenceMapper = {
- 'show_pcidss': 'pcidss',
- 'show_hipaa': 'hipaa',
- 'show_gdpr': 'gdpr'}
+ "show_pcidss": "pcidss",
+ "show_hipaa": "hipaa",
+ "show_gdpr": "gdpr",
+}
+
+
[docs]@dataclass
class ProfileReportPreference:
show_gdpr: ProfileReportPreferenceConfig
@@ -148,9 +148,86 @@ Source code for appknox.mapper
@classmethod
def from_json(cls, data):
return cls(
- show_gdpr=ProfileReportPreferenceConfig(value=data['show_gdpr']['value']),
- show_hipaa=ProfileReportPreferenceConfig(value=data['show_hipaa']['value']),
- show_pcidss=ProfileReportPreferenceConfig(value=data['show_pcidss']['value'])
+ show_gdpr=ProfileReportPreferenceConfig(value=data["show_gdpr"]["value"]),
+ show_hipaa=ProfileReportPreferenceConfig(value=data["show_hipaa"]["value"]),
+ show_pcidss=ProfileReportPreferenceConfig(
+ value=data["show_pcidss"]["value"]
+ ),
+ )
+
+
+[docs]@dataclass
+class InheritedPreference:
+ _fields = ["value", "is_inherited"]
+
+ value: bool
+ is_inherited: bool
+
+ @classmethod
+ def from_json(cls, data: typing.Dict[str, bool]) -> "InheritedPreference":
+ return cls(value=data["value"], is_inherited=data["is_inherited"])
+
+
+[docs]@dataclass
+class ReportPreference:
+ _fields = [
+ "show_api_scan",
+ "show_manual_scan",
+ "show_static_scan",
+ "show_dynamic_scan",
+ "show_ignored_analyses",
+ "show_hipaa",
+ "show_pcidss",
+ ]
+
+ show_api_scan: bool
+ show_manual_scan: bool
+ show_static_scan: bool
+ show_dynamic_scan: bool
+ show_ignored_analyses: bool
+ show_hipaa: InheritedPreference
+ show_pcidss: InheritedPreference
+
+ @classmethod
+ def from_json(cls, data: typing.Dict[str, typing.Any]) -> "ReportPreference":
+ return cls(
+ show_api_scan=data["show_api_scan"],
+ show_manual_scan=data["show_manual_scan"],
+ show_static_scan=data["show_static_scan"],
+ show_dynamic_scan=data["show_dynamic_scan"],
+ show_ignored_analyses=data["show_ignored_analyses"],
+ show_hipaa=InheritedPreference.from_json(data["show_hipaa"]),
+ show_pcidss=InheritedPreference.from_json(data["show_pcidss"]),
+ )
+
+
+[docs]@dataclass
+class Report:
+ _fields = [
+ "id",
+ "language",
+ "generated_on",
+ "progress",
+ "rating",
+ "preferences",
+ ]
+
+ id: int
+ language: str
+ generated_on: datetime.datetime
+ progress: int
+ rating: str
+ preferences: ReportPreference
+
+ @classmethod
+ def from_json(cls, data: typing.Dict[str, typing.Any]) -> "Report":
+ return cls(
+ id=data["id"],
+ language=data["language"],
+ generated_on=data["generated_on"],
+ progress=data["progress"],
+ rating=data["rating"],
+ preferences=ReportPreference.from_json(data["preferences"]),
)
@@ -211,15 +288,15 @@ Related Topics
-
+
@@ -236,8 +313,8 @@ Quick search
©2017, XYSec Labs Pte. Ltd..
|
- Powered by Sphinx 1.6.2
- & Alabaster 0.7.12
+ Powered by Sphinx 6.1.3
+ & Alabaster 0.7.13
diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt
index 05dd58b..6adf7de 100644
--- a/docs/_sources/index.rst.txt
+++ b/docs/_sources/index.rst.txt
@@ -165,16 +165,16 @@ Get the analyses for this new file:
.. code-block:: python
- >>> client.get_analyses(6)[:3]
- [Analysis(id=267, risk=2, status=3, cvss_base=6.8,
- findings=[{'title': None, 'description': 'Unprotected service: com.appknox.mfva.ExportedService'}],
- updated_on='2017-06-27 08:28:35.166608+00:00', vulnerability_id=1),
- Analysis(id=235, risk=3, status=3, cvss_base=7.3,
- findings=[{'title': None, 'description': 'pathPrefix=/'}],
- updated_on='2017-06-27 08:28:35.240543+00:00', vulnerability_id=2),
- Analysis(id=236, risk=3, status=3, cvss_base=7.7,
- findings=[{'title': None, 'description': 'Debug enabled within the app'}],
- updated_on='2017-06-27 08:28:35.296126+00:00', vulnerability_id=3)]
+
+ >>> client.get_analyses(1)[3]
+ [Analysis(id=7, risk=0, status=3, cvss_base=0.0, cvss_vector='', cvss_version=3, cvss_metrics_humanized=[],
+ findings=[], updated_on='2023-10-20T07:00:28.201515Z', vulnerability=7, owasp=['M3_2016'], pcidss=['4_1'], hipaa=['164_312_e_1'], cwe=['CWE_296'], mstg=['MSTG_3_2', 'MSTG_3_3', 'MSTG_3_3'], owaspapi2023=[], asvs=[], gdpr=['gdpr_25', 'gdpr_32'], computed_risk=0, overridden_risk=None),
+ Analysis(id=8, risk=0, status=3, cvss_base=0.0, cvss_vector='', cvss_version=3, cvss_metrics_humanized=[],
+ findings=[], updated_on='2023-10-20T07:00:28.525211Z', vulnerability=8, owasp=['M3_2016'], pcidss=['4_1'], hipaa=['164_312_e_1'], cwe=['CWE_297'], mstg=['MSTG_5_3'], owaspapi2023=[], asvs=[], gdpr=['gdpr_25', 'gdpr_32'], computed_risk=0, overridden_risk=None),
+ Analysis(id=9, risk=0, status=3, cvss_base=0.0, cvss_vector='', cvss_version=3, cvss_metrics_humanized=[],
+ findings=[], updated_on='2023-10-20T07:00:28.857579Z', vulnerability=9, owasp=['M3_2016'], pcidss=[], hipaa=[], cwe=['CWE_749'], mstg=['MSTG_6_6'], owaspapi2023=[], asvs=[], gdpr=['gdpr_25', 'gdpr_32'], computed_risk=0, overridden_risk=None)]
+
+
Note the ``vulnerability_id`` for ``Analysis(id=235)``. To get details about this vulnerability:
diff --git a/docs/_static/pygments.css b/docs/_static/pygments.css
index 691aeb8..0d49244 100644
--- a/docs/_static/pygments.css
+++ b/docs/_static/pygments.css
@@ -17,6 +17,7 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
diff --git a/docs/genindex.html b/docs/genindex.html
index 13a77ae..f7536ed 100644
--- a/docs/genindex.html
+++ b/docs/genindex.html
@@ -145,8 +145,6 @@ D
- - direct_get() (appknox.client.ApiResource method)
-
- direct_get_http_response() (appknox.client.ApiResource method)
- download_report_data() (appknox.client.Appknox method)
@@ -190,8 +188,6 @@
G
- gdpr (appknox.mapper.Analysis attribute)
- generate_access_token() (appknox.client.Appknox method)
-
- - get() (appknox.client.ApiResource method)
- get_analyses() (appknox.client.Appknox method)
@@ -206,14 +202,10 @@ G
- get_organizations() (appknox.client.Appknox method)
- get_owasp() (appknox.client.Appknox method)
-
- - get_owasps() (appknox.client.Appknox method)
- get_pcidss() (appknox.client.Appknox method)
-
- - get_pcidsses() (appknox.client.Appknox method)
- get_profile_report_preference() (appknox.client.Appknox method)
@@ -228,8 +220,6 @@ G
- get_unselected_report_preference() (appknox.client.Appknox method)
- get_user() (appknox.client.Appknox method)
-
- - get_vulnerabilities() (appknox.client.Appknox method)
- get_vulnerability() (appknox.client.Appknox method)
@@ -349,6 +339,8 @@ O
- owasp (appknox.mapper.Analysis attribute)
- OWASP (class in appknox.mapper)
+
+ - owaspapi2023 (appknox.mapper.Analysis attribute)
@@ -362,10 +354,6 @@ P
(appknox.mapper.Submission attribute)
- paginated_data() (appknox.client.Appknox method)
-
- paginated_drf_data() (appknox.client.Appknox method)
-
pcidss (appknox.mapper.Analysis attribute)
PCIDSS (class in appknox.mapper)
@@ -377,8 +365,6 @@ P
platform (appknox.mapper.Project attribute)
poll_for_file_from_submission_id() (appknox.client.Appknox method)
-
- post() (appknox.client.ApiResource method)
profile (appknox.mapper.File attribute)
@@ -418,8 +404,6 @@ R
S