-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
125 lines (99 loc) · 4.2 KB
/
app.py
File metadata and controls
125 lines (99 loc) · 4.2 KB
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
122
123
124
125
from flask import Flask, render_template, request, redirect, url_for, flash, session
from werkzeug.security import generate_password_hash, check_password_hash
from itsdangerous import URLSafeTimedSerializer, SignatureExpired, BadSignature
from models import db, User
app = Flask(__name__)
app.secret_key = "secret-key"
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///auth.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
s = URLSafeTimedSerializer(app.secret_key)
def validate_password(password, confirm_password):
"""Returns an error message string if invalid, or None if valid."""
if len(password) < 8:
return "Password must be at least 8 characters long"
if password != confirm_password:
return "Passwords do not match"
return None
@app.route("/")
def home():
return redirect(url_for("login"))
@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
confirm_password = request.form["confirm_password"]
error = validate_password(password, confirm_password)
if error:
flash(error, "error")
return redirect(url_for("register"))
hashed_password = generate_password_hash(password)
if User.query.filter_by(username=username).first():
flash("Username already exists", "error")
return redirect(url_for("register"))
user = User(username=username, password=hashed_password)
db.session.add(user)
db.session.commit()
flash("Registration successful", "success")
return redirect(url_for("login"))
return render_template("register.html")
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
user = User.query.filter_by(username=username).first()
if user and check_password_hash(user.password, password):
session["user_id"] = user.id
session["username"] = user.username
return redirect(url_for("dashboard"))
flash("Invalid credentials", "error")
return render_template("login.html")
@app.route("/reset_request", methods=["GET", "POST"])
def reset_request():
if request.method == "POST":
username = request.form["username"]
user = User.query.filter_by(username=username).first()
if user:
token = s.dumps(username, salt="recover-key")
link = url_for("reset_token", token=token, _external=True)
return f'<h1>Password Reset</h1><p>Click this link to reset your password: <a href="{link}">{link}</a></p>'
flash("Username not found", "error")
return redirect(url_for("reset_request"))
return render_template("reset_request.html")
@app.route("/reset_password/<token>", methods=["GET", "POST"])
def reset_token(token):
try:
username = s.loads(token, salt="recover-key", max_age=3600)
except (SignatureExpired, BadSignature):
flash("The link is invalid or expired", "error")
return redirect(url_for("login"))
if request.method == "POST":
password = request.form["password"]
confirm_password = request.form["confirm_password"]
error = validate_password(password, confirm_password)
if error:
flash(error, "error")
return redirect(url_for("reset_token", token=token))
hashed_password = generate_password_hash(password)
user = User.query.filter_by(username=username).first()
if user:
user.password = hashed_password
db.session.commit()
flash("Password updated successfully", "success")
return redirect(url_for("login"))
return render_template("reset_password.html")
@app.route("/dashboard")
def dashboard():
if "user_id" not in session:
return redirect(url_for("login"))
return render_template("dashboard.html")
@app.route("/logout")
def logout():
session.clear()
return redirect(url_for("login"))
if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run(debug=True)