diff options
| author | Mitsuo Tokumori <[email protected]> | 2023-10-27 19:58:19 -0500 |
|---|---|---|
| committer | Mitsuo Tokumori <[email protected]> | 2023-10-27 19:58:19 -0500 |
| commit | 4dd7f82f86f32f18a1c881749848f0c5333a40ce (patch) | |
| tree | dc1b043f3ec7d2bf76e837f3e89caf6dec5851c1 /flaskr/views/auth.py | |
| parent | f59b3ba871f1086beb147c2de46f0cd60ce070c2 (diff) | |
| download | ustayml-4dd7f82f86f32f18a1c881749848f0c5333a40ce.tar.gz ustayml-4dd7f82f86f32f18a1c881749848f0c5333a40ce.tar.bz2 ustayml-4dd7f82f86f32f18a1c881749848f0c5333a40ce.zip | |
Move views to the views/ directory
Diffstat (limited to 'flaskr/views/auth.py')
| -rw-r--r-- | flaskr/views/auth.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/flaskr/views/auth.py b/flaskr/views/auth.py new file mode 100644 index 0000000..3689eba --- /dev/null +++ b/flaskr/views/auth.py @@ -0,0 +1,102 @@ +"""Authentication blueprint""" + +import functools + +from flask import ( + Blueprint, flash, g, redirect, render_template, request, session, url_for +) +from werkzeug.security import check_password_hash, generate_password_hash +from flaskr.db import get_db + +bp = Blueprint('auth', __name__, url_prefix='/auth') + [email protected]('/register', methods=('GET', 'POST')) +def register(): + if request.method == 'POST': + # Form validation + username = request.form['username'] + password = request.form['password'] + db = get_db() + error = None + + if not username: + error = 'Username is required.' + elif not password: + error = 'Password is required.' + + if error is None: + try: + # NOTE: don't use f-string here. Use `?` placeholders so that + # database library can escape the fields + # (otherwise SQL injection vulnerability) + db.execute( + "INSERT INTO user (username, password) VALUES (?, ?)", + (username, generate_password_hash(password)), + ) + db.commit() + except db.IntegrityError: + error = f"User {username} is already registered." + else: + return redirect(url_for("auth.login")) + + flash(error) + + return render_template('auth/register.html') + + [email protected]('/login', methods=('GET', 'POST')) +def login(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + db = get_db() + error = None + user = db.execute( + 'SELECT * FROM user WHERE username = ?', (username,) + ).fetchone() + + if user is None: + error = 'Incorrect username.' + elif not check_password_hash(user['password'], password): + error = 'Incorrect password.' + + if error is None: + session.clear() + session['user_id'] = user['id'] + return redirect(url_for('index')) + + flash(error) + + return render_template('auth/login.html') + + +# runs before the view function, no matter what URL is requested [email protected]_app_request +def load_logged_in_user(): + user_id = session.get('user_id') + + if user_id is None: + g.user = None + else: + g.user = get_db().execute( + 'SELECT * FROM user WHERE id = ?', (user_id,) + ).fetchone() + + [email protected]('/logout') +def logout(): + session.clear() + return redirect(url_for('index')) + + +# Define decorator to require authentication in other views +def login_required(view): + """view is a function that returns HTML (and is part of a blueprint)""" + @functools.wraps(view) + def wrapped_view(**kwargs): + if g.user is None: + return redirect(url_for('auth.login')) + + return view(**kwargs) + + return wrapped_view
\ No newline at end of file |
