Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
sys.exit(errno)
setup(
name='rc-cts',
setup_requires=['setuptools_scm'],
use_scm_version={"root": "../", "relative_to": __file__},
url='https://www.resilientsystems.com/',
license='MIT',
author='IBM Resilient',
install_requires=[
'resilient_circuits>=28.0.0',
'rc-webserver'
],
tests_require=["pytest",
"pytest_resilient_circuits"],
cmdclass={"test": PyTest},
author_email='support@resilientsystems.com',
description="Resilient Circuits Custom Threat Service",
long_description="Resilient Circuits Custom Threat Service Component",
packages=find_packages(),
include_package_data=True,
platforms='any',
classifiers=[
'Programming Language :: Python',
],
entry_points={
# Register the component with resilient_circuits
"resilient.circuits.components": ["ThreatService = rc_cts.components.threat_webservice:CustomThreatService",
"SearcherExample = rc_cts.components.searcher_example:SearcherExample"],
"resilient.circuits.configsection": ["gen_config = rc_cts.components.threat_webservice:config_section_data"]
}
def __init__(self, request_id=None, name="unknown", artifact=None, channel=searcher_channel()):
super(ThreatServiceLookupEvent, self).__init__(name=name)
self.channels = (channel,)
self.request_id = request_id
self.cts_channel = channel
self.artifact = artifact
self.name = name
# because this is used in 'resutil threatservicetest'
# and we want to return an immediate (not async) response
return response_object
# If we already have a completed query for this key, return it immmediately
request_data = self.cache.get(cache_key)
if request_data and request_data.get("complete"):
response_object["hits"] = request_data.get("hits", [])
return response_object
response.status = 303
response_object["retry_secs"] = self.first_retry_secs
# Add the request to the cache, then notify searchers that there's a new request
self.cache.setdefault(cache_key, {"id": request_id, "artifact": body, "hits": [], "complete": False})
evt = ThreatServiceLookupEvent(request_id=request_id, name=artifact_type, artifact=body, channel=cts_channel)
self.async_helper.fire(evt, HELPER_CHANNEL)
return response_object
def _lookup_complete(self, event, *args, **kwargs):
"""
A lookup event was completed
"""
if not isinstance(event.parent, ThreatServiceLookupEvent):
return
results = event.parent.value.getValue()
artifact = event.parent.artifact
cts_channel = event.parent.cts_channel
request_id = event.parent.request_id
LOG.info("Lookup complete: %s, %s", event.parent, results)
# Depending on how many components handled this lookup event,
# the results can be a single value (dict), or an array, or None,
# or an exception, or a tuple (type, exception, traceback)
hits = []
complete = True
if isinstance(results, list):
for result in results:
if result:
self.later_retry_secs = int(self.options.get(CONFIG_LATER_RETRY_SECS.key, CONFIG_LATER_RETRY_SECS.default)) or 60
# Size of the request cache
self.cache_size = int(self.options.get(CONFIG_CACHE_SIZE.key, CONFIG_CACHE_SIZE.default))
# TTL of the request cache (millis before we give up on a request lookup)
self.cache_ttl = int(self.options.get(CONFIG_CACHE_TTL.key, CONFIG_CACHE_TTL.default))
# Limit to the number of queries we'll answer for unfinished searchers (count before giving up on them)
self.max_retries = int(self.options.get(CONFIG_MAX_RETRIES.key, CONFIG_MAX_RETRIES.default))
# IDs and their results are maintained in a cache so that we can set
# an upper bound on the number of in-progress and recent lookups.
self.cache = TTLCache(maxsize=self.cache_size, ttl=self.cache_ttl)
# Helper component does event dispatch work
self.async_helper = CustomThreatServiceHelper(self)
(self.helper_thread, self.bridge) = self.async_helper.start()
urls = ["{0}/{1}".format(self.channel, e) for e in self.events()]
LOG.info("Web handler for %s", ", ".join(urls))
def __init__(self, maincomponent):
super(CustomThreatServiceHelper, self).__init__()
self.maincomponent = maincomponent
def __init__(self, opts):
super(CustomThreatService, self).__init__(**_make_args(opts))
# Configurable options
self.options = opts.get(CONFIG_SECTION, {})
# Do we support "file-content" artifacts? Default is no.
# TODO add implementation support to parse the file content
self.support_upload_file = bool(self.options.get(CONFIG_UPLOAD_FILE.key, CONFIG_UPLOAD_FILE.default))
# Default time that this service will tell Resilient to retry
self.first_retry_secs = int(self.options.get(CONFIG_FIRST_RETRY_SECS.key, CONFIG_FIRST_RETRY_SECS.default)) or 5
self.later_retry_secs = int(self.options.get(CONFIG_LATER_RETRY_SECS.key, CONFIG_LATER_RETRY_SECS.default)) or 60
# Size of the request cache
self.cache_size = int(self.options.get(CONFIG_CACHE_SIZE.key, CONFIG_CACHE_SIZE.default))
# TTL of the request cache (millis before we give up on a request lookup)
self.cache_ttl = int(self.options.get(CONFIG_CACHE_TTL.key, CONFIG_CACHE_TTL.default))
# the results can be a single value (dict), or an array, or None,
# or an exception, or a tuple (type, exception, traceback)
hits = []
complete = True
if isinstance(results, list):
for result in results:
if result:
if isinstance(result, (tuple, ThreatLookupIncompleteException)):
LOG.info("Retry later!")
complete = False
elif isinstance(result, (tuple, Exception)):
LOG.error("No hits due to exception")
else:
hits.append(result)
elif results:
if isinstance(results, (tuple, ThreatLookupIncompleteException)):
LOG.info("Retry later!")
complete = False
elif isinstance(results, (tuple, Exception)):
LOG.error("No hits due to exception")
else:
hits.append(results)
# Store the result and mark as complete (or not)
cache_key = (cts_channel, request_id)
self.cache[cache_key] = {"id": request_id, "artifact": artifact, "hits": hits, "complete": complete}
def __init__(self, *args, **kwargs):
super(MyResilientMock,self).__init__(*args, **kwargs)
self.incident = {
"create_date": 1485448269000,
"name": "test",
"id": 2314
}
def __init__(self, *props):
super(Hit, self).__init__(props=[prop for prop in list(props) if prop["value"] is not None])