Exemplo n.º 1
0
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 []
Exemplo n.º 2
0
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 []
Exemplo n.º 3
0
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 []
Exemplo n.º 4
0
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()]
Exemplo n.º 5
0
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 []
Exemplo n.º 6
0
def handleResetPassword(environ, start_response):
    c = utils.getCursor()
    o = parse_qs(environ['QUERY_STRING'])
    if "email" in o:
        c.execute("select * from users where email = ?", [o['email'][0]])
        user = c.fetchone()
        if user is None:
            start_response("500 Internal Server Response", [])
            return ["No user with this email".encode()]
        else:
            updateLink = ''.join(
                random.SystemRandom().choice(string.ascii_uppercase +
                                             string.digits) for _ in range(8))

            c.execute('''update users set resetPwLink = ? where id = ?''',
                      [updateLink, user['id']])

            email = create_msg(message_name='FAMDB password reset',
                               message_text='To reset your password go to: ' +
                               utils.serverAddress +
                               '/changePassword.html?link=' + updateLink,
                               email_from=utils.emailAddress,
                               email_to=user['email'])
            smtp_server = connect_to_server()
            smtp_server.sendmail(utils.emailAddress, user['email'],
                                 email.as_string())
            smtp_server.quit()
            c.connection.commit()
            c.connection.close()
            start_response("200 OK", [])
            return []
    else:
        start_response("500 Internal Server Response", [])
        return ["No email supplied".encode()]
Exemplo n.º 7
0
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 []
Exemplo n.º 8
0
def initDb():
    c = utils.getCursor()

    # Create table
    c.execute('''CREATE TABLE if not exists missions
                 (id integer primary key,
                  missionName text,
                  lastPlayed text,
                   missionAuthor text,
                  missionModified text,
                  framework text,
                   isBroken integer default 0,
                  needsRevision integer default 0,
                   missionPlayers int,
                   missionType text,
                   missionMap text,
                    playedCounter int default 0,
                    missionDesc text,
                    missionNotes text,
                    status varchar(24) default 'WIP')''')

    c.execute('''CREATE TABLE if not exists users
                 (id integer primary key, login text, email text, password text, createDate text, lastLogin text, permissionLevel integer, sessionKey text,
                 discordId text)''')
    # Create table
    c.execute('''CREATE TABLE if not exists versions
                 (id integer primary key, missionId integer, existsOnMM integer default 1, existsOnMain integer default 0, name text, createDate text, toBeDeletedMM integer default 0, toBeDeletedMain integer default 0, requestedTransfer integer default 0, requestedTesting integer default 0)'''
              )

    c.execute('''CREATE TABLE if not exists comments
                 (id integer primary key autoincrement, contents text, user text, createDate text, missionId integer, versionId integer)'''
              )

    c.execute('''CREATE TABLE if not exists sessions
                 (id integer primary key, missionNames text, date text, host text, name text, players integer)'''
              )

    c.execute("select * from users where sessionKey is null")

    try:
        c.execute('''ALTER TABLE users add resetPwLink text''')
    except:
        pass
    usersWithout = c.fetchall()

    for user in usersWithout:
        sessionKey = Random.new().read(AES.block_size)
        c.execute("update users set sessionKey = ? where id = ?",
                  [sessionKey, user['id']])

    # Save (commit) the changes
    c.connection.commit()

    # We can also close the connection if we are done with it.
    # Just be sure any changes have been committed or they will be lost.
    c.connection.close()
Exemplo n.º 9
0
def handleAuthors(environ, start_response):
    c = utils.getCursor()
    c.execute(
        "select distinct missionAuthor from missions order by missionAuthor")
    authors = c.fetchall()

    authorDto = [split(x['missionAuthor']) for x in authors]
    authorDto = [item.strip() for sublist in authorDto for item in sublist]
    authorDto = list(sorted(set(authorDto), key=lambda s: s.lower()))
    encode = json.dumps(authorDto).encode()
    start_response("200 OK", [])
    return [encode]
Exemplo n.º 10
0
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 []
Exemplo n.º 11
0
def handleCleanup(environ, start_response):
    c = utils.getCursor()
    # if you're a low admin
    if not utils.checkUserPermissions(environ['user'], 2):
        start_response("403 Permission Denied", [])
        return ["Access Denied"]

    for origin in ['main', 'missionMaker']:
        if origin == 'main':
            missionDirPrefix = utils.missionMainDir
            missionArchivePrefix = utils.missionMainArchive
            toBeArchivedProperty = 'toBeArchivedMain'
            toBeDeletedProperty = 'toBeDeletedMain'
            existsProperty = 'existsOnMain'
        else:
            missionDirPrefix = utils.missionMakerDir
            missionArchivePrefix = utils.missionMakerArchive
            toBeArchivedProperty = 'toBeArchivedMM'
            toBeDeletedProperty = 'toBeDeletedMM'
            existsProperty = 'existsOnMM'

        c.execute('''select * from versions where ''' + toBeArchivedProperty +
                  ''' = 1''')
        toBeArchived = c.fetchall()

        for forArchival in toBeArchived:
            with open(missionDirPrefix + "/" + forArchival['name'],
                      'rb') as f_in:
                with gzip.open(
                        os.path.join(missionArchivePrefix,
                                     forArchival['name'] + ".gz"),
                        'wb') as f_out:
                    shutil.copyfileobj(f_in, f_out)
                    os.remove(f_in.name)

        c.execute('''select * from versions where ''' + toBeDeletedProperty +
                  ''' = 1''')
        toBeDeleted = c.fetchall()
        for deleteMe in toBeDeleted:
            os.remove(os.path.join(missionDirPrefix, deleteMe['name']))

        c.execute("update versions set " + existsProperty + " = 0, " +
                  toBeArchivedProperty + " = 0, " + toBeDeletedProperty +
                  " = 0 where " + toBeArchivedProperty + " = 1 or " +
                  toBeDeletedProperty + " = 1")
    c.connection.commit()
    c.connection.close()

    start_response("200 OK", [])
    return []
Exemplo n.º 12
0
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 []
Exemplo n.º 13
0
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 []
Exemplo n.º 14
0
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()]
Exemplo n.º 15
0
def handleMissions(environ, start_response):
    c = utils.getCursor()

    o = parse_qs(environ['QUERY_STRING'])

    query, params = constructQuery(o)
    # retrieve all the missions that match our parameters

    c.execute("select * from missions where " + query, params)
    missionsFromDb = c.fetchall()

    # if any missions were returned, return all versions associated with those missions
    if len(missionsFromDb) > 0:
        ids = [str(x['id']) for x in missionsFromDb]
        # sqlite can't take lists, so we need to transform it into a string
        #    then format the string into the query so that it doesn't get treated as a string
        idParameter = ",".join(ids)

        c.execute(str.format('''select * from versions where missionId in ({}) order by missionId''', idParameter))
        versionsFromDb = c.fetchall()
        # group the mission by their mission Id
        versionsGroupedByMission = {}
        for k, g in itertools.groupby(versionsFromDb, lambda x: x['missionId']):
            versionsGroupedByMission[k] = list(g)

        c.execute(str.format('''SELECT * FROM comments WHERE missionId IN ({}) ORDER BY missionId''', idParameter))

        commentsFromDb = c.fetchall()
        # group the comments by their mission Id
        commentsGroupedByMission = {}

        for k, g in itertools.groupby(commentsFromDb, lambda x: x['missionId']):
            commentsGroupedByMission[k] = list(g)

    else:
        versionsGroupedByMission = []
        commentsGroupedByMission = []

    user = environ['user']

    # transform the row objects into objects that can be serialized
    m = [toDto(x, versionsGroupedByMission, commentsGroupedByMission, user) for x in missionsFromDb]
    encode = json.dumps(m).encode()

    start_response("200 OK", [])
    return [encode]
Exemplo n.º 16
0
def handleMissions(environ, start_response):
    c = utils.getCursor()

    o = parse_qs(environ['QUERY_STRING'])

    missionIds = None
    if "new" in o:
        fancyQuery = "select missionId from versions join missions on versions.missionId = missions.id where versions.createDate > missions.lastPlayed and existsOnMain = 1 and tobeDeletedMain = 0"
        c.execute(fancyQuery)
        missionIds = c.fetchall()
    if "needsTransfer" in o:
        fancyQuery = "select missionId from versions where existsOnMain = 0 and existsOnMM = 1 and toBeDeletedMM = 0"
        c.execute(fancyQuery)
        missionIds = c.fetchall()

    query, params = constructQuery(o, missionIds)
    # retrieve all the missions that match our parameters

    c.execute("select * from missions where " + query, params)
    missionsFromDb = c.fetchall()

    # if any missions were returned, return all versions associated with those missions
    if len(missionsFromDb) > 0:
        ids = [str(x['id']) for x in missionsFromDb]
        # sqlite can't take lists, so we need to transform it into a string
        #    then format the string into the query so that it doesn't get treated as a string
        idParameter = ",".join(ids)

        c.execute(str.format('''select * from versions where missionId in ({}) order by missionId''', idParameter))
        versionsFromDb = c.fetchall()
        # group the mission by their mission Id
        versionsGroupedByMission = {}
        for k, g in itertools.groupby(versionsFromDb, lambda x: x['missionId']):
            versionsGroupedByMission[k] = list(g)
    else:
        versionsGroupedByMission = []


    user = environ['user']

    # transform the row objects into objects that can be serialized
    m = [toDto(x, versionsGroupedByMission, user) for x in missionsFromDb]
    encode = json.dumps(m).encode()

    start_response("200 OK", [])
    return [encode]
Exemplo n.º 17
0
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 []
Exemplo n.º 18
0
def handleDownload(environ, start_response):
    c = utils.getCursor()
    o = parse_qs(environ['QUERY_STRING'])
    versionId = o['versionId']
    c.execute("select * from versions where id = ?", versionId)
    version = c.fetchone()
    if version['existsOnMain'] == 1:
        dir = utils.missionMainDir
    else:
        dir = utils.missionMakerDir
    with open(
            dir + "/" + version['name'],
            mode="rb",
    ) as stream:
        start_response('200 OK',
                       [('Content-Disposition',
                         'attachment; filename="' + version['name'] + '"')])
        return [stream.read()]
Exemplo n.º 19
0
def handleCleanup(environ, start_response):
    c = utils.getCursor()
    # if you're a low admin
    if not utils.checkUserPermissions(environ['user'], 2):
        start_response("403 Permission Denied", [])
        return ["Access Denied"]

    for origin in ['main', 'missionMaker']:
        if origin == 'main':
            missionDirPrefix = utils.missionMainDir
            toBeDeletedProperty = 'toBeDeletedMain'
            existsProperty = 'existsOnMain'
        else:
            missionDirPrefix = utils.missionMakerDir
            toBeDeletedProperty = 'toBeDeletedMM'
            existsProperty = 'existsOnMM'

        c.execute('''select * from versions where ''' + toBeDeletedProperty +
                  ''' = 1''')
        toBeDeleted = c.fetchall()
        for deleteMe in toBeDeleted:
            try:
                os.remove(os.path.join(missionDirPrefix, deleteMe['name']))
            except OSError:
                pass

        c.execute("update versions set " + existsProperty + " = 0, " +
                  toBeDeletedProperty + " = 0 where " + toBeDeletedProperty +
                  " = 1")
    c.execute(
        "SELECT id FROM versions WHERE existsOnMM = 0 AND existsOnMain = 0")
    versionRowsToBeDeleted = c.fetchall()
    ids = [str(x['id']) for x in versionRowsToBeDeleted]
    idParameter = ",".join(ids)
    c.execute(
        str.format('''DELETE FROM comments WHERE versionId IN ({})''',
                   idParameter))

    c.execute("delete from versions where existsOnMM = 0 and existsOnMain = 0")
    c.connection.commit()
    c.connection.close()

    start_response("200 OK", [])
    return []
Exemplo n.º 20
0
def handleGetSession(environ, start_response):
    c = utils.getCursor()
    o = parse_qs(environ['QUERY_STRING'])
    if "sessionId" in o:
        c.execute("select * from sessions where id = ?", [o['sessionId'][0]])
    else:
        c.execute("select * from sessions")
    sessions = c.fetchall()

    user = environ['user']
    sessionDtos = [dict(x) for x in sessions]
    for x in sessionDtos:
        x['missionNamesList'] = x['missionNames'].split(",")
        if user is not None:
            if user.permissionLevel >= 2:
                x['allowedToEdit'] = True

    start_response("200 OK", [])
    return [json.dumps(sessionDtos).encode()]
Exemplo n.º 21
0
def handleUsers(environ, start_response):
    user = environ['user']
    c = utils.getCursor()
    c.execute("select id, login, permissionLevel, lastLogin, email from users")
    allUsers = c.fetchall()

    userDtos = [dict(x) for x in allUsers]

    if user is None:
        start_response("403 Permission Denied", [])
        return ["Access Denied"]

    if user is not None and user.permissionLevel > 2:
        for x in userDtos:
            x['permissionLevels'] = [x['permissionLevel']] + [-1, 0, 1, 2, 3]
    else:
        for x in userDtos:
            x['permissionLevels'] = x['permissionLevel']

    encode = json.dumps(userDtos).encode()
    start_response("200 OK", [])
    return [encode]
Exemplo n.º 22
0
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 []
Exemplo n.º 23
0
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()]
Exemplo n.º 24
0
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()]
Exemplo n.º 25
0
def authorToUser(author):
    c = utils.getCursor()
    c.execute("select discordId from users where login = ?", [author])
    user = c.fetchone()
    return None if user is None else user[0]
Exemplo n.º 26
0
def handleSync(environ, start_response):
    c = utils.getCursor()
    if utils.checkUserPermissions(environ['user'], 3):

        c.execute(str.format('''select * from versions order by missionId'''))
        versionsFromDb = c.fetchall()

        for version in versionsFromDb:
            existsOnMM = False
            if version['existsOnMM']:
                existsOnMM = True
                if not Path(utils.missionMakerDir + "/" + version['name']).is_file():
                    existsOnMM = False
                    c.execute(str.format('''update versions set existsOnMM=0 where id = {}''', version['id']))

            existsOnMain = False
            if version['existsOnMain']:
                existsOnMain = True
                if not Path(utils.missionMainDir + "/" + version['name']).is_file():
                    existsOnMain = False
                    c.execute(str.format('''update versions set existsOnMain=0 where id = {}''', version['id']))

            if not existsOnMain and not existsOnMM:
                c.execute(str.format('''delete from versions where id = {}''', version['id']))

        c.connection.commit()
        c.connection.close()

        c = utils.getCursor()

        c.execute('''select id, missionName from missions''')

        missions = c.fetchall()
        fileNames = os.listdir(utils.missionMakerDir)

        filesGroupedByMissionName = {}
        for k, g in itertools.groupby(fileNames, lambda x: sanatizeFileName(x)):
            filesGroupedByMissionName[k] = list(g)

        c.execute('''select name from versions''')
        versionRows = c.fetchall()
        versions = [x['name'] for x in versionRows]

        # for each db mission
        # find all files that match
        # for each file
        # find out if file is in db
        # if not
        # add to db
        for mission in missions:
            sanitizedName = sanatizeMissionName(mission['missionName'])
            if sanitizedName in filesGroupedByMissionName:

                filesForThisMission = filesGroupedByMissionName[sanitizedName]
                for fileForThisMission in filesForThisMission:
                    if not fileForThisMission in versions:
                        c.execute(
                            "insert into versions(missionId, name, createDate) values (?, ?, ?)",
                            [mission['id'], fileForThisMission, date.today()])

                    c.execute("update versions set existsOnMM = 1 where name = ?", [fileForThisMission])

        c.connection.commit()
        c.connection.close()

        c = utils.getCursor()

        fileNames = os.listdir(utils.missionMainDir)

        filesGroupedByMissionName = {}
        for k, g in itertools.groupby(fileNames, lambda x: sanatizeFileName(x)):
            filesGroupedByMissionName[k] = list(g)

        c.execute('''select name from versions''')
        versionRows = c.fetchall()
        versions = [x['name'] for x in versionRows]

        # for each db mission
        # find all files that match
        # for each file
        # find out if file is in db
        # if not
        # add to db
        for mission in missions:
            sanitizedName = sanatizeMissionName(mission['missionName'])
            if sanitizedName in filesGroupedByMissionName:

                filesForThisMission = filesGroupedByMissionName[sanitizedName]
                for fileForThisMission in filesForThisMission:
                    if not fileForThisMission in versions:
                        c.execute(
                            "insert into versions(missionId, name, createDate, existsOnMM) values (?, ?, ?, ?)",
                            [mission['id'], fileForThisMission, date.today(), False])
                    c.execute("update versions set existsOnMain = 1 where name = ?", [fileForThisMission])

        c.connection.commit()
        c.connection.close()


    else:
        start_response("403 Permission Denied", [])
        return ["Access Denied".encode()]

    start_response("200 OK", [])
    return []
Exemplo n.º 27
0
def handleUpload(environ, start_response):
    c = utils.getCursor()
    o = parse_qs(environ['QUERY_STRING'])
    missionId = o['missionId'][0]
    if not utils.checkUserPermissions(environ['user'], 2, missionId):
        start_response("403 Permission Denied", [])
        return ["Access Denied"]

    # This monstrosity of code was copied from the internet, I barely understand how it works

    content_type = environ.get('CONTENT_TYPE', '0')
    if not content_type:
        start_response("500 Internal Server Error", [])
        return ["Content-Type header doesn't contain boundary".encode()]
    boundary = content_type.split("=")[1].encode()
    remainbytes = int(environ.get('CONTENT_LENGTH', '0'))

    if remainbytes > (20 * 1024 * 1024):
        start_response("500 Internal Server Error", [])
        return ["20 MB is the max size".encode()]

    line = environ['wsgi.input'].readline()
    remainbytes -= len(line)
    if not boundary in line:
        start_response("500 Internal Server Error", [])
        return ["Content NOT begin with boundary".encode()]
    line = environ['wsgi.input'].readline()
    remainbytes -= len(line)
    decode = line.decode()
    regex = r'Content-Disposition.*name="upload_file"; filename="(.*)".*'
    fn = re.findall(regex, decode)
    if not fn:
        start_response("500 Internal Server Error", [])
        return ["Can't find out file name...".encode()]

    fileName = fn[0]

    # protect from filesystem roaming
    fileName = fileName.replace("..", "")

    if not fileName.endswith(".pbo"):
        start_response("500 Internal Server Error", [])
        return ["Only .pbo files are allowed".encode()]

    fullPath = os.path.join(utils.missionMakerDir, fileName).replace("\n", "")
    line = environ['wsgi.input'].readline()
    remainbytes -= len(line)
    line = environ['wsgi.input'].readline()
    remainbytes -= len(line)
    try:
        out = open(fullPath, 'wb')
    except IOError:
        start_response("500 Internal Server Error", [])
        return ["Can't create file to write, do you have permission to write?".encode()]

    preline = environ['wsgi.input'].readline()
    remainbytes -= len(preline)
    while remainbytes > 0:
        line = environ['wsgi.input'].readline()
        remainbytes -= len(line)
        if boundary in line:
            preline = preline[0:-1]
            if preline.endswith(b'\r'):
                preline = preline[0:-1]
            out.write(preline)
            out.close()
        else:
            out.write(preline)
            preline = line

    # rest of the properties are set by defaults in the table
    c.execute(
        "INSERT INTO versions(missionId, name, createDate) VALUES (?, ?, ?)",
        [missionId, fileName, date.today()])
    c.connection.commit()
    c.connection.close()

    start_response("200 OK", [])
    return ["success".encode()]
Exemplo n.º 28
0
def authorToUser(author):
    c = utils.getCursor()
    c.execute("SELECT discordId FROM users WHERE login = ?", [author.strip()])
    return c.fetchone()[0]