Example #1
0
def oauth_login():
    endpoint = get_app_config('OAUTH_AUTHORIZATION_ENDPOINT') \
        or get_config('oauth_authorization_endpoint') \
        or 'https://auth.majorleaguecyber.org/oauth/authorize'

    if get_config('user_mode') == 'teams':
        scope = 'profile team'
    else:
        scope = 'profile'

    client_id = get_app_config('OAUTH_CLIENT_ID') or get_config('oauth_client_id')

    if client_id is None:
        error_for(
            endpoint='auth.login',
            message='OAuth Settings not configured. '
                    'Ask your CTF administrator to configure MajorLeagueCyber integration.'
        )
        return redirect(url_for('auth.login'))

    redirect_url = "{endpoint}?response_type=code&client_id={client_id}&scope={scope}&state={state}".format(
        endpoint=endpoint,
        client_id=client_id,
        scope=scope,
        state=session['nonce']
    )
    return redirect(redirect_url)
Example #2
0
def oauth_login():
    endpoint = (get_app_config("OAUTH_AUTHORIZATION_ENDPOINT")
                or get_config("oauth_authorization_endpoint")
                or "https://auth.majorleaguecyber.org/oauth/authorize")

    if get_config("user_mode") == "teams":
        scope = "profile team"
    else:
        scope = "profile"

    client_id = get_app_config("OAUTH_CLIENT_ID") or get_config(
        "oauth_client_id")

    if client_id is None:
        error_for(
            endpoint="auth.login",
            message="OAuth Settings not configured. "
            "Ask your CTF administrator to configure MajorLeagueCyber integration.",
        )
        return redirect(url_for("auth.login"))

    redirect_url = "{endpoint}?response_type=code&client_id={client_id}&scope={scope}&state={state}".format(
        endpoint=endpoint,
        client_id=client_id,
        scope=scope,
        state=session["nonce"])
    return redirect(redirect_url)
Example #3
0
def oauth_redirect():
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
    if request.values.get('error'):
        log("logins", "[{date}] {ip} - Received redirect without OAuth code")
        error_for(endpoint="auth.login", message=str(request.values['error']))
        return redirect(url_for("auth.login"))
    else:
        discord = make_session(state=session.get('oauth2_state'))
        token = discord.fetch_token(
            "https://discordapp.com/api/oauth2/token",
            client_secret="kHLKALybV7qJmlYCsvAr5URdFl1jh4F2",
            authorization_response=request.url)

        discord = make_session(token=token)
        discord_user = discord.get(
            "https://discordapp.com/api/users/@me").json()
        guilds = discord.get(
            "https://discordapp.com/api/users/@me/guilds").json()

        user = Users.query.filter_by(email=discord_user['email']).first()
        if user is None:
            user = Users(
                name=discord_user['username'],
                email=discord_user['email'],
                oauth_id=discord_user['id'],
            )
            db.session.add(user)
            db.session.commit()
        login_user(user)
        return redirect(url_for("challenges.listing"))
Example #4
0
    def reddit_login():
        endpoint = (get_app_config("REDDIT_AUTHORIZATION_ENDPOINT")
                    or get_config("reddit_authorization_endpoint")
                    or "https://ssl.reddit.com/api/v1/authorize")

        client_id = get_app_config("REDDIT_CLIENT_ID") or get_config(
            "reddit_client_id")
        callback_url = get_app_config("REDDIT_CALLBACK_URL") or get_config(
            "reddit_callback_url")

        if client_id is None:
            error_for(
                endpoint="reddit.login",
                message="Reddit OAuth Settings not configured. "
                "Ask your CTF administrator to configure Reddit integration.",
            )
            return redirect(url_for("auth.login"))

        redirect_url = "{endpoint}?client_id={client_id}&response_type=code&state={state}&redirect_uri={callback_url}&duration=temporary&scope=identity".format(
            endpoint=endpoint,
            client_id=client_id,
            state=session["nonce"],
            callback_url=callback_url)
        return redirect(redirect_url)
Example #5
0
def oauth_redirect():
    oauth_code = request.args.get("code")
    state = request.args.get("state")
    if session["nonce"] != state:
        log("logins", "[{date}] {ip} - OAuth State validation mismatch")
        error_for(endpoint="auth.login",
                  message="OAuth State validation mismatch.")
        return redirect(url_for("auth.login"))

    if oauth_code:
        url = (get_app_config("OAUTH_TOKEN_ENDPOINT")
               or get_config("oauth_token_endpoint")
               or "https://auth.majorleaguecyber.org/oauth/token")

        client_id = get_app_config("OAUTH_CLIENT_ID") or get_config(
            "oauth_client_id")
        client_secret = get_app_config("OAUTH_CLIENT_SECRET") or get_config(
            "oauth_client_secret")
        headers = {"content-type": "application/x-www-form-urlencoded"}
        data = {
            "code": oauth_code,
            "client_id": client_id,
            "client_secret": client_secret,
            "grant_type": "authorization_code",
        }
        token_request = requests.post(url, data=data, headers=headers)

        if token_request.status_code == requests.codes.ok:
            token = token_request.json()["access_token"]
            user_url = (get_app_config("OAUTH_API_ENDPOINT")
                        or get_config("oauth_api_endpoint")
                        or "https://api.majorleaguecyber.org/user")

            headers = {
                "Authorization": "Bearer " + str(token),
                "Content-type": "application/json",
            }
            api_data = requests.get(url=user_url, headers=headers).json()

            user_id = api_data["id"]
            user_name = api_data["name"]
            user_email = api_data["email"]

            user = Users.query.filter_by(email=user_email).first()
            if user is None:
                # Check if we are allowing registration before creating users
                if registration_visible():
                    user = Users(
                        name=user_name,
                        email=user_email,
                        oauth_id=user_id,
                        verified=True,
                    )
                    db.session.add(user)
                    db.session.commit()
                else:
                    log("logins",
                        "[{date}] {ip} - Public registration via MLC blocked")
                    error_for(
                        endpoint="auth.login",
                        message=
                        "Public registration is disabled. Please try again later.",
                    )
                    return redirect(url_for("auth.login"))

            if get_config("user_mode") == TEAMS_MODE:
                team_id = api_data["team"]["id"]
                team_name = api_data["team"]["name"]

                team = Teams.query.filter_by(oauth_id=team_id).first()
                if team is None:
                    team = Teams(name=team_name,
                                 oauth_id=team_id,
                                 captain_id=user.id)
                    db.session.add(team)
                    db.session.commit()

                team.members.append(user)
                db.session.commit()

            if user.oauth_id is None:
                user.oauth_id = user_id
                user.verified = True
                db.session.commit()

            login_user(user)

            return redirect(url_for("challenges.listing"))
        else:
            log("logins", "[{date}] {ip} - OAuth token retrieval failure")
            error_for(endpoint="auth.login",
                      message="OAuth token retrieval failure.")
            return redirect(url_for("auth.login"))
    else:
        log("logins", "[{date}] {ip} - Received redirect without OAuth code")
        error_for(endpoint="auth.login",
                  message="Received redirect without OAuth code.")
        return redirect(url_for("auth.login"))
Example #6
0
def oauth_redirect():
    oauth_code = request.args.get('code')
    state = request.args.get('state')
    if session['nonce'] != state:
        log('logins', "[{date}] {ip} - OAuth State validation mismatch")
        error_for(endpoint='auth.login', message='OAuth State validation mismatch.')
        return redirect(url_for('auth.login'))

    if oauth_code:
        url = get_app_config('OAUTH_TOKEN_ENDPOINT') \
            or get_config('oauth_token_endpoint') \
            or 'https://auth.majorleaguecyber.org/oauth/token'

        client_id = get_app_config('OAUTH_CLIENT_ID') or get_config('oauth_client_id')
        client_secret = get_app_config('OAUTH_CLIENT_SECRET') or get_config('oauth_client_secret')
        headers = {
            'content-type': 'application/x-www-form-urlencoded'
        }
        data = {
            'code': oauth_code,
            'client_id': client_id,
            'client_secret': client_secret,
            'grant_type': 'authorization_code'
        }
        token_request = requests.post(url, data=data, headers=headers)

        if token_request.status_code == requests.codes.ok:
            token = token_request.json()['access_token']
            user_url = get_app_config('OAUTH_API_ENDPOINT') \
                or get_config('oauth_api_endpoint') \
                or 'http://api.majorleaguecyber.org/user'

            headers = {
                'Authorization': 'Bearer ' + str(token),
                'Content-type': 'application/json'
            }
            api_data = requests.get(url=user_url, headers=headers).json()

            user_id = api_data['id']
            user_name = api_data['name']
            user_email = api_data['email']

            user = Users.query.filter_by(email=user_email).first()
            if user is None:
                user = Users(
                    name=user_name,
                    email=user_email,
                    oauth_id=user_id,
                    verified=True
                )
                db.session.add(user)
                db.session.commit()

            if get_config('user_mode') == TEAMS_MODE:
                team_id = api_data['team']['id']
                team_name = api_data['team']['name']

                team = Teams.query.filter_by(oauth_id=team_id).first()
                if team is None:
                    team = Teams(
                        name=team_name,
                        oauth_id=team_id
                    )
                    db.session.add(team)
                    db.session.commit()

                team.members.append(user)
                db.session.commit()

            login_user(user)

            return redirect(url_for('challenges.listing'))
        else:
            log('logins', "[{date}] {ip} - OAuth token retrieval failure")
            error_for(
                endpoint='auth.login',
                message='OAuth token retrieval failure.'
            )
            return redirect(url_for('auth.login'))
    else:
        log('logins', "[{date}] {ip} - Received redirect without OAuth code")
        error_for(
            endpoint='auth.login',
            message='Received redirect without OAuth code.'
        )
        return redirect(url_for('auth.login'))
Example #7
0
def oauth_redirect():
    oauth_code = request.args.get("code")
    state = request.args.get("state")
    if session["nonce"] != state:
        log("logins", "[{date}] {ip} - OAuth State validation mismatch")
        error_for(endpoint="auth.login",
                  message="OAuth State validation mismatch.")
        return redirect(url_for("auth.login"))

    if oauth_code:
        url = (get_app_config("OAUTH_TOKEN_ENDPOINT")
               or get_config("oauth_token_endpoint")
               or "https://auth.majorleaguecyber.org/oauth/token")

        client_id = get_app_config("OAUTH_CLIENT_ID") or get_config(
            "oauth_client_id")
        client_secret = get_app_config("OAUTH_CLIENT_SECRET") or get_config(
            "oauth_client_secret")
        headers = {"content-type": "application/x-www-form-urlencoded"}
        data = {
            "code": oauth_code,
            "client_id": client_id,
            "client_secret": client_secret,
            "grant_type": "authorization_code",
        }
        token_request = requests.post(url, data=data, headers=headers)

        if token_request.status_code == requests.codes.ok:
            token = token_request.json()["access_token"]
            user_url = (get_app_config("OAUTH_API_ENDPOINT")
                        or get_config("oauth_api_endpoint")
                        or "https://api.majorleaguecyber.org/user")

            headers = {
                "Authorization": "Bearer " + str(token),
                "Content-type": "application/json",
            }
            api_data = requests.get(url=user_url, headers=headers).json()

            user_id = api_data["id"]
            user_name = api_data["name"]
            user_email = api_data["email"]

            user = Users.query.filter_by(email=user_email).first()
            if user is None:
                # Check if we are allowing registration before creating users
                if registration_visible() or mlc_registration():
                    user = Users(
                        name=user_name,
                        email=user_email,
                        oauth_id=user_id,
                        verified=True,
                    )
                    db.session.add(user)
                    db.session.commit()
                else:
                    log("logins",
                        "[{date}] {ip} - Public registration via MLC blocked")
                    error_for(
                        endpoint="auth.login",
                        message=
                        "Public registration is disabled. Please try again later.",
                    )
                    return redirect(url_for("auth.login"))

            if get_config("user_mode") == TEAMS_MODE:
                team_id = api_data["team"]["id"]
                team_name = api_data["team"]["name"]

                team = Teams.query.filter_by(oauth_id=team_id).first()
                if team is None:
                    num_teams_limit = int(get_config("num_teams", default=0))
                    num_teams = Teams.query.filter_by(banned=False,
                                                      hidden=False).count()
                    if num_teams_limit and num_teams >= num_teams_limit:
                        abort(
                            403,
                            description=
                            f"Reached the maximum number of teams ({num_teams_limit}). Please join an existing team.",
                        )

                    team = Teams(name=team_name,
                                 oauth_id=team_id,
                                 captain_id=user.id)
                    db.session.add(team)
                    db.session.commit()
                    clear_team_session(team_id=team.id)

                team_size_limit = get_config("team_size", default=0)
                if team_size_limit and len(team.members) >= team_size_limit:
                    plural = "" if team_size_limit == 1 else "s"
                    size_error = "Teams are limited to {limit} member{plural}.".format(
                        limit=team_size_limit, plural=plural)
                    error_for(endpoint="auth.login", message=size_error)
                    return redirect(url_for("auth.login"))

                team.members.append(user)
                db.session.commit()

            if user.oauth_id is None:
                user.oauth_id = user_id
                user.verified = True
                db.session.commit()
                clear_user_session(user_id=user.id)

            login_user(user)

            return redirect(url_for("challenges.listing"))
        else:
            log("logins", "[{date}] {ip} - OAuth token retrieval failure")
            error_for(endpoint="auth.login",
                      message="OAuth token retrieval failure.")
            return redirect(url_for("auth.login"))
    else:
        log("logins", "[{date}] {ip} - Received redirect without OAuth code")
        error_for(endpoint="auth.login",
                  message="Received redirect without OAuth code.")
        return redirect(url_for("auth.login"))
Example #8
0
    def oauth_redirect():
        oauth_code = request.args.get("code")
        state = request.args.get("state")
        if session["nonce"] != state:
            log("logins", "[{date}] {ip} - OAuth State validation mismatch")
            error_for(endpoint="auth.login",
                      message="OAuth State validation mismatch.")
            return redirect(url_for("auth.login"))

        if oauth_code:
            url = (get_app_config("REDDIT_TOKEN_ENDPOINT")
                   or get_config("reddit_token_endpoint")
                   or "https://ssl.reddit.com/api/v1/access_token")

            client_id = get_app_config("REDDIT_CLIENT_ID") or get_config(
                "reddit_client_id")
            client_secret = get_app_config(
                "REDDIT_CLIENT_SECRET") or get_config("reddit_client_secret")
            reddit_user_agent = get_app_config(
                "REDDIT_USER_AGENT") or get_config("reddit_user_agent")
            callback_url = get_app_config("REDDIT_CALLBACK_URL") or get_config(
                "reddit_callback_url")
            client_auth = requests.auth.HTTPBasicAuth(client_id, client_secret)

            headers = {
                "content-type": "application/x-www-form-urlencoded",
                "User-Agent": reddit_user_agent
            }

            token_request = requests.post(url,
                                          auth=client_auth,
                                          data={
                                              "grant_type":
                                              "authorization_code",
                                              "code": oauth_code,
                                              "redirect_uri": callback_url
                                          },
                                          headers=headers)

            if token_request.status_code == requests.codes.ok:
                token = token_request.json()["access_token"]
                user_url = (get_app_config("REDDIT_API_ENDPOINT")
                            or get_config("reddit_api_endpoint")
                            or "https://oauth.reddit.com/api/v1/me")

                headers = {
                    "Authorization": "Bearer " + str(token),
                    "User-Agent": reddit_user_agent
                }
                api_response = requests.get(url=user_url, headers=headers)
                log("logins", str(api_response))
                api_data = api_response.json()

                user_id = api_data["id"]
                user_name = api_data["name"]
                user_email = api_data["name"] + "@reddit.com"

                user = Users.query.filter_by(name=user_name).first()
                if user is None:
                    # Check if we are allowing registration before creating users
                    if registration_visible():
                        user = Users(
                            name=user_name,
                            email=user_email,
                            oauth_id=user_id,
                            verified=True,
                        )
                        db.session.add(user)
                        db.session.commit()
                    else:
                        log(
                            "logins",
                            "[{date}] {ip} - Public registration via Reddit blocked"
                        )
                        error_for(
                            endpoint="auth.login",
                            message=
                            "Public registration is disabled. Please try again later.",
                        )
                        return redirect(url_for("auth.login"))

                if get_config("user_mode") == TEAMS_MODE:
                    team_id = api_data["team"]["id"]
                    team_name = api_data["team"]["name"]

                    team = Teams.query.filter_by(oauth_id=team_id).first()
                    if team is None:
                        team = Teams(name=team_name,
                                     oauth_id=team_id,
                                     captain_id=user.id)
                        db.session.add(team)
                        db.session.commit()

                    team_size_limit = get_config("team_size", default=0)
                    if team_size_limit and len(
                            team.members) >= team_size_limit:
                        plural = "" if team_size_limit == 1 else "s"
                        size_error = "Teams are limited to {limit} member{plural}.".format(
                            limit=team_size_limit, plural=plural)
                        error_for(endpoint="auth.login", message=size_error)
                        return redirect(url_for("auth.login"))

                    team.members.append(user)
                    db.session.commit()

                if user.oauth_id is None:
                    user.oauth_id = user_id
                    user.verified = True
                    db.session.commit()

                login_user(user)

                return redirect(url_for("challenges.listing"))
            else:
                log("logins", "[{date}] {ip} - OAuth token retrieval failure")
                log("logins", str(token_request))
                log("logins", str(token_request.status_code))
                log("logins", token_request.json()["access_token"])
                error_for(endpoint="auth.login",
                          message="OAuth token retrieval failure.")
                return redirect(url_for("auth.login"))
        else:
            log("logins",
                "[{date}] {ip} - Received redirect without OAuth code")
            error_for(endpoint="auth.login",
                      message="Received redirect without OAuth code.")
            return redirect(url_for("auth.login"))