Example #1
0
def remove_member(request: _Parsed,
                  clan: str,
                  creds: CredManager = CredManager):
    if not ALLOW_REMOVALS:
        raise AppException("Players can not be removed from the clan now!")
    user = creds.user
    json = request.json
    to_remove = json.get("user")
    clan_data = get_clan_by_id(clan)

    members = clan_data.members

    if user != clan_data.leader and not creds.is_admin:
        raise AppException(f"You cannot edit settings for Clan {clan}")

    if to_remove not in members:
        if to_remove not in clan_data.clan_requests:
            raise AppException(f"User is not a member of Clan {clan}")

        remove_player_request(clan_data, get_user_by_id(to_remove))
    else:
        remove_player_from_clan(clan_data, get_user_by_id(to_remove))

    if len(clan_data.members) == 0:
        delete_from_db(clan_data, True)

    save_to_db()
    data = clan_data.as_json
    if user == to_remove:
        data.pop("_secure_")
    return {"clan_data": data}
Example #2
0
def request_to_join(request: _Parsed,
                    clan: str,
                    event_name: str,
                    creds: CredManager = CredManager):
    get = request.json.get
    user = creds.user
    user_data = get_user_by_id(user)

    registration_data = get("registration_data")
    assert_user_has_discord(
        user_data, error_message="You have not connected discord yet!")
    assert_user_is_clanless(user_data, event_name, prefix="You are")

    maximum = MAX_MEMBER_COUNT.get(event_name)

    clan_data = get_clan_by_id(clan)
    if len(clan_data.members) == maximum:
        raise AppException(
            f"Clan {clan_data.team_name} already has {maximum} members")

    if user in clan_data.clan_invites:
        add_player_with_side_effects(clan_data, user_data)
    else:
        current_requests = clan_data.clan_requests
        if user in current_requests:
            raise AppException(
                f"You have already requested to join Clan {clan}")

        add_player_request(clan_data, user_data)

    add_registration_data(user_data, event_name, registration_data)

    save_to_db()
    return {"user_data": user_data.as_json}
Example #3
0
def validate_file(event, data):
    # APPROVED_DOMAINS = ("drive.google.com", "pastebin.com", "discord.com")
    if event not in EVENTS_REQUIRING_SUBMISSION:
        raise AppException("Invalid event!")
    parsed = urlparse(data)
    if parsed.scheme.lower() not in ("http", "https") or not parsed.netloc:
        raise AppException("Invalid URL")
Example #4
0
def add_member(request: _Parsed, clan: str, creds: CredManager = CredManager):
    user = creds.user
    json = request.json
    to_add = json.get("user")
    if to_add == user:
        raise AppException("You cannot add yourself to a team!")

    clan_data = get_clan_by_id(clan)
    members = clan_data.members
    if user not in members and not creds.is_admin:
        raise AppException(f"You cannot edit settings for Clan {clan}")

    clan_event = clan_data.team_event
    maximum = MAX_MEMBER_COUNT.get(clan_event)
    if maximum == len(members):
        raise AppException(f"Clan has reached the max limit of players")

    addee_data = get_user_by_id(to_add)

    assert_user_is_clanless(addee_data, clan_event)

    clan_requests = clan_data.clan_requests
    if to_add in clan_requests:
        add_player_with_side_effects(clan_data, addee_data)

    else:
        # the player hasn't requested to join, invite them
        invites = addee_data.clan_invites.get(clan_event) or []

        if clan in invites:
            raise AppException("Already Invited!")
        add_player_invite(clan_data, addee_data)

    save_to_db()
    return {"clan_data": clan_data.as_json}
Example #5
0
def login(request: _Parsed):
    json = request.json
    get = json.get
    user = get("user", "").strip().lower()
    password = get("password", "")
    invalids = []
    if not user:
        invalids.append("username")
    if not password:
        invalids.append("password")
    if invalids:
        raise AppException(f"Invalid {' and '.join(invalids)}", code=401)
    user_data = get_user_by_id(user)
    password_hash = user_data.password_hash
    if not check_password_hash(password_hash, password):
        raise AppException("Incorrect Password", code=401)
    username = user_data.user
    access_token = create_token(issue_access_token(username))
    refresh_token = create_token(issue_refresh_token(username, password_hash))

    return json_response(
        {"data": {
            "success": True,
            "user_data": user_data.as_json
        }},
        headers={
            "x-access-token": access_token,
            "x-refresh-token": refresh_token
        },
    )
Example #6
0
 def _validate_user(self, user: str):
     length = len(user)
     if length > 30:
         raise AppException("Username cannot be longer than 30 characters")
     if length < 4:
         raise AppException("Username cannot be shorter than 4 characters")
     if sanitize(user) != user:
         raise AppException("Username cannot have special characters or whitespace")
Example #7
0
 def _validate_team_name(self, val):
     val_len = len(val)
     if val_len > 80:
         raise AppException("Team name must be less than 30 characters")
     if val_len < 4:
         raise AppException("Team name must be atleast 4 characters")
     if sanitize(val) != val:
         raise AppException("Invalid characters in team name")
Example #8
0
def edit(request: _Parsed, user: str, creds: CredManager = CredManager):
    editable_fields = ("email", "school", "name")
    current_user = creds.user
    if user != current_user:
        raise AppException("Cannot edit ( not allowed )")
    json = request.json
    edit_field = json.get("field")
    if edit_field not in editable_fields:
        raise AppException("Requested field cannot be edited")
    new_value = json.get("new_value")
    user_data = get_user_by_id(current_user)

    setattr(user_data, edit_field, new_value)
    save_to_db()
    return user_data.as_json
Example #9
0
def setup_discord(request: _Parsed, creds=CredManager):
    user = get_user_by_id(creds.user)
    if all(x for x in (
            user.discord_id,
            user.discord_access_token,
            user.discord_refresh_token,
            user.discord_token_expires_in,
    )):
        raise AppException("Discord already linked!!")
    code = request.json["code"]

    discord_response = exchange_code(code)

    access = discord_response["access"]
    refresh = discord_response["refresh"]
    expires = discord_response["expires"]
    discord_id = discord_response["discord_id"]

    user.discord_id = discord_id
    user.discord_access_token = access
    user.discord_refresh_token = refresh
    user.discord_token_expires_in = expires

    save_to_db()

    return {"user_data": user.as_json}
Example #10
0
def decode_token(data: str) -> dict:
    try:
        return _decode_token(data, _SIGNING_KEY)
    except _EXPIRED:
        return None
    except:
        raise AppException("Invalid token")
Example #11
0
def decode_token(data: str) -> dict:
    try:
        return _decode_token(data, _SIGNING_KEY, algorithms=["HS512"])
    except _EXPIRED:
        return None
    except Exception as e:
        print(e)
        raise AppException("Invalid token", 400)
Example #12
0
def score_team(request: ParsedRequest, team, creds=CredManager):
    json = request.json
    team_data = get_clan_by_id(team)
    score = int(json["score"])
    if not 0 <= score <= 20:
        raise AppException("Invalid value of score")
    round_num = int(json["round"])
    if team_data.current_round != round_num:
        raise AppException("User has already been rated for this round")
    # validate_score(score,team_data.team_event)
    # if only allow scores  5+ to progress
    if score > 5 and get_config(
            team_data.team_event).number_of_rounds < round_num:
        team_data.current_round += 1
    team_data.score.append(score)
    save_to_db()
    return SUCCESS
Example #13
0
def requalify(request: ParsedRequest, team, creds=CredManager):

    team_data = get_clan_by_id(team)
    if not team_data.is_disqualifed:
        raise AppException("Team not disqualified")
    team_data.is_disqualified = False
    save_to_db()
    return SUCCESS
Example #14
0
def query_user(data: dict) -> dict:
    access = data["access"]
    req = requests.get(f"{API_ENDPOINT}/users/@me", auth=TokenAuth(access))
    js = req.json()
    if not req.ok:
        print(js)
        raise AppException("Error while fetching user data from discord")
    data["discord_id"] = js["id"]
    return data
Example #15
0
def get_user_details(request: _Parsed,
                     user: str,
                     creds: CredManager = CredManager):
    current_user = creds.user
    if current_user is not None and (user == "me"
                                     or current_user == user.lower()):
        return self_details(request, creds)

    raise AppException("Not authorized", 403)
Example #16
0
def assert_user_has_discord(user: UserTable,
                            error_message="No discord connection found!"):
    if any(not x for x in (
            user.discord_id,
            user.discord_access_token,
            user.discord_refresh_token,
            user.discord_token_expires_in,
    )):
        raise AppException(error_message)
Example #17
0
    def __setattr__(self, key: str, val):
        if self._is_same_value(key, val):
            return

        if key == "team_event":
            if val not in EVENT_NAMES:
                raise AppException(f"Invalid Event name {val}")

        if key == "team_name":
            val = val.lower()
            self._validate_team_name(val)

        if key == "is_disqualified" and not val:
            # if we are requalifying someone, also clear the disqualification reason
            if self.__inited:
                super().__setattr__("disqualification_reason", None)
        if key == "members" and len(val) > 5:
            raise AppException("Team can only have 5 players at amx")
        super().__setattr__(key, val)
Example #18
0
def verify_email(token: str):
    token = decode_token(token)
    assert_token_is_valid(token)
    user = token["u"]
    user_data = get_user_by_id(user)
    if user_data.email == token["e"]:
        user_data.has_verified_email = True
        save_to_db()
        return True
    raise AppException("Could not verify email")
Example #19
0
def disqualify(request: ParsedRequest, team, creds=CredManager):

    reason = request.json["reason"].strip()

    team_data = get_clan_by_id(team)
    if team_data.is_disqualifed:
        raise AppException("Already disqualified")
    team_data.is_disqualified = True
    team_data.disqualification_reason = reason
    save_to_db()
    return SUCCESS
Example #20
0
def submit(request: _Parsed, event: str, team_name: str, creds=CredManager):
    json: dict = request.json
    submit_data = json["data"]
    submission_round = json["round"]

    validate_file(event, submit_data)

    team_data = get_clan_by_id(team_name)
    if creds.user != team_data.leader:
        raise AppException("Only the clan leader can submit")

    if len(team_data.submissions) > submission_round:
        raise AppException("Already submitted!")

    if team_data.current_round != submission_round:
        raise AppException("Invalid level")

    team_data.submissions.append(submit_data)
    team_data.submitted_at = time()
    save_to_db()
    return {"team_data": team_data.as_json}
Example #21
0
def get_user_details(request: _Parsed,
                     user: str,
                     creds: CredManager = CredManager):
    current_user = creds.user
    if user == "me" or current_user == user.lower():
        if current_user is not None:
            return self_details(request, creds)
        raise AppException("Not Authenticated")
    user_details = get_user_by_id(user)
    json = user_details.as_json
    json.pop("_secure_")
    return {"user_data": json}
Example #22
0
def verify_password(token: str, new_password: str):
    token = decode_token(token)
    assert_token_is_valid(token)

    user = token["u"]
    user_data = get_user_by_id(user)
    if not check_password_hash(token["ch"],
                               user_data.user + user_data.password_hash):
        raise AppException("Password already changed!")

    user_data.password_hash = new_password
    save_to_db()
Example #23
0
def create_team(request: _Parsed,
                team_event,
                creds: CredManager = CredManager):
    json = request.json
    get = json.get
    team_name = get("team_name")
    if team_event not in EVENT_NAMES:
        # bail out before hitting the db
        raise AppException("Event does not exist")

    registration_data = get("registration_data")

    user = get_user_by_id(creds.user)

    assert_user_has_discord(
        user,
        error_message="Cannot create clan without integrating with discord")

    assert_user_is_clanless(user, team_event, prefix="You are")

    members = [creds.user]
    try:
        team = TeamTable(
            team_name=team_name,
            team_event=team_event,
            members=members,
            leader=creds.user,
        )
        user.team_data[team_event] = {
            "name": team_name,
            "registration_data": validate(registration_data, team_event),
        }

        add_to_db(team)
    except Exception as e:
        if isinstance(getattr(e, "orig", None), IntegrityError):
            raise AppException("clan name taken")
        raise e
    return {"clan_data": team.as_json}
Example #24
0
def get_token(strict=True):
    headers = request.headers
    # should just use Authorization here...
    received_access_token = headers.get("x-access-token")

    if not received_access_token:
        if strict:
            raise AppException("No authentication provided")
        return None
    try:
        access = decode(received_access_token)
    except Exception:
        if strict:
            raise AppException("Invalid token")
        return None

    if access is None:
        if strict:
            raise AppException("refresh")
        return None

    return access
Example #25
0
def music_shape(
    artist_name: str = None,
    daw_used: str = None,
    music_platform_link: str = None,
    category: str = None,
) -> dict:
    if category not in ("edm", "lofi"):
        raise AppException("Invalid Music category")
    return {
        "artist_name": artist_name,
        "daw_used": daw_used,
        "music_platform_link": music_platform_link,
        "category": category,
    }
Example #26
0
def get_file_list(request: _Parsed,
                  user: str,
                  creds: CredManager = CredManager):
    if creds.user is None or (creds.user != user):
        raise AppException("Not authorized", 403)

    # pylint: disable=no-member
    files = (db.session.query(
        *[c for c in File.__table__.c if c.name != "binary"]).filter(
            File.owner_user == user, File.data_type == "encrypted_blob").all())
    # pylint: enable=no-member
    ret = [f._asdict() for f in files]

    return {"files": ret}
Example #27
0
def _post_to_discord(data):
    r = requests.post(f"{API_ENDPOINT}/oauth2/token", data=data)

    if not r.ok:
        print(r.text)
        # return
        raise AppException("Discord api gave invalid response")
    js = r.json()
    return {
        "access": js["access_token"],
        "refresh": js.get("refresh_token"),
        "expires": js["expires_in"],
        "token_type": "discord",
    }
Example #28
0
def register_for_game(request: _Parsed,
                      game: str,
                      creds: CredManager = CredManager):
    get = request.json.get
    game = get("gaming_event__game")
    data = get("registration_data")

    user = creds.user

    user_data = get_user_by_id(user)
    event = "gaming"
    team_data = user_data.team_data.get(event)
    if team_data is None:
        raise AppException("Please register for the event first")

    game_data = team_data.get("game_data") or {}

    reg_data = game_data.get(game)
    if reg_data is not None:
        raise AppException("Already submitted details!")
    mutate(team_data, "game_data", "game",
           init_user_gaming_data_dict(data, game))
    save_to_db()
    return {"user_data": user_data.as_json}
Example #29
0
def register(request: _Parsed):
    json = request.json
    get = json.get
    user = get("user")
    name = get("name")
    password = get("password")

    try:
        user_data = UserTable(user, name, password)
        add_to_db(user_data)
        print("registered ", user)
        return {"user_data": user_data.as_json}
    except Exception as e:
        if isinstance(getattr(e, "orig", None), IntegrityError):
            raise AppException("User exists", 409)
        raise e
Example #30
0
def reset_password(request: _Parsed, creds=CredManager):
    user = creds.user
    js = request.json
    current_password = js["current_password"]
    new_password = js["new_password"]
    u_data = get_user_by_id(user)
    hashed_pw = u_data.password_hash
    if not check_password_hash(hashed_pw, current_password):
        raise AppException("Incorrect Password", 401)
    u_data.password_hash = new_password
    save_to_db()
    return {
        "user_data":
        u_data.as_json,
        "message":
        "Please do not close the window while CollegeWarden re encrypts your files with the new password",
    }