Ejemplo n.º 1
0
async def submit_vote_handler(request: web_request.Request) -> web.Response:
    """Record user votes"""
    vote_input = await request.json()

    auth_key = vote_input["voteKey"]

    if not keys.key_valid(auth_key, keys.vote_keys):
        return web.Response(status=401, text="Invalid or expired vote token")

    user_id = keys.vote_keys[auth_key]["userID"]
    user_name = keys.vote_keys[auth_key]["userName"]
    user_votes = vote_input["votes"]

    week = compo.get_week(False)

    # If user has submitted a vote already, then remove it, so we can
    # replace it with the new one
    for v in week["votes"]:
        if int(v["userID"]) == int(user_id):
            week["votes"].remove(v)

    # Find the user's entry
    user_entry = None

    for entry in week["entries"]:
        if entry["discordID"] == user_id:
            user_entry = entry
            break

    # Remove the user's vote on their own entry (Search by UUID to prevent name spoofing).
    if user_entry is not None:
        user_votes = [
            vote for vote in user_votes
            if vote["entryUUID"] != user_entry["uuid"]
        ]

        # Find the user's highest rating
        max_vote = max(vote["rating"] for vote in user_votes)

        # Grant the user rating equal to their highest vote on each category
        for param in week["voteParams"]:
            user_votes.append({
                "entryUUID": user_entry["uuid"],
                "voteForName": user_name,
                "voteParam": param,
                "rating": max_vote
            })

    vote_data = {
        "ratings": user_votes,
        "userID": user_id,
        "userName": user_name
    }

    week["votes"].append(vote_data)

    compo.save_weeks()

    return web.Response(status=200, text="FRICK yeah")
Ejemplo n.º 2
0
async def admin_preview_handler(request: web_request.Request) -> web.Response:
    """Display next weeks votable entries"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    return web.json_response(format_week(compo.get_week(True), False))
Ejemplo n.º 3
0
async def admin_archive_handler(request: web_request.Request) -> web.Response:
    """Archive current week, move next week to current, and create a new week"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    compo.move_to_next_week()

    return web.Response(status=204, text="Nice")
Ejemplo n.º 4
0
async def admin_handler(request: web_request.Request) -> web.Response:
    """Display admin forms (No data; will be fetched by Vue)"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=404, text="File not found")

    html = admin_template.replace("[VUE-URL]", get_vue_url())

    return web.Response(status=200, body=html, content_type="text/html")
Ejemplo n.º 5
0
async def admin_handler(request: web_request.Request) -> web.Response:
    """Display admin forms (No data; will be fetched by Vue)"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    urls = get_urls()
    html = admin_template.replace("[VUE-URL]", urls["vue"])
    html = html.replace("[POPPER-URL]", urls["popper"])
    html = html.replace("[TOOLTIP-URL]", urls["v-tooltip"])

    return web.Response(status=200, body=html, content_type="text/html")
Ejemplo n.º 6
0
async def get_entry_handler(request: web_request.Request) -> web.Response:
    """Return an entry for editing"""
    auth_key = request.match_info["authKey"]

    if not compo.get_week(True)["submissionsOpen"]:
        return web.Response(status=400,
                            text="Submissions are currently closed!")

    if not keys.key_valid(auth_key, keys.edit_keys):
        return web.Response(status=401, text="Invalid or expired link")

    key = keys.edit_keys[auth_key]

    entry = compo.find_entry_by_uuid(key["entryUUID"])

    return web.json_response(get_editable_entry(entry))
Ejemplo n.º 7
0
async def admin_deletevote_handler(
        request: web_request.Request) -> web.Response:
    """Delete every vote from an user"""
    auth_key = request.match_info["authKey"]
    user_id = request.match_info["userID"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    week = compo.get_week(False)
    week["votes"] = [
        vote for vote in week["votes"] if vote["userID"] != user_id
    ]

    compo.save_weeks()

    return web.Response(status=204)
Ejemplo n.º 8
0
async def admin_viewvote_handler(request: web_request.Request) -> web.Response:
    """?"""
    auth_key = request.match_info["authKey"]
    user_id = request.match_info["userID"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    week = compo.get_week(False)

    for v in week["votes"]:
        if int(v["userID"]) == int(user_id):
            return web.Response(status=200,
                                body=json.dumps(v),
                                content_type="application/json")

    return web.Response(status=404, text="File not found")
Ejemplo n.º 9
0
async def admin_spoof_handler(request: web_request.Request) -> web.Response:
    """Create a fake new entry

       TODO: Take in more data?
    """
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    entry_data = await request.json()

    new_entry = compo.create_blank_entry(entry_data["entrantName"],
                                         int(entry_data["discordId"]))
    week = compo.get_week(entry_data["nextWeek"])
    week["entries"].append(new_entry)

    return web.Response(status=204, text="Nice")
Ejemplo n.º 10
0
async def admin_get_data_handler(request: web_request.Request) -> web.Response:
    """Display admin data:

       - Week information
       - Submissions
       - Votes
    """
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    this_week = compo.get_week(False)
    next_week = compo.get_week(True)

    weeks = [format_week(this_week, True), format_week(next_week, True)]
    votes = get_week_votes(this_week)

    data = {"weeks": weeks, "votes": votes}

    return web.json_response(data)
Ejemplo n.º 11
0
async def admin_control_handler(request: web_request.Request) -> web.Response:
    """Update week information"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    this_week = compo.get_week(False)
    next_week = compo.get_week(True)

    data = await request.json()

    next_week["theme"] = data["weeks"][1]["theme"]
    next_week["date"] = data["weeks"][1]["date"]
    next_week["submissionsOpen"] = data["weeks"][1]["submissionsOpen"]

    this_week["theme"] = data["weeks"][0]["theme"]
    this_week["date"] = data["weeks"][0]["date"]
    this_week["votingOpen"] = data["weeks"][0]["votingOpen"]

    compo.save_weeks()
    return web.Response(status=204, text="Nice")
Ejemplo n.º 12
0
 def test_return_bool(self, valid_key, expired_key):
     assert isinstance(keys.key_valid(valid_key[0], valid_key[1]), bool)
     assert isinstance(keys.key_valid(valid_key[0], {}), bool)
     assert isinstance(keys.key_valid(expired_key[0], expired_key[1]), bool)
Ejemplo n.º 13
0
 def test_expired_key_removed(self, expired_key):
     key, store, args = expired_key
     keys.key_valid(key, store)
     assert key not in store
Ejemplo n.º 14
0
 def test_key_expired(self, expired_key):
     assert keys.key_valid(expired_key[0], expired_key[1]) == False
Ejemplo n.º 15
0
 def test_key_not_in_store(self, valid_key):
     assert keys.key_valid(valid_key[0], {}) == False
Ejemplo n.º 16
0
 def test_key_valid(self, valid_key):
     assert keys.key_valid(valid_key[0], valid_key[1])
Ejemplo n.º 17
0
async def file_post_handler(request: web_request.Request) -> web.Response:
    """Handle user submission.
       If user was an admin, mark entry as meddled with.

       This takes multipart/form-encoding because of large files
    """
    auth_key = request.match_info["authKey"]
    uuid = request.match_info["uuid"]

    is_authorized_user = (keys.key_valid(auth_key, keys.edit_keys)
                          and keys.edit_keys[auth_key]["entryUUID"] == uuid
                          and compo.get_week(True)["submissionsOpen"])

    is_admin = keys.key_valid(auth_key, keys.admin_keys)
    is_authorized = is_authorized_user or is_admin
    if not is_authorized:
        return web.Response(status=401, text="Invalid or expired link")

    # Find the entry
    choice = None
    for which_week in [True, False]:
        week = compo.get_week(which_week)

        for entryIndex, entry in enumerate(week["entries"]):
            if entry["uuid"] == uuid:
                choice = (week, entryIndex, entry)
                break

    if choice is None:
        return web.Response(status=404,
                            text="That entry doesn't seem to exist")

    week, entryIndex, entry = choice

    # Process it
    reader = await request.multipart()
    if reader is None:
        return web.Response(status=400, text="Error uploading data idk")

    async for field in reader:
        if is_admin:
            if field.name == "entrantName":
                entry["entrantName"] = \
                    (await field.read(decode=True)).decode("utf-8")
            elif field.name == "entryNotes":
                entry["entryNotes"] = \
                    (await field.read(decode=True)).decode("utf-8")
                if entry["entryNotes"] == "undefined":
                    entry["entryNotes"] = ""
            elif field.name == "deleteEntry":
                week["entries"].remove(entry)
                compo.save_weeks()
                return web.Response(status=200,
                                    text="Entry successfully deleted.")

        if field.name == "entryName":
            entry["entryName"] = \
                (await field.read(decode=True)).decode("utf-8")
        elif field.name == "mp3Link":
            url = (await field.read(decode=True)).decode("utf-8")
            if len(url) > 1:
                if not any(
                        url.startswith(host)
                        for host in config["allowed_hosts"]):
                    return web.Response(
                        status=400,
                        text="You entered a link to a website we don't allow.")

                entry["mp3"] = url
                entry["mp3Format"] = "external"
                entry["mp3Filename"] = ""
        elif field.name == "mp3" or field.name == "pdf":
            if field.filename == "":
                continue
            if not field.filename.endswith(field.name):
                errMsg = "Wrong file format! Expected %s" % field.name
                return web.Response(status=400, text=errMsg)

            size = 0
            entry[field.name] = None

            entry[field.name + "Filename"] = field.filename

            if field.name == "mp3":
                entry["mp3Format"] = "mp3"

            while True:
                chunk = await field.read_chunk()
                if not chunk:
                    break
                size += len(chunk)
                if size > 1000 * 1000 * 8:  # 8MB limit
                    entry[field.name] = None
                    entry[field.name + "Filename"] = None
                    return web.Response(status=413, text=too_big_text)
                if entry[field.name] is None:
                    entry[field.name] = chunk
                else:
                    entry[field.name] += chunk

    if not is_admin:
        # Move the entry to the end of the list
        week["entries"].append(week["entries"].pop(entryIndex))

    compo.save_weeks()

    await bot.submission_message(entry, is_admin)

    return web.Response(status=204)