def selftest_function(opts): """ Simple test to verify McAfee ESM connectivity. """ options = opts.get("fn_mcafee_esm", {}) try: # Instantiate RequestsCommon object rc = RequestsCommon(opts=opts, function_opts=options) # Check config file and change trust_cert to Boolean options = check_config(options) url = options["esm_url"] + "/rs/esm/v2/caseGetCaseList" headers = get_authenticated_headers(rc, options["esm_url"], options["esm_username"], options["esm_password"], options["trust_cert"]) r = rc.execute_call_v2('post', url, headers=headers, verify=options["trust_cert"], proxies=rc.get_proxies()) if r.status_code == 200: return {"state": "success", "status_code": r.status_code} else: return {"state": "failure", "status_code": r.status_code} except Exception as e: return {"state": "failure", "status_code": e}
def _delete_domain_function(self, event, *args, **kwargs): """Function: This is a function implementation that uses the Cisco API to delete a domain from the shared customer’s domain list.""" try: validate_fields(['cisco_domain'], kwargs) # Get the function parameters: cisco_domain = kwargs.get("cisco_domain") # text self.log.info(u'Deleting {} from list'.format(cisco_domain)) rp = ResultPayload(SECTION_NAME, **kwargs) url = '/'.join( (self.options['url'], 'domains', '{}?customerKey={}')) url = url.format(cisco_domain.strip(), self.apikey) self.log.debug(url) rc = RequestsCommon(self.opts, self.options) content, msg = rc.execute_call_v2("delete", url, callback=callback) if msg: yield StatusMessage(msg) else: yield StatusMessage( u"Delete domain for '{}' was successful".format( cisco_domain)) # Return the results results = rp.done(False if msg else True, None if msg else content, msg) # backward compatibility results['value'] = None if msg else content yield FunctionResult(results) except Exception as err: self.log.error(err) yield FunctionError()
def delete_app(self, guid, *args, **kwargs): """ Deletes an app. :param guid: String GUID of the app to delete. :return: Information about the app. """ oauth_authorization_headers = { "accept": "application/json", "Content-Type": "application/json", "charset": "utf-8" } self._add_authentication_headers(oauth_authorization_headers) rc = RequestsCommon(self.opts, self.options) app_status = {} response = rc.execute_call_v2('DELETE', self.base_url + self.CF_APP.format(guid), headers=oauth_authorization_headers) if response.status_code == 204: # return status code for update log.info("Successful deletion of {}".format(guid)) app_status["success"] = True else: app_status["success"] = False app_status["details"] = "Couldn't delete." app_status["last_updated"] = None log.error("Error while deleting cf application {}.".format(guid)) log.debug(response) return app_status
def selftest_function(opts): """ Placeholder for selftest function. An example use would be to test package api connectivity. Suggested return values are be unimplemented, success, or failure. """ options = opts.get("fn_mxtoolbox", {}) # Setup the URL request url = '/'.join((options['url'], 'mx', "?argument={}&Authorization={}")) url = url.format('abc.com', options['api_token']) # Make URL request rc = RequestsCommon(opts, options) state, reason = "", "" try: response = rc.execute_call_v2("get", url, headers=HEADERS) # Check the results if response.status_code == 200: state = "success" else: state = "failure" reason = response.error except Exception as ex: state = "failure" reason = str(ex) result = {"state": state, "reason": reason} log.info(result) return result
def selftest_function(opts): """ Simple api test to confirm access """ options = opts.get("fn_geocoding", {}) url = options['url'] payload = { "key": options['api_key'], "latlng": "42.3656119,-71.0805841" } rc = RequestsCommon(opts, options) response = rc.execute_call_v2("get", url, params=payload) if response and response.json()['status'] == "OK": return { "state": "success", "response": response.json() } else: log.error(response) return { "state": "failure", "reason": str(response.text) }
def test_resp_types(self): IPIFY = TestFunctionRequests.URL_TEST_DATA_RESULTS rc = RequestsCommon(None, None) # J S O N json_result = rc.execute_call("get", "{}?format=json".format(IPIFY), None) try: json.dumps(json_result) except (TypeError, OverflowError): self.fail("result is not json") # T E X T text_result = rc.execute_call("get", "{}?format=text".format(IPIFY), None, resp_type='text') self.assertIsNotNone(text_result) # B Y T E S bytes_result = rc.execute_call("get", "{}?format=text".format(IPIFY), None, resp_type='bytes') self.assertIsNotNone(bytes_result) self.assertTrue(isinstance(bytes_result, bytes))
def _isitphishing_url_function(self, event, *args, **kwargs): """Function: isitphishing_url This function takes URL string as a required parameter. It queries the Vade Secure isiphishing API to analyze the URL to determine if it is PHISHING or SPAM. The results contain the result of the query in 'contents' and the URL input parameter to the function. """ try: rp = ResultPayload(PACKAGE_NAME, **kwargs) # Get the function parameters: isitphishing_url = kwargs.get("isitphishing_url") # text log = logging.getLogger(__name__) log.info("isitphishing_url: %s", isitphishing_url) # Form the URL for API request. API_URL = u"{0}/url".format(self.options["isitphishing_api_url"]) # Get the license key to access the API endpoint. auth_token = get_license_key(self.options["isitphishing_name"], self.options["isitphishing_license"]) # Build the header and the data payload. headers = { "Authorization": u'Bearer {}'.format(auth_token), "Content-type": "application/json", } payload = { "url": isitphishing_url, "force": False, "smart": True, "timeout": 8000 } yield StatusMessage( "Query IsItPhishing.org endpoint for status of URL {0}.". format(isitphishing_url)) # Make URL request rc = RequestsCommon(self.opts, self.options) response = rc.execute_call_v2("post", API_URL, json=payload, headers=headers, proxies=rc.get_proxies()) if response.status_code == 200: success = True else: success = False response_json = response.json() results = rp.done(success, response_json) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as err: yield FunctionError(err)
def create_app(self, values): """ Creating an app with the provided values. :param values: Values to be passed to the REST call. :return: """ if values is None: raise ValueError("To create an app proper values are needed") oauth_authorization_headers = { "accept": "application/json", "Content-Type": "application/json", "charset": "utf-8" } self._add_authentication_headers(oauth_authorization_headers) rc = RequestsCommon(self.opts, self.options) app_status = {} response = rc.execute_call_v2('POST', self.base_url + self.CF_ALL_APPS, headers=oauth_authorization_headers, json=values) if response.status_code == 201: # return status code for update log.info("Successful creation ") app_status = response.json() app_status["success"] = True else: app_status["success"] = False app_status["details"] = "Couldn't create." app_status["last_updated"] = None log.error("Error while creating cf application.") log.error(response.json()) log.debug(response) return app_status
def get_app_instances(self, guid, *args, **kwargs): """ Gets instances' information for the app. :param guid: String Application to get the instances data for. :return: Information about all the app instances. """ oauth_authorization_headers = { "accept": "application/json", "Content-Type": "application/json", "charset": "utf-8" } self._add_authentication_headers(oauth_authorization_headers) rc = RequestsCommon(self.opts, self.options) app_status = {} response = rc.execute_call_v2('GET', self.base_url + self.CF_APP_INSTANCES.format(guid), headers=oauth_authorization_headers) if response.status_code == 200: # return status code for update log.info("Got instance information for {}".format(guid)) app_status = response.json() app_status["success"] = True else: app_status["success"] = False app_status["details"] = "Couldn't get instances for {}.".format( guid) app_status["last_updated"] = None log.error( "Error getting instance information for {}.".format(guid)) log.debug(response) return app_status
def selftest_function(opts): """ Simple test to confirm access to Cisco AMP for endpoint API connectivity. """ options = opts.get(SECTION_NAME, {}) try: url = '/'.join((options['url'], 'events?customerKey={}')) url = url.format(options['api_token']) test_data = { "alertTime": "2013-02-08T11:14:26.0Z", "deviceId": "ba6a59f4-e692-4724-ba36-c28132c761de", "deviceVersion": "13.7a", "dstDomain": "internetbadguys.com", "dstUrl": "http://internetbadguys.com/a-bad-url", "eventTime": "2013-02-08T09:30:26.0Z", "protocolVersion": options.get('protocol_version'), "providerName": options.get('provider_name') } rc = RequestsCommon(opts, options) content, msg = rc.execute_call_v2("post", url, json=test_data, verify=False, headers=HEADERS, callback=callback) return {"state": "failure" if msg else "success", "reason": msg} except Exception as e: return {"state": "failure", "reason": e}
def _event_function(self, event, *args, **kwargs): """Function: This is a function implementation that uses the Cisco API to post a Malware event""" try: rp = ResultPayload(SECTION_NAME, **kwargs) url = '/'.join((self.options['url'], 'events?customerKey={}')) url = url.format(self.apikey) self.log.debug(url) data, cisco_dstdomain = self.createdataobject(kwargs) rc = RequestsCommon(self.opts, self.options) content, msg = rc.execute_call_v2("post", url, json=data, verify=False, headers=HEADERS, callback=callback) if msg: yield StatusMessage(msg) else: yield StatusMessage( u"Add Domain for '{}' was successful".format( cisco_dstdomain)) results = rp.done(False if msg else True, None if msg else content, msg) # backward compatibility results['value'] = None if msg else content # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as err: self.log.error(err) yield FunctionError(err)
def selftest_function(opts): """ Placeholder for selftest function. An example use would be to test package api connectivity. Suggested return values are be unimplemented, success, or failure. """ # Getting the Config file parameters. options = opts.get("fn_spamhaus_query", {}) wqs_url = options.get('spamhaus_wqs_url') + "{}/{}" dqs_key = options.get('spamhaus_dqs_key') # Header data header_data = {'Authorization': 'Bearer {}'.format(dqs_key)} requestcommon_object = RequestsCommon(function_opts=options) proxies_data = requestcommon_object.get_proxies() try: response_json = requestcommon_object.execute_call( 'GET', wqs_url.format('AUTHBL', '127.0.0.2'), headers=header_data, proxies=proxies_data, callback=spamhaus_call_error) return {"state": "Success"} except Exception as err_msg: log.info(err_msg) return {"state": "Failed"}
def get_app_info(self, guid, *args, **kwargs): """ Extract JSON information for the application with given guid. :param guid: String GUID for the app to extract information for :return: """ oauth_authorization_headers = { "accept": "application/json", "content-type": "application/json", "charset": "utf-8" } self._add_authentication_headers(oauth_authorization_headers) rc = RequestsCommon(self.opts, self.options) response = rc.execute_call_v2('GET', self.base_url + self.CF_APP_INFO.format(guid), headers=oauth_authorization_headers) if response.status_code == 200: apps_data = response.json() else: log.error("Error while getting CF application information.") log.debug(response) apps_data = {"status": response.status_code} return apps_data
def create(self, host, username=None, password=None, token=None, cafile=None, opts=None, function_opts=None): """ Create headers used for REST Api calls :param host: qradar host :param username: qradar user login :param password: qradar password :param token: Use token or username/password to auth :param cafile: :param opts: app.config options :param function_opts: function parameters from app.config :return: """ self.headers = {'Accept': 'application/json'} if username and password: self.qradar_auth = base64.b64encode( (username + ':' + password).encode('ascii')) self.headers['Authorization'] = b"Basic " + self.qradar_auth elif token: self.qradar_token = token self.headers["SEC"] = self.qradar_token if host.startswith("http"): self.api_url = "{}/api/".format(host) else: self.api_url = "https://{}/api/".format(host) self.cafile = cafile self.rc = RequestsCommon(opts, function_opts)
def selftest_function(opts): """ Placeholder for selftest function. An example use would be to test package api connectivity. Suggested return values are be unimplemented, success, or failure. """ options = opts.get("fn_slack", {}) # validate input validate_fields(['api_token'], options) # configuration specific slack parameters api_token = options['api_token'] state, reason = "", "" try: # get proxies if they exist rc = RequestsCommon(opts=opts, function_opts=options) # Initialize SlackClient slack_utils = SlackUtils(api_token, proxies=rc.get_proxies()) api_test_results = slack_utils.api_test() if api_test_results.get("ok"): state = "success" else: state = "failure" reason = api_test_results.get("error", "") except Exception as ex: state = "failure" reason = str(ex) result = {"state": state, "reason": reason} log.info(result) return result
def get_job_template_by_project(opts, options, filter_by_project, template_pattern): """ get job templates, optionally based on project name :param opts: app.config file :param options: app.config section just for this integration :param filter_by_project: name of project to search for, may contain wildcards :param template_pattern: filter list of templates by wildcards :return: list of templates by project """ url = "/".join((clean_url(options.get('url')), TOWER_API_BASE, LIST_URL)) basic_auth, cafile = get_common_request_items(options) rc = RequestsCommon(opts, options) next_url = "/".join((TOWER_API_BASE, LIST_URL)) result_templates = [] while next_url: url = "/".join((clean_url(clean_url(options.get('url'))), next_url)) results = rc.execute_call_v2("get", url, auth=basic_auth, verify=cafile) json_results = results.json() if filter_by_project: project_templates = project_pattern_match(json_results['results'], filter_by_project) result_templates.extend(template_pattern_match(project_templates, template_pattern)) else: result_templates.extend(template_pattern_match(json_results['results'], template_pattern)) # get next paged set of results next_url = json_results['next'] return result_templates
def get_job_template_by_name(opts, options, filter_by_name): """ get job templates, optionally based on template name :param opts: app.config file :param options: app.config section just for this integration :param filter_by_name: name of template to search for :return: found template or None """ basic_auth, cafile = get_common_request_items(options) rc = RequestsCommon(opts, options) next_url = "/".join((TOWER_API_BASE, LIST_URL)) # continue as long as paged results exist while next_url: url = "/".join((clean_url(options.get('url')), next_url)) results = rc.execute_call_v2("get", url, auth=basic_auth, verify=cafile) json_results = results.json() if filter_by_name: for template in json_results['results']: # template names are case sensitive if template['name'] == filter_by_name.strip(): return template # get next paged set of results next_url = json_results['next'] return None
def selftest_function(opts): """ Test package api connectivity. Return success or failure based in status code """ options = opts.get("fn_pulsedive", {}) log.info("key: %s, url: %s", options["pulsedive_api_key"], options["pulsedive_api_url"]) # form the url request api_url = "{}/search.php?".format(options["pulsedive_api_url"]) # set generic params for indicator pulsedive_data = {"type": all, "risk": all} rc = RequestsCommon(opts, options) # initialize state, reason = "", "" try: resp = rc.execute_call_v2("get", url=api_url, params=pulsedive_data) # Check the results if resp.status_code == 200: state = "success" else: state = "failure" reason = resp.error except Exception as err: state = "failure" reason = str(err) result = {"state": state, "reason": reason} log.info(result) return result
def get_app_guids(self, application_names): """ Gets the guids for the list of application names provided :param application_names: list List of names that guid need to be found for :return: Dict - key: application name, value: guid """ oauth_authorization_headers = { "accept": "application/json", "content-type": "application/x-www-form-urlencoded", "charset": "utf-8" } self._add_authentication_headers(oauth_authorization_headers) rc = RequestsCommon(self.opts, self.options) result = {} response = rc.execute_call_v2('GET', self.base_url + self.CF_ALL_APPS, headers=oauth_authorization_headers) if response.status_code == 200: app_resources = response.json()["resources"] for resource in app_resources: res_app_name = resource["entity"]["name"] guid = resource["metadata"]["guid"] if res_app_name in application_names: result[res_app_name] = guid # if all the apps have been identified, no need to keep looping if len(result.keys()) == len(application_names): break else: raise ValueError("Error while getting CF applications metadata") return result
def __init__(self, opts, options): self.rc = RequestsCommon(opts, options) self.api_key = options.get("phishai_api_key") self.timeout_seconds = int( options.get("timeout_seconds", DEFAULT_TIMEOUT)) self.headers = {'Authorization': self.api_key} self.cafile = options.get('cafile') self.bundle = os.path.expanduser(self.cafile) if self.cafile else False
def test_timeout_v2(self): URL = "/".join((TestFunctionRequests.URL_TEST_HTTP_STATUS_CODES, "200?sleep=30000")) rc = RequestsCommon(None, None) with self.assertRaises(IntegrationError): resp = rc.execute_call_v2("get", URL, timeout=2)
def sitereview(self, url, value): payload = {"url": value, "captcha":""} rc = RequestsCommon(self.opts, self.options) result = rc.execute_call('post', url, payload=payload, headers=HEADERS, resp_type='text') dict_to_str = json.dumps(xmltodict.parse(result)) return json.loads(dict_to_str)
def test_basicauth_v2(self): URL = "/".join( (TestFunctionRequests.URL_TEST_HTTP_VERBS, "basic-auth")) basicauth = ("postman", "password") rc = RequestsCommon(None, None) resp = rc.execute_call_v2("get", URL, auth=basicauth) self.assertTrue(resp.json().get("authenticated"))
def test_statuscode_v2(self): URL = TestFunctionRequests.URL_TEST_HTTP_STATUS_CODES rc = RequestsCommon(None, None) resp = rc.execute_call_v2("get", "/".join((URL, "200"))) with self.assertRaises(IntegrationError): resp = rc.execute_call_v2("get", "/".join((URL, "400")))
def test_v2_resp_type(self): IPIFY = TestFunctionRequests.URL_TEST_DATA_RESULTS rc = RequestsCommon(None, None) # R E S P O N S E Object response = rc.execute_call_v2("get", "{}?format=json".format(IPIFY)) self.assertTrue(isinstance(response, requests.models.Response))
def _ansible_tower_list_job_templates_function(self, event, *args, **kwargs): """Function: Run an ansible module outside of the job template""" try: validate_fields(("url"), self.options) # validate key app.config settings # Get the function parameters: tower_hosts = kwargs.get("tower_hosts") # text tower_module = self.get_select_param( kwargs.get("tower_module")) # text tower_arguments = kwargs.get("tower_arguments") # text tower_inventory = kwargs.get("tower_inventory") # number tower_credential = kwargs.get("tower_credential") # number log = logging.getLogger(__name__) log.info("tower_hosts: %s", tower_hosts) log.info("tower_module: %s", tower_module) log.info("tower_arguments: %s", tower_arguments) log.info("tower_inventory: %s", tower_inventory) log.info("tower_credential: %s", tower_credential) result = ResultPayload(SECTION_HDR, **kwargs) rc = RequestsCommon(self.opts, self.options) # PUT YOUR FUNCTION IMPLEMENTATION CODE HERE yield StatusMessage("starting...") url = "/".join( (clean_url(self.options['url']), TOWER_API_BASE, AD_HOC_URL)) # common basic_auth, cafile = get_common_request_items(self.options) arguments = { "module_name": tower_module, "limit": tower_hosts, "module_args": tower_arguments, "inventory": tower_inventory, "credential": tower_credential } rc = RequestsCommon(self.opts, self.options) results = rc.execute_call_v2("post", url, auth=basic_auth, json=arguments, headers=JSON_HEADERS, verify=cafile) result_payload = result.done(True, results.json()) yield StatusMessage("done...") # Produce a FunctionResult with the results yield FunctionResult(result_payload) except Exception: yield FunctionError()
def test_statuscode_callback_v2(self): URL = "/".join( (TestFunctionRequests.URL_TEST_HTTP_STATUS_CODES, "300")) def callback(resp): if resp.status_code != 300: raise ValueError(resp.status_code) rc = RequestsCommon(None, None) resp = rc.execute_call_v2("get", URL, callback=callback)
def _teams_post_message_function(self, event, *args, **kwargs): """Function: Post a message to a Microsoft Teams channel""" try: validate_fields(['incident_id', 'teams_channel', 'teams_payload'], kwargs) # Get the function parameters: incident_id = kwargs.get("incident_id") # number task_id = kwargs.get("task_id") # number teams_channel = kwargs.get("teams_channel") # text teams_payload = kwargs.get("teams_payload") # text teams_mrkdown = kwargs.get("teams_mrkdown", False) # boolean log = logging.getLogger(__name__) log.info("incident_id: %s", incident_id) log.info("task_id: %s", task_id) log.info("teams_channel: %s", teams_channel) log.info("teams_payload: %s", teams_payload) log.info("teams_mrkdown: %s", teams_mrkdown) yield StatusMessage("starting...") result_payload = ResultPayload(SECTION_NAME, **kwargs) # get the webhook for the channel webhook = self.options.get(teams_channel) if not webhook: raise ValueError("Unable to find channel: %s in app.config", teams_channel) request_common = RequestsCommon(self.opts) payload_json = json.loads( teams_payload.replace("\n", "").replace("None", "null")) proxies = request_common.get_proxies() card = pymsteams.connectorcard( webhook, http_proxy=proxies['http'] if proxies else None, https_proxy=proxies['https'] if proxies else None, http_timeout=TIMEOUT) self.build_conversation(card, incident_id, task_id, payload_json, teams_mrkdown) card.send() yield StatusMessage("done...") results = result_payload.done(True, None) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception: yield FunctionError()
def selftest_function(opts): """ Placeholder for selftest function. An example use would be to test package api connectivity. Suggested return values are be unimplemented, success, or failure. """ # Read option from app.config options = opts.get("urlscanio", {}) # check that an API key and URLs are provided validate_fields(['urlscanio_api_key', 'urlscanio_report_url', 'urlscanio_screenshot_url'], options) # set API key and report URL urlscanio_api_key = options['urlscanio_api_key'] urlscanio_report_url = options['urlscanio_report_url'] # Construct the parameters to send to urlscan.io urlscanio_headers = {'Content-Type': 'application/json', 'API-Key': urlscanio_api_key} urlscanio_data = { "url": "https://www.ibm.com" } # Set URL to make a request to urlscanio_scan_url = "{}/scan/".format(urlscanio_report_url) # Initialize RequestsCommon req_common = RequestsCommon() # Attempt the request state, reason = "", "" try: resp = req_common.execute_call_v2("POST", urlscanio_scan_url, headers=urlscanio_headers, data=json.dumps(urlscanio_data)) if resp.status_code == 200: state = "success" reason = "Connected to urlscanio API" else: state = "failure" reason = "Test failed with http status code {}".format(resp.status_code) except Exception as e: state = "failure" reason = str(e) result = { "state": state, "reason": reason } log.info(result) return result
def test_headers_v2(self): # G E T with headers headers = { "Content-type": "application/json; charset=UTF-8", "my-sample-header": "my header" } URL = "/".join((TestFunctionRequests.URL_TEST_HTTP_VERBS, "headers")) rc = RequestsCommon() json_result = rc.execute_call_v2("get", URL, headers=headers) self.assertEqual(json_result.json()['headers'].get("my-sample-header"), "my header")