app.py
Python script, ASCII text executable
1
import flask
2
from flask_sqlalchemy import SQLAlchemy
3
from flask_bcrypt import Bcrypt
4
from flask_httpauth import HTTPBasicAuth
5
from markupsafe import escape, Markup
6
from flask_migrate import Migrate
7
from jinja2_fragments.flask import render_block
8
import config
9
import markdown
10
11
12
app = flask.Flask(__name__)
13
bcrypt = Bcrypt(app)
14
15
16
app.config["SQLALCHEMY_DATABASE_URI"] = config.DB_URI
17
app.config["SECRET_KEY"] = config.DB_PASSWORD
18
19
20
db = SQLAlchemy(app)
21
migrate = Migrate(app, db)
22
23
24
@app.template_filter("split")
25
def split(value, separator=None, maxsplit=-1):
26
return value.split(separator, maxsplit)
27
28
29
with app.app_context():
30
class User(db.Model):
31
username = db.Column(db.String(32), unique=True, nullable=False, primary_key=True)
32
password_hashed = db.Column(db.String(60), nullable=False)
33
34
def __init__(self, username, real_name, password):
35
self.username = username
36
self.real_name = real_name
37
self.password_hashed = bcrypt.generate_password_hash(password).decode("utf-8")
38
39
40
@app.route("/")
41
def index():
42
return flask.render_template("home.html")
43
44
45
@app.route("/accounts")
46
def accounts():
47
return flask.render_template("login.html")
48
49
50
@app.route("/login", methods=["POST"])
51
def login():
52
username = flask.request.form["username"]
53
password = flask.request.form["password"]
54
55
user = db.session.get(User, username)
56
57
if user is None:
58
flask.flash("This username is not registered.")
59
return flask.redirect("/accounts")
60
61
if not bcrypt.check_password_hash(user.password_hashed, password):
62
flask.flash("Incorrect password.")
63
return flask.redirect("/accounts")
64
65
flask.flash("You have been logged in.")
66
67
flask.session["username"] = username
68
return flask.redirect("/")
69
70
71
@app.route("/logout")
72
def logout():
73
flask.session.pop("username", None)
74
flask.flash("You have been logged out.")
75
return flask.redirect("/")
76
77
78
@app.route("/signup", methods=["POST"])
79
def signup():
80
username = flask.request.form["username"]
81
password = flask.request.form["password"]
82
83
if db.session.get(User, username) is not None:
84
flask.flash("This username is already taken.")
85
return flask.redirect("/accounts")
86
87
if set(username) > set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"):
88
flask.flash("Usernames can only contain the Latin alphabet, digits, hyphens, and underscores.")
89
return flask.redirect("/accounts")
90
91
if len(username) < 3 or len(username) > 32:
92
flask.flash("Usernames must be between 3 and 32 characters long.")
93
return flask.redirect("/accounts")
94
95
if len(password) < 6:
96
flask.flash("Passwords must be at least 6 characters long.")
97
return flask.redirect("/accounts")
98
99
user = User(username, None, password)
100
db.session.add(user)
101
db.session.commit()
102
103
flask.session["username"] = username
104
105
flask.flash("You have been registered and logged in.")
106
107
return flask.redirect("/")
108
109
110
@app.route("/profile", defaults={"username": None})
111
@app.route("/profile/<username>")
112
def profile(username):
113
if username is None:
114
if "username" in flask.session:
115
return flask.redirect("/profile/" + flask.session["username"])
116
else:
117
flask.flash("Please log in to perform this action.")
118
return flask.redirect("/accounts")
119
120
user = db.session.get(User, username)
121
if user is None:
122
return flask.abort(404)
123
124
return flask.render_template("profile.html", user=user)
125