aboutsummaryrefslogtreecommitdiffstats
path: root/src/expense/auth/login.py
blob: 00f78ebdfa5cda132b75e65ec4366d4bdd403fc6 (plain) (blame)
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
from typing import Optional, Union
from flask import (
    redirect,
    render_template,
    request,
    url_for,
)
from flask_login import current_user, login_user

from flask_wtf import FlaskForm
from werkzeug import Response
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, InputRequired

from .blueprint import auth
from ..model import User
from .. import db


class LoginForm(FlaskForm):
    """
    The Login Form.
    The validate method has be improved to do validating the user
    """
    username = StringField(validators=[DataRequired(), InputRequired()])
    password = PasswordField(validators=[DataRequired(), InputRequired()])
    submit = SubmitField("Log In")

    def validate(self, *args, **kwargs):
        if not super().validate(*args, **kwargs):
            return False

        username = self.username.data
        password = self.password.data

        user = db.session.scalars(
            db.select(User).where(User.name == username)
        ).one_or_none()
        if user is None:
            self.username.errors.append("Invalid username")  # type: ignore
            return False

        if not user.password == password:
            self.password.errors.append("Invalid password")  # type: ignore
            return False

        self.user = user
        return True


@auth.route("/login", methods=("GET", "POST"))
def login() -> Union[str, Response]:
    """
    The view for Loging in the User
    """
    if current_user.is_authenticated:  # type: ignore
        return redirect(request.args.get("next", default=url_for("index")))
    form = LoginForm()
    if form.validate_on_submit():
        login_user(form.user)
        return redirect(request.args.get("next", default=url_for("index")))

    return render_template("auth/login.html", form=form)