def tokens(): token = request.headers.get("Authorization") if token and request.content_type == "application/json": try: token_type, token = token.split(" ", 1) user = lookup_user_token(token) except UserNotFoundException: abort(401) except UserTokenExpiredException: abort(401) except Exception: abort(401) else: login_user(user)
def login(): errors = get_errors() if request.method == "POST": name = request.form["name"] captcha_response = request.form['g-recaptcha-response'] if not is_human(captcha_response): # This user exists but the password is wrong error_captcha = "The response parameter is missing" return render_template("login.html", error_captcha=error_captcha) # Check if the user submitted an email address or a team name if validators.validate_email(name) is True: user = Users.query.filter_by(email=name).first() else: user = Users.query.filter_by(name=name).first() if user: if user and verify_password(request.form["password"], user.password): session.regenerate() login_user(user) log("logins", "[{date}] {ip} - {name} logged in") db.session.close() if request.args.get("next") and validators.is_safe_url( request.args.get("next")): return redirect(request.args.get("next")) return redirect(url_for("challenges.listing")) else: # This user exists but the password is wrong log("logins", "[{date}] {ip} - submitted invalid password for {name}") errors.append("Your username or password is incorrect") db.session.close() return render_template("login.html", errors=errors) else: # This user just doesn't exist log("logins", "[{date}] {ip} - submitted invalid account information") errors.append("Your username or password is incorrect") db.session.close() return render_template("login.html", errors=errors) else: db.session.close() return render_template("login.html", errors=errors)
def setup(): errors = get_errors() if not config.is_setup(): if not session.get("nonce"): session["nonce"] = generate_nonce() if request.method == "POST": # General ctf_name = request.form.get("ctf_name") ctf_description = request.form.get("ctf_description") user_mode = request.form.get("user_mode", USERS_MODE) set_config("ctf_name", ctf_name) set_config("ctf_description", ctf_description) set_config("user_mode", user_mode) # Style theme = request.form.get("ctf_theme", "core") set_config("ctf_theme", theme) theme_color = request.form.get("theme_color") theme_header = get_config("theme_header") if theme_color and bool(theme_header) is False: # Uses {{ and }} to insert curly braces while using the format method css = ( '<style id="theme-color">\n' ":root {{--theme-color: {theme_color};}}\n" ".navbar{{background-color: var(--theme-color) !important;}}\n" ".jumbotron{{background-color: var(--theme-color) !important;}}\n" "</style>\n").format(theme_color=theme_color) set_config("theme_header", css) # DateTime start = request.form.get("start") end = request.form.get("end") set_config("start", start) set_config("end", end) set_config("freeze", None) # Administration name = request.form["name"] email = request.form["email"] password = request.form["password"] name_len = len(name) == 0 names = Users.query.add_columns("name", "id").filter_by(name=name).first() emails = (Users.query.add_columns( "email", "id").filter_by(email=email).first()) pass_short = len(password) == 0 pass_long = len(password) > 128 valid_email = validators.validate_email(request.form["email"]) team_name_email_check = validators.validate_email(name) if not valid_email: errors.append("Please enter a valid email address") if names: errors.append("That user name is already taken") if team_name_email_check is True: errors.append("Your user name cannot be an email address") if emails: errors.append("That email has already been used") if pass_short: errors.append("Pick a longer password") if pass_long: errors.append("Pick a shorter password") if name_len: errors.append("Pick a longer user name") if len(errors) > 0: return render_template( "setup.html", errors=errors, name=name, email=email, password=password, state=serialize(generate_nonce()), ) admin = Admins(name=name, email=email, password=password, type="admin", hidden=True) # Index page index = """<div> <div style="width: 108.6%;"> <img class="w-100 mx-auto d-block" src="themes/core/static/img/logo1.PNG" /> <img class="w-100 mx-auto d-block" src="themes/core/static/img/logo4.PNG" /> <img class="w-100 mx-auto d-block" src="themes/core/static/img/logo2.PNG" /> </div> </div>""".format(request.script_root) page = Pages(title=None, route="index", content=index, draft=False) # Visibility set_config("challenge_visibility", "private") set_config("registration_visibility", "public") set_config("score_visibility", "public") set_config("account_visibility", "public") # Verify emails set_config("verify_emails", None) set_config("mail_server", None) set_config("mail_port", None) set_config("mail_tls", None) set_config("mail_ssl", None) set_config("mail_username", None) set_config("mail_password", None) set_config("mail_useauth", None) # Set up default emails set_config("verification_email_subject", DEFAULT_VERIFICATION_EMAIL_SUBJECT) set_config("verification_email_body", DEFAULT_VERIFICATION_EMAIL_BODY) set_config( "successful_registration_email_subject", DEFAULT_SUCCESSFUL_REGISTRATION_EMAIL_SUBJECT, ) set_config( "successful_registration_email_body", DEFAULT_SUCCESSFUL_REGISTRATION_EMAIL_BODY, ) set_config("user_creation_email_subject", DEFAULT_USER_CREATION_EMAIL_SUBJECT) set_config("user_creation_email_body", DEFAULT_USER_CREATION_EMAIL_BODY) set_config("password_reset_subject", DEFAULT_PASSWORD_RESET_SUBJECT) set_config("password_reset_body", DEFAULT_PASSWORD_RESET_BODY) set_config( "password_change_alert_subject", "Password Change Confirmation for {ctf_name}", ) set_config( "password_change_alert_body", ("Your password for {ctf_name} has been changed.\n\n" "If you didn't request a password change you can reset your password here: {url}" ), ) set_config("setup", True) try: db.session.add(admin) db.session.commit() except IntegrityError: db.session.rollback() try: db.session.add(page) db.session.commit() except IntegrityError: db.session.rollback() login_user(admin) db.session.close() with app.app_context(): cache.clear() return redirect(url_for("views.static_html")) return render_template( "setup.html", nonce=session.get("nonce"), state=serialize(generate_nonce()), themes=config.get_themes(), ) return redirect(url_for("views.static_html"))
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: 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") 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"))
def register(): errors = get_errors() if request.method == "POST": name = request.form.get("name", "").strip() email_address = request.form.get("email", "").strip().lower() password = request.form.get("password", "").strip() name_len = len(name) == 0 names = Users.query.add_columns("name", "id").filter_by(name=name).first() emails = (Users.query.add_columns( "email", "id").filter_by(email=email_address).first()) pass_short = len(password) == 0 pass_long = len(password) > 128 valid_email = validators.validate_email(email_address) team_name_email_check = validators.validate_email(name) if not valid_email: errors.append("Please enter a valid email address") if email.check_email_is_whitelisted(email_address) is False: errors.append( "Only email addresses under {domains} may register".format( domains=get_config("domain_whitelist"))) if names: errors.append("That user name is already taken") if team_name_email_check is True: errors.append("Your user name cannot be an email address") if emails: errors.append("That email has already been used") if pass_short: errors.append("Pick a longer password") if pass_long: errors.append("Pick a shorter password") if name_len: errors.append("Pick a longer user name") if len(errors) > 0: return render_template( "register.html", errors=errors, name=request.form["name"], email=request.form["email"], password=request.form["password"], ) else: with app.app_context(): user = Users(name=name, email=email_address, password=password) db.session.add(user) db.session.commit() db.session.flush() login_user(user) if config.can_send_mail() and get_config( "verify_emails" ): # Confirming users is enabled and we can send email. log( "registrations", format= "[{date}] {ip} - {name} registered (UNCONFIRMED) with {email}", ) email.verify_email_address(user.email) db.session.close() return redirect(url_for("auth.confirm")) else: # Don't care about confirming users if ( config.can_send_mail() ): # We want to notify the user that they have registered. email.successful_registration_notification(user.email) log("registrations", "[{date}] {ip} - {name} registered with {email}") db.session.close() if is_teams_mode(): return redirect(url_for("teams.private")) return redirect(url_for("challenges.listing")) else: return render_template("register.html", errors=errors)