Gurkenkönig
Gurkenkönig

Reputation: 828

Password only auth in Flask

I would like to implement a simple basic password authentication without username in flask. Different routes should have different passwords: In @app.route("/project/<string:project_name>", methods=["GET"]) I would like to assign every project with a differing password. The app is very small and security is not a big concern the solution should therefore also be as simple as possible.

Upvotes: 2

Views: 601

Answers (2)

Daedalus
Daedalus

Reputation: 416

A potential solution.

forms.py

from flask_wtf import FlaskForm
from wtforms import PasswordField, StringField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    project_name = StringField('Project_name', id='project_name')
    password = PasswordField('Password',id='password', validators[DataRequired()])

models.py

from flask_login import UserMixin
from sqlalchemy import Binary
from app import db

class Project(db.Model, UserMixin):

    __tablename__ = 'Project'
    project_name = Column(String, unique=True)
    password = Column(Binary)

routes.py

from flask import render_template, redirect, request, url_for
from flask_login import login_user
from app.models import Project
## this could be a simple string comparison **not suggested.
from app.base.util import verify_pass 

@app.route('/login', methods=['GET', 'POST'])
def login():
    """
    """

    login_form = LoginForm(request.form)

    if request.method == 'POST':
    
        # read form data
        password = request.form['password']
        # project's password given its name.
        project = Project.query.filter_by(project_name=project_name).first()

        # Verify password.
        if project and verify_pass(password, project.password):
            # Success.
            login_user(user)
            return redirect(url_for('app.index'))

    # Something (user or pass) is not ok
    return render_template( 'login.html', 
                            msg='Wrong password.', 
                            form=login_form
                        )

Upvotes: 1

Bilal Qandeel
Bilal Qandeel

Reputation: 727

I think this should serve as a solution for you:

    pwd = ''

    def password_form(project_name):
        # The HTML form asking for password
        return '''<form method="post">
                  <label for="pass">Please enter project's password:</label>
                  <input type="pwd" id="pwd" name="pwd" required>
                  <input type="submit" value="Sign in">
                  </form>'''

    def check_password(pwd, project_name):
        # I set the password to be the reversed name of the project, you can change it
        return pwd == project_name[::-1]

    @app.route("/project/<string:project_name>", methods=["GET", "POST"])
    def project(project_name):
        if request.method == "POST":
            pwd = request.form['pwd']  # pass the form field name as key
            if check_password(pwd, project_name):
                return 'success!'
                # Return the project's HTML page. If it has a template matching the project's name:
                #return render_template(f'{project_name}.html')
            else:
                # Wrong password, the form will reload
                return password_form(project_name)
        if request.method == "GET":
            return password_form(project_name)

Upvotes: 1

Related Questions