broken auth WIP

This commit is contained in:
forest 2020-05-09 20:36:14 -05:00
parent 119d4a0052
commit 246ef00540
7 changed files with 122 additions and 13 deletions

View File

@ -30,7 +30,7 @@ source .venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
``` ```
Run an instance of Postgres (I used docker for this, point is its listening on localhost:5432) Run an instance of Postgres (I used docker for this, you can use whatever you want, point is its listening on localhost:5432)
``` ```
docker run -it -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres docker run -it -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres

53
capsulflask/auth.py Normal file
View File

@ -0,0 +1,53 @@
import functools
from flask import Blueprint
from flask import g
from flask import redirect
from flask import url_for
from flask import session
from capsulflask.db import get_model
bp = Blueprint("auth", __name__, url_prefix="/auth")
def account_required(view):
"""View decorator that redirects anonymous users to the login page."""
@functools.wraps(view)
def wrapped_view(**kwargs):
if session.get("account") is None:
return redirect(url_for("auth.login"))
return view(**kwargs)
return wrapped_view
@bp.route("/register", methods=("GET", "POST"))
def register():
if request.method == "POST":
email = request.form["email"]
model = get_model()
error = None
if not email:
error = "Email is required."
elif (
model.
):
error = f"User {username} is already registered."
if error is None:
# the name is available, store it in the database and go to
# the login page
db.execute(
"INSERT INTO user (username, password) VALUES (?, ?)",
(username, generate_password_hash(password)),
)
db.commit()
return redirect(url_for("auth.login"))
flash(error)
return render_template("auth/register.html")

View File

@ -8,6 +8,7 @@ from psycopg2 import pool
from flask import current_app from flask import current_app
from flask import g from flask import g
from capsulflask.model import Model
def init_app(app): def init_app(app):
databaseUrl = urlparse(app.config['DATABASE_URL']) databaseUrl = urlparse(app.config['DATABASE_URL'])
@ -30,14 +31,14 @@ def init_app(app):
with open(join(schemaMigrationsPath, filename), 'rb') as file: with open(join(schemaMigrationsPath, filename), 'rb') as file:
schemaMigrations[key] = file.read().decode("utf8") schemaMigrations[key] = file.read().decode("utf8")
db = app.config['PSYCOPG2_CONNECTION_POOL'].getconn() connection = app.config['PSYCOPG2_CONNECTION_POOL'].getconn()
hasSchemaVersionTable = False hasSchemaVersionTable = False
actionWasTaken = False actionWasTaken = False
schemaVersion = 0 schemaVersion = 0
desiredSchemaVersion = 2 desiredSchemaVersion = 2
cursor = db.cursor() cursor = connection.cursor()
cursor.execute(""" cursor.execute("""
SELECT table_name, table_schema FROM information_schema.tables WHERE table_schema = '{}' SELECT table_name, table_schema FROM information_schema.tables WHERE table_schema = '{}'
@ -52,7 +53,7 @@ def init_app(app):
print("no table named schemaversion found in the {} schema. running migration 01_up".format(app.config['DATABASE_SCHEMA'])) print("no table named schemaversion found in the {} schema. running migration 01_up".format(app.config['DATABASE_SCHEMA']))
try: try:
cursor.execute(schemaMigrations["01_up"]) cursor.execute(schemaMigrations["01_up"])
db.commit() connection.commit()
except: except:
print("unable to create the schemaversion table because: {}".format(my_exec_info_message(sys.exc_info()))) print("unable to create the schemaversion table because: {}".format(my_exec_info_message(sys.exc_info())))
exit(1) exit(1)
@ -74,7 +75,7 @@ def init_app(app):
)) ))
try: try:
cursor.execute(schemaMigrations[migrationKey]) cursor.execute(schemaMigrations[migrationKey])
db.commit() connection.commit()
except KeyError: except KeyError:
print("missing schema migration script: {}_xyz.sql".format(migrationKey)) print("missing schema migration script: {}_xyz.sql".format(migrationKey))
exit(1) exit(1)
@ -97,7 +98,7 @@ def init_app(app):
cursor.close() cursor.close()
app.config['PSYCOPG2_CONNECTION_POOL'].putconn(db) app.config['PSYCOPG2_CONNECTION_POOL'].putconn(connection)
print("{} current schemaVersion: \"{}\"".format( print("{} current schemaVersion: \"{}\"".format(
("schema migration completed." if actionWasTaken else "schema is already up to date. "), schemaVersion ("schema migration completed." if actionWasTaken else "schema is already up to date. "), schemaVersion
@ -106,17 +107,20 @@ def init_app(app):
app.teardown_appcontext(close_db) app.teardown_appcontext(close_db)
def get_db(): def get_model():
if 'db' not in g: if 'model' not in g:
g.db = current_app.config['PSYCOPG2_CONNECTION_POOL'].getconn() connection = current_app.config['PSYCOPG2_CONNECTION_POOL'].getconn()
return g.db cursor = connection.cursor()
g.model = Model(connection, cursor)
return g.model
def close_db(e=None): def close_db(e=None):
db = g.pop("db", None) model = g.pop("model", None)
if db is not None: if model is not None:
current_app.config['PSYCOPG2_CONNECTION_POOL'].putconn(db) model.cursor.close()
current_app.config['PSYCOPG2_CONNECTION_POOL'].putconn(model.connection)
def my_exec_info_message(exec_info): def my_exec_info_message(exec_info):
return "{}: {}".format(".".join([exec_info[0].__module__, exec_info[0].__name__]), exec_info[1]) return "{}: {}".format(".".join([exec_info[0].__module__, exec_info[0].__name__]), exec_info[1])

10
capsulflask/model.py Normal file
View File

@ -0,0 +1,10 @@
class Model:
def __init__(self, connection, cursor):
self.connection = connection
self.cursor = cursor
def emailExists(self, email):
self.cursor.execute("SELECT * FROM accounts WHERE email = %(email)s", {"email": email})
return len(self.cursor.fetchall()) > 0

View File

@ -0,0 +1,5 @@
CREATE TABLE schemaversion (
version INT PRIMARY KEY NOT NULL
);
INSERT INTO schemaversion(version) VALUES (1);

View File

@ -0,0 +1,9 @@
DROP TABLE payments;
DROP TABLE logintokens;
DROP TABLE vms;
DROP TABLE accounts;
UPDATE schemaversion SET version = 1;

View File

@ -0,0 +1,28 @@
CREATE TABLE accounts (
email TEXT PRIMARY KEY NOT NULL,
);
CREATE TABLE vms (
id TEXT PRIMARY KEY NOT NULL,
email TEXT REFERENCES accounts(email) ON DELETE RESTRICT,
created TIMESTAMP NOT NULL,
deleted TIMESTAMP NOT NULL,
);
CREATE TABLE payments (
email TEXT REFERENCES accounts(email) ON DELETE RESTRICT,
created TIMESTAMP NOT NULL,
dollars INTEGER NOT NULL,
PRIMARY KEY (email, created)
);
CREATE TABLE logintokens (
email TEXT REFERENCES accounts(email) ON DELETE RESTRICT,
created TIMESTAMP NOT NULL,
token TEXT NOT NULL,
PRIMARY KEY (email, created)
);
UPDATE schemaversion SET version = 2;