def handleTesting(environ, start_response): missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) missionId = missionJson['missionId'] versionId = missionJson['versionId'] # If you're a MM user and this is your mission, or you're a low admin if not utils.checkUserPermissions(environ['user'], 1, missionId): start_response("403 Permission Denied", []) return ["Access Denied"] c = utils.getCursor() c.execute("SELECT name FROM versions WHERE id = ?", [versionId]) version = c.fetchone() fileName = version[0] if Path(utils.missionMakerDir + "/" + fileName).is_file(): c.execute("UPDATE missions SET status='Testing' WHERE id = ?", [missionId]) c.execute("UPDATE versions SET requestedTesting=1 WHERE id = ?", [versionId]) if utils.discordHookUrl != '': c.execute("SELECT missionName, missionAuthor FROM missions WHERE id = ?", [missionId]) missionStuff = c.fetchone() missionName = missionStuff[0] missionAuthor = missionStuff[1] payload = {'content': 'Rejoice Comrades! ' + missionAuthor + ' has prepared a new adventure for us!\n' + missionName + ' now has ' + fileName + ' requested for testing.'} r = requests.post(utils.discordHookUrl, data=payload) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleSaveMission(environ, start_response): c = utils.getCursor() missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) # create a blank row, then update that row so that we don't have 2 different statements if 'missionId' not in missionJson: c.execute("insert into missions (missionName) values (?)", [missionJson['missionName']]) c.execute("select max(id) from missions") missionId = c.fetchone()[0] hasPermissions = utils.checkUserPermissions(environ['user'], 0) else: missionId = missionJson['missionId'] c.execute("select * from missions where id = ?", [missionId]) mission = c.fetchone() if mission is None: start_response("500 Internal Server Response", []) return [ "Stop trying to edit a mission that doesn't exist".encode() ] hasPermissions = utils.checkUserPermissions(environ['user'], 2, missionId) if not hasPermissions: start_response("403 Permission Denied", []) return ["Access Denied"] query, params = constructQuery(missionJson) params.append(missionId) c.execute("update missions set " + query + "where id=?", params) c.connection.commit() c.connection.close() start_response("201 Created", []) return [(str(missionId)).encode()]
def handlePermissionLevel(environ, start_response): c = utils.getCursor() permissionLevelString = utils.environToContents(environ) permissionLevelJson = json.loads(permissionLevelString) userId = permissionLevelJson['id'] permissionLevel = permissionLevelJson['permissionLevel'] if utils.checkUserPermissions(environ['user'], 3): c.execute("update users set permissionLevel = ? where id = ?", [permissionLevel, userId]) c.execute("select * from users where permissionLevel = 3") if c.fetchone() is None: start_response("500 Internal Server Error", []) return [ "No admin users found, there must be at least one high admin (3)" .encode() ] else: start_response("200 OK", []) c.connection.commit() c.connection.close() else: start_response("403 Permission Denied", []) return ["Access Denied".encode()] return []
def handleLogin(environ, start_response): c = utils.getCursor() loginJsonString = utils.environToContents(environ) loginJson = json.loads(loginJsonString) login = loginJson['login'].strip() passw = loginJson['password'] c.execute('''select * from users where login = ?''', [login]) user = c.fetchone() if user is None: start_response("500 Internal Server Response", []) return ["No user with this login".encode()] if sha256_crypt.verify(passw, user['password']): cookie = cookies.SimpleCookie() cookie['famdbSessionId'] = utils.userRowToSessionId(user) header1 = ('set-cookie', cookie.output(header='')) cookie = cookies.SimpleCookie() cookie['permissionLevel'] = user['permissionLevel'] header2 = ('set-cookie', cookie.output(header='')) print("returning to user:"******"200 OK", [header1, header2]) c.execute("update users set lastLogin = ?", [date.today()]) c.connection.commit() c.connection.close() else: start_response("500 Internal Server Response", []) return ["incorrect password".encode()] return []
def handleMove(environ, start_response): user = environ['user'] missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) missionId = missionJson['missionId'] versionId = missionJson['versionId'] # If you're a MM user and this is your mission, or you're a low admin if not (utils.checkUserPermissions( user, 1, missionId=missionId, collector=utils.AND) or utils.checkUserPermissions(user, 2)): start_response("403 Permission Denied", []) return ["Access Denied"] c = utils.getCursor() c.execute("select name from versions where id = ?", [versionId]) fileName = c.fetchone()[0] if Path(utils.missionMakerDir + "/" + fileName).is_file(): copyfile(utils.missionMakerDir + "/" + fileName, utils.missionMainDir + "/" + fileName) c.execute("update versions set existsOnMain=1 where id = ?", [versionId]) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleChangePassword(environ, start_response): changePasswordString = utils.environToContents(environ) changePasswordJson = json.loads(changePasswordString) c = utils.getCursor() c.execute("select * from users where resetPwLink = ?", [changePasswordJson['link']]) userRow = c.fetchone() if userRow is None: start_response("500 internal server error", []) return [ "Unable to find user with this link, try reset password again". encode() ] else: c.execute( '''update users set password = ?, resetPwLink = null where id = ?''', [ sha256_crypt.encrypt(changePasswordJson['password']), userRow['id'] ]) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleComment(environ, start_response): user = environ['user'] missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) missionId = missionJson['missionId'] comment = html.escape(missionJson['comment']) rejection = True if 'rejection' in missionJson and missionJson['rejection'] == True else False # If you're a MM user and this is your mission, or you're a low admin if rejection and not ( utils.checkUserPermissions(user, 1, missionId=missionId, collector=utils.AND) or utils.checkUserPermissions( user, 2)): start_response("403 Permission Denied", []) return ["Access Denied"] c = utils.getCursor() c.execute("select name, id from versions where id = (select max(id) from versions where missionId = ?)", [missionId]) versionRow = c.fetchone() fileName = versionRow[0] versionId = versionRow[1] if rejection: c.execute("UPDATE missions SET status ='Broken' WHERE id = ?", [missionId]) c.execute("UPDATE versions SET requestedTransfer=0, requestedTesting=0 WHERE id = ?", [versionId]) c.execute("insert into comments (missionId, user, contents, createDate, versionId) values (?,?,?,?, ?)", [missionId, user.login, comment, datetime.now(), versionId]) if utils.discordHookUrl != '': c.execute("select missionName, missionAuthor from missions where id = ?", [missionId]) missionFromDb = c.fetchone() missionName = missionFromDb[0] unawareAuthors = filter(lambda author: author.strip() != user.login, [author for author in missionFromDb[1].split(",")]) missionAuthorDiscordIds = filter(None, [authorToUser(author) for author in unawareAuthors]) # Only send the message if there is at least one ID to send to if len(list(missionAuthorDiscordIds)) > 0: missionAuthorDiscordIds = ['<@' + discordId + ">" for discordId in missionAuthorDiscordIds] if rejection: payload = { 'content': 'Despair ' + ' '.join(missionAuthorDiscordIds) + '! ' + fileName + ' has been rejected'} else: payload = {'content': ' '.join(missionAuthorDiscordIds) + '! ' + missionName + ' has a new comment. '} r = requests.post(utils.discordHookUrl, data=payload) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleMove(environ, start_response): user = environ['user'] missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) missionId = missionJson['missionId'] versionId = missionJson['versionId'] # If you're a MM user and this is your mission, or you're a low admin if not (utils.checkUserPermissions( user, 1, missionId=missionId, collector=utils.AND) or utils.checkUserPermissions(user, 2)): start_response("403 Permission Denied", []) return ["Access Denied"] c = utils.getCursor() c.execute("select name from versions where id = ?", [versionId]) fileName = c.fetchone()[0] if Path(utils.missionMakerDir + "/" + fileName).exists(): copyfile(utils.missionMakerDir + "/" + fileName, utils.missionMainDir + "/" + fileName) c.execute( "UPDATE versions SET existsOnMain=1, requestedTransfer=0, requestedTesting=0 WHERE id = ?", [versionId]) c.execute("update missions set status ='Ready' where id = ?", [missionId]) if utils.discordHookUrl != '': c.execute("select missionAuthor from missions where id = ?", [missionId]) missionFromDb = c.fetchone() missionAuthorDiscordIds = filter( None, [authorToUser(author) for author in missionFromDb[0].split(",")]) missionAuthorDiscordIds = [ '<@' + discordId + ">" for discordId in missionAuthorDiscordIds ] payload = { 'content': 'Rejoice ' + ' '.join(missionAuthorDiscordIds) + '! ' + fileName + ' has been accepted' } r = requests.post(utils.discordHookUrl, data=payload) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleSessionDelete(environ, start_response): c = utils.getCursor() sessionJsonString = utils.environToContents(environ) sessionJson = json.loads(sessionJsonString) sessionId = sessionJson['sessionId'] if not utils.checkUserPermissions(environ['user'], 2): start_response("403 Permission Denied", []) return ["Access Denied"] c.execute("delete from sessions where id = ?", [sessionId]) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleEditSession(environ, start_response): c = utils.getCursor() editSessionString = utils.environToContents(environ) editSessionJson = json.loads(editSessionString) sessionDate = editSessionJson['date'] # if you're a low admin if not utils.checkUserPermissions(environ['user'], 2): start_response("403 Permission Denied", []) return ["Access Denied".encode()] if 'id' not in editSessionJson: c.execute("insert into sessions (date) values (?)", [sessionDate]) c.execute("select max(id) from sessions") sessionId = c.fetchone()[0] else: sessionId = editSessionJson['id'] c.execute("select missionNames from sessions where id = ?", [sessionId]) existingMissionNames = c.fetchone() c.execute( "update sessions set missionNames = ?, host = ?, name = ?, players = ?, date = ? where id = ? ", toParams(editSessionJson, sessionId)) missions = editSessionJson['missionNames'] newMissions = [] if existingMissionNames['missionNames'] is not None: existingMissionNames = existingMissionNames['missionNames'].split(",") for mission in missions: if mission in existingMissionNames: existingMissionNames.remove(mission) else: newMissions.append(mission) else: newMissions = missions for mission in newMissions: c.execute( "update missions set playedCounter = playedCounter+1, lastPlayed=? where missionName =?", [sessionDate, mission]) c.connection.commit() c.connection.close() start_response("201 Created", []) return [("location:" + str(sessionId)).encode()]
def handleMissionDelete(environ, start_response): c = utils.getCursor() missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) missionId = missionJson['missionId'] # if you're a low admin or this is your mission if not utils.checkUserPermissions(environ['user'], 2, missionId): start_response("403 Permission Denied", []) return ["Access Denied"] c.execute("delete from versions where missionId = ?", [missionId]) c.execute("delete from missions where id = ?", [missionId]) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleArchive(environ, start_response): c = utils.getCursor() missionJsonString = utils.environToContents(environ) missionJson = json.loads(missionJsonString) missionId = missionJson['missionId'] versionId = missionJson['versionId'] origin = missionJson['origin'] # if you're a low admin or this is your mission if not utils.checkUserPermissions(environ['user'], 2, missionId): start_response("403 Permission Denied", []) return ["Access Denied"] if origin == 'main': property = 'toBeArchivedMain' else: property = 'toBeArchivedMM' c.execute('''update versions set ''' + property + ''' = 1 where id = ?''', [versionId]) c.connection.commit() c.connection.close() start_response("200 OK", []) return []
def handleCreateUser(environ, start_response): c = utils.getCursor() loginJsonString = utils.environToContents(environ) signUpJson = json.loads(loginJsonString) login = signUpJson['login'].strip() email = signUpJson['email'].strip() passw = signUpJson['password'] c.execute('''select * from users where login = ? or email = ?''', [login, email]) if login == '': start_response("500 Internal Server Error", []) return ["Did you think you were funny making a blank user name?".encode()] if email == '': start_response("500 Internal Server Error", []) return ["Did you think you were funny making a blank email?".encode()] if passw == '': start_response("500 Internal Server Error", []) return ["Did you think you were funny making a blank password?".encode()] if c.fetchone() is None: from Crypto import Random sessionKey = Random.new().read(AES.block_size) c.execute( '''insert into users (login, password, email, lastLogin, permissionLevel, sessionKey) values (?, ?, ?, ?, ?, ?)''', [login, sha256_crypt.encrypt(passw), email, date.today(), 0, sessionKey]) c.execute('''select * from users where login = ?''', [login]) user = c.fetchone() if user['id'] == 1: c.execute("update users set permissionLevel = 3 where id = 1") cookie = cookies.SimpleCookie() cookie['sessionId'] = utils.userRowToSessionId(user) start_response("200 OK", [('set-cookie', cookie.output(header=''))]) c.connection.commit() c.connection.close() return [] else: start_response("500 Internal Server Error", []) return ["user with that login or email already exists".encode()]
def handleCreateUser(environ, start_response): c = utils.getCursor() loginJsonString = utils.environToContents(environ) signUpJson = json.loads(loginJsonString) login = html.escape(signUpJson['login'].strip()) email = html.escape(signUpJson['email'].strip()) discordId = signUpJson['discordId'].strip() negativeRegex = re.compile(r'^[0-9]{18}$') if not negativeRegex.match(discordId): start_response("500 Internal Server Error", []) return [ "Discord ID required." " <a href='https://support.discordapp.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-'>" " See This</a>".encode() ] passw = signUpJson['password'] c.execute('''select * from users where login = ? or email = ?''', [login, email]) if login == '': start_response("500 Internal Server Error", []) return [ "Did you think you were funny making a blank user name?".encode() ] if email == '': start_response("500 Internal Server Error", []) return ["Did you think you were funny making a blank email?".encode()] if passw == '': start_response("500 Internal Server Error", []) return [ "Did you think you were funny making a blank password?".encode() ] if c.fetchone() is None: from Crypto import Random sessionKey = Random.new().read(AES.block_size) c.execute( '''insert into users (login, password, email, lastLogin, permissionLevel, sessionKey, discordId) values (?, ?, ?, ?, ?, ?, ?)''', [ login, sha256_crypt.encrypt(passw), email, date.today(), 0, sessionKey, discordId ]) c.execute('''select * from users where login = ?''', [login]) user = c.fetchone() if user['id'] == 1: c.execute("update users set permissionLevel = 3 where id = 1") cookie = cookies.SimpleCookie() cookie['famdbSessionId'] = utils.userRowToSessionId(user) header1 = ('set-cookie', cookie.output(header='')) cookie = cookies.SimpleCookie() cookie['permissionLevel'] = user['permissionLevel'] header2 = ('set-cookie', cookie.output(header='')) start_response("200 OK", [header1, header2]) c.connection.commit() c.connection.close() if utils.discordHookUrl != '': payload = { 'content': 'Comrades! Welcome our new mission maker <@' + discordId + '>. Hopefully they add will a great many missions to our cause!' } r = requests.post(utils.discordHookUrl, data=payload) return [] else: start_response("500 Internal Server Error", []) return ["user with that login or email already exists".encode()]