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")
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
def getAttrByID(attr: str, ID: int): ''' Retrieves a specified attrubute from an entry of the scriptLog SQL table based on primary key - ID @param attr - one of the columns of the scriptLog table ID - primary key of scriptLog @return e - error created during execution of function or Success if no error occurs s - the specified attribute's value from the entry retrieved from the SQL table ''' val = None command = """SELECT (""" + attr + """) FROM sl WHERE ID = """ + str( ID) + """;""" e, slTuple = sqlFuncs.getRow(command, "getAttrByID", "ScriptLog") if (e == pref.getError(pref.ERROR_SUCCESS)): if (slTuple == None): e = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR, args=("getAttrByID", "ScriptLog", 0, 1)) elif (len(slTuple) != 1): e = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR, args=("getAttrByID", "ScriptLog", len(slTuple), 1)) else: val = slTuple[0] return e, val
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 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() )
def test_setAttrAndReset(self): #check that the value is correct to start err, unknownErr = pref.get(pref.ERROR_UNKNOWN) self.assertEqual( pref.getError(pref.ERROR_UNKNOWN).code, unknownErr.code) self.assertEqual(pref.Success.code, err.code) #set new value err = pref.setAttr(pref.ERROR_UNKNOWN, "error") self.assertEqual(pref.Success.code, err.code) #check new value err, unknownErr = pref.get(pref.ERROR_UNKNOWN) self.assertEqual("error", unknownErr) self.assertEqual(pref.Success.code, err.code) #reset config pref.resetConfig() #check that the value was reset err, unknownErr = pref.get(pref.ERROR_UNKNOWN) self.assertEqual( pref.getError(pref.ERROR_UNKNOWN).code, unknownErr.code) self.assertEqual(pref.Success.code, err.code)
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 test_deleteU(self): createTablesBig() err = tou.UserTable().delete(2) errExp = pref.getError(pref.ERROR_SUCCESS) err2, u = tou.UserTable.getByID(2) errExp2 = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR, args=("getByID", "User", 0, 6)) self.assertEqual(err, errExp) self.assertEqual(err2, errExp2) self.assertEqual(u, None)
def test_deleteC(self): createTablesBig() err = toc.ComputerTable().delete(1) errExp = pref.getError(pref.ERROR_SUCCESS) err2, c = toc.ComputerTable.getByID(1) errExp2 = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR, args=("getByID", "Computer", 0, 10)) self.assertEqual(err, errExp) self.assertEqual(err2, errExp2) self.assertEqual(c, None)
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 editEntry(entry: ScriptLog): ''' Updates a row in the scriptLog SQL table based on the entry object passed. Overwrites all attributes of the row with the values of the entry object. Overwrites row based on the ID of the entry object. @param entry: ScriptLog - ScriptLog object, must have ID != None or error will be thrown @return e - most recent error when executing function or Success if no error occurs sl - ScriptLog object corresponding to row updated in SQL table. Should be the same as entry passed to function if no error occured ''' sl = entry if (entry.ID == None): e = pref.getError(pref.ERROR_NO_ID_PROVIDED, args=("editEntry", "ScriptLog")) else: command = """UPDATE sl SET """ for attr, value in entry.__dict__.items(): if (attr == "ID"): pass else: command = command + str(attr) if (value == None): command = command + """ = NULL""" elif attr[-4:] == "Time": command = command + """ = """ + """\"""" + str( value.strftime('%Y-%m-%d %H:%M:%S.%f')) + """\"""" elif isinstance(value, str): command = command + """ = """ + """\"""" + str( value) + """\"""" else: command = command + """ = """ + str(value) command = command + """, """ command = command[:-2] #remove last ' ,' command = command + """ WHERE ID = """ + str(entry.ID) + """;""" e = sqlFuncs.exeCommand(command, "editEntry", "ScriptLog") if (e == pref.getError(pref.ERROR_SUCCESS)): command2 = """SELECT * FROM sl WHERE ID = """ + str( entry.ID) + """;""" e, row = sqlFuncs.getRow(command2, "editEntry", "ScriptLog") if (e == pref.getError(pref.ERROR_SUCCESS)): e, sl = tupleToScriptLog(row, "editEntry") return e, sl
def test_addComputerWrongIP(self): '''tries to add a computer with the wrong password''' pref.setAttr(pref.CONFIG_PUBLIC_SSH_KEY, "asdfasdfasd") error = ssh.sshConnection.addNewComputer("69.69.69.69", self.username, "WRONGPASSWORD!@##@!") self.assertEqual(error, pref.getError(pref.ERROR_CONNECTION_FAILED))
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))
def test_editEntrySL(self): createTablesBig() err, sl = tosl.ScriptLogTable().getByID(2) # change some of sl's attributes sl.scriptID = 1 sl.userID = 1 sl.compID = 1 sl.startTime = dt.now() sl.endTime = dt.now() sl.returnVal = -1 sl.errorCode = 0 sl.stdoutFile = "stdoutFile new" sl.stderrFile = "stderrFile new" sl.asAdmin = False # write these edits to table err, sl2 = tosl.ScriptLogTable().editEntry(sl) errExp = pref.getError(pref.ERROR_SUCCESS) # checks self.assertEqual(err, errExp) self.assertEqual(sl.ID, sl2.ID) self.assertEqual(sl.scriptID, sl.scriptID) self.assertEqual(sl.userID, sl.userID) self.assertEqual(sl.compID, sl.compID) self.assertEqual(sl.startTime, sl.startTime) self.assertEqual(sl.endTime, sl.endTime) self.assertEqual(sl.returnVal, sl.returnVal) self.assertEqual(sl.errorCode, sl.errorCode) self.assertEqual(sl.stdoutFile, sl.stdoutFile) self.assertEqual(sl.stderrFile, sl.stderrFile) self.assertEqual(sl.asAdmin, sl.asAdmin)
def test_editEntryC(self): createTablesBig() err, c = toc.ComputerTable().getByID(2) # change some of c's attributes c.userID = 2 c.name = "newName" c.nickName = "newNickName" c.desc = "newDesc" c.username = "******" c.IP = "newIP" c.dtModified = dt.now() c.asAdmin = True # write these edits to table err, c2 = toc.ComputerTable().editEntry(c) errExp = pref.getError(pref.ERROR_SUCCESS) # checks self.assertEqual(err, errExp) self.assertEqual(c.userID, c2.userID) self.assertEqual(c.name, c2.name) self.assertEqual(c.nickName, c2.nickName) self.assertEqual(c.desc, c2.desc) self.assertEqual(c.username, c2.username) self.assertEqual(c.IP, c2.IP) self.assertEqual(c.dtCreated, c2.dtCreated) self.assertEqual(c.dtModified, c2.dtModified) self.assertEqual(c.asAdmin, c2.asAdmin)
def test_editEntryS(self): createTablesBig() err, s = tos.ScriptTable().getByID(2) # change some of s's attributes s.name = "newName" s.fileName = "newFilename.sh" s.author = 1 s.desc = "New desc" s.size = 200.0 s.isAdmin = False s.dtModified = dt.now() # write these edits to table err, s2 = tos.ScriptTable().editEntry(s) errExp = pref.getError(pref.ERROR_SUCCESS) # checks self.assertEqual(err, errExp) self.assertEqual(s.ID, s2.ID) self.assertEqual(s.name, s2.name) self.assertEqual(s.fileName, s2.fileName) self.assertEqual(s.author, s2.author) self.assertEqual(s.desc, s2.desc) self.assertEqual(s.dtCreated, s2.dtCreated) self.assertEqual(s.dtModified, s2.dtModified) self.assertEqual(s.size, s2.size) self.assertEqual(s.isAdmin, s2.isAdmin)
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)
def copyFileToComputer(ftp_client: paramiko.SFTPClient, remoteFolder: str, resFolder: str, filename: str) -> pref.Error: ''' Copies a file to a remote computer ftp_client @param ftp_client:parmiko.STFPClient the ssh ftp connection what the file will be transferred over @param remoteFolder:str ''' err = pref.Success #creates folder if it doesn't exist try: ftp_client.mkdir(remoteFolder, mode=0o777) ftp_client.chmod(remoteFolder, mode=0o777) except: #This is happen if the folder already exists . pass #copies file try: ftp_client.put("{}{}".format(resFolder, filename), "{}{}".format(remoteFolder, filename)) except Exception as e: print(e) #couldn't find script on sever. err = pref.getError(pref.ERROR_FILE_NOT_FOUND, args=(resFolder + filename)) logger.error(err) try: ftp_client.chmod("{}{}".format(remoteFolder, filename), 0o777) except: pass if (ftp_client): ftp_client.close() return err
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 test_deleteSL_F(self): createTablesBig() err = tosl.ScriptLogTable().delete(99) # delete non-existent computer errExp = pref.getError(pref.ERROR_SQL_RETURN_MISSING_ATTR, args=("getAttrByID", "ScriptLog", 0, 11)) # print(err) # print(errExp) self.assertEqual(err, errExp)
def test_addEntryU(self): createEmptyTables() u = tou.UserTable().createEntry("rbroders", "hella_secure_hashed_password", True) err = tou.UserTable().add(u) errExp = pref.getError(pref.ERROR_SUCCESS) self.assertEqual(err, errExp) self.assertEqual(u.ID, 1)
def test_deleteTableU_S(self): createTables() err = tosl.ScriptLogTable().deleteTable() err = tos.ScriptTable().deleteTable() err = toc.ComputerTable().deleteTable() err = tou.UserTable().deleteTable() errExp = pref.getError(pref.ERROR_SUCCESS) self.assertEqual(err, errExp)
def test_addComputerNonexistentUser(self): ''' Tries to add a computer on a server with a user that doesn't exist ''' pref.setAttr(pref.CONFIG_PUBLIC_SSH_KEY, "asdfasdfasd") error = ssh.sshConnection.addNewComputer(self.ip, "Wrong_User", "WRONGPASSWORD!@##@!") self.assertEqual(error, pref.getError(pref.ERROR_SSH_AUTHENTICATION_FAILED))
def getWithQuery(query: str): ''' #TODO *add description*. @param *add param*. @return *add return*. ''' skelScript = Script(0, "SkeletonScriptName", "SkeletonScriptName.py", 1, "Skeleton Script Description", datetime.datetime.now(), datetime.datetime.now(), 0, False) return pref.getError(pref.ERROR_SUCCESS), skelScript
def test_getByIDU(self): createTables() err, u = tou.UserTable().getByID(1) errExp = pref.getError(pref.ERROR_SUCCESS) self.assertEqual(err, errExp) self.assertEqual(u.ID, 1) self.assertEqual(u.username, "rbroders") self.assertEqual(u.password, "hella_secure_hashed_password") self.assertEqual(u.admin, True)
def getAll(): ''' Retreives all entries from the user SQL table and returns them as a list of user objects @param None. @return uList - list of user objects. ''' command = """SELECT * FROM u;""" e, rows = sqlFuncs.getAllRows(command, "getAll", "User") uList = [] if (e == pref.getError(pref.ERROR_SUCCESS)): if (rows != None): for row in rows: e, u = tupleToUser(row, "getAll") if (e == pref.getError(pref.ERROR_SUCCESS)): uList.append(u) return e, uList
def getWithQuery(query: str): ''' #TODO *add description*. @param *add param*. @return *add return*. ''' skelComp = Computer(0, 0, "RachelsComputer1", "RaquelsComp1", "Rachel's computer description 1", "root","127.0.0.1", datetime.datetime.now(), datetime.datetime.now(), False) return pref.getError(pref.ERROR_SUCCESS), skelComp
def getAll(): ''' Retreives all entries from the computer SQL table and returns them as a list of computer objects @param None. @return cList - list of computer objects. ''' command = """SELECT * FROM c;""" e, rows = sqlFuncs.getAllRows(command, "getAll", "Computer") cList = [] if(e == pref.getError(pref.ERROR_SUCCESS)): if (rows != None): for row in rows: e, c = tupleToComputer(row, "getAll") if(e == pref.getError(pref.ERROR_SUCCESS)): cList.append(c) return e, cList
def test_addComputerScripDNE(self): ''' Tries to add a computer on a server with a user that doesn't exist ''' pref.setAttr(pref.CONFIG_PUBLIC_SSH_KEY, "asdfasdfasd") pref.setAttr(pref.CONFIG_ADD_COMPUTER_SCRIPT, "DNE") error = ssh.sshConnection.addNewComputer(self.ip, self.username, "WRONGPASSWORD!@##@!") self.assertEqual(error, pref.getError(pref.ERROR_SSH_AUTHENTICATION_FAILED))
def getAll(): ''' Retreives all entries from the scriptLog SQL table and returns them as a list of scriptLog objects @param None. @return slList - list of scriptLog objects. ''' command = """SELECT * FROM sl;""" e, rows = sqlFuncs.getAllRows(command, "getAll", "ScriptLog") slList = [] if (e == pref.getError(pref.ERROR_SUCCESS)): if (rows != None): for row in rows: e, sl = tupleToScriptLog(row, "getAll") if (e == pref.getError(pref.ERROR_SUCCESS)): slList.append(sl) return e, slList