aboutsummaryrefslogtreecommitdiffhomepage
path: root/apioforum/auth.py
blob: 39cf1f86f17b583793521f05a7b41d0b550b71a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from flask import (
    Blueprint, session, request, url_for, render_template, redirect,
    flash, g
)
from werkzeug.security import check_password_hash, generate_password_hash
from .db import get_db
import functools

bp = Blueprint("auth", __name__, url_prefix="/auth")

def get_next():
    return request.args.get('next',url_for('index'))

@bp.route("/login",methods=('GET','POST'))
def login():
    if request.method == "POST":
        username = request.form["username"]
        password = request.form["password"]
        db = get_db()
        err = None
        user = db.execute(
            "SELECT password FROM users WHERE username = ?;",(username,)
        ).fetchone()
        if not username:
            err = "username required"
        elif not password:
            err = "password required"
        elif user is None or not check_password_hash(user['password'], password):
            err = "invalid login"

        if err is None:
            session.clear()
            session['user'] = username
            flash("logged in successfully")
            return redirect(get_next())

        flash(err)
        
    return render_template("auth/login.html")


@bp.route("/register", methods=("GET","POST"))
def register():
    if request.method == "POST":
        username = request.form["username"]
        password = request.form["password"]
        db = get_db()
        err = None
        if not username:
            err = "Username required"
        elif not password:
            err = "Password required"
        elif db.execute(
            "SELECT 1 FROM users WHERE username = ?;", (username,)
        ).fetchone() is not None:
            err = f"User {username} is already registered."
        elif len(username) > 20:
            err = "username can't be longer than 20 characters"
        elif not username.isalnum():
            err = "username must be alphanumeric"

        if err is None:
            db.execute(
                "INSERT INTO users (username, password, joined) VALUES (?,?,current_timestamp);",
                (username,generate_password_hash(password))
            )
            db.commit()
            flash("successfully created account")
            session['user'] = username
            return redirect(get_next())

        flash(err)
            
    return render_template("auth/register.html")

@bp.route("/logout")
def logout():
    session.clear()
    flash("logged out successfully")
    return redirect(get_next())

@bp.before_app_request
def load_user():
    username = session.get("user")
    if username is None:
        g.user = None
        g.user_info = None
    else:
        row = get_db().execute(
            "SELECT * FROM users WHERE username = ?;", (username,)
        ).fetchone()
        if row is None:
            g.user = None
            g.user_info = None
        else:
            g.user = row['username']
            g.user_info = row
        

def login_required(view):
    @functools.wraps(view)
    def wrapped(**kwargs):
        print(g.user)
        if g.user is None:
            return redirect(url_for("auth.login"))
        return view(**kwargs)
    return wrapped

@bp.route("/cool")
def cool():
    user = session.get("user")
    if user is None:
        return "you are not logged in"
    else:
        return f"you are logged in as {user}"

@bp.route("/cooler")
@login_required
def cooler():
    return "bee"