Skip to content

Commit

Permalink
Update Hackuity integration: API key auth, Hackuity.Findings.Status.L…
Browse files Browse the repository at this point in the history
…astClosedAt (#26558)

* Hackuity: API key auth, status last closed at

* Update docker image.

---------

Co-authored-by: Danny_Fried <[email protected]>
  • Loading branch information
Rogdham and thefrieddan1 authored May 24, 2023
1 parent 2c71ecd commit 30551d8
Show file tree
Hide file tree
Showing 12 changed files with 37 additions and 76 deletions.
Binary file modified Packs/Hackuity/Author_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 12 additions & 60 deletions Packs/Hackuity/Integrations/Hackuity/Hackuity.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ def __init__(
self,
url: str,
namespace: str,
login: str,
password: str,
apikey: str,
verify: bool = True,
proxy: bool = True,
):
self.namespace = namespace
self.login = login
self.password = password
self.apikey = apikey
base_url = f"{url.rstrip('/')}/api/v1"
super().__init__(base_url=base_url, verify=verify, proxy=proxy)

Expand Down Expand Up @@ -70,9 +68,8 @@ def http_request(
json_data: Dict[str, Any] = None,
resp_type: str = "json",
): # pragma: no cover
access_token = self.get_access_token()
headers = {
"authorization": f"Bearer {access_token}",
"authorization": f"Basic {self.apikey}",
"content-type": "application/json",
"user-agent": USER_AGENT,
}
Expand All @@ -86,55 +83,6 @@ def http_request(
error_handler=self.http_error_handler,
)

def get_access_token(self) -> str:
"""Get an access token from integration cache or by loggin in"""
integration_context = get_integration_context()
access_token = integration_context.get("access_token")
access_token_expiration = integration_context.get("access_token_expiration", 0)

# use already existing access token if possible
if access_token and time.time() < access_token_expiration:
return access_token

# log in
demisto.info("API login")
try:
response = self._http_request(
method="POST",
url_suffix="/authentication/idp/oauth2/token",
data={
"grant_type": "password",
"scope": self.namespace,
"username": self.login,
"password": self.password,
},
headers={
"content-type": "application/x-www-form-urlencoded",
"user-agent": USER_AGENT,
},
)
except DemistoException as e:
# extract error description in case of OAuth error
try:
error_description = e.res.json()["error_description"]
except Exception:
raise e # failled to get error description
# format error message
raise DemistoException(
message=f"Authentication error: {error_description}",
exception=e.exception,
res=e.res,
) from e

set_integration_context(
{
# clear other keys to force refresh
"access_token": response["access_token"],
"access_token_expiration": int(time.time()) + response["expires_in"],
}
)
return response["access_token"]

def get_user_id(self) -> str:
"""Get the id of the user"""
integration_context = get_integration_context()
Expand Down Expand Up @@ -373,7 +321,7 @@ def none_or_apply(item: Optional[str], apply: Callable[[str], T]) -> Optional[T]
def test_module(client: Client) -> str:
"""Tests API connectivity and authentication"""
# excption formating in case of authentication error
# is already done in client.get_access_token
# is already done in client.http_error_handler
set_integration_context({}) # reset cache
client.fetch_user()
return "ok"
Expand Down Expand Up @@ -446,6 +394,12 @@ def hackuity_search_findings_command(
["findingStatus", "subState"],
["Status", "SubState"],
),
(
["findingStatus", "lastClosedAt"],
["Status", "LastClosedAt"],
None,
format_date,
),
(
["findingStatus", "score", "hyScore"],
["Score", "TRS"],
Expand Down Expand Up @@ -654,8 +608,7 @@ def main() -> None: # pragma: no cover

url = demisto.params()["url"]
namespace = demisto.params()["namespace"]
login = demisto.params()["login"]["identifier"]
password = demisto.params()["login"]["password"]
apikey = demisto.params().get("apikey")

verify_certificate = not demisto.params().get("insecure", False)
proxy = demisto.params().get("proxy", False)
Expand All @@ -678,8 +631,7 @@ def main() -> None: # pragma: no cover
client = Client(
url=url,
namespace=namespace,
login=login,
password=password,
apikey=apikey,
verify=verify_certificate,
proxy=proxy,
)
Expand Down
17 changes: 9 additions & 8 deletions Packs/Hackuity/Integrations/Hackuity/Hackuity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ configuration:
required: true
type: 0
- defaultvalue: ""
display: Login
name: login
display: API key
name: apikey
required: true
type: 9
type: 4
- display: Trust any certificate (not secure)
name: insecure
required: false
Expand All @@ -26,8 +26,7 @@ configuration:
name: proxy
required: false
type: 8
description: From a war-room, query your Hackuity cockpit in order to seamlessly retrieve
information related to your vulnerability stock.
description: From a war-room, query your Hackuity cockpit in order to seamlessly retrieve information related to your vulnerability stock.
display: Hackuity
name: Hackuity
script:
Expand All @@ -42,8 +41,7 @@ script:
secret: false
- &argument_asset_type
default: false
description: The type of the asset if the asset name is specified (by default,
restricts to IPs & domains)
description: The type of the asset if the asset name is specified (by default, restricts to IPs & domains)
isArray: false
name: asset_type
required: false
Expand Down Expand Up @@ -132,6 +130,9 @@ script:
- contextPath: Hackuity.Findings.Status.SubState
description: The sub-state of the finding
type: String
- contextPath: Hackuity.Findings.Status.LastClosedAt
description: The date of the last time the finding was closed
type: Date
- contextPath: Hackuity.Findings.VulnType.ID
description: The ID of the vulnerability type
type: String
Expand Down Expand Up @@ -234,7 +235,7 @@ script:
script: '-'
type: python
subtype: python3
dockerimage: demisto/python3:3.10.11.54132
dockerimage: demisto/python3:3.10.11.59581
fromversion: 6.0.0
tests:
- No tests (auto formatted)
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ Copy the *server URL* and *namespace* values from the *about page* of your Hacku

#### Credentials

Enter the *login* and *password* of a valid user of your Hackuity instance. Creating a dedicated user for this purpose is recommended.
Generate an *API key* for a valid user of your Hackuity instance. Creating a dedicated user for this purpose is recommended.
Binary file modified Packs/Hackuity/Integrations/Hackuity/Hackuity_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Packs/Hackuity/Integrations/Hackuity/Hackuity_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def util_get_json(directory, filename):

@pytest.fixture
def mocked_client(mocker):
client = Client("https://xxx.api.hackuity.io", "N012345654321", "foo", "bar")
client = Client("https://xxx.api.hackuity.io", "N012345654321", "apikey")

def mocked_http_request(url_suffix: str = "", **_: Any):
return util_get_json("api", "_".join(url_suffix.split("/")[-2:]))
Expand Down
4 changes: 2 additions & 2 deletions Packs/Hackuity/Integrations/Hackuity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ This integration was integrated and tested with version 1.25.0 of Hackuity
| --- | --- |
| Corporate server URL | True |
| Namespace | True |
| Login | True |
| Password | True |
| API key | True |
| Trust any certificate (not secure) | False |
| Use system proxy settings | False |

Expand Down Expand Up @@ -57,6 +56,7 @@ Search for findings in Hackuity.
| Hackuity.Findings.Status.Ignored | Boolean | Whether the finding is ignored |
| Hackuity.Findings.Status.State | String | The state of the finding |
| Hackuity.Findings.Status.SubState | String | The sub-state of the finding |
| Hackuity.Findings.Status.LastClosedAt | Date | The date of the last time the finding was closed |
| Hackuity.Findings.VulnType.ID | String | The ID of the vulnerability type |
| Hackuity.Findings.VulnType.Name | String | The name of the vulnerability type |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"assetType": "IPV4",
"findingId": "RE5isckTYGbU9LVCc76NTV",
"findingStatus": {
"lastClosedAt": "2022-01-01T13:37:42Z",
"score": {
"environmental": 10,
"hyScore": 980
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"Attributes": {},
"Score": { "CVSS": 5.8, "TRS": 671 },
"ID": "nDoKTtbR6tanVtgmtP5BQo",
"Status": { "Ignored": true, "State": "OPEN", "SubState": "POTENTIAL" },
"Status": { "Ignored": true, "State": "OPEN", "SubState": "POTENTIAL", "LastClosedAt": null },
"VulnType": { "ID": "123", "Name": "Lorem ipsum" }
},
{
Expand All @@ -20,7 +20,7 @@
"Attributes": { "cve_id": "CVE-2014-0160" },
"Score": { "CVSS": 10, "TRS": 980 },
"ID": "RE5isckTYGbU9LVCc76NTV",
"Status": { "Ignored": false, "State": "CLOSED", "SubState": "FP" },
"Status": { "Ignored": false, "State": "CLOSED", "SubState": "FP", "LastClosedAt": "2022-01-01T13:37:42Z" },
"VulnType": { "ID": "456", "Name": "Dolor amet" }
}
]
1 change: 1 addition & 0 deletions Packs/Hackuity/ReleaseNotes/1_0_7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"breakingChanges":true,"breakingChangesNotes":"Authentification is now performed with API keys instead of user credentials. API keys can be created on the Hackuity platform from user settings."}
6 changes: 6 additions & 0 deletions Packs/Hackuity/ReleaseNotes/1_0_7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#### Integrations
##### Hackuity
- Updated the Docker image to: *demisto/python3:3.10.11.59581*.
- **Breaking change**: Authentification is now performed with API keys instead of user credentials; API keys can be created on the Hackuity platform from user settings
- Add *Hackuity.Findings.Status.LastClosedAt*
- Update logo
4 changes: 2 additions & 2 deletions Packs/Hackuity/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Hackuity",
"description": "From a war-room, query your Hackuity cockpit in order to seamlessly retrieve information related to your vulnerability stock.",
"support": "partner",
"currentVersion": "1.0.6",
"currentVersion": "1.0.7",
"author": "Hackuity",
"url": "https://www.hackuity.io/support",
"email": "",
Expand All @@ -12,4 +12,4 @@
"tags": [],
"useCases": [],
"keywords": []
}
}

0 comments on commit 30551d8

Please sign in to comment.