def getConductFlowProperties(conductID, flowID): conductObj = conduct._conduct().query(api.g["sessionData"], id=conductID)["results"] if len(conductObj) == 1: conductObj = conductObj[0] else: return {}, 404 flow = [x for x in conductObj["flow"] if x["flowID"] == flowID] if len(flow) == 1: flow = flow[0] formData = None if "type" in flow: if flow["type"] == "trigger": triggerObj = trigger._trigger().query( api.g["sessionData"], id=flow["triggerID"])["results"] if len(triggerObj) == 1: triggerObj = triggerObj[0] else: return {}, 404 _class = model._model().getAsClass(api.g["sessionData"], id=triggerObj["classID"]) if len(_class) == 1: _class = _class[0].classObject() else: return {}, 404 triggerObj = _class().getAsClass(api.g["sessionData"], id=triggerObj["_id"]) if len(triggerObj) == 1: triggerObj = triggerObj[0] else: return {}, 404 if "_properties" in dir(triggerObj): formData = triggerObj._properties().generate(triggerObj) else: formData = webui._properties().generate(triggerObj) elif flow["type"] == "action": actionObj = action._action().query( api.g["sessionData"], id=flow["actionID"])["results"] if len(actionObj) == 1: actionObj = actionObj[0] else: return {}, 404 _class = model._model().getAsClass(api.g["sessionData"], id=actionObj["classID"]) if len(_class) == 1: _class = _class[0].classObject() actionObj = _class().getAsClass(api.g["sessionData"], id=actionObj["_id"]) if len(actionObj) == 1: actionObj = actionObj[0] else: return {}, 404 if "_properties" in dir(actionObj): formData = actionObj._properties().generate(actionObj) else: formData = webui._properties().generate(actionObj) return {"formData": formData}, 200
def getObjectFromCode(codeFunction): functionName = codeFunction.split("(")[0] args = regexCommor.split(codeFunction[(len(functionName) + 1):-1]) classObject = model._model().getAsClass( query={"name": functionName})[0].classObject() classObject.enabled = True members = [ attr for attr in dir(classObject) if not callable(getattr(classObject, attr)) and not "__" in attr and attr ] for arg in args: key = arg.split("=")[0] value = helpers.typeCast(arg[len(key) + 1:]) for member in members: if key == member: if type(getattr(classObject, member)) == type(value): setattr(classObject, member, value) break elif type(getattr(classObject, member)) == str: setattr(classObject, member, str(value)) break elif type(getattr(classObject, member)) == float and type(value) == int: setattr(classObject, member, float(value)) break elif type(getattr(classObject, member)) == int and type(value) == float: setattr(classObject, member, int(value)) break return classObject()
def getConductPropertyTypes(): result = [] models = model._model().query(api.g["sessionData"], query={ "$and": [{ "$or": [{ "name": "action" }, { "classType": "_action" }, { "classType": "_trigger" }, { "name": "trigger" }] }, { "$or": [{ "hidden": False }, { "hidden": { "$exists": False } }] }] }, sort=[("name", 1)])["results"] for modelItem in models: result.append({"_id": modelItem["_id"], "name": modelItem["name"]}) return {"results": result}, 200
def newFlow(conductID): conductObj = conduct._conduct().getAsClass(api.g["sessionData"], id=conductID) if len(conductObj) == 1: conductObj = conductObj[0] else: return {}, 404 access, accessIDs, adminBypass = db.ACLAccess(api.g["sessionData"], conductObj.acl, "write") if access: data = json.loads(api.request.data) # Get new UUID store within current conduct flow and return UUID newFlowID = str(uuid.uuid4()) flow = {"flowID": newFlowID, "next": []} # Creating new object of model type _class = model._model().getAsClass(api.g["sessionData"], id=data["classID"]) if _class: subtype = _class[0].name _class = _class[0].classObject() newFlowObjectID = _class().new(flow["flowID"]).inserted_id # Working out by bruteforce which type this is ( try and load it by parent class and check for error) - get on trigger if it does not exist will return None modelFlowObjectType = "action" if len(trigger._trigger().getAsClass(api.g["sessionData"], id=newFlowObjectID)) > 0: modelFlowObjectType = "trigger" modelFlowObject = _class().getAsClass(api.g["sessionData"], id=newFlowObjectID) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] else: return {}, 404 modelFlowObject.acl = { "ids": [{ "accessID": api.g["sessionData"]["primaryGroup"], "read": True, "write": True, "delete": True }] } modelFlowObject.update(["acl"], sessionData=api.g["sessionData"]) flow["type"] = modelFlowObjectType if subtype != "action" and subtype != "trigger": flow["subtype"] = subtype flow["{0}{1}".format(modelFlowObjectType, "ID")] = str(newFlowObjectID) # Adding UI position for cloned object webui._modelUI().new(conductID, conductObj.acl, flow["flowID"], data["x"], data["y"], modelFlowObject.name) # Appending new object to conduct conductObj.flow.append(flow) conductObj.update(["flow"], sessionData=api.g["sessionData"]) return {}, 201 else: return {}, 403 return {}, 404
def newConduct(): data = json.loads(api.request.data) if data["action"] == "new": class_ = model._model().getAsClass(api.g["sessionData"], query={"name": "conduct"}) if class_: class_ = class_[0] access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], class_.acl, "read") if access: conductID = str(conduct._conduct().new( data["name"]).inserted_id) return {"result": True, "conductID": conductID}, 201 return {}, 403
def failedTrigger(workerID, failureType, msg=""): triggers = trigger._trigger().query( query={"name": "failedTriggers"})["results"] if len(triggers) > 0: triggerWorkers = trigger._trigger().query( query={"workerID": workerID})["results"] if len(triggerWorkers) > 0: trigger_ = triggers[0] worker_ = triggerWorkers[0] _class = model._model().getAsClass(id=trigger_["classID"]) if len(_class) == 1: _class = _class[0].classObject() if _class: triggerClass = _class().getAsClass(id=trigger_["_id"]) if len(triggerClass) == 1: triggerClass = triggerClass[0] if triggerClass: events = [{ "type": "systemEvent", "eventType": failureType, "workerID": workerID, "triggerID": worker_["_id"], "triggerName": worker_["name"], "msg": msg }] audit._audit().add( "Error", failureType, { "type": "systemEvent", "eventType": failureType, "workerID": workerID, "triggerID": worker_["_id"], "triggerName": worker_["name"], "msg": msg }) # Notify conducts that have a trigger failure trigger within flow workers.workers.new("trigger:{0}".format(trigger_["_id"]), triggerClass.notify, (events, ))
def getClassByName(match, sessionData): return model._model().query(query={"className": match})["results"]
def systemInstall(): # Adding ENC secure systemSecure = _system().query(query={"name": "secure"})["results"] if len(systemSecure) < 1: systemSecure = _system().new("secure").inserted_id systemSecure = _system().get(systemSecure) systemSecure.data = {"string": secrets.token_hex(32)} systemSecure.update(["data"]) # Installing model if that DB is not installed if "model" not in db.list_collection_names(): logging.debug("DB Collection 'model' Not Found : Creating...") # Creating default model required so other models can be registered logging.debug("Registering default model class...") m = model._model() m.name = "model" m.classID = None m.acl = { "ids": [{ "accessID": "0", "delete": True, "read": True, "write": True }] } m.className = "_model" m.classType = "_document" m.location = "core.model" m.insert_one(m.parse()) if "conducts" not in db.list_collection_names(): logging.debug("DB Collection conducts Not Found : Creating...") model.registerModel("conduct", "_conduct", "_document", "core.models.conduct") if "triggers" not in db.list_collection_names(): logging.debug("DB Collection action Not Found : Creating...") model.registerModel("trigger", "_trigger", "_document", "core.models.trigger") if "actions" not in db.list_collection_names(): logging.debug("DB Collection action Not Found : Creating...") model.registerModel("action", "_action", "_document", "core.models.action") if "webui" not in db.list_collection_names(): logging.debug("DB Collection webui Not Found : Creating...") model.registerModel("flowData", "_flowData", "_document", "core.models.webui") if "modelUI" not in db.list_collection_names(): logging.debug("DB Collection modelUI Not Found : Creating...") model.registerModel("modelUI", "_modelUI", "_document", "core.models.webui") if "clusterMembers" not in db.list_collection_names(): logging.debug("DB Collection clusterMembers Not Found : Creating...") model.registerModel("clusterMember", "_clusterMember", "_document", "core.cluster") # System - failedTriggers from core.models import trigger triggers = trigger._trigger().query( query={"name": "failedTriggers"})["results"] if len(triggers) < 1: from system.models import trigger as systemTrigger model.registerModel("failedTriggers", "_failedTriggers", "_trigger", "system.models.trigger") if not systemTrigger._failedTriggers().new("failedTriggers"): logging.debug("Unable to register failedTriggers", -1) return False temp = model._model().getAsClass(query={"name": "failedTriggers"}) if len(temp) == 1: temp = temp[0] temp.hidden = True temp.update(["hidden"]) # System - Actions from core.models import action actions = action._action().query(query={"name": "resetTrigger"})["results"] if len(actions) < 1: from system.models import action as systemAction model.registerModel("resetTrigger", "_resetTrigger", "_action", "system.models.action") if not systemAction._resetTrigger().new("resetTrigger"): logging.debug("Unable to register resetTrigger", -1) return False temp = model._model().getAsClass(query={"name": "resetTrigger"}) if len(temp) == 1: temp = temp[0] temp.hidden = True temp.update(["hidden"]) from core import auth # Adding models for user and groups model.registerModel("user", "_user", "_document", "core.auth") model.registerModel("group", "_group", "_document", "core.auth") # Adding default admin group adminGroup = auth._group().getAsClass(query={"name": "admin"}) if len(adminGroup) == 0: adminGroup = auth._group().new("admin") adminGroup = auth._group().getAsClass(query={"name": "admin"}) adminGroup = adminGroup[0] # Adding default root user rootUser = auth._user().getAsClass(query={"username": "******"}) if len(rootUser) == 0: rootPass = randomString(30) rootUser = auth._user().new("root", "root", rootPass) rootUser = auth._user().getAsClass(query={"username": "******"}) logging.debug("Root user created! Password is: {}".format(rootPass), -1) rootUser = rootUser[0] # Adding root to group if rootUser._id not in adminGroup.members: adminGroup.members.append(rootUser._id) adminGroup.update(["members"]) # Adding primary group for root user rootUser.primaryGroup = adminGroup._id rootUser.update(["primaryGroup"]) return True
def getClassObject(classID, sessionData): return model._model().getAsClass(sessionData, id=classID)
def saveConduct(conductID): data = json.loads(api.request.data) conductObj = conduct._conduct().getAsClass(api.g["sessionData"], id=conductID) if len(conductObj) == 1: conductObj = conductObj[0] else: return {}, 404 if data["action"] == "new": access, accessIDs, adminBypass = db.ACLAccess(api.g["sessionData"], conductObj.acl, "write") if access: # Get new UUID store within current conduct flow and return UUID newFlowID = str(uuid.uuid4()) flow = {"flowID": newFlowID, "next": []} conductObj.flow.append(flow) conductObj.update(["flow"], sessionData=api.g["sessionData"]) return {"result": True, "flowID": newFlowID}, 201 else: return {}, 403 # Clone an existing object into a new object if data["action"] == "clone": access, accessIDs, adminBypass = db.ACLAccess(api.g["sessionData"], conductObj.acl, "write") if access: flow = [ x for x in conductObj.flow if x["flowID"] == data["operatorId"] ] if len(flow) == 1: flow = flow[0] data = json.loads(api.request.data) modelFlowObject = None # Check if the modelType and object are unchanged if "type" in flow: if flow["type"] == "trigger": modelFlowObject = trigger._trigger().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "trigger" if flow["type"] == "action": modelFlowObject = action._action().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "action" # Was it possible to load an existing object if modelFlowObject: # Create new flowItem newFlowID = str(uuid.uuid4()) flow = { "flowID": newFlowID, "type": flow["type"], "next": [] } # New object required _class = model._model().getAsClass( api.g["sessionData"], id=modelFlowObject.classID) if _class: _class = _class[0].classObject() # Bug exists as name value is not requried by db class but is for core models - this could result in an error if new model is added that does not accept name within new function override newFlowObjectID = _class().new( flow["flowID"]).inserted_id # Working out by bruteforce which type this is ( try and load it by parent class and check for error) - get on trigger if it does not exist will return None modelFlowObjectClone = _class().getAsClass( api.g["sessionData"], id=newFlowObjectID) if len(modelFlowObjectClone) == 1: modelFlowObjectClone = modelFlowObjectClone[0] else: return {}, 404 # Setting values in cloned object members = [ attr for attr in dir(modelFlowObject) if not callable(getattr(modelFlowObject, attr)) and not "__" in attr and attr ] dontCopy = ["_id", "name"] updateList = [] for member in members: if member not in dontCopy: setattr(modelFlowObjectClone, member, getattr(modelFlowObject, member)) updateList.append(member) modelFlowObjectClone.update( updateList, sessionData=api.g["sessionData"]) # Set conduct flow to correct type and objectID flow["{0}{1}".format(flow["type"], "ID")] = str(newFlowObjectID) conductObj.flow.append(flow) conductObj.update(["flow"], sessionData=api.g["sessionData"]) return {"result": True, "flowID": newFlowID}, 201 else: return {}, 403 # Add existing object to flow elif data["action"] == "existing": access, accessIDs, adminBypass = db.ACLAccess(api.g["sessionData"], conductObj.acl, "write") if access: newFlowID = str(uuid.uuid4()) flow = {"flowID": newFlowID, "next": []} if data["type"] == "trigger": flow["type"] = "trigger" flow["triggerID"] = data["triggerID"] elif data["type"] == "action": flow["type"] = "action" flow["actionID"] = data["actionID"] conductObj.flow.append(flow) conductObj.update(["flow"], sessionData=api.g["sessionData"]) return {"result": True, "flowID": newFlowID}, 201 else: return {}, 403 elif data["action"] == "save": access, accessIDs, adminBypass = db.ACLAccess(api.g["sessionData"], conductObj.acl, "write") if access: flowData = data["flowData"] newFlowData = {} flowPopList = [] for flow in flowData['links']: if flow != "{}>{}".format( flowData['links'][flow]['fromOperator'], flowData['links'][flow]['toOperator']): newFlowData["{}>{}".format( flowData['links'][flow]['fromOperator'], flowData['links'][flow] ['toOperator'])] = flowData['links'][flow] flowPopList.append(flow) if len(newFlowData) > 0: flowData['links'].update(newFlowData, sessionData=api.g["sessionData"]) for popItem in flowPopList: flowData['links'].pop(popItem) poplistOperator = [] poplistLink = [] for operatorID in flowData["operators"]: operatorFound = None for flow in conductObj.flow: flowID = flow["flowID"] if operatorID == flowID: operatorFound = flowID connections = [] for link in flowData["links"]: if flowData["links"][link][ "fromOperator"] == flowID: connections.append( flowData["links"][link]["toOperator"]) for connection in connections: foundFlow = False for index, nextFlowID in enumerate(conductObj.flow[ conductObj.flow.index(flow)]["next"]): if type(nextFlowID) is dict: if connection == nextFlowID["flowID"]: foundFlow = True conductObj.flow[conductObj.flow.index( flow)]["next"][index] = { "flowID": connection, "logic": nextFlowID["logic"] } else: if connection == nextFlowID: foundFlow = True conductObj.flow[conductObj.flow.index( flow)]["next"][index] = { "flowID": connection, "logic": True } if not foundFlow: conductObj.flow[conductObj.flow.index( flow)]["next"].append({ "flowID": connection, "logic": True }) notUpdatedPopList = [] for nextFlowID in conductObj.flow[ conductObj.flow.index(flow)]["next"]: if nextFlowID["flowID"] not in connections: notUpdatedPopList.append(nextFlowID) for notUpdatedPopItem in notUpdatedPopList: del conductObj.flow[conductObj.flow.index(flow)][ "next"][conductObj.flow[conductObj.flow.index( flow)]["next"].index(notUpdatedPopItem)] if not operatorFound: for link in flowData["links"]: if flowData["links"][link][ "toOperator"] == operatorID or flowData[ "links"][link][ "fromOperator"] == operatorID: poplistLink.append(link) poplistOperator.append(operatorID) # Checking to ensure every flow that exists is also still within the flowData i.e. it has not been deleted poplistFlow = [] for flow in conductObj.flow: flowID = flow["flowID"] if len([x for x in flowData["operators"] if x == flowID]) == 0: poplistFlow.append(flow) # Deleting any items that were found within flowData but not in the conduct flow for pop in poplistOperator: del flowData["operators"][pop] for pop in poplistLink: del flowData["links"][pop] for pop in poplistFlow: del conductObj.flow[conductObj.flow.index(pop)] # checking if conduct has been enabled or name changed if "conductName" in data: conductObj.name = data["conductName"] if "conductEnabled" in data: conductObj.enabled = data["conductEnabled"] if "conductACL" in data: try: conductObj.acl = json.loads(data["conductACL"]) except: pass # Updating all possible updated values conductObj.update(["flow", "name", "enabled", "acl"], sessionData=api.g["sessionData"]) existingFlow = webui._flowData().query( query={"conductID": conductID})["results"] if len(existingFlow) > 0: existingFlow = existingFlow[0] existingFlow = webui._flowData().load(existingFlow["_id"]) existingFlow.flowData = flowData existingFlow.update(["flowData"], sessionData=api.g["sessionData"]) else: webui._flowData().new(conductID, flowData) return {"result": True, "flowData": flowData}, 201 return {"result": True, "flowData": flowData}, 200 else: return {}, 403 return {"result": False}, 404
def setConductFlow(conductID, flowID): # List of attributes that are prevented from updating - this needs to be made more dynamic and part of class design unsafeUpdateList = [ "_id", "classID", "lastCheck", "lastRun", "lastResult", "workerID", "startCheck" ] conductObj = conduct._conduct().query(api.g["sessionData"], id=conductID)["results"] conductObj = conductObj[0] conductObj = conduct._conduct().getAsClass(api.g["sessionData"], id=conductObj["_id"]) if len(conductObj) == 1: conductObj = conductObj[0] else: return {}, 404 flow = [x for x in conductObj.flow if x["flowID"] == flowID] if len(flow) == 1: flow = flow[0] data = json.loads(api.request.data) modelFlowObject = None # Check if the modelType and object are unchanged if "type" in flow: if flow["type"] == "trigger": modelFlowObject = trigger._trigger().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "trigger" if flow["type"] == "action": modelFlowObject = action._action().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "action" # Was it possible to load an existing object if modelFlowObject: # Check that the object model is still the same if modelFlowObject.classID == data["newClassID"]: # Get flow object correct class _class = model._model().getAsClass( api.g["sessionData"], id=modelFlowObject.classID) if len(_class) == 1: _class = _class[0] _class = _class.classObject() else: return {}, 404 modelFlowObject = _class().getAsClass( api.g["sessionData"], id=modelFlowObject._id) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] else: return {}, 404 else: modelFlowObject = None # New object required if not modelFlowObject: _class = model._model().getAsClass(api.g["sessionData"], id=data["newClassID"]) if _class: _class = _class[0].classObject() # Bug exists as name value is not requried by db class but is for core models - this could result in an error if new model is added that does not accept name within new function override newFlowObjectID = _class().new(flow["flowID"]).inserted_id # Working out by bruteforce which type this is ( try and load it by parent class and check for error) - get on trigger if it does not exist will return None modelFlowObjectType = "action" if len(trigger._trigger().getAsClass(api.g["sessionData"], id=newFlowObjectID)) > 0: modelFlowObjectType = "trigger" modelFlowObject = _class().getAsClass(api.g["sessionData"], id=newFlowObjectID) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] else: return {}, 404 modelFlowObject.acl = { "ids": [{ "accessID": api.g["sessionData"]["primaryGroup"], "read": True, "write": True, "delete": True }] } modelFlowObject.update(["acl"]) # Set conduct flow to correct type and objectID flow["type"] = modelFlowObjectType flow["{0}{1}".format(modelFlowObjectType, "ID")] = str(newFlowObjectID) conductObj.update(["flow"], sessionData=api.g["sessionData"]) # Updating new or existing modeFlowObject if modelFlowObject: updateItemsList = [] changeLog = {} # Getting schema information so types can be set correctly class_ = model._model().getAsClass(api.g["sessionData"], id=modelFlowObject.classID) if class_: _class = modelFlowObject # Builds list of permitted ACL access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], _class.acl, "write") if access: for dataKey, dataValue in data.items(): fieldAccessPermitted = True # Checking if sessionData is permitted field level access if _class.acl and not adminBypass: fieldAccessPermitted = db.fieldACLAccess( api.g["sessionData"], _class.acl, dataKey, "write") if fieldAccessPermitted: # Change update database entry _id if dataKey not in unsafeUpdateList: if hasattr(_class, dataKey): changeLog[dataKey] = {} changeLog[dataKey][ "currentValue"] = getattr( _class, dataKey) if type(getattr(_class, dataKey)) is str: if dataValue: if _class.setAttribute( dataKey, str(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is int: try: if _class.setAttribute( dataKey, int(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) except ValueError: if _class.setAttribute( dataKey, 0, sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is float: try: if _class.setAttribute( dataKey, float(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) except ValueError: if _class.setAttribute( dataKey, 0, sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is bool: if _class.setAttribute( dataKey, bool(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr( _class, dataKey)) is dict or type( getattr(_class, dataKey)) is list: if dataValue: if _class.setAttribute( dataKey, json.loads(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) # Commit back to database if updateItemsList: _class.update(updateItemsList, sessionData=api.g["sessionData"]) # Adding audit record if "_id" in api.g["sessionData"]: audit._audit().add( "model", "update", { "_id": api.g["sessionData"]["_id"], "objects": helpers.unicodeEscapeDict(changeLog) }) else: audit._audit().add("model", "update", { "objects": helpers.unicodeEscapeDict(changeLog) }) return {"type": modelFlowObjectType}, 200 else: return {}, 403 return {}, 404
def run(self, data, persistentData, actionResult): now = int(time.time()) conductsCache = {} foundOccurrenceCache = {} # Finding occurrences that have expired their lull time foundOccurrences = occurrence._occurrence().query(query={ "lullTime": { "$lt": now }, "lullTimeExpired": { "$lt": 1 } })["results"] foundOccurrencesIDs = [] for foundOccurrence in foundOccurrences: # Adding IDs of found occurrences to the delete list as they are now cleared foundOccurrencesIDs.append(db.ObjectId(foundOccurrence["_id"])) # Notifiying clears if foundOccurrence["occurrenceFlowID"] not in foundOccurrenceCache: tempOccurrence = _occurrence().load( foundOccurrence["occurrenceActionID"]) foundOccurrenceCache[foundOccurrence["occurrenceFlowID"]] = { "triggerID": None, "conducts": [] } if tempOccurrence.enabled: conducts = conduct._conduct().query( query={ "flow.actionID": tempOccurrence._id, "flow.flowID": foundOccurrence["occurrenceFlowID"], "enabled": True })["results"] foundOccurrenceCache[foundOccurrence["occurrenceFlowID"]][ "exitCodeMode"] = { "actionID": tempOccurrence._id, "conducts": conducts } conducts = foundOccurrenceCache[foundOccurrence[ "occurrenceFlowID"]]["exitCodeMode"]["conducts"] data = conduct.dataTemplate() data["flowData"]["trigger_id"] = tempOccurrence._id data["flowData"]["clearOccurrence"] = True # If occurrence contains the orgnial data var and event then apply it to the data passsed to clear if "data" in foundOccurrence: data["flowData"]["event"] = foundOccurrence["data"]["event"] data["flowData"]["var"] = foundOccurrence["data"]["var"] for conduct_ in conducts: loadedConduct = None if conduct_["classID"] not in conductsCache: # Dynamic loading for classType model _class = model._model().get( conduct_["classID"]).classObject() if _class: loadedConduct = _class().load(conduct_["_id"]) conductsCache[conduct_["classID"]] = loadedConduct else: logging.debug( "Cannot locate occurrence by ID, occurrenceID='{0}'" .format(foundOccurrence["occurrenceFlowID"]), 6) else: loadedConduct = conductsCache[conduct_["classID"]] if loadedConduct: try: cache.globalCache.delete("occurrenceCacheMatch", foundOccurrence["match"]) eventStat = { "first": True, "current": 0, "total": 1, "last": True } tempData = conduct.copyData(data) tempData["flowData"]["eventStats"] = eventStat loadedConduct.triggerHandler( foundOccurrence["occurrenceFlowID"], tempData, flowIDType=True) except Exception as e: pass # Error handling is needed here # Deleting expired occurrences if len(foundOccurrencesIDs) > 0: foundOccurrences = occurrence._occurrence().api_delete( query={"_id": { "$in": foundOccurrencesIDs }}) logging.debug( "Occurrences cleared, result='{0}'".format(foundOccurrences), 7) activeOccurrences = occurrence._occurrence()._dbCollection.aggregate([{ "$project": { "triggerID": { "$toObjectId": '$triggerID' }, "lastLullCheck": 1, "lullTime": 1 } }, { "$lookup": { "from": "triggers", "localField": "triggerID", "foreignField": "_id", "as": "triggers" } }, { "$unwind": "$triggers" }, { "$match": { "lullTime": { "$lt": now }, "$expr": { "$gt": ["$triggers.lastCheck", "$lastLullCheck"] } } }]) updateOccurrenceIDs = [] for activeOccurrence in activeOccurrences: updateOccurrenceIDs.append(activeOccurrence["_id"]) # Increment all with expired lullTime if len(updateOccurrenceIDs) > 0: incrementedOccurrences = occurrence._occurrence().api_update( query={"_id": { "$in": updateOccurrenceIDs }}, update={ "$inc": { "lullTimeExpired": -1 }, "$set": { "lastLullCheck": int(time.time()) } }) logging.debug( "Occurrences incremented, result='{0}'".format( incrementedOccurrences), 7) actionResult["result"] = True actionResult["rc"] = 0 return actionResult
def updateFlow(conductID, flowID): conductObj = conduct._conduct().getAsClass(api.g["sessionData"], id=conductID) if len(conductObj) == 1: conductObj = conductObj[0] else: return {}, 404 flow = [x for x in conductObj.flow if x["flowID"] == flowID] if len(flow) == 1: flow = flow[0] data = json.loads(api.request.data) if data["action"] == "update": access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], conductObj.acl, "write") if access: if "x" in data and "y" in data: try: x = int(data["x"]) y = int(data["y"]) except: return {}, 403 flowUI = webui._modelUI().getAsClass(api.g["sessionData"], query={ "flowID": flow["flowID"], "conductID": conductID }) if len(flowUI) == 1: flowUI = flowUI[0] if "x" in data and "y" in data: flowUI.x = x flowUI.y = y flowUI.update(["x", "y"], sessionData=api.g["sessionData"]) if "title" in data: flowUI.title = data["title"] flowUI.update(["title"], sessionData=api.g["sessionData"]) return {}, 200 else: webui._modelUI().new(conductID, conductObj.acl, flow["flowID"], x, y) return {}, 201 elif data["action"] == "copy": access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], conductObj.acl, "write") if access: flow = [ x for x in conductObj.flow if x["flowID"] == data["operatorId"] ] if len(flow) == 1: flow = flow[0] newFlowID = str(uuid.uuid4()) newFlow = { "flowID": newFlowID, "type": flow["type"], "{0}{1}".format(flow["type"], "ID"): flow["{0}{1}".format(flow["type"], "ID")], "next": [] } flowUI = webui._modelUI().getAsClass(api.g["sessionData"], query={ "flowID": flow["flowID"], "conductID": conductID })[0] webui._modelUI().new(conductID, conductObj.acl, newFlow["flowID"], data["x"], data["y"], flowUI.title) conductObj.flow.append(newFlow) conductObj.update(["flow"], sessionData=api.g["sessionData"]) return {}, 201 elif data["action"] == "clone": access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], conductObj.acl, "write") if access: flow = [ x for x in conductObj.flow if x["flowID"] == data["operatorId"] ] if len(flow) == 1: flow = flow[0] data = json.loads(api.request.data) modelFlowObject = None # Check if the modelType and object are unchanged if "type" in flow: if flow["type"] == "trigger": modelFlowObject = trigger._trigger().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "trigger" if flow["type"] == "action": modelFlowObject = action._action().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "action" # Was it possible to load an existing object if modelFlowObject: # Create new flowItem newFlowID = str(uuid.uuid4()) flow = { "flowID": newFlowID, "type": flow["type"], "next": [] } # New object required _class = model._model().getAsClass( api.g["sessionData"], id=modelFlowObject.classID) if _class: _class = _class[0].classObject() # Bug exists as name value is not requried by db class but is for core models - this could result in an error if new model is added that does not accept name within new function override newFlowObjectID = _class().new( flow["flowID"]).inserted_id # Working out by bruteforce which type this is ( try and load it by parent class and check for error) - get on trigger if it does not exist will return None modelFlowObjectClone = _class().getAsClass( api.g["sessionData"], id=newFlowObjectID) if len(modelFlowObjectClone) == 1: modelFlowObjectClone = modelFlowObjectClone[ 0] else: return {}, 404 # Setting values in cloned object members = [ attr for attr in dir(modelFlowObject) if not callable( getattr(modelFlowObject, attr)) and not "__" in attr and attr ] dontCopy = ["_id", "name"] updateList = [] for member in members: if member not in dontCopy: setattr( modelFlowObjectClone, member, getattr(modelFlowObject, member)) updateList.append(member) modelFlowObjectClone.update( updateList, sessionData=api.g["sessionData"]) # Set conduct flow to correct type and objectID flow["{0}{1}".format( flow["type"], "ID")] = str(newFlowObjectID) conductObj.flow.append(flow) # Adding UI position for cloned object flowUI = webui._modelUI().getAsClass( api.g["sessionData"], query={ "flowID": flowID, "conductID": conductID })[0] webui._modelUI().new( conductID, conductObj.acl, flow["flowID"], data["x"], data["y"], "Copy - {0}".format(flowUI.title)) conductObj.update( ["flow"], sessionData=api.g["sessionData"]) return {"result": True}, 201 return {}, 404
def generateFlow(currentFlow, flowDict, triggers, actions): flowCode = "" processQueue = [] indentLevel = 0 logic = None while True: if currentFlow: obj = None if currentFlow["type"] == "trigger": for t in triggers: if flow["triggerID"] == t._id: obj = t break for nextFlow in currentFlow["next"]: processQueue.append({ "flowID": nextFlow["flowID"], "indentLevel": indentLevel + 1, "logic": nextFlow["logic"] }) elif currentFlow["type"] == "action": for a in actions: if currentFlow["actionID"] == a._id: obj = a break for nextFlow in currentFlow["next"]: processQueue.append({ "flowID": nextFlow["flowID"], "indentLevel": indentLevel + 1, "logic": nextFlow["logic"] }) if obj: classObj = _class = model._model().getAsClass( api.g["sessionData"], id=obj.classID) classObj = classObj[0] blacklist = [ "_id", "acl", "classID", "workerID", "startCheck", "nextCheck", "lastUpdateTime", "lastCheck" ] members = [ attr for attr in dir(obj) if not callable(getattr(obj, attr)) and not "__" in attr and attr ] params = [] for member in members: if member not in blacklist: value = getattr(obj, member) if type(value) == str: value = "\"{0}\"".format(value) params.append("{0}={1}".format(member, value)) if currentFlow["type"] == "action": flowCode += "\r\n{0}logic({1})->{2}({3})".format( ("\t" * indentLevel), logic, classObj.name, ",".join(params)) else: if len(flowCode) > 0: flowCode += "\r\n{0}{1}({2})".format( ("\t" * indentLevel), classObj.name, ",".join(params)) else: flowCode = "{0}({1})".format( classObj.name, ",".join(params)) if len(processQueue) == 0: break else: nextFlowID = processQueue[-1]["flowID"] indentLevel = processQueue[-1]["indentLevel"] logic = processQueue[-1]["logic"] processQueue.pop() if nextFlowID in flowDict: currentFlow = flowDict[nextFlowID] else: currentFlow = None return flowCode
def install(self): # Register models model.registerModel("occurrence", "_occurrence", "_action", "plugins.occurrence.models.action") model.registerModel("occurrence clean", "_occurrenceClean", "_action", "plugins.occurrence.models.action") model.registerModel("occurrenceUpdate", "_occurrenceUpdate", "_action", "plugins.occurrence.models.action") # Finding conduct foundConducts = conduct._conduct().query( query={"name": "occurrenceCore"})["results"] if len(foundConducts) == 0: # Install c = conduct._conduct().new("occurrenceCore") c = conduct._conduct().get(c.inserted_id) elif len(foundConducts) == 1: # Reinstall c = conduct._conduct().get(foundConducts[0]["_id"]) else: # Count invalid return False # Finding trigger foundTriggers = trigger._trigger().query( query={"name": "occurrenceCore"})["results"] if len(foundTriggers) == 0: # Install t = trigger._trigger().new("occurrenceCore") t = trigger._trigger().get(t.inserted_id) elif len(foundTriggers) == 1: # Reinstall t = trigger._trigger().get(foundTriggers[0]["_id"]) else: # Count invalid return False # Finding action foundActions = action._occurrenceClean().query( query={"name": "occurrenceCore"})["results"] if len(foundActions) == 0: # Install a = action._occurrenceClean().new("occurrenceCore") a = action._occurrenceClean().get(a.inserted_id) elif len(foundActions) == 1: # Reinstall a = action._occurrenceClean().get(foundActions[0]["_id"]) else: # Count invalid return False c.triggers = [t._id] flowTriggerID = str(uuid.uuid4()) flowActionID = str(uuid.uuid4()) c.flow = [{ "flowID": flowTriggerID, "type": "trigger", "triggerID": t._id, "next": [{ "flowID": flowActionID, "logic": True }] }, { "flowID": flowActionID, "type": "action", "actionID": a._id, "next": [] }] webui._modelUI().new( c._id, { "ids": [{ "accessID": "0", "delete": True, "read": True, "write": True }] }, flowTriggerID, 0, 0, "") webui._modelUI().new( c._id, { "ids": [{ "accessID": "0", "delete": True, "read": True, "write": True }] }, flowActionID, 100, 0, "") c.acl = { "ids": [{ "accessID": "0", "delete": True, "read": True, "write": True }] } c.enabled = True c.update(["triggers", "flow", "enabled", "acl"]) t.acl = { "ids": [{ "accessID": "0", "delete": True, "read": True, "write": True }] } t.schedule = "60-90s" t.enabled = True t.update(["schedule", "enabled", "acl"]) a.acl = { "ids": [{ "accessID": "0", "delete": True, "read": True, "write": True }] } a.enabled = True a.update(["enabled", "acl"]) # Hide Created Models temp = model._model().getAsClass(query={"name": "occurrence clean"}) if len(temp) == 1: temp = temp[0] temp.hidden = True temp.update(["hidden"]) return True