Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Penfield AI Pull Request 2 #15523

Merged
merged 17 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added Packs/PenfieldAI/.pack-ignore
Empty file.
88 changes: 88 additions & 0 deletions Packs/PenfieldAI/.secrets-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
FE80:0000:0000:0000:0202:B3FF:FE1E:8329
2001:0db8:85a3:0000:0000:8a2e:0370:7334
2001:0db8:85a3:1337:0000:8a2e:0370:7334
2001:db8:a0b:12f0::1
1.1.1.1
user@example.com
8.8.8.8
192.168.1.1
192.168.1.12
6.6.6.6
2001:db8:a0b:12f0::1aaa
http://example.com
2001:db8:a0b:12f0::98aa
FE80::0202:B3FF:FE1E:8329
10.10.10.10
https://exchange.xforce.ibmcloud.com
user@example.com
8.8.8.8
https://google.com
https://example.com
https://docs.microsoft.com
192.168.0.0
10.0.0.0
172.16.0.0
127.0.0.0
169.254.0.0
https://192.12.12.3
192.12.12.3
192.168.2.1
https://some_url.com
xsoar.pan.dev
@test.com
registrar@test.com
11.111.11.11
::deb
http://www.letsseeifyoucanfindthisone4444.co.il
111.11.11.111
https://www.a.com
http://www.c.com
mt.kb.user@gmail.com
@pytest.mark.parametrize
1::6:7:8
1:2:3:4:5:6::8
1:2::8
1:2:3:4::8
['::2:3:4:5:6:7:8', '1::3:4:5:6:7:8']
::2:3:4:5:6:7:8
1::3:4:5:6:7:8
a@gmail.com
1a:2b::4c:5:6:7:8
1a:2b::4c:5abc
['1a:2b::4c:5:6:7:8', '1a:2b::4c:5abc']
DBotScoreType.FILE,
2.5.29.17
2.5.29.14
2.5.29.15
2.5.29.37
2.5.29.35
2.5.29.31
2.5.29.32
['1.3.6.1', '5.5.7.1']
2.5.29.19
1.3.6.1
:attr:`Retry.BACKOFF_MAX`.
dict_safe_get(dict,['something',
http://crl3.digicert.com
http://crl4.digicert.com
https://www.digicert.com
http://ocsp.digicert.com
http://cacerts.digicert.com
KEY-----\\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFw'
KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFw'
key_identifier="0f80611c823161d52f28e78d4638b42ce1c6d9e2"
digest="b34972bb12121b8851cd5564ff9656dcbca3f288",
log_id="f65c942fd1773022145418083094568ee34d131933bfdf0c2f200bcc4ef164e3",
log_id="5cdc4392fee6ab4544b15e9ad456e61037fbd5fa47dca17394b25ee6f6c70eca",
sha256='bc33cf76519f1ec5ae7f287f321df33a7afd4fd553f364cf3c753f91ba689f8d',
sha1='2392ea5cd4c2a61e51547570634ef887ab1942e9',
spki_sha256='94b716aeda21cd661949cfbf3f55457a277da712cdce0ab31989a4f288fad9b9',
"2392ea5cd4c2a61e51547570634ef887ab1942e9",
"94b716aeda21cd661949cfbf3f55457a277da712cdce0ab31989a4f288fad9b9",
2.23.140.1
'53e6baa124f54462786f1122e98e38ff1be3de82fe2a96b1849a8637043fd847eec7e0f53307bddf7a066565292d500c36c941f1f3bb9dcac807b2f4a0bfce1b',
http://proxy
http://testproxy
https://testproxy
http://165.225.225.99
165.225.225.99
Binary file added Packs/PenfieldAI/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.
112 changes: 112 additions & 0 deletions Packs/PenfieldAI/Integrations/Penfield/Penfield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import urllib3
import traceback
import demistomock as demisto
from CommonServerPython import * # pylint: disable=unused-wildcard-import
from CommonServerUserPython import * # noqa


# Disable insecure warnings
urllib3.disable_warnings()

''' CLIENT CLASS '''


class Client(BaseClient):
def live_assign_get(self, analyst_ids, category, created, arg_id, name, severity) -> str:
params = assign_params(
analyst_ids=analyst_ids,
category=category,
created=created,
id=arg_id,
name=name,
severity=severity
)
response = self._http_request(
method='POST',
url_suffix='/api/v1/xsoar_live_assign/',
params=params
)
return response['analyst']

def test(self) -> str:
response = self._http_request(
method='GET',
url_suffix='/api/v1/xsoar_live_assign/'
)
return response


''' HELPER FUNCTIONS '''


def get_assignee(client: Client, args) -> CommandResults:
analyst_ids = argToList(args.get('analyst_ids'))
category = args.get('category')
created = args.get('created')
arg_id = args.get('id')
name = args.get('name')
severity = args.get('severity')
analyst = client.live_assign_get(analyst_ids, category, created, arg_id, name, severity)
human_readable = tableToMarkdown(
'Analyst Penfield Recommends',
analyst,
headers=['Recommendation'],
headerTransform=pascalToSpace,
removeNull=True
)
return CommandResults(
readable_output=human_readable,
outputs_prefix='Penfield.Recommended',
outputs_key_field='Analyst',
outputs=analyst
)


def test_api(client: Client):
return client.test()


''' MAIN FUNCTION '''


def main() -> None:
api_key = demisto.params().get('apikey')
base_url = urljoin(demisto.params()['url'], '')
verify_certificate = not demisto.params().get('insecure', False)
proxy = demisto.params().get('proxy', False)

demisto.debug(f'Command being called is {demisto.command()}')
try:
headers = {
'Authorization': f'Bearer {api_key}'
}
client = Client(
base_url=base_url,
verify=verify_certificate,
headers=headers,
proxy=proxy
)

if demisto.command() == 'test-module':
result = test_api(client)
if int(result) == 0:
return_results('ok')
else:
raise RuntimeError('Penfield API cannot be reached')

elif demisto.command() == 'penfield-get-assignee':
result = get_assignee(client, demisto.args())
return_results(result)

# Log exceptions and return errors
except Exception as e:
demisto.error(traceback.format_exc()) # print the traceback
return_error(
f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}'
)


''' ENTRY POINT '''

if __name__ in ('__main__', '__builtin__', 'builtins'):
main()
74 changes: 74 additions & 0 deletions Packs/PenfieldAI/Integrations/Penfield/Penfield.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
category: Case Management
commonfields:
id: Penfield
version: -1
configuration:
- defaultvalue: https://example.com/
display: Your server URL
name: url
required: true
type: 0
- display: API Key
additionalinfo: The API Key to use for connection
name: apikey
required: true
type: 4
- display: Trust any certificate (not secure)
name: insecure
required: false
type: 8
- display: Use system proxy settings
name: proxy
required: false
type: 8
description: "The penfield-get-assignee command takes in necessary context data, and returns\
\ the analyst that Penfield believes the incident should be assigned to based on\
\ Penfield's models of skill and process. The test command verfies that the endpoint\
\ is reachable."
display: 'Penfield'
name: Penfield
script:
commands:
- name: penfield-get-assignee
description: 'Calls the Penfield API and returns the analyst Penfield recommends
assigning the incident to. This information is saved in the output, but the
incident will not be automatically assigned.'
outputs:
- contextPath: Penfield.Recommended.Analyst
description: The XSOAR analyst Penfield recommends assigning the incident to.
type: String
arguments:
- name: analyst_ids
description: 'An array of XSOAR analyst IDs for Penfield to choose from when
determining who to assign to.'
required: true
isArray: true
- name: category
required: true
description: 'The category of the incident to assign. Can be taken from incident
Context Data.'
- name: created
required: true
description: 'The creation_date of the incident to assign. Can be taken from
incident Context Data.'
- name: id
required: true
description: 'The id of the incident to assign. Can be taken from incident Context
Data.'
- name: name
required: true
description: 'The name of the incident to assign. Can be taken from incident
Context Data.'
- name: severity
required: true
description: 'The severity of the incident to assign. Can be taken from incident
Context Data.'
isfetch: false
runonce: false
script: '-'
type: python
subtype: python3
dockerimage: demisto/python3:3.9.8.24399
fromversion: 6.0.0
tests:
- No tests (auto formatted)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Integration Help

For this integration, you will need to have a deployed instance of PenfieldCore. Please contact Penfield to get this done. During the setup process, Penfield will provide an API key and the URL of the endpoint, which will vary depending upon how the setup was performed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions Packs/PenfieldAI/Integrations/Penfield/Penfield_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import demistomock as demisto
from Penfield import main, get_assignee, Client
import json
import io


def util_load_json(path):
with io.open(path, mode='r', encoding='utf-8') as f:
return json.loads(f.read())


def test_main(mocker):
mock_users = "username1,username2"
mock_incident = util_load_json('test_data/test_incident.json')

mocker.patch.object(demisto, 'command', return_value="penfield-get-assignee")
mocker.patch.object(demisto, 'args', return_value={'analysts': mock_users, 'incident': mock_incident})
mocker.patch('Penfield.get_assignee', return_value="test")
mocker.patch.object(demisto, 'results')
mocker.patch.object(demisto, 'params', return_value={'url': 'https://fakeurl.ai/api/v1/xsoar_live_assign/'})

main()

assert demisto.results.call_args.args[0] == 'test'


def test_get_assignee(mocker):

mock_users = "username1,username2"

mocker.patch.object(demisto, 'args', return_value={
'analyst_ids': mock_users,
'category': 'test_category',
'created': '2021-03-02',
'arg_id': 123,
'name': 'test name',
'severity': 'high'
})
mocker.patch('Penfield.Client.live_assign_get', return_value="test_cr_response")

api_key = demisto.params().get('apikey')
base_url = 'https://test.com'
verify_certificate = not demisto.params().get('insecure', False)
proxy = demisto.params().get('proxy', False)

headers = {
'Authorization': f'Bearer {api_key}'
}
client = Client(
base_url=base_url,
verify=verify_certificate,
headers=headers,
proxy=proxy
)

assert type(get_assignee(client, demisto.args())).__name__ == "CommandResults"
18 changes: 18 additions & 0 deletions Packs/PenfieldAI/Integrations/Penfield/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pylint = "*"
pytest = "==5.0.1"
pytest-mock = "*"
requests-mock = "*"
pytest-asyncio = "*"

[packages]
pytest = "*"
requests = "*"

[requires]
python_version = "3.7"
Loading