def test_clear_all_user_sessions():
    app = create_ctfd()
    with app.app_context():
        register_user(app)

        # Users by default should have a non-admin type
        user = Users.query.filter_by(id=2).first()
        with app.test_request_context("/"):
            login_user(user)
            user = get_current_user()
            assert user.id == 2
            assert user.type == "user"
            assert is_admin() is False

            # Set the user's updated type
            user = Users.query.filter_by(id=2).first()
            user.type = "admin"
            app.db.session.commit()

            # Should still return False because this is still cached
            assert is_admin() is False

            clear_all_user_sessions()

            # Should now return True after clearing cache
            assert is_admin() is True
    destroy_ctfd(app)
示例#2
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"))
示例#3
0
def login():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]
        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)
示例#4
0
    def token_login():
        secret = current_app.secret_key
        if not secret:
           abort(500)

        data = request.form or request.get_json()
        token = data.get('token', None)
        if not token:
            log('logins', "[{date}] {ip} Token not found ({keys})", keys=",".join(data.keys()))
            abort(403)

        serializer = URLSafeTimedSerializer(secret)

        try:
            tokenized_username = serializer.loads(token, max_age=30)
        except SignatureExpired:
            log('logins', "[{date}] {ip} Token has expired")
            abort(403)
        except BadSignature:
            log('logins', "[{date}] {ip} Bad Token Signature")
            abort(403)

        user = Users.query.filter_by(name=tokenized_username).first()
        if not user:
            log('logins', "[{date}] {ip} Bad username")
            abort(403)

        session.regenerate()

        login_user(user)
        log('logins', "[{date}] {ip} - {name} logged in via token")
        db.session.close()
        return jsonify(success=True)
示例#5
0
    def confirm_auth_provider(auth_provider):
        if not provider_users.has_key(auth_provider):
            return redirect('/')

        provider_user = provider_users[oauth_provider]()  # Resolved lambda
        session.regenerate()
        if provider_user is not None:
            login_user(provider_user)
        return redirect('/')
示例#6
0
    def register():  # register
        def error(msg):
            return {"success": False, "data": msg}

        name = request.json.get("name", "").strip()
        email_address = request.json.get("email", "").strip().lower()
        password = request.json.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:
            return error("Please enter a valid email address")
        if email.check_email_is_whitelisted(email_address) is False:
            return error("Only email addresses under {domains} may register".format(
                domains=get_config("domain_whitelist")
            ))
        if names:
            return error("That user name is already taken")
        if team_name_email_check is True:
            return error("Your user name cannot be an email address")
        if emails:
            return error("That email has already been used")
        if pass_short:
            return error("Pick a longer password")
        if pass_long:
            return error("Pick a shorter password")
        if name_len:
            return error("Pick a longer user name")

        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"
            ):
                email.verify_email_address(user.email)
                db.session.close()
                return {"success": True, "data": url_for("auth.confirm")}
            else:
                if (config.can_send_mail()):
                    email.successful_registration_notification(user.email)
        db.session.close()
        return {"success": True, "data": None}
示例#7
0
文件: oauth2.py 项目: yakovk/CTFd
    def confirm_auth_provider(auth_provider):
        if auth_provider not in provider_users:
            return redirect('/')

        provider_user = provider_users[oauth_provider]()  # Resolved lambda
        if provider_user is not None:
            session.regenerate()
            login_user(provider_user)
            db.session.close()
        return redirect('/')
示例#8
0
def login():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]

        # 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.password is None:
                errors.append(
                    "Your account was registered with a 3rd party authentication provider. "
                    "Please try logging in with a configured authentication provider."
                )
                return render_template("login.html", errors=errors)

            if user and verify_password(request.form["password"],
                                        user.password):
                session.regenerate()

                login_user(user)
                log("logins",
                    "[{date}] {ip} - {name} logged in",
                    name=user.name)

                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}",
                    name=user.name,
                )
                errors.append("用户名或密码错误")
                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("用户名或密码错误")
            db.session.close()
            return render_template("login.html", errors=errors)
    else:
        db.session.close()
        return render_template("login.html", errors=errors)
示例#9
0
 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)
示例#10
0
文件: oidc.py 项目: yakovk/CTFd
    def handle_authorize(remote, token, user_info):

        with app.app_context():
            user = get_or_create_user(
                email=user_info["email"],
                name=user_info["name"])

            if user is not None:
                session.regenerate()
                login_user(user)
                log("logins", "[{date}] {ip} - " + user.name + " logged in")
                db.session.close()
                return redirect(url_for("challenges.listing"))

        return redirect('/')
示例#11
0
def register():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]
        password = request.form["password"]

        name_len = len(name) == 0
        names = Users.query.add_columns("name", "id").filter_by(name=name).first()
        pass_short = len(password) == 0
        pass_long = len(password) > 128

        if names:
            errors.append("That user name is already taken")
        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"],
                password=request.form["password"],
            )
        else:
            with app.app_context():
                user = Users(
                    name=name.strip(),
                    password=password.strip(),
                )
                db.session.add(user)
                db.session.commit()
                db.session.flush()

                login_user(user)

        log("registrations", "[{date}] {ip} - {name} registered")
        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)
示例#12
0
文件: auth.py 项目: itsTurnip/CTFd
def login():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]

        # 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("Неверное имя пользователя или пароль")
                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("Неверное имя пользователя или пароль")
            db.session.close()
            return render_template("login.html", errors=errors)
    else:
        db.session.close()
        return render_template("login.html", errors=errors)
示例#13
0
文件: auth.py 项目: xmsec/LanCTFd
def login():
    errors = get_errors()
    if request.method == 'POST':
        name = request.form['name']

        # 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 check_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)
示例#14
0
 def login():  # login
     req = request.json
     if 'name' not in req or 'password' not in req:
         return {"success": False, "data": None}
     name = req['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 and verify_password(request.json["password"], user.password):
         session.regenerate()
         login_user(user)
         db.session.close()
         return {
             "success": True, "data": {
             "nonce": session["nonce"],
         }}
     else:
         db.session.close()
         return {"success": False, "data": "Your username or password is incorrect"}
示例#15
0
文件: auth.py 项目: shareef12/CTFd
def register():
    errors = get_errors()
    if request.method == 'POST':
        name = request.form['name']
        email_address = 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_address).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)

        local_id, _, domain = email_address.partition('@')

        domain_whitelist = get_config('domain_whitelist')

        if not valid_email:
            errors.append("Please enter a valid email address")
        if domain_whitelist:
            domain_whitelist = domain_whitelist.split(',')
            if domain not in domain_whitelist:
                errors.append(
                    "Only email addresses under {domains} may register".format(
                        domains=', '.join(domain_whitelist))
                )
        if names:
            errors.append('That team name is already taken')
        if team_name_email_check is True:
            errors.append('Your team 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 team 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.strip(),
                    email=email_address.lower(),
                    password=password.strip()
                )
                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.sendmail(
                            request.form['email'],
                            "You've successfully registered for {}".format(get_config('ctf_name'))
                        )

        log('registrations', "[{date}] {ip} - {name} registered with {email}")
        db.session.close()
        return redirect(url_for('challenges.listing'))
    else:
        return render_template('register.html', errors=errors)
示例#16
0
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()
        phone = request.form.get("phone", "").strip()
        student_id = request.form.get("student_id", "").strip()
        realname = request.form.get("realname", "").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)

        phone_valid = len(phone) == 11

        student_id_exist = Users.query.add_columns(
            'student_id', 'id').filter_by(student_id=student_id).first()

        student_id_valid = StudentID.query.add_columns(
            'student_id', 'id').filter_by(student_id=student_id).first()

        phone_exist = Users.query.add_columns(
            'phone', 'id').filter_by(phone=phone).first()
        realname_empty = len(realname) == 0

        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 not phone_valid:
            errors.append("Wrong phone number format")
        if not student_id_valid:
            errors.append("Invalid student id")

        if realname_empty:
            errors.append("Realname can't be empty")
        if student_id_exist:
            errors.append("That student id is already taken")
        if phone_exist:
            errors.append("That phone number is already taken")

        if len(errors) > 0:
            return render_template("register.html",
                                   errors=errors,
                                   name=request.form["name"],
                                   email=request.form["email"],
                                   password=request.form["password"],
                                   student_id=student_id,
                                   realname=realname,
                                   phone=phone)
        else:
            with app.app_context():
                user = Users(name=name,
                             email=email_address,
                             password=password,
                             student_id=student_id,
                             realname=realname,
                             phone=phone)
                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)
示例#17
0
文件: views.py 项目: sigpwny/CTFd
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
            ctf_logo = request.files.get("ctf_logo")
            if ctf_logo:
                f = upload_file(file=ctf_logo)
                set_config("ctf_logo", f.location)

            ctf_small_icon = request.files.get("ctf_small_icon")
            if ctf_small_icon:
                f = upload_file(file=ctf_small_icon)
                set_config("ctf_small_icon", f.location)

            theme = request.form.get("ctf_theme", DEFAULT_THEME)
            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
            )

            # Create an empty index page
            page = Pages(title=None, route="index", content="", draft=False)

            # Upload banner
            default_ctf_banner_location = url_for("views.themes", path="img/logo.png")
            ctf_banner = request.files.get("ctf_banner")
            if ctf_banner:
                f = upload_file(file=ctf_banner, page_id=page.id)
                default_ctf_banner_location = url_for("views.files", path=f.location)

            # Splice in our banner
            index = f"""<div class="row">
    <div class="col-md-6 offset-md-3">
        <img class="w-100 mx-auto d-block" style="max-width: 500px;padding: 50px;padding-top: 14vh;" src="{default_ctf_banner_location}" />
        <h3 class="text-center">
            <p>A cool CTF platform from <a href="https://ctfd.io">ctfd.io</a></p>
            <p>Follow us on social media:</p>
            <a href="https://twitter.com/ctfdio"><i class="fab fa-twitter fa-2x" aria-hidden="true"></i></a>&nbsp;
            <a href="https://facebook.com/ctfdio"><i class="fab fa-facebook fa-2x" aria-hidden="true"></i></a>&nbsp;
            <a href="https://github.com/ctfd"><i class="fab fa-github fa-2x" aria-hidden="true"></i></a>
        </h3>
        <br>
        <h4 class="text-center">
            <a href="admin">Click here</a> to login and setup your CTF
        </h4>
    </div>
</div>"""
            page.content = index

            # Visibility
            set_config(
                ConfigTypes.CHALLENGE_VISIBILITY, ChallengeVisibilityTypes.PRIVATE
            )
            set_config(
                ConfigTypes.REGISTRATION_VISIBILITY, RegistrationVisibilityTypes.PUBLIC
            )
            set_config(ConfigTypes.SCORE_VISIBILITY, ScoreVisibilityTypes.PUBLIC)
            set_config(ConfigTypes.ACCOUNT_VISIBILITY, AccountVisibilityTypes.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"))
        try:
            return render_template("setup.html", state=serialize(generate_nonce()))
        except TemplateNotFound:
            # Set theme to default and try again
            set_config("ctf_theme", DEFAULT_THEME)
            return render_template("setup.html", state=serialize(generate_nonce()))
    return redirect(url_for("views.static_html"))
示例#18
0
文件: views.py 项目: kenz-g147/CTFd-1
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")
            if theme_color:
                # Uses {{ and }} to insert curly braces while using the format method
                css = (
                    ":root {{--theme-color: {theme_color};}}\n"
                    ".navbar{{background-color: var(--theme-color) !important;}}\n"
                    ".jumbotron{{background-color: var(--theme-color) !important;}}\n"
                ).format(theme_color=theme_color)
                set_config("css", 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 class="row">
    <div class="col-md-6 offset-md-3">
        <img class="w-100 mx-auto d-block" style="max-width: 500px;padding: 50px;padding-top: 14vh;" src="themes/core/static/img/logo.png" />
        <h3 class="text-center">
            <p>A cool CTF platform from <a href="https://ctfd.io">ctfd.io</a></p>
            <p>Follow us on social media:</p>
            <a href="https://twitter.com/ctfdio"><i class="fab fa-twitter fa-2x" aria-hidden="true"></i></a>&nbsp;
            <a href="https://facebook.com/ctfdio"><i class="fab fa-facebook fa-2x" aria-hidden="true"></i></a>&nbsp;
            <a href="https://github.com/ctfd"><i class="fab fa-github fa-2x" aria-hidden="true"></i></a>
        </h3>
        <br>
        <h4 class="text-center">
            <a href="admin">Click here</a> to login and setup your CTF
        </h4>
    </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_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"))
示例#19
0
def setup():
    if not config.is_setup():
        if not session.get("nonce"):
            session["nonce"] = generate_nonce()
        if request.method == "POST":
            ctf_name = request.form["ctf_name"]
            set_config("ctf_name", ctf_name)

            # CSS
            set_config("start", "")

            # Admin user
            name = request.form["name"]
            email = request.form["email"]
            password = request.form["password"]
            admin = Admins(name=name,
                           email=email,
                           password=password,
                           type="admin",
                           hidden=True)

            user_mode = request.form["user_mode"]

            set_config("user_mode", user_mode)

            # Index page

            index = """<div class="row">
    <div class="col-md-6 offset-md-3">
        <img class="w-100 mx-auto d-block" style="max-width: 500px;padding: 50px;padding-top: 14vh;" src="themes/core/static/img/logo.png" />
        <h3 class="text-center">
            <p>A HACKEREARTH CTF platform</p>
                    </h3>
        <br>
        <h4 class="text-center">
            <a href="admin">Click here</a> to login and setup your CTF
        </h4>
    </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")

            # Start time
            set_config("start", None)
            set_config("end", None)
            set_config("freeze", None)

            # 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_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()
            app.setup = False
            with app.app_context():
                cache.clear()

            return redirect(url_for("views.static_html"))
        return render_template("setup.html", nonce=session.get("nonce"))
    return redirect(url_for("views.static_html"))
示例#20
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"))
示例#21
0
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 class="row">
    <div class="col-md-6 offset-md-3">
        <img class="w-100 mx-auto d-block" style="max-width: 500px;padding: 50px;padding-top: 14vh;" src="themes/core/static/img/logo.png" />
        <h3 class="text-center">
            <p>CTF</p>
        </h3>
        <br>
        <h4 class="text-center">
            <a href="admin">Click here</a> to login and setup your CTF
        </h4>
    </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"))
示例#22
0
文件: views.py 项目: shareef12/CTFd
def setup():
    if not config.is_setup():
        if not session.get('nonce'):
            session['nonce'] = generate_nonce()
        if request.method == 'POST':
            ctf_name = request.form['ctf_name']
            set_config('ctf_name', ctf_name)

            # CSS
            set_config('start', '')

            # Admin user
            name = request.form['name']
            email = request.form['email']
            password = request.form['password']
            admin = Admins(name=name,
                           email=email,
                           password=password,
                           type='admin',
                           hidden=True)

            user_mode = request.form['user_mode']

            set_config('user_mode', user_mode)

            # Index page

            index = """<div class="row">
    <div class="col-md-6 offset-md-3">
        <img class="w-100 mx-auto d-block" style="max-width: 500px;padding: 50px;padding-top: 14vh;" src="themes/core/static/img/logo.png" />
        <h3 class="text-center">
            <p>A cool CTF platform from <a href="https://ctfd.io">ctfd.io</a></p>
            <p>Follow us on social media:</p>
            <a href="https://twitter.com/ctfdio"><i class="fab fa-twitter fa-2x" aria-hidden="true"></i></a>&nbsp;
            <a href="https://facebook.com/ctfdio"><i class="fab fa-facebook fa-2x" aria-hidden="true"></i></a>&nbsp;
            <a href="https://github.com/ctfd"><i class="fab fa-github fa-2x" aria-hidden="true"></i></a>
        </h3>
        <br>
        <h4 class="text-center">
            <a href="admin">Click here</a> to login and setup your CTF
        </h4>
    </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')

            # Start time
            set_config('start', None)
            set_config('end', None)
            set_config('freeze', None)

            # 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)

            setup = 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()
            app.setup = False
            with app.app_context():
                cache.clear()

            return redirect(url_for('views.static_html'))
        return render_template('setup.html', nonce=session.get('nonce'))
    return redirect(url_for('views.static_html'))
示例#23
0
文件: auth.py 项目: shareef12/CTFd
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'))
示例#24
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"))
示例#25
0
def register():
    errors = get_errors()
    if request.method == "POST":
        name = request.form["name"]
        email_address = 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_address).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 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.strip(),
                    email=email_address.lower(),
                    password=password.strip(),
                )
                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.sendmail(
                            request.form["email"],
                            "You've successfully registered for {}".format(
                                get_config("ctf_name")),
                        )

        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)
示例#26
0
文件: auth.py 项目: HackRU/CTFd
def login():
    errors = get_errors()
    if request.method == "POST":
        email = request.form["name"]

        url = "https://api.hackru.org/dev"
        content = {
            "email": email,
            "password": request.form["password"]
        }
        response = requests.post(url + "/authorize", data=json.dumps(content))
        if response.json()["statusCode"] == 200:

            token = (response.json()["body"]["token"])
            content = {
                "email": email,
                "token": token,
                "query": {
                    "email": email
                }
            }
            response = requests.post(url + "/read", data=json.dumps(content))
            print(response.json())
            if (response.json()["body"][0]["registration_status"] not in ["confirmed"]):
                errors.append("your registration status has not been confirmed. please go to hackru.org and confirm it, if issues continue contact [email protected]")
                db.session.close()
                return render_template("login.html", errors=errors)
            name = response.json()["body"][0].get("first_name", "") + " " + response.json()["body"][0].get("last_name", ""); #get name
            email_address = email
            password = request.form["password"]

            website = None
            affiliation = response.json()["body"][0].get("school", "") #maybe do school?
            country = None
            try:
                with app.app_context():
                    user = Users(name=name, email=email_address, password=password)

                    if website:
                        user.website = website
                    if affiliation:
                        user.affiliation = affiliation
                    if country:
                        user.country = country

                    db.session.add(user)
                    db.session.commit()
                    db.session.flush()

                    login_user(user)

                log("registrations", "[{date}] {ip} - {name} registered with {email}")
                db.session.close()

                return redirect(url_for("challenges.listing"))
            except:
                print("ALREADY A USER")
                user = Users.query.filter_by(email=email_address).first()
                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 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)
示例#27
0
def setup():
    if not config.is_setup():
        if not session.get("nonce"):
            session["nonce"] = generate_nonce()
        if request.method == "POST":
            ctf_name = request.form["ctf_name"]
            set_config("ctf_name", ctf_name)

            # CSS
            set_config("start", "")

            # Admin user
            name = request.form["name"]
            email = request.form["email"]
            password = request.form["password"]
            admin = Admins(name=name,
                           email=email,
                           password=password,
                           type="admin",
                           hidden=True)

            user_mode = request.form["user_mode"]

            set_config("user_mode", user_mode)

            # Index page

            index = """<div class="section section-hero" id="home" style="background-image: url('/themes/H1ve-theme/static/img/bg.jpg'); background-position: 10% 50%">
    <div class="section-inner">
        <div class="table-container-outer container">
            <div class="table-container-inner">
                <div data-0="transform[swing]:translateY(0px);opacity[swing]:1" data-250="transform[swing]:translateY(-50px);opacity[swing]:0">
                    <img class="img-responsive ctf_logo" src="/themes/H1ve-theme/static/img/h1ve.png" height="150px" width="150px" alt="H1ve-Logo">
                <h1 class="hero-header" data-150="transform[swing]:translateX(0px);opacity[swing]:1" data-550="transform[swing]:translateX(-25px);opacity[swing]:0">D0g3 <strong class="main-color">Lab</strong></h1>
                <h2 class="hero-subheader" data-200="transform[swing]:translateX(0px);opacity[swing]:1" data-500="transform[swing]:translateX(25px);opacity[swing]:0">CTF <strong class="main-color">Online</strong></h2>
                <div data-250="transform[swing]:translateY(0px);opacity[swing]:1" data-550="transform[swing]:translateY(-15px);opacity[swing]:0">
                    <div class="divider">//</div>
                </div>
                <div data-350="transform[swing]:translateY(0px);opacity[swing]:1" data-650="transform[swing]:translateY(-15px);opacity[swing]:0">
                    <p class="">收集各类自创/大型CTF比赛赛题,提供容器化专属题目环境,供广大CTF爱好者学习。</p>
                    <p class="">如有侵权,或题目问题请电联<a href="mailto:[email protected]">[email protected]</a></p>
                </div>
                <div>
                    <p>

                    </p>
                </div>
                <p> &copy; 2019 <a href="https://www.d0g3.cn">D0g3</a> | 道之若极,行必有格 | Power By <a href="https://github.com/D0g3-Lab/H1ve/">H1ve</a></p>
            </div>
        </div>
        <div class="scroll-icon visible-lg" data-600="opacity[swing]:1" data-850="opacity[swing]:0">
            <span class="icon icon-basic-magic-mouse"></span>
        </div>
    </div>
    </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")

            # Start time
            set_config("start", None)
            set_config("end", None)
            set_config("freeze", None)

            # 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_config("setup", True)
            # add h1ve-theme as default theme
            set_config("ctf_theme", "H1ve-theme")

            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()
            app.setup = False
            with app.app_context():
                cache.clear()

            return redirect(url_for("views.static_html"))
        return render_template("setup.html", nonce=session.get("nonce"))
    return redirect(url_for("views.static_html"))
示例#28
0
def register():
    errors = get_errors()
    if request.method == 'POST':
        name = request.form['name']
        email_address = 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_address).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 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 team name is already taken')
        if team_name_email_check is True:
            errors.append('Your team 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 team name')
        if ' ' in name:
            errors.append('Your User name should not contain space')
        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.strip(),
                             email=email_address.lower(),
                             password=password.strip())
                db.session.add(user)
                db.session.commit()
                db.session.flush()

                login_user(user)
                # system("docker exec server-skr useradd -m %s -s /bin/bash" % name.strip())
                # system('''docker exec server-skr bash -c 'echo "%s:%s" | chpasswd' ''' % (name.strip(),password.strip()))
                # system("docker exec server-skr chmod 700 /home/%s" % name.strip())
                # system("docker exec server-skr cp -r /home/user/. /home/%s/" % name.strip())
                # system("docker exec server-skr chmod 4755 /home/%s/challenges/binary1/overflow" % name.strip())
                # system("docker exec server-skr chmod 4755 /home/%s/challenges/binary2/overflow2" % name.strip())
                # system("docker exec server-skr chmod 4755 /home/%s/challenges/format-string/format-string" % name.strip())
                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.sendmail(
                            request.form['email'],
                            "You've successfully registered for {}".format(
                                get_config('ctf_name')))

        log('registrations', "[{date}] {ip} - {name} registered with {email}")
        db.session.close()
        return redirect(url_for('challenges.listing'))
    else:
        return render_template('register.html', errors=errors)
def discord_oauth_callback():
    """
    Callback response configured to come from Discord's OAuth2 redirect

    :return: Redirect to users login home page (or error)
    """
    log.debug("Request: [{}]".format(request))
    log.debug("Session: [{}]".format(session))
    log.debug("OAuth Response Code: [{}]".format(request.args.get("code")))
    global discord_oauth
    token = discord_oauth.get_access_token(request.args.get("code"))
    log.debug("token=[{}]".format(token))
    user_json = discord_oauth.get_user_info(token)
    log.debug("User data: [{}]".format(str(user_json)))
    # process user info/login/etc
    if user_json:
        # lookup by email
        user = Users.query.filter_by(email=user_json["email"]).first()
        discord_user = DiscordUser.query.filter_by(id=user_json["id"]).first()
        if user is None:
            # Check if user changed email
            if discord_user:
                user = Users.query.filter_by(email=discord_user.email)
                if user:
                    user.email = user_json["email"]
                    discord_user.email = user_json["email"]
                    db.session.commit()
                else:
                    log.error(
                        "Login failed: user[{user}], discord_user[{d_user}], \
                        oauth[{user_json}]".format(user=user,
                                                   d_user=discord_user,
                                                   user_json=user_json))
                    return "Error logging in via Discord Oauth2"
            else:
                # Create new user
                user = Users(name=user_json["username"],
                             email=user_json["email"],
                             oauth_id=user_json["id"],
                             verified=user_json["verified"])
                discord_user = DiscordUser(
                    id=user_json["id"],
                    username=user_json["username"],
                    discriminator=user_json["discriminator"],
                    avatar_hash=user_json["avatar"],
                    mfa_enabled=user_json["mfa_enabled"],
                    verified=user_json["verified"],
                    email=user_json["email"])
                db.session.add(user)
                db.session.add(discord_user)
                db.session.commit()
        else:
            # Create Discord association if does not exist (legacy support)
            if not discord_user:
                discord_user = DiscordUser(
                    id=user_json["id"],
                    username=user_json["username"],
                    discriminator=user_json["discriminator"],
                    avatar_hash=user_json["avatar"],
                    mfa_enabled=user_json["mfa_enabled"],
                    verified=user_json["verified"],
                    email=user_json["email"])
                db.session.add(discord_user)
                db.session.commit()
        # Login
        login_user(user)
    else:
        return "Error logging in via Discord OAuth2"
    return redirect('/challenges')
示例#30
0
def register():
    errors = get_errors()
    if current_user.authed():
        return redirect(url_for("challenges.listing"))

    if request.method == "POST":
        name = request.form.get("name", "").strip()
        email_address = request.form.get("email", "").strip().lower()
        password = request.form.get("password", "").strip()

        website = request.form.get("website")
        affiliation = request.form.get("affiliation")
        country = request.form.get("country")
        registration_code = request.form.get("registration_code", "")

        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 get_config("registration_code"):
            if (registration_code.lower() != get_config("registration_code",
                                                        default="").lower()):
                errors.append(
                    "The registration code you entered was incorrect")

        # Process additional user fields
        fields = {}
        for field in UserFields.query.all():
            fields[field.id] = field

        entries = {}
        for field_id, field in fields.items():
            value = request.form.get(f"fields[{field_id}]", "").strip()
            if field.required is True and (value is None or value == ""):
                errors.append("Please provide all required fields")
                break

            # Handle special casing of existing profile fields
            if field.name.lower() == "affiliation":
                affiliation = value
                break
            elif field.name.lower() == "website":
                website = value
                break

            if field.field_type == "boolean":
                entries[field_id] = bool(value)
            else:
                entries[field_id] = value

        if country:
            try:
                validators.validate_country_code(country)
                valid_country = True
            except ValidationError:
                valid_country = False
        else:
            valid_country = True

        if website:
            valid_website = validators.validate_url(website)
        else:
            valid_website = True

        if affiliation:
            valid_affiliation = len(affiliation) < 128
        else:
            valid_affiliation = True

        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("该用户名已被使用")
        if team_name_email_check is True:
            errors.append("您的用户名不能是电子邮件地址")
        if emails:
            errors.append("电子邮件地址已被使用")
        if pass_short:
            errors.append("密码长度不够")
        if pass_long:
            errors.append("密码过长")
        if name_len:
            errors.append("用户名长度不够")
        if valid_website is False:
            errors.append("Blog/网站 必须是以http或https开头的正确URL")
        if valid_country is False:
            errors.append("无效的地区")
        if valid_affiliation is False:
            errors.append("单位/组织 过长")

        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)

                if website:
                    user.website = website
                if affiliation:
                    user.affiliation = affiliation
                if country:
                    user.country = country

                db.session.add(user)
                db.session.commit()
                db.session.flush()

                for field_id, value in entries.items():
                    entry = UserFieldEntries(field_id=field_id,
                                             value=value,
                                             user_id=user.id)
                    db.session.add(entry)
                db.session.commit()

                login_user(user)

                if request.args.get("next") and validators.is_safe_url(
                        request.args.get("next")):
                    return redirect(request.args.get("next"))

                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}",
                        name=user.name,
                        email=user.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",
            format="[{date}] {ip} - {name} registered with {email}",
            name=user.name,
            email=user.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)