コード例 #1
0
def deleteFlowLink(conductID, fromFlowID, toFlowID):
    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:
        fromFlow = [x for x in conductObj.flow if x["flowID"] == fromFlowID]
        if len(fromFlow) > 0:
            fromFlow = fromFlow[0]
            for nextflow in fromFlow["next"]:
                if nextflow["flowID"] == toFlowID:
                    if db.fieldACLAccess(api.g["sessionData"], conductObj.acl,
                                         "flow", "delete"):
                        conductObj.flow[conductObj.flow.index(
                            fromFlow)]["next"].remove(nextflow)
                        conductObj.update(["flow"])
                        return {}, 200
                    return {}, 403
        return {}, 404
    else:
        return {}, 403
コード例 #2
0
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
コード例 #3
0
 def getModelSchema(modelName):
     class_ = loadModel(modelName)
     if class_:
         access, accessIDs, adminBypass = db.ACLAccess(
             api.g["sessionData"], class_.acl, "read")
         if access:
             return class_.classObject()().api_getSchema(), 200
         else:
             return {}, 403
     else:
         return {}, 404
コード例 #4
0
def setConductFlowLogic(conductID, flowID, nextflowID):
    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:
        flow = [x for x in conductObj.flow if x["flowID"] == flowID]
        data = json.loads(api.request.data)
        if len(flow) == 1:
            flow = flow[0]
            if "next" in flow:
                found = False
                for key, nextFlow in enumerate(flow["next"]):
                    if type(nextFlow) is str:
                        if nextFlow == nextflowID:
                            nextFlow = {"flowID": nextflowID}
                            found = True
                    elif type(nextFlow) is dict:
                        if nextFlow["flowID"] == nextflowID:
                            found = True
                    if found:
                        if "true" == data["logic"].lower():
                            flow["next"][key] = {
                                "flowID": nextFlow["flowID"],
                                "logic": True
                            }
                        elif "false" == data["logic"].lower():
                            flow["next"][key] = {
                                "flowID": nextFlow["flowID"],
                                "logic": False
                            }
                        elif data["logic"].startswith("if"):
                            flow["next"][key] = {
                                "flowID": nextFlow["flowID"],
                                "logic": data["logic"]
                            }
                        else:
                            try:
                                flow["next"][key] = {
                                    "flowID": nextFlow["flowID"],
                                    "logic": int(data["logic"])
                                }
                            except ValueError:
                                return {}, 403
                        conductObj.update(["flow"],
                                          sessionData=api.g["sessionData"])
                        return {}, 200
    else:
        return {}, 403
    return {}, 404
コード例 #5
0
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
コード例 #6
0
 def deleteModelObject(modelName, objectID):
     class_ = loadModel(modelName)
     if class_:
         _class = class_.classObject()().getAsClass(
             api.g["sessionData"], id=objectID)
         if len(_class) == 1:
             _class = _class[0]
             access, accessIDs, adminBypass = db.ACLAccess(
                 api.g["sessionData"], _class.acl, "delete")
             if access:
                 result = class_.classObject()().api_delete(id=objectID)
                 if result["result"]:
                     return result, 200
             else:
                 return {}, 403
     return {}, 404
コード例 #7
0
 def newModelObject(modelName):
     class_ = loadModel(modelName)
     if class_:
         access, accessIDs, adminBypass = db.ACLAccess(
             api.g["sessionData"], class_.acl, "read")
         if access:
             class_ = class_.classObject()()
             if api.g["sessionData"]:
                 class_.acl = {
                     "ids": [{
                         "accessID":
                         api.g["sessionData"]["primaryGroup"],
                         "read":
                         True,
                         "write":
                         True,
                         "delete":
                         True
                     }]
                 }
             newObjectID = super(type(class_), class_).new().inserted_id
             return {"result": {"_id": str(newObjectID)}}, 200
     return {}, 404
コード例 #8
0
def newFlowLink(conductID, fromFlowID, toFlowID):
    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:
        fromFlow = [x for x in conductObj.flow if x["flowID"] == fromFlowID][0]
        toFlow = [x for x in conductObj.flow if x["flowID"] == toFlowID][0]
        nextFlows = [x for x in fromFlow["next"] if x["flowID"] == toFlowID]
        if len(nextFlows) == 0:
            if toFlow["type"] != "trigger":
                fromFlow["next"].append({"flowID": toFlowID, "logic": True})
                conductObj.update(["flow"], sessionData=api.g["sessionData"])
                return {}, 201
            else:
                return {}, 403
        return {}, 200
    else:
        return {}, 403
コード例 #9
0
def deleteFlow(conductID, flowID):
    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:
        flow = [x for x in conductObj.flow if x["flowID"] == flowID]
        if len(flow) == 1:
            flow = flow[0]
            for flowItemsValue in conductObj.flow:
                for nextflowValue in flowItemsValue["next"]:
                    if nextflowValue["flowID"] == flowID:
                        conductObj.flow[conductObj.flow.index(
                            flowItemsValue)]["next"].remove(nextflowValue)
            conductObj.flow.remove(flow)
            conductObj.update(["flow"], sessionData=api.g["sessionData"])
        return {}, 200
    else:
        return {}, 404
コード例 #10
0
def dropExistingObject(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)
        if data["action"] == "drop":
            newFlowID = str(uuid.uuid4())
            flow = {
                "flowID": newFlowID,
                "type": data["flowType"],
                "{0}{1}".format(data["flowType"], "ID"): data["_id"],
                "next": []
            }
            modelFlowObject = None
            if data["flowType"] == "trigger":
                modelFlowObject = trigger._trigger().getAsClass(
                    api.g["sessionData"], id=data["_id"])[0]
            elif data["flowType"] == "action":
                modelFlowObject = action._action().getAsClass(
                    api.g["sessionData"], id=data["_id"])[0]
            if modelFlowObject:
                name = modelFlowObject.name
            else:
                name = flow["flowID"]

            webui._modelUI().new(conductID, conductObj.acl, flow["flowID"],
                                 data["x"], data["y"], name)
            conductObj.flow.append(flow)
            conductObj.update(["flow"], sessionData=api.g["sessionData"])
            return {}, 201
    return {}, 404
コード例 #11
0
        def updateModelObject(modelName, objectID):
            class_ = loadModel(modelName)
            if class_:
                data = json.loads(api.request.data)
                if data["action"] == "update":
                    updateItemsList = []
                    changeLog = {}
                    data = data["data"]
                    _class = class_.classObject()().getAsClass(
                        api.g["sessionData"], id=objectID)
                    if len(_class) == 1:
                        _class = _class[0]
                        # 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:
                                    # _id is a protected mongodb object and cant be updated
                                    if dataKey != "_id":
                                        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:
                                                # Convert string object to bool
                                                if type(dataValue) is str:
                                                    if dataValue.lower(
                                                    ) == "true":
                                                        dataValue = True
                                                    else:
                                                        dataValue = False
                                                if _class.setAttribute(
                                                        dataKey,
                                                        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)
                                # 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 {}, 200
                        else:
                            return {}, 403
            return {}, 404
コード例 #12
0
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
コード例 #13
0
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
コード例 #14
0
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