class Connection(insightconnect_plugin_runtime.Connection): def __init__(self): super(self.__class__, self).__init__(input=ConnectionSchema()) self.client = None def connect(self, params): api_key = params.get(Input.API_KEY)["secretKey"] user_id = params.get(Input.USER_ID) org_id = params.get(Input.ORG_ID) timeout = params.get(Input.TIMEOUT, 120) self.client = ThreatStack(api_key=api_key, user_id=user_id, org_id=org_id, api_version=2, timeout=timeout) def test(self): now = datetime.datetime.now().strftime("%Y-%m-%d") try: self.client.http_request(method="get", path="agents", params={ "from": now, "until": now }) except (ThreatStackAPIError, ThreatStackClientError, APIRateLimitError) as e: raise ConnectionTestException(cause="An error occurred!", assistance=e) return {"success": True}
def connect(self, params): api_key = params.get(Input.API_KEY)["secretKey"] user_id = params.get(Input.USER_ID) org_id = params.get(Input.ORG_ID) timeout = params.get(Input.TIMEOUT, 120) self.client = ThreatStack(api_key=api_key, user_id=user_id, org_id=org_id, api_version=2, timeout=timeout)
def connect(self, params): k = params['api_key'] params['api_key'] = k['secretKey'] if params.get('org_id') == '': params['org_id'] = None self.client = ThreatStack(**params)
def test_list_logs(): responses.add(responses.GET, "https://app.threatstack.com/api/v1/logs", content_type="application/json", body='[ \ { \ "timestamp": 1398277257000, \ "user": "******", \ "type": "queue", \ "action": "add", \ "description": "Event of type audit added to Queue", \ "context": [ \ { \ "id": "20c2bac3-86c2-88c3-2f1c-12c2b5c3b153", \ "type": "audit", \ "agent": { \ "name": "precise64", \ "policy_id": "524c4b9aa086e1195900000d", \ "id": "52fd46e3277f3a26000008" \ }, \ "name": "/bin/nc.openbsd" \ } \ ], \ "source": "queue:add", \ "user_id": "524c4a59a086e11959000008", \ "organization_id": "524c4a59a086e11959000009" \ }, \ { \ "timestamp": 1398277257000, \ "user": "******", \ "type": "queue", \ "action": "add", \ "description": "Event of type audit added to Queue", \ "context": [ \ { \ "id": "20c2bac3-86c2-88c3-2f1c-12c2b5c3b153", \ "type": "audit", \ "agent": { \ "name": "precise64", \ "policy_id": "524c4b9aa086e1195900000d", \ "id": "52fd46e3277f3a26000008" \ }, \ "name": "/bin/nc.openbsd" \ } \ ], \ "source": "queue:add", \ "user_id": "524c4a59a086e11959000008", \ "organization_id": "524c4a59a086e11959000009" \ } \ ]') ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.logs.list(page=1) assert isinstance(response, GeneratorType) count = 0 for org in response: count += 1 assert count == 2
def test_get_alert(): responses.add( responses.GET, "https://api.threatstack.com/v2/alerts/52ebb55fdf5fb93e710002ba", content_type="application/json", body='{ \ "active": true, \ "agent_id": "52eafd46e5777f3a26000008", \ "alert_policy_id": "524c4b9aa086e1195900000c", \ "count": 6, \ "created_at": 1391179102237, \ "dismissed": false, \ "expires_at": 1391182702237, \ "id": "52ebb55fdf5fb93e710002ba", \ "key": "525740a144414e7d1c00000b-52eafd46e5777f3a26000008-aebc6afbb8a542a00de8fb45ccd5694a", \ "last_notified_at": "2014-01-31T14:38:29.329Z", \ "last_updated_at": "2014-01-31T14:39:18.682Z", \ "rule_id": "525740a144414e7d1c00000b", \ "severity": 1, \ "title": "Netcat Detected!", \ "type": "rule", \ "unread": true \ }') ts = ThreatStack(api_key="test_api_key", org_id="test_org_id", user_id="test_user_id") response = ts.alerts.get("52ebb55fdf5fb93e710002ba") assert isinstance(response, dict) assert response["id"] == "52ebb55fdf5fb93e710002ba"
def test_get_policy(): responses.add(responses.GET, "https://app.threatstack.com/api/v1/policies/524c4b9aa086e1195900000a", content_type="application/json", body='{ \ "file_integrity_rules": [], \ "updated_at": "2013-10-25T17:42:42.446Z", \ "created_at": "2013-10-02T16:36:42.000Z", \ "read_only": true, \ "firewall_enabled": true, \ "enabled": true, \ "description": "This is the default policy", \ "name": "Default Policy", \ "id": "524c4b9aa086e1195900000a", \ "organization_id": "524c4a59a086e11959000009", \ "alert_policy_id": "524c4b9aa086e1195900000c", \ "agent_count": 1, \ "firewall_rule_count": 3, \ "alert_rule_count": 2 \ }' ) ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.policies.get("524c4b9aa086e1195900000a") assert isinstance(response, dict) assert response["id"] == "524c4b9aa086e1195900000a"
def test_v2_list_agents(): responses.add(responses.GET, "https://api.threatstack.com/v2/agents", content_type="application/json", body='{ \ "token": "", \ "agents": [ \ { \ "activated_at": "2014-01-31T14:36:24.359Z", \ "pause": false, \ "online": false, \ "enabled": true, \ "updated_at": "2014-01-31T01:32:54.000Z", \ "last_reported_at": "2014-02-03T22:39:28.912Z", \ "created_at": "2014-01-31T01:32:54.000Z", \ "ip_address": "189.173.23.133", \ "version": "1.0.8", \ "status": "active", \ "name": "precise64", \ "description": "", \ "hostname": "webserver-2", \ "agent_id": "524c4a59a086e11959000009-6cc8d9b0-8a17-11e3-a2e3-ffced68b988625dda8300db4f718", \ "id": "52eafd46e5777f3a26000008", \ "policy_id": "524c4b9aa086e1195900000d", \ "organization_id": "524c4a59a086e11959000002" \ }, \ { \ "activated_at": "2014-01-31T14:36:24.359Z", \ "pause": false, \ "online": true, \ "enabled": true, \ "updated_at": "2014-01-31T01:32:54.000Z", \ "last_reported_at": "2014-02-03T22:39:28.912Z", \ "created_at": "2014-01-31T01:32:54.000Z", \ "ip_address": "189.173.23.134", \ "version": "1.0.8", \ "status": "active", \ "name": "precise64", \ "description": "", \ "hostname": "webserver-2", \ "agent_id": "524c4a59a086e11959000009-6cc8d9b0-8a17-11e3-a2e3-ffced68b988625dda8300db4f719", \ "id": "52eafd46e5777f3a26000009", \ "policy_id": "524c4b9aa086e1195900000d", \ "organization_id": "524c4a59a086e11959000002" \ } \ ] \ }') ts = ThreatStack(api_key="test_api_key", org_id="test_org_id", api_version=2) response = ts.agents.list() assert isinstance(response, GeneratorType) count = 0 for agent in response: assert agent["organization_id"] == "524c4a59a086e11959000002" count += 1 assert count == 2
def test_get_agent(): responses.add(responses.GET, "https://app.threatstack.com/api/v1/agents/52eafd46e5777f3a26000009", content_type="application/json", body='{ \ "activated_at": "2014-01-31T14:36:24.359Z", \ "pause": false, \ "online": true, \ "enabled": true, \ "updated_at": "2014-01-31T01:32:54.000Z", \ "last_reported_at": "2014-02-03T22:39:28.912Z", \ "created_at": "2014-01-31T01:32:54.000Z", \ "ip_address": "189.173.23.134", \ "version": "1.0.8", \ "status": "active", \ "name": "precise64", \ "description": "", \ "hostname": "webserver-2", \ "agent_id": "524c4a59a086e11959000009-6cc8d9b0-8a17-11e3-a2e3-ffced68b988625dda8300db4f719", \ "id": "52eafd46e5777f3a26000009", \ "policy_id": "524c4b9aa086e1195900000d", \ "organization_id": "524c4a59a086e11959000002" \ }' ) ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.agents.get("52eafd46e5777f3a26000009") assert isinstance(response, dict) assert response["hostname"] == "webserver-2"
def test_list_alerts(): responses.add(responses.GET, "https://app.threatstack.com/api/v1/alerts", content_type="application/json", body='[ \ { \ "active": true, \ "agent_id": "52eafd46e5777f3a26000008", \ "alert_policy_id": "524c4b9aa086e1195900000c", \ "count": 6, \ "created_at": 1391179102237, \ "dismissed": false, \ "expires_at": 1391182702237, \ "id": "52ebb55fdf5fb93e710002bd", \ "key": "525740a144414e7d1c00000b-52eafd46e5777f3a26000008-aebc6afbb8a542a00de8fb45ccd5694b", \ "last_notified_at": "2014-01-31T14:38:29.329Z", \ "last_updated_at": "2014-01-31T14:39:18.682Z", \ "rule_id": "525740a144414e7d1c00000b", \ "severity": 1, \ "title": "Netcat Detected!", \ "type": "rule", \ "unread": true \ }, \ { \ "active": true, \ "agent_id": "52eafd46e5777f3a26000008", \ "alert_policy_id": "524c4b9aa086e1195900000c", \ "count": 6, \ "created_at": 1391179102237, \ "dismissed": false, \ "expires_at": 1391182702237, \ "id": "52ebb55fdf5fb93e710002ba", \ "key": "525740a144414e7d1c00000b-52eafd46e5777f3a26000008-aebc6afbb8a542a00de8fb45ccd5694a", \ "last_notified_at": "2014-01-31T14:38:29.329Z", \ "last_updated_at": "2014-01-31T14:39:18.682Z", \ "rule_id": "525740a144414e7d1c00000b", \ "severity": 1, \ "title": "Netcat Detected!", \ "type": "rule", \ "unread": true \ } \ ]') ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.alerts.list(page=1) assert isinstance(response, GeneratorType) count = 0 for alerts in response: count += 1 assert count == 2
def test_list_policies(): responses.add(responses.GET, "https://app.threatstack.com/api/v1/policies", content_type="application/json", body='[ \ { \ "file_integrity_rules": [], \ "updated_at": "2013-10-25T17:42:42.446Z", \ "created_at": "2013-10-02T16:36:42.000Z", \ "read_only": true, \ "firewall_enabled": true, \ "enabled": true, \ "description": "This is the default policy", \ "name": "Default Policy", \ "id": "524c4b9aa086e1195900000a", \ "organization_id": "524c4a59a086e11959000009", \ "alert_policy_id": "524c4b9aa086e1195900000c", \ "agent_count": 1, \ "firewall_rule_count": 3, \ "alert_rule_count": 2 \ }, \ { \ "file_integrity_rules": [], \ "updated_at": "2013-10-25T17:42:42.446Z", \ "created_at": "2013-10-02T16:36:42.000Z", \ "read_only": true, \ "firewall_enabled": true, \ "enabled": true, \ "description": "This is the default policy", \ "name": "Default Policy", \ "id": "524c4b9aa086e1195900000d", \ "organization_id": "524c4a59a086e11959000009", \ "alert_policy_id": "524c4b9aa086e1195900000c", \ "agent_count": 1, \ "firewall_rule_count": 3, \ "alert_rule_count": 2 \ } \ ]' ) ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.policies.list(page=1) assert isinstance(response, GeneratorType) count = 0 for policy in response: count += 1 assert count == 2
def test_list_organizations(): responses.add(responses.GET, "https://app.threatstack.com/api/v1/organizations", content_type="application/json", body='[ \ {"role": "user", "id": "acbd18db4cc2f85cedef654fccc4a4d8", "name": "Foo\'s Organization"}, \ {"role": "user", "id": "37b51d194a7513e45b56f6524f2d51f2", "name": "Bar\'s Organization"} \ ]') ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.organizations.list() assert isinstance(response, GeneratorType) count = 0 for org in response: count += 1 assert count == 2
def test_get_organization_users(): responses.add( responses.GET, "https://app.threatstack.com/api/v1/organizations/acbd18db4cc2f85cedef654fccc4a4dG8/users", content_type="application/json", body='[ \ { \ "id": "1010101010ababababab2020", \ "display_name": "John Doe", \ "name": {"last": "Doe", "first": "John"}, \ "updated_at": "2013-10-02T16:31:21.000Z", \ "organization_id": "37b51d194a7513e45b56f6524f2d51f2", \ "role": "owner", \ "email": "*****@*****.**" \ }, \ { \ "id": "1010101010ababababab2021", \ "display_name": "Charles Xavier", \ "name": {"last": "Xavier", "first": "Charles"}, \ "updated_at": "2013-09-16T21:24:06.000Z", \ "organization_id": "37b51d194a7513e45b56f6524f2d51f2", \ "role": "user", \ "email": "*****@*****.**" \ } \ ]') ts = ThreatStack(api_key="test_api_key", api_version=1) response = ts.organizations.users("acbd18db4cc2f85cedef654fccc4a4dG8") assert isinstance(response, GeneratorType) count = 0 for user in response: assert user["organization_id"] == "37b51d194a7513e45b56f6524f2d51f2" count += 1 assert count == 2
def test_get_organziation(): with pytest.raises(ThreatStackClientError) as ex: ts = ThreatStack(api_key="test_api_key", api_version=1) org = ts.organizations.get() assert "API method not supported" in str(ex.value)
def test_v2_bad_api_version(): with pytest.raises(ThreatStackClientError) as ex: ts = ThreatStack(api_key="test_api_key", api_version=0) assert 'Invalid API version' in str(ex.value)
def test_v2_missing_api_key(): with pytest.raises(ThreatStackClientError) as ex: ts = ThreatStack(api_version=2) assert 'api_key is required' in str(ex.value)
def test_v2_missing_org_id(): with pytest.raises(ThreatStackClientError) as ex: ts = ThreatStack(api_version=2, api_key="test_api_key") assert 'org_id is required' in str(ex.value)
import logging import os from threatstack import ThreatStack log_level = os.environ.get('LOG_LEVEL', 'INFO') logging.root.setLevel(logging.getLevelName(log_level)) _logger = logging.getLogger(__name__) # Initialize client. THREATSTACK_API_KEY = os.environ.get('THREATSTACK_API_KEY') THREATSTACK_ORG_ID = os.environ.get('THREATSTACK_ORG_ID') THREATSTACK_USER_ID = os.environ.get('THREATSTACK_USER_ID') threatstack_client = ThreatStack( api_key=THREATSTACK_API_KEY, org_id=THREATSTACK_ORG_ID, user_id=THREATSTACK_USER_ID ) # Initialize AWS client AWS_SNS_TOPIC_ARN = os.environ.get('AWS_SNS_TOPIC_ARN') sns_client = boto3.client('sns') def _get_agent_from_alert(alert): '''Return a ruleset from a Threat Stack alert.''' agent_id = alert.get('agentId') if agent_id is not None: agent = threatstack_client.agents.get(agent_id) else: agent = {} return agent