示例#1
0
 def test_deleteSL(self):
     createTablesBig()
     stdoutFile = pref.getNoCheck(
         pref.CONFIG_SCRIPT_LOG_PATH) + "STDOUT_test_script_name_3.log"
     stderrFile = pref.getNoCheck(
         pref.CONFIG_SCRIPT_LOG_PATH) + "STDERR_test_script_name_3.log"
     open(stdoutFile, "a")  # create files to be deleted
     open(stderrFile, "a")  # create files to be deleted
     existsBefore1 = path.exists(stdoutFile)
     existsBefore2 = path.exists(stderrFile)
     err = tosl.ScriptLogTable().delete(3)
     errExp = pref.getError(pref.ERROR_SUCCESS)
     err2, sl = tosl.ScriptLogTable.getByID(3)
     errExp2 = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR,
                             args=("getByID", "ScriptLog", 0, 11))
     existsAfter1 = path.exists(stdoutFile)
     existsAfter2 = path.exists(stderrFile)
     self.assertEqual(existsBefore1, True)
     self.assertEqual(existsBefore2, True)
     self.assertEqual(err, errExp)
     self.assertEqual(err2, errExp2)
     self.assertEqual(existsAfter1, False)
     self.assertEqual(existsAfter2, False)
     self.assertEqual(sl, None)
     open(stdoutFile, "a")  # recreate deleted files
     open(stderrFile, "a")
示例#2
0
def login(data: dict) -> str:
    '''
    This function is to handle the act of logging into the users account. 
    @param dict data, the dictonary of the users input data
    @return a json of the error code
    '''
    #makesure the prefs contain a username and password
    try:
        username = data[pref.getNoCheck(pref.LOGIN_USERNAME)]
        password = hashlib.sha256(data[pref.getNoCheck(pref.LOGIN_PASSWORD)].encode()).hexdigest()
    except:
        return jsonify(Error = pref.getError(pref.ERROR_ATTRIBUTE_NOT_FOUND).toJson())
    

    if " " in username or ";" in username:
        return jsonify(Error = pref.getError(pref.ERROR_USERNAME_INVALID).toJson())

    userID = tableLogin.UserTable.checkLogin(username=username, password=password)
    
    # ErrorCode = None
    if userID != -1:
        ErrorCode = pref.Success
        session["userID"] = userID
    else:
        ErrorCode = pref.getError(pref.ERROR_USER_AUTHENTICATION_ERROR, args=(username))
    
    
    return jsonify(
        Error = ErrorCode.toJson()
    )
示例#3
0
 def test_addEntrySL(self):
     createEmptyTables()
     # need user entry first for foreign key
     u = tou.UserTable().createEntry("rbroders",
                                     "hella_secure_hashed_password", True)
     err = tou.UserTable().add(u)  # uID will be 1
     # need script entry for foreign key
     s = tos.ScriptTable().createEntry("test_script_name",
                                       "test_script_name.sh", 1,
                                       "emptry script used for testing",
                                       False)
     err = tos.ScriptTable().add(s)
     # need computer entry for foreign key
     c = toc.ComputerTable().createEntry(
         1, "RachelsSurface", "Raquels Computer",
         "Rachel's wonderful awful computer", "rbroders",
         "idk how IPs are formatted ya yeet", False)
     err = toc.ComputerTable().add(c)
     # scriptLog entry
     sl = tosl.ScriptLogTable().createEntry(1, 1, 1, False)
     err = tosl.ScriptLogTable().add(sl)
     errExp = pref.getError(pref.ERROR_SUCCESS)
     # check stdout/stderr file creation
     outPath = pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH) + sl.stdoutFile
     errPath = pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH) + sl.stderrFile
     self.assertEqual(os.path.exists(outPath), True)
     self.assertEqual(os.path.exists(errPath), True)
     # check error and scriptlog ID
     self.assertEqual(err, errExp)
     self.assertEqual(sl.ID, 1)
示例#4
0
def apiRequest():
    '''
    API Request /api
    used for all operations between frontend and backend
      ie
        RUN_SCRIPT
        MANAGE_SCRIPT
        MANAGE_COMPUTERS
        MANAGE_SCRIPT_LOGS
        SCHEDULE_SCRIPT
        GET_FILE
    request:
      {
        op: <operation:string>
        data: <opData:dict>
      }
    return:
      {
        Error:
      }
    '''
    logger.info("api request: {}".format(request.json))
    # if not("userID" in session):
    #     session.pop("userID", None)

    #Makes sure user is logged in if not redirect to login
    userID = None
    try:
        userID = session[pref.getNoCheck(pref.REQ_VAR_USER_ID)]
    except:
        return redirect(pref.getNoCheck("/#/"))

    err = pref.Success

    #names of request vars
    bodyName = pref.getNoCheck(pref.REQ_VAR_BODY)
    dataName = pref.getNoCheck(pref.REQ_VAR_DATA)
    jsonOpName = pref.getNoCheck(pref.REQ_VAR_OP)

    try:
        opName = pref.CONFIG_OPERATIONS + ":" + request.json[bodyName][
            jsonOpName]
        data = request.json[bodyName][dataName]
    except:
        err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(request.json))
        logger.error(err)

    returnValue = None

    if (err == pref.Success):
        err, op = pref.get(opName)

    if (err == pref.Success):
        apiFtn = OPS[op]
        returnValue = apiFtn(data)
    else:
        logger.error(err)
        returnValue = jsonify(Error=err.toJson(), data={})
    return (returnValue, 200)
 def add(entry: ScriptLog):
     '''
     Takes a scriptLog object (which has not yet been added to the scriptLog SQL table), 
         adds it to the table and updates scriptLog object's ID (ID is automatically 
         generated using sqlite AUTOINCREMENT) 
     This function is meant to take a scriptLog object generated from a call to the 
         createEntry function.
     @param 
         entry - object of class ScriptLog
     @return 
         e - most recent error when executing function or Success if no error occurs
     '''
     ID = None
     command = """ INSERT INTO sl (id, scriptID, userID, compID, startTime, endTime, returnVal, errorCode, stdoutFile, stderrFile, asAdmin) VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"""
     data = entry.paramToList()
     e, ID = sqlFuncs.insert(command, data, "add", "ScriptLog")
     entry.ID = ID  # access ID through entry object after executing this function
     ######### create names/files for stdoutFile, stderrFile - {STDOUT/STDERR}_SCRIPT_ID.log #########
     # (1) Add names to entry object
     if (e == pref.getError(pref.ERROR_SUCCESS)):
         e, scriptName = tos.ScriptTable().getAttrByID(
             "name", entry.scriptID)
         if e == pref.getError(pref.ERROR_SUCCESS):
             entry.stdoutFile = "STDOUT_" + str(scriptName) + "_" + str(
                 ID
             ) + ".log"  # access stdoutFile through entry object after executing this function
             entry.stderrFile = "STDERR_" + str(scriptName) + "_" + str(
                 ID
             ) + ".log"  # access stderrFile through entry object after executing this function
             # (2) Write names to sql entry
             command2 = """UPDATE sl SET stdoutFile = \"""" + str(
                 entry.stdoutFile) + """\", stderrFile = \"""" + str(
                     entry.stderrFile) + """\" WHERE id = """ + str(
                         ID) + """;"""
             e = sqlFuncs.exeCommand(command2, "add", "ScriptLog")
             # (3) Create files
             if (e == pref.getError(pref.ERROR_SUCCESS)):
                 e = createFile(
                     e, pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH),
                     entry.stdoutFile)
                 if (e == pref.getError(pref.ERROR_SUCCESS)):
                     e = createFile(
                         e, pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH),
                         entry.stderrFile)
     if (
             e != pref.getError(pref.ERROR_SUCCESS)
     ):  # if any errors occured along the way, revert any potential changes (catch all)
         entry.stdoutFile = None
         entry.stderrFile = None
     return e  #FIXME - should actions be undone if any errors occur along the way *thinking* - for loop
    def test_setConfigFileComplex(self):
        err = pref.setConfigFile("tests/res/test2Conf.yaml")
        self.assertEqual(err.code, pref.Success.code)

        self.assertEqual("null", pref.getError(pref.ERROR_UNKNOWN))

        self.assertEqual("/test", pref.getNoCheck(pref.CONFIG_LOGIN_ENDPOINT))
示例#7
0
def getAllRows(command: str, commandName: str, tableName:type):
    '''
    Executes a select command for a single row in the SQL database. Requires no extra data and returns the selected row.
    @param 
        command - SQL command as a string
        commandName - name of the function calling exeCommand. Used for error creation.
        tableName - name of the table command is being executed. Used for error creation. In full word form i.e. script, not s.
    @return 
        row - tuple for row selected.
    '''
    e = pref.getError(pref.ERROR_SUCCESS)
    rows = None
    try: # attempt to create connection
        con = sqlite3.connect(pref.getNoCheck(pref.CONFIG_DB_PATH))
        con.execute('PRAGMA foreign_keys = 1') #enable foreign keys
        try: # attempt to do select command and get row
            cur = con.cursor()
            cur.execute(command)
            rows = cur.fetchall()
            cur.close()
        except Error as err: # select failed
            e = pref.getError(pref.ERROR_EXECUTE_SQLITE3_COMMAND, args=(commandName, tableName, err)) # return error with specific info
        con.commit()
        con.close()
    except Error as err: # connection creation failed
        e = pref.getError(pref.ERROR_CREATE_SQLITE3_CONNECTION, args = (command, tableName, err)) # return error with specific info
        
    return e, rows
示例#8
0
def exeCommand(command: str, commandName: str, tableName:type):
    '''
    Executes a command in the SQL database which requires no extra data passed to the call and expects no return.
    @param 
        command - SQL command as a string
        commandName - name of the function calling exeCommand. Used for error creation.
        tableName - name of the table command is being executed. Used for error creation. In full word form i.e. script, not s.
    @return 
        None.
    '''
    e = pref.getError(pref.ERROR_SUCCESS)
    try: # attempt to create connection
        con = sqlite3.connect(pref.getNoCheck(pref.CONFIG_DB_PATH))
        con.execute('PRAGMA foreign_keys = 1') #enable foreign keys
        try: # attempt to execute some command
            cur = con.cursor()
            cur.execute(command)
            con.commit()
        except Error as err: # command execution failed
            e = pref.getError(pref.ERROR_EXECUTE_SQLITE3_COMMAND, args=(commandName, tableName, err)) # return error with specific info
        con.close()
    except Error as err: # connection creation failed
        e = pref.getError(pref.ERROR_CREATE_SQLITE3_CONNECTION, args = (command, tableName, err)) # return error with specific info

    return e
    def delete(ID: int):
        '''
        Removes a scriptLog entry from the database based on it's ID. 
        Also removes the corresponding files (stdout/stderr) from directory.
        @param 
            ID: int - primary key of scriptLog
        @return 
            e - most recent error when executing function or Success if no error occurs
        '''
        e, stdoutFile = ScriptLogTable.getAttrByID("stdoutFile", ID)
        e, stderrFile = ScriptLogTable.getAttrByID("stderrFile", ID)
        if (e == pref.getError(pref.ERROR_SUCCESS)):
            command = """DELETE FROM sl WHERE ID = """ + str(ID) + """;"""
            e = sqlFuncs.exeCommand(command, "delete", "ScriptLog")
            if (
                    e == pref.getError(pref.ERROR_SUCCESS)
            ):  # If deleted from db successfully, remove corresponding stdout/stderr files
                path = pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH)
                try:
                    os.remove(path + stdoutFile)
                    os.remove(path + stderrFile)
                except OSError as err:
                    e = pref.getError(pref.ERROR_FILE_NOT_FOUND,
                                      args=(str(stdoutFile) + "/" +
                                            str(stderrFile)))

        return e
    def createEntry(name: str, fileName: str, author: int, desc: str, isAdmin: bool): 
        '''
        Creates a script object. Some parameters must be passed in, some will be calculated 
        in this function and some can only be filled when the script is added to the SQL 
        table (these parameters will be set to None until the script is added to the SQL table).
        @param 
            name: str - use defined name to identify file 
            fileName: str - identifying fileName
            author: int - primary key of user table to indicate which user created the script 
            desc: str - user defined script description
            isAdmin: bool - whether or not the script requires admin access to run
        @return 
            script - script object created
        '''
        script = None
        # id will be set when object is added to table
        id = None
        # set dtCreated
        dtCreated = dt.now()
        # set dtModified (will be same as dtCreated initially)
        dtModified = dtCreated
        # set size
        filePath = str(pref.getNoCheck(pref.CONFIG_SCRIPT_PATH)) + fileName
        try:
            fileStats = os.stat(filePath)
            fileSizeB = fileStats.st_size
        except OSError as err:
            fileSizeB = 0.0 # set size to zero script file does not exist

        # create script object
        script = Script(None, name, fileName, author, desc, dtCreated, dtModified, fileSizeB, isAdmin)

        return script 
示例#11
0
def mockApp() -> app.test_client_class:
    pref.setAttr(pref.CONFIG_SCRIPT_PATH, "tests/res/data/scripts/")
    pref.setAttr(pref.CONFIG_SCRIPT_LOG_PATH, "tests/res/data/scriptLogs/")

    c = app.test_client()
    with c.session_transaction() as sess:
        sess[pref.getNoCheck(pref.REQ_VAR_USER_ID)] = 1
    return c
示例#12
0
def manageComputers(data: dict) -> str:

    logger.info("Processing Manage Computer Request")

    #Get vars names
    tableName = pref.getNoCheck(pref.TABLE_COMPUTER)

    #Convert to general request
    jsonData = manageTable(tableName, data)

    return jsonData
示例#13
0
def manageScripts(data: dict) -> str:

    logger.info("Processing Manage Script Request")

    #Get vars names
    tableName = pref.getNoCheck(pref.TABLE_SCRIPT)

    #Convert to general request
    jsonData = manageTable(tableName, data)

    return jsonData
示例#14
0
def manageTable(tableName: str, data: dict):
    err = pref.Success
    opName = pref.getNoCheck(pref.REQ_VAR_FUNC_OP)
    op = None
    opDataName = pref.getNoCheck(pref.REQ_VAR_DATA)
    opData = None
    #gets data from dict
    try:
        opData = data[opDataName]
        op = data[opName]
    except:
        err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))
        logger.error(err)

    if (err == pref.Success):
        jsonData = tableReqHelpers.processRequest(tableName, op, opData)
    else:
        jsonData = jsonify(Error=err.toJson())

    return jsonData
示例#15
0
 def test_deleteS2(self):
     createTablesBig()
     open(
         pref.getNoCheck(pref.CONFIG_SCRIPT_PATH) + "sleepScript copy.sh",
         "a")  # create file to be deleted
     existsBefore = path.exists(
         pref.getNoCheck(pref.CONFIG_SCRIPT_PATH) + "sleepScript copy.sh")
     err = tos.ScriptTable().delete(4)
     errExp = pref.getError(pref.ERROR_SUCCESS)
     err2, s = tos.ScriptTable.getByID(4)
     errExp2 = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR,
                             args=("getByID", "Script", 0, 9))
     existsAfter = path.exists(
         pref.getNoCheck(pref.CONFIG_SCRIPT_PATH) + "sleepScript copy.sh")
     self.assertEqual(existsBefore, True)
     self.assertEqual(err, errExp)
     self.assertEqual(err2, errExp2)
     self.assertEqual(existsAfter, False)
     self.assertEqual(s, None)
     open(
         pref.getNoCheck(pref.CONFIG_SCRIPT_PATH) + "sleepScript copy.sh",
         "a")  # recreate deleted file
示例#16
0
def loginRequest():
    logger.info("login request")

    #names of request vars
    bodyName = pref.getNoCheck(pref.REQ_VAR_BODY)
    dataName = pref.getNoCheck(pref.REQ_VAR_DATA)
    jsonOpName = pref.getNoCheck(pref.REQ_VAR_OP)

    opName = pref.CONFIG_LOGIN_OPERATION + ":" + request.json[bodyName][
        jsonOpName]
    data = request.json[bodyName][dataName]

    returnValue = None

    err, op = pref.get(opName)
    if (err == pref.Success):
        loginFtn = LOGIN_OPS[op]
        returnValue = loginFtn(data)
    else:
        logger.error(err)
        returnValue = jsonify(Error=err.toJson(), data={})
    return (returnValue, 200)
示例#17
0
 def test_api_getall_scriptLogs(self):
     '''
 Tests get all for scriptLogs
 '''
     params = {
         pref.getNoCheck(pref.REQ_VAR_BODY): {
             pref.getNoCheck(pref.REQ_VAR_OP):
             pref.getAttrName(
                 pref.getNoCheck(pref.OPERATION_MANAGE_SCRIPT_LOGS)),
             pref.getNoCheck(pref.REQ_VAR_DATA): {
                 pref.getNoCheck(pref.REQ_VAR_FUNC_OP):
                 pref.getNoCheck(pref.TABLE_OP_GET_ALL),
                 pref.getNoCheck(pref.REQ_VAR_DATA): {}
             }
         }
     }
     rv = self.c.post('/api', json=params)
     self.assertEqual(rv.get_json()["Error"]["code"], 0)
示例#18
0
    def test_get_by_ID(self):
        '''
    Tests get by id for an object that exists
    '''
        params = {
            pref.getNoCheck(pref.REQ_VAR_BODY): {
                pref.getNoCheck(pref.REQ_VAR_OP):
                pref.getAttrName(pref.getNoCheck(
                    pref.OPERATION_MANAGE_SCRIPT)),
                pref.getNoCheck(pref.REQ_VAR_DATA): {
                    pref.getNoCheck(pref.REQ_VAR_FUNC_OP):
                    pref.getNoCheck(pref.TABLE_OP_GET_BY_ID),
                    pref.getNoCheck(pref.REQ_VAR_DATA): {
                        pref.getNoCheck(pref.REQ_VAR_ID): 1,
                    }
                }
            }
        }

        rv = self.c.post("/api", json=params)

        self.assertEqual(rv.get_json()["Error"]["code"], 0)
        self.assertEqual(rv.get_json()["entry"]["ID"], '1')
示例#19
0
    def test_get_by_ID_DNE(self):
        '''
    Tests get by id for an object that doesnt exist
    '''
        params = {
            pref.getNoCheck(pref.REQ_VAR_BODY): {
                pref.getNoCheck(pref.REQ_VAR_OP):
                pref.getAttrName(pref.getNoCheck(
                    pref.OPERATION_MANAGE_SCRIPT)),
                pref.getNoCheck(pref.REQ_VAR_DATA): {
                    pref.getNoCheck(pref.REQ_VAR_FUNC_OP):
                    pref.getNoCheck(pref.TABLE_OP_GET_BY_ID),
                    pref.getNoCheck(pref.REQ_VAR_DATA): {
                        pref.getNoCheck(pref.REQ_VAR_ID): 99,
                    }
                }
            }
        }

        rv = self.c.post("/api", json=params)

        self.assertEqual(
            rv.get_json()["Error"]["code"],
            pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR).code)
示例#20
0
def insert(command: str, data: tuple, commandName: str, tableName:type):
    '''
    Executes an insert command in the SQL database which requires extra data and returns the automatically generated primary key ID.
    @param 
        command - SQL command as a string
        data - tuple of data being inserted that is not NULL
        commandName - name of the function calling exeCommand. Used for error creation.
        tableName - name of the table command is being executed. Used for error creation. In full word form i.e. script, not s.
    @return 
        ret : int - ID assigned to inserted row
    '''
    e = pref.getError(pref.ERROR_SUCCESS)
    ret = None
    try: # attempt to create connection
        con = sqlite3.connect(pref.getNoCheck(pref.CONFIG_DB_PATH))
        con.execute('PRAGMA foreign_keys = 1') #enable foreign keys
        try: # attempt to execute insert command
            cur = con.cursor()
            cur.execute(command, data)
        except Error as err: # command execution failed
            e = pref.getError(pref.ERROR_EXECUTE_SQLITE3_COMMAND, args=(commandName, tableName, err)) # return error with specific info
        
        try: # attempt to get return data
            command2 = """SELECT last_insert_rowid();"""
            cur.execute(command2)
            row = cur.fetchone()
            if row != None:
                ret = row[0]
            cur.close()
        except Error as err: # return gathering failed
            e = pref.getError(pref.ERROR_EXECUTE_SQLITE3_COMMAND, args=(commandName, tableName, err)) # return error with specific info
        con.commit()
        con.close()  
    except Error as err: # connection creation failed
        e = pref.getError(pref.ERROR_CREATE_SQLITE3_CONNECTION, args = (command, tableName, err)) # return error with specific info        

    return e, ret
示例#21
0
    def test_login_request_success(self):
        '''
    Tests a login request with a valid login
    '''

        params = {
            pref.getNoCheck(pref.REQ_VAR_BODY): {
                pref.getNoCheck(pref.REQ_VAR_OP):
                pref.getAttrName(pref.getNoCheck(pref.LOGIN_LOGIN)),
                pref.getNoCheck(pref.REQ_VAR_DATA): {
                    pref.getNoCheck(pref.LOGIN_USERNAME): "unittest",
                    pref.getNoCheck(pref.LOGIN_PASSWORD): "unittest"
                }
            }
        }

        rv = self.c.post('/login', json=params)
        self.assertEqual(rv.get_json()["Error"]["code"], 0)
示例#22
0
    def test_api_runScript(self):
        '''
    Tests runScript from and endpoint perpective
    '''
        params = {
            pref.getNoCheck(pref.REQ_VAR_BODY): {
                pref.getNoCheck(pref.REQ_VAR_OP):
                pref.getNoCheck(pref.OPERATION_RUN_SCRIPT),
                pref.getNoCheck(pref.REQ_VAR_DATA): {
                    pref.getNoCheck(pref.REQ_VAR_SCRIPT_ID): 1,
                    pref.getNoCheck(pref.REQ_VAR_COMPUTER_ID): 1,
                }
            }
        }
        rv = self.c.post('/api', json=params)

        expected = {"Error": pref.Success.toJson(), "Id": 1}
        print(rv.get_json())
        self.assertEqual(rv.get_json(), expected)
示例#23
0
    def test_login_request_fail(self):
        '''
    Tests a login request with a invalid login due to invalid password
    '''

        params = {
            pref.getNoCheck(pref.REQ_VAR_BODY): {
                pref.getNoCheck(pref.REQ_VAR_OP):
                pref.getAttrName(pref.getNoCheck(pref.LOGIN_LOGIN)),
                pref.getNoCheck(pref.REQ_VAR_DATA): {
                    pref.getNoCheck(pref.LOGIN_USERNAME): "unittest",
                    pref.getNoCheck(pref.LOGIN_PASSWORD): "IncorrectPassword"
                }
            }
        }

        rv = self.c.post('/login', json=params)
        self.assertEqual(
            rv.get_json()["Error"]["code"],
            pref.getError(pref.ERROR_USER_AUTHENTICATION_ERROR).code)
def processRequest(tableName: pref.prefENUM, tableOP: pref.prefENUM,
                   data: dict):
    '''
  Completes a table request 
  @param tableName the name of the table from preferences ie pref.TABLE_COMPUTER, pref.TABLE_SCRIPT, pref.TABLE_SCRIPT_LOGS
  @param tableOp the operation of the script pref.TABLE_OP_GET_BY_ID, pref.TABLE_OP_ADD ....
  @param data request data from the tableOP
  @return jsonfiy value contiaining error and data
  '''
    #table classes dictionary linked to the preference value
    tableClasses = {
        pref.getNoCheck(pref.TABLE_SCRIPT): scriptTable.ScriptTable,
        pref.getNoCheck(pref.TABLE_SCRIPT_LOGS): scriptLogTable.ScriptLogTable,
        pref.getNoCheck(pref.TABLE_COMPUTER): computerTable.ComputerTable,
    }
    table = tableClasses[tableName]

    #Return value
    err = pref.Success
    returnVal = None

    #get file
    if (tableOP == pref.getNoCheck(pref.TABLE_OP_GET_FILE)):

        err = pref.Success

        #Gets id
        id = None
        Filetype = None
        FP = None
        try:
            id = data[pref.getNoCheck(pref.REQ_VAR_ID)]
            Filetype = data[pref.getNoCheck(pref.REQ_VAR_FILE_TYPE)]
            FP = data[pref.getNoCheck(pref.REQ_VAR_FP)]
        except:  #Invalid request
            err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))
            logger.error(err)

        #gets the element by id
        err, entry = table.getByID(id)

        if (err == pref.Success):
            #get file file
            if (Filetype == pref.getNoCheck(pref.REQ_VAR_FILE_STDOUT)):
                scriptPath = pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH)
                filename = scriptPath + entry.stdoutFile
            elif (Filetype == pref.getNoCheck(pref.REQ_VAR_FILE_STDERR)):
                scriptPath = pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH)
                filename = scriptPath + entry.stderrFile
            elif (Filetype == pref.getNoCheck(pref.REQ_VAR_FILE_SCRIPT)):
                scriptPath = pref.getNoCheck(pref.CONFIG_SCRIPT_PATH)
                filename = scriptPath + entry.fileName

            fp = open(filename, "r")
            fp.seek(FP, os.SEEK_SET)
            fileData = "".join(fp.readlines())
            newFP = fp.tell()

            returnVal = jsonify(Error=err.toJson(), entry=fileData, FP=newFP)

    #add to table
    elif (tableOP == pref.getNoCheck(pref.TABLE_OP_ADD)):

        err, entry = createObjFromReq(tableName, table, data)

        #Computer only used to add ssh key to computer
        if (err == pref.Success
                and tableName == pref.getNoCheck(pref.TABLE_COMPUTER)):
            try:
                username = data[pref.getNoCheck(pref.REQ_VAR_USERNAME)]
                password = data[pref.getNoCheck(pref.REQ_VAR_PASSWORD)]
                IP = data[pref.getNoCheck(pref.REQ_VAR_IP)]
            except:
                err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))
                logger.error(err)

            #Add ssh key to computer uer password and username
            if (err == pref.Success):
                err = ssh.sshConnection.addNewComputer(IP, username, password)

        #add entry to table
        id = -1
        if (err == pref.Success):
            err = table.add(entry)
            if (err == pref.Success):
                id = entry.ID
        #return value

        returnVal = jsonify(Error=err.toJson(), Id=id)

    #delete from table
    elif (tableOP == pref.getNoCheck(pref.TABLE_OP_DEL)):
        id = None
        try:
            id = data[pref.getNoCheck(pref.REQ_VAR_ID)]

        except:  #Invalid request
            err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))
            logger.error(err)

        #Delete from table
        if (err == pref.Success):
            err = table.delete(id)
        returnVal = jsonify(Error=err.toJson())
    #remove from table
    elif (tableOP == pref.getNoCheck(pref.TABLE_OP_GET_ALL)):
        err, entries = table.getAll()

        entriesJson = []
        for entry in entries:
            entriesJson.append(entry.toJson())

        returnVal = jsonify(Error=err.toJson(), entries=entriesJson)

    #Get By ID
    elif (tableOP == pref.getNoCheck(pref.TABLE_OP_GET_BY_ID)):
        id = None
        try:
            id = data[pref.getNoCheck(pref.REQ_VAR_ID)]
        except:
            err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))

        #Gets the entry by id
        if (err == pref.Success):
            err, entry = table.getByID(id)

        #Creates return request
        entryResponse = None
        if (err == pref.Success): entryResponse = entry.toJson()
        returnVal = jsonify(Error=err.toJson(), entry=entryResponse)

    elif (tableOP == pref.getNoCheck(pref.TABLE_OP_EDIT)):
        err, entry = createObjFromReq(tableName, table, data, isEdit=True)

        try:
            entry.ID = data[pref.getNoCheck(pref.REQ_VAR_ID)]
        except:
            err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))

        if (err == pref.Success):
            err, entry = table.editEntry(entry)

        #create return object
        returnVal = jsonify(Error=err.toJson(), entry=entry.toJson())

    else:  #This will never happen
        logger.warning("DIDN'T FIND TABLE REQUEST FAILED")
        err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))
        returnVal = jsonify(Error=err.toJson())

    return returnVal
def createObjFromReq(tableName: str,
                     table: tableOp.Table,
                     data: dict,
                     isEdit: bool = False) -> Tuple[pref.Error, tableOp.Entry]:
    '''
  creates a table object from a request data
  @param tableName the name of the table being use ie computer
  @param data tableData that the object will be created from
  @param isEdit only used for edit script to know if it should be overwriting a file or not
  @return newly created object
  '''
    entry = None
    err = pref.Success

    if (tableName == pref.getNoCheck(pref.TABLE_COMPUTER)):
        #computer table
        #vars
        userID = None
        nickName = None
        desc = None
        username = None
        IP = None
        asAdmin = None

        #run add computer script
        try:
            userID = session[pref.getNoCheck(pref.REQ_VAR_USER_ID)]
        except:
            err = pref.getError(pref.ERROR_NOT_LOGGED_IN)

        #Retrives data from request
        if (err == pref.Success):
            try:
                nickName = data[pref.getNoCheck(pref.REQ_VAR_NICK_NAME)]
                desc = data[pref.getNoCheck(pref.REQ_VAR_DESC)]
                username = data[pref.getNoCheck(pref.REQ_VAR_USERNAME)]
                IP = data[pref.getNoCheck(pref.REQ_VAR_IP)]
                asAdmin = data[pref.getNoCheck(pref.REQ_VAR_IS_ADMIN)]
            except:
                err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))

        #create computer
        if (err == pref.Success):
            entry = computerTable.ComputerTable.createEntry(
                userID, None, nickName, desc, username, IP, asAdmin)

    elif (tableName == pref.getNoCheck(pref.TABLE_SCRIPT)):
        #script table
        name = None
        filename = None
        desc = None
        isAdmin = None
        scriptData = None
        userID = None

        err = pref.Success

        try:
            userID = session[pref.getNoCheck(pref.REQ_VAR_USER_ID)]
        except:
            err = pref.getError(pref.ERROR_NOT_LOGGED_IN)

        if (err == pref.Success):
            try:
                name = data[pref.getNoCheck(pref.REQ_VAR_NICK_NAME)]
                desc = data[pref.getNoCheck(pref.REQ_VAR_DESC)]
                filename = data[pref.getNoCheck(pref.REQ_VAR_FILE_NAME)]
                scriptData = data[pref.getNoCheck(pref.REQ_VAR_SCRIPT_DATA)]
                isAdmin = data[pref.getNoCheck(pref.REQ_VAR_IS_ADMIN)]
            except:
                err = pref.getError(pref.ERROR_INVALID_REQUEST, args=(data))

        #create file in script folder. overwrite if it already exists (only for edit)
        try:
            scriptPath = pref.getNoCheck(pref.CONFIG_SCRIPT_PATH)

            #should it overwrite or be a new file
            writeMode = "x"
            if (isEdit): writeMode = "w"

            fp = open("{}{}".format(scriptPath, filename), writeMode)
            fp.write(scriptData)
        except:
            print("ere")
            err = pref.getError(pref.ERROR_CANT_CREATE_FILE, args=(name))

        #create computer
        if (err == pref.Success):
            entry = scriptTable.ScriptTable.createEntry(
                name, filename, userID, desc, isAdmin)

    return err, entry
示例#26
0
    def connect(self) -> pref.Error:
        '''
    Connects its self to the computer based on
    the computer object passed in init.
    The computer with its IP and username.
    Before a computer can be connected to for the
    first time addComputer must first be run on it.
    @returns the error code pref.Success if it worked
    '''

        err = pref.Success

        for _ in range(1):
            #make sure ip isnt Blacklisted
            blackListFileName = pref.getNoCheck(pref.CONFIG_BLACKLIST_IP_FILE)
            if (blackListFileName != ""):
                blackList = None
                try:
                    blackList = [
                        line.rstrip("\n") for line in open(blackListFileName)
                    ]
                except:
                    tempErr = pref.getError(pref.ERROR_FILE_NOT_FOUND,
                                            args=(blackListFileName))
                    logger.error(tempErr)
                    break

                err = whitelistBlackList.confirmValidIP(
                    self.computer.IP, blackList)
            else:
                logger.warning("no ip blacklist no filtering")

            #Create ssh client with basic autoadd settings
            self.ssh = paramiko.SSHClient()
            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            #Get Keyfile from preferences
            try:
                keyFileName = pref.getNoCheck(pref.CONFIG_PRIVATE_SSH_KEY)
                keyFile = paramiko.RSAKey.from_private_key_file(keyFileName)
            except:
                err = pref.getError(pref.ERROR_CANT_FIND_SSH_KEY,
                                    args=(keyFileName))
                logger.error(err)
                break

            #connect to the computer
            #TODO test self.computer.IP, needs list of blacklisted commands
            try:
                self.ssh.connect(self.computer.IP,
                                 username=self.computer.username,
                                 pkey=keyFile,
                                 timeout=5,
                                 allow_agent=False)
            #Authentication error rerun addComputer on this computer to fix
            except paramiko.ssh_exception.AuthenticationException as e:
                err = pref.getError(pref.ERROR_SSH_AUTHENTICATION_FAILED,
                                    args=(self.computer.username,
                                          self.computer.IP))
                logger.error(err)
                break
            #Failed to connect
            except:
                err = pref.getError(pref.ERROR_CONNECTION_FAILED,
                                    args=(self.computer.username,
                                          self.computer.IP))
                logger.error(err)

        return err
示例#27
0
    def addNewComputer(computerIP: str, username: str,
                       password: str) -> pref.Error:
        '''
    adds a new computer with using its username and password
    @param computerIP:str ip of the computer to add as a string.
    @param username:str username of the computer not user adding the computer.
    @param password:str password of the user described above.
    @return err
    '''

        #init values
        err = pref.Success
        ssh = None
        ftp_client = None
        remoteFolder = None
        stdin = None
        stdout = None
        stderr = None

        for _ in range(1):
            #make sure ip isnt Blacklisted
            blackListFileName = pref.getNoCheck(pref.CONFIG_BLACKLIST_IP_FILE)
            if (blackListFileName != ""):
                blackList = None
                try:
                    blackList = [
                        line.rstrip("\n") for line in open(blackListFileName)
                    ]
                except:
                    tempErr = pref.getError(pref.ERROR_FILE_NOT_FOUND,
                                            args=(blackListFileName))
                    logger.error(tempErr)
                    break

                err = whitelistBlackList.confirmValidIP(computerIP, blackList)
                if (err != pref.Success):
                    logger.error(err)
                    break
            else:
                logger.warning("no ip blacklist no filtering")

            #get shh public key
            sshKey = pref.getNoCheck(pref.CONFIG_PUBLIC_SSH_KEY)

            #if its empty row public sshkey empty
            if (sshKey == None or sshKey.strip().strip("\n") == ""):
                err = pref.getError(pref.ERROR_EMPTY_SSH_PUBLIC_KEY)
                logger.error(err)
                break

            #Create ssh client with basic autoadd settings
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            #Connects to computer with password and username
            try:
                ssh.connect(computerIP,
                            username=username,
                            password=password,
                            timeout=5,
                            look_for_keys=False,
                            allow_agent=False)
                ftp_client = ssh.open_sftp()
            #Incorrect username or password
            except paramiko.ssh_exception.AuthenticationException as e:
                err = pref.getError(pref.ERROR_SSH_AUTHENTICATION_FAILED,
                                    args=(username, computerIP))
                logger.error(err)
                break
            #Connection timed out or port rejected.
            except:
                err = pref.getError(pref.ERROR_CONNECTION_FAILED,
                                    args=(username, computerIP))
                logger.error(err)
                break

            #Create tempfolder on the remote computer.
            remoteFolder = pref.getNoCheck(pref.CONFIG_REMOTE_FOLDER)
            addSSHKeyScript = pref.getNoCheck(pref.CONFIG_ADD_COMPUTER_SCRIPT)
            resFolder = pref.getNoCheck(pref.CONFIG_RES_FOLDER)

            #Add ssh file to server and change permissions.
            err = copyFileToComputer(ftp_client, remoteFolder, resFolder,
                                     addSSHKeyScript)
            if (err != pref.Success):
                break

            #Run setup script with sshKey config file.
            try:
                stdin, stdout, stderr = ssh.exec_command(
                    "sshkey=\"{}\" {}{} > /dev/null; echo $?".format(
                        sshKey, remoteFolder, addSSHKeyScript))
            except:
                #failed to execute script.
                err = pref.getError(pref.ERROR_SSH_FAILED_TO_EXECUTE_SCRIPT,
                                    args=(addSSHKeyScript))
                logger.error(err)
                break

            #Check error code of script.
            errCode = "".join(stdout.readlines()).rstrip("\n")
            if (errCode != "0"):
                err = pref.getError(
                    pref.ERROR_SSH_SCRIPT_FAILED_WITH_ERROR_CODE,
                    args=(errCode))
                logger.error(err)

        return err
示例#28
0
    def getOutput(self, stdout: paramiko.ChannelFile,
                  stderr: paramiko.ChannelFile):
        '''
    This should never be called from outside this class.
    And should be run in another thread retriving the output from the 
    script running on the remote computer
    it is assumed the scriptLog is already set before this function
    '''

        #sets it so chanels arent blocking
        stdout.channel.setblocking(0)
        stderr.channel.setblocking(0)

        stdout_buffer = ""
        stderr_buffer = ""

        #scriptLog folder
        logFolder = pref.getNoCheck(pref.CONFIG_SCRIPT_LOG_PATH)
        try:
            stdoutFile = open(
                "{}{}".format(logFolder, self.scriptLog.stdoutFile), "w")
            stderrFile = open(
                "{}{}".format(logFolder, self.scriptLog.stderrFile), "w")
        except:
            #Couldn't create stdout and stderr file aborting and display warning
            err = pref.getError(pref.ERROR_CANT_CREATE_FILE,
                                args=("{} and {}".format(
                                    self.scriptLog.stdoutFile,
                                    self.scriptLog.stderrFile)))
            logger.error(err)
            return
        #writes basic info to stdout and stderr
        stdoutFile.write("Script Start at: {}\n".format(
            datetime.datetime.now()))
        stderrFile.write("Script Start at: {}\n".format(
            datetime.datetime.now()))
        stdoutFile.flush()
        stderrFile.flush()
        #gets the output
        while not stdout.channel.exit_status_ready(
        ) or not stderr.channel.exit_status_ready(
        ) or stdout.channel.recv_ready() or stderr.channel.recv_ready():

            retrivedInput = False
            #stdout
            try:
                stdout_buffer = stdout.readline()
                stdoutFile.write("{}: {}".format(datetime.datetime.now(),
                                                 stdout_buffer))
                stdoutFile.flush()
                retrivedInput = True
            except:
                pass

            #stderr
            try:
                stderr_buffer = stderr.readline()
                stderrFile.write("{}: {}".format(datetime.datetime.now(),
                                                 stderr_buffer))
                stderrFile.flush()
                retrivedInput = True
            except:
                pass

            #sleeps to lower cpu usage
            if (not retrivedInput):
                time.sleep(pref.getNoCheck(pref.CONFIG_OUTPUT_TIMEOUT))
        #writes rest of data
        for line in stdout.readlines():
            stdoutFile.write("{}: {}".format(datetime.datetime.now(), line))
        for line in stderr.readlines():
            stderrFile.write("{}: {}".format(datetime.datetime.now(), line))

        stdoutFile.close()
        stderrFile.close()

        #gets returnValue
        stdoutFile = open("{}{}".format(logFolder, self.scriptLog.stdoutFile),
                          "r+")
        stdoutFile.seek(0, os.SEEK_END)
        end = stdoutFile.tell()
        buffer = ""
        counter = 1
        while (buffer != "\n"):
            stdoutFile.seek(end - counter, os.SEEK_SET)
            buffer = stdoutFile.read(1)
            counter += 1

        returnValue = stdoutFile.readline().split("Returned: ")

        err = pref.Success
        #Failed to get return value error reading connection losted
        if len(returnValue) == 1:
            err = pref.getError(pref.ERROR_SSH_CONNECTION_LOST,
                                args=(self.computer.username, self.computer.IP,
                                      self.script.name))
            returnValue = None
            logger.error(err)
        else:
            returnValue = returnValue[-1]
            logger.info("Complete script {} with return value {}".format(
                self.script.name, returnValue))
        self.scriptLog.endTime = datetime.datetime.now()
        self.scriptLog.errorCode = err.code
        self.scriptLog.returnVal = returnValue
        self.ssh.close()

        #Writes return value to db
        scriptLogTable.ScriptLogTable.editEntry(self.scriptLog)
示例#29
0
    def run(self) -> Tuple[pref.Error, int]:
        ''' Runs a script based on the script passed in init'''

        ftp_client = None
        err = pref.Success

        for _ in range(1):

            #creates sftp connection
            try:
                ftp_client = self.ssh.open_sftp()
            except:
                err = pref.getError(pref.ERROR_UNKNOWN)
                break

            #Paths for scripts
            remoteFolder = pref.getNoCheck(pref.CONFIG_REMOTE_FOLDER)
            scriptFolder = pref.getNoCheck(pref.CONFIG_SCRIPT_PATH)

            #Checks whitelistBlackList
            for _ in range(1):
                blackListFileName = pref.getNoCheck(
                    pref.CONFIG_BLACKLIST_CMD_FILE)
                if (blackListFileName != ""):
                    blackList = None
                    try:
                        blackList = [
                            line.rstrip("\n")
                            for line in open(blackListFileName)
                        ]
                    except:
                        tempErr = pref.getError(pref.ERROR_FILE_NOT_FOUND,
                                                args=(blackListFileName))
                        logger.error(tempErr)
                        break

                    err = whitelistBlackList.confirmValidCommads(
                        "{}{}".format(scriptFolder, self.script.fileName),
                        blackList)
                    if (err != pref.Success):
                        logger.error(err)
                        break
                else:
                    logger.warning("no cmd blacklist no filtering")

            #Error during blacklist
            if err != pref.Success:
                logger.error(err)
                break

            #Copies script over
            err = copyFileToComputer(ftp_client, remoteFolder, scriptFolder,
                                     self.script.fileName)
            if (err != pref.Success):
                break

            #Executes script

            #windows echo command
            #echoCmd = "echo Returned $?"
            echoCmd = "printf \"\\n\nReturned: %d\" $?"
            _, stdout, stderr = self.ssh.exec_command("{}{}; {}".format(
                remoteFolder, self.script.fileName, echoCmd))

            #creates Script logs
            self.scriptLog = scriptLogTable.ScriptLogTable.createEntry(
                self.script.ID, self.userID, self.computer.ID,
                self.computer.asAdmin)
            err = scriptLogTable.ScriptLogTable.add(self.scriptLog)

            if (err == pref.Success):
                outputThread = threading.Thread(target=self.getOutput,
                                                daemon=True,
                                                args=(stdout, stderr))
                outputThread.start()

        id = self.scriptLog.ID if self.scriptLog != None else -1
        return err, id
 def test_getNoCheck(self):
     login = pref.getNoCheck(pref.CONFIG_LOGIN_ENDPOINT)
     self.assertEqual("/login", login)