def propose_from_flows(current, flow_ids, labels, approvers, name=None): """Launch a hunt from the flows on these labels.""" hunt_id = utils.new_hunt_id() now = time.time() also_upload_files = False result = agent.Flow.from_keywords( name=name or hunt_id, flow_id=hunt_id, created_time=now, creator=utils.get_current_username(current), ticket=dict( location=dict( __type__="HTTPLocation", base=utils.route_api('/control/hunt_ticket'), path_prefix=hunt_id, )), ) db = current.db seen = set() for flow_id in flow_ids: row = db(db.flows.flow_id == flow_id).select().first() if row: for action in row.flow.actions: if action.rekall_session.get("also_upload_files"): also_upload_files = True if isinstance(action, actions.PluginAction): action = actions.PluginAction.from_keywords( plugin=action.plugin, rekall_session=action.rekall_session, collection=dict( __type__="JSONCollection", location=dict( __type__="BlobUploader", base=html.URL( c="api", f="control", args=['upload'], host=True), path_template=( "collection/%s/{part}" % hunt_id), )), args=action.args) # Dedupe identical canned actions. key = action.to_json() if key in seen: continue seen.add(key) result.actions.append(action) if also_upload_files: result.file_upload = dict( __type__="FileUploadLocation", flow_id=hunt_id, base=html.URL(c="api", f='control/file_upload', host=True)) # Add the hunt to the hunts table. db.hunts.insert( hunt_id=hunt_id, creator=result.creator, flow=result, labels=labels, state="Proposed", timestamp=now) for approver in approvers: users.send_notifications( current, approver, "HUNT_APPROVAL_REQUEST", dict( hunt_id=hunt_id, user=utils.get_current_username(current))) audit.log(current, "HuntProposal", hunt_id=hunt_id) return {}
def LOAD(c=None, f='index', args=None, vars=None, extension=None, target=None, ajax=False, ajax_trap=False, url=None, user_signature=False, timeout=None, times=1, content='loading...', post_vars=Storage(), **attr): """ LOADs a component into the action's document Args: c(str): controller f(str): function args(tuple or list): arguments vars(dict): vars extension(str): extension target(str): id of the target ajax(bool): True to enable AJAX behaviour ajax_trap(bool): True if `ajax` is set to `True`, traps both links and forms "inside" the target url(str): overrides `c`, `f`, `args` and `vars` user_signature(bool): adds hmac signature to all links with a key that is different for every user timeout(int): in milliseconds, specifies the time to wait before starting the request or the frequency if times is greater than 1 or "infinity" times(integer or str): how many times the component will be requested "infinity" or "continuous" are accepted to reload indefinitely the component """ if args is None: args = [] vars = Storage(vars or {}) target = target or 'c' + str(random.random())[2:] attr['_id'] = target request = current.request if '.' in f: f, extension = f.rsplit('.', 1) if url or ajax: url = url or html.URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) # timing options if isinstance(times, basestring): if times.upper() in ("INFINITY", "CONTINUOUS"): times = "Infinity" else: # FIXME: should be a ValueError raise TypeError("Unsupported times argument %s" % times) elif isinstance(times, int): if times <= 0: raise ValueError( "Times argument must be greater than zero, 'Infinity' or None" ) else: # NOTE: why do not use ValueError only? raise TypeError("Unsupported times argument type %s" % type(times)) if timeout is not None: if not isinstance(timeout, integer_types): raise ValueError("Timeout argument must be an integer or None") elif timeout <= 0: raise ValueError( "Timeout argument must be greater than zero or None") statement = "$.web2py.component('%s','%s', %s, %s);" \ % (url, target, timeout, times) attr['_data-w2p_timeout'] = timeout attr['_data-w2p_times'] = times else: statement = "$.web2py.component('%s','%s');" % (url, target) attr['_data-w2p_remote'] = url if target is not None: return html.DIV(content, **attr) else: if not isinstance(args, (list, tuple)): args = [args] c = c or request.controller other_request = Storage(request) other_request['env'] = Storage(request.env) other_request.controller = c other_request.function = f other_request.extension = extension or request.extension other_request.args = List(args) other_request.vars = vars other_request.get_vars = vars other_request.post_vars = post_vars other_response = Response() other_request.env.path_info = '/' + \ '/'.join([request.application, c, f] + [str(a) for a in other_request.args]) other_request.env.query_string = \ vars and html.URL(vars=vars).split('?')[1] or '' other_request.env.http_web2py_component_location = \ request.env.path_info other_request.cid = target other_request.env.http_web2py_component_element = target other_request.restful = types.MethodType(request.restful.__func__, other_request) # A bit nasty but needed to use LOAD on action decorates with @request.restful() other_response.view = '%s/%s.%s' % (c, f, other_request.extension) other_environment = copy.copy(current.globalenv) # FIXME: NASTY other_response._view_environment = other_environment other_response.generic_patterns = \ copy.copy(current.response.generic_patterns) other_environment['request'] = other_request other_environment['response'] = other_response ## some magic here because current are thread-locals original_request, current.request = current.request, other_request original_response, current.response = current.response, other_response page = run_controller_in(c, f, other_environment) if isinstance(page, dict): other_response._vars = page other_response._view_environment.update(page) page = run_view_in(other_response._view_environment) current.request, current.response = original_request, original_response js = None if ajax_trap: link = html.URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) js = "$.web2py.trap_form('%s','%s');" % (link, target) script = js and html.SCRIPT(js, _type="text/javascript") or '' return html.TAG[''](html.DIV(html.XML(page), **attr), script)
def launch_canned_flows(current, client_id, name): db = current.db row = db(db.canned_flows.name == name).select().first() if not row: raise ValueError("There is no canned flow with name '%s'" % name) also_upload_files = False flow_id = utils.new_flow_id() for action in row.flow.actions: if action.rekall_session.get("also_upload_files"): also_upload_files = True action.collection = dict(__type__="JSONCollection", location=dict( __type__="BlobUploader", base=html.URL(c="api", f="control", args=['upload'], host=True), path_template=("collection/%s/{part}" % flow_id), )) flow = agent.Flow.from_keywords( name=name, flow_id=flow_id, created_time=time.time(), ticket=dict(location=dict( __type__="HTTPLocation", base=utils.route_api('/control/ticket'), path_prefix=flow_id, )), actions=row.flow.actions, ) if also_upload_files: flow.file_upload = dict(__type__="FileUploadLocation", flow_id=flow_id, base=html.URL(c="api", f='control/file_upload', host=True)) db.flows.insert( flow_id=flow_id, client_id=client_id, status=agent.FlowStatus.from_keywords(timestamp=time.time(), client_id=client_id, flow_id=flow_id, status="Pending"), creator=utils.get_current_username(current), flow=flow, timestamp=flow.created_time.timestamp, ) firebase.notify_client(client_id) audit.log(current, "FlowLaunchCanned", flow_id=flow_id, canned_flow=name, client_id=client_id) return {}
def __call__(self, c=None, f='index', args=None, vars=None, extension=None, target=None, ajax=False, ajax_trap=False, url=None, user_signature=False, content='loading...', **attr): if args is None: args = [] vars = Storage(vars or {}) target = target or 'c' + str(random.random())[2:] attr['_id'] = target request = current.request if '.' in f: f, extension = f.rsplit('.', 1) if url or ajax: url = url or html.URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) script = html.SCRIPT('$.web2py.component("%s","%s")' % (url, target), _type="text/javascript") return html.TAG[''](script, html.DIV(content, **attr)) else: if not isinstance(args, (list, tuple)): args = [args] c = c or request.controller other_request = Storage(request) other_request['env'] = Storage(request.env) other_request.controller = c other_request.function = f other_request.extension = extension or request.extension other_request.args = List(args) other_request.vars = vars other_request.get_vars = vars other_request.post_vars = Storage() other_response = Response() other_request.env.path_info = '/' + \ '/'.join([request.application, c, f] + [str(a) for a in other_request.args]) other_request.env.query_string = \ vars and html.URL(vars=vars).split('?')[1] or '' other_request.env.http_web2py_component_location = \ request.env.path_info other_request.cid = target other_request.env.http_web2py_component_element = target other_response.view = '%s/%s.%s' % (c, f, other_request.extension) other_environment = copy.copy(self.environment) other_response._view_environment = other_environment other_response.generic_patterns = \ copy.copy(current.response.generic_patterns) other_environment['request'] = other_request other_environment['response'] = other_response ## some magic here because current are thread-locals original_request, current.request = current.request, other_request original_response, current.response = current.response, other_response page = run_controller_in(c, f, other_environment) if isinstance(page, dict): other_response._vars = page other_response._view_environment.update(page) page = run_view_in(other_response._view_environment) current.request, current.response = original_request, original_response js = None if ajax_trap: link = html.URL(request.application, c, f, r=request, args=args, vars=vars, extension=extension, user_signature=user_signature) js = "$.web2py.trap_form('%s','%s');" % (link, target) script = js and html.SCRIPT(js, _type="text/javascript") or '' return html.TAG[''](html.DIV(html.XML(page), **attr), script)
def launch_plugin_flow(current, client_id, rekall_session, plugin, plugin_arg): """Launch the flow on the client.""" db = current.db flow_id = utils.new_flow_id() spec = plugins.RekallAPI(current).get(plugin) if not spec: raise ValueError("Unknown plugin") # Validate both plugin args and session args. validate_plugin_args(plugin_arg, spec) validate_plugin_args(rekall_session, plugins.SessionAPI(current)) flow = agent.Flow.from_keywords( flow_id=flow_id, created_time=time.time(), ticket=dict(location=dict( __type__="HTTPLocation", base=utils.route_api('/control/ticket'), path_prefix=flow_id, )), actions=[ dict(__type__="PluginAction", plugin=plugin, args=plugin_arg, rekall_session=rekall_session, collection=dict(__type__="JSONCollection", location=dict( __type__="BlobUploader", base=html.URL(c="api", f="control", args=['upload'], host=True), path_template=("collection/%s/{part}" % flow_id), ))) ]) if rekall_session.get("also_upload_files"): flow.file_upload = dict(__type__="FileUploadLocation", flow_id=flow_id, base=html.URL(c="api", f='control/file_upload', host=True)) db.flows.insert( flow_id=flow_id, client_id=client_id, status=agent.FlowStatus.from_keywords(timestamp=time.time(), client_id=client_id, flow_id=flow_id, status="Pending"), creator=utils.get_current_username(current), flow=flow, timestamp=flow.created_time.timestamp, ) firebase.notify_client(client_id) audit.log(current, "FlowLaunchPlugin", flow_id=flow_id, plugin=plugin, client_id=client_id) return {}