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