broken auth WIP
This commit is contained in:
parent
119d4a0052
commit
246ef00540
@ -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
53
capsulflask/auth.py
Normal 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")
|
@ -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
10
capsulflask/model.py
Normal 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
|
@ -0,0 +1,5 @@
|
|||||||
|
CREATE TABLE schemaversion (
|
||||||
|
version INT PRIMARY KEY NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO schemaversion(version) VALUES (1);
|
@ -0,0 +1,9 @@
|
|||||||
|
DROP TABLE payments;
|
||||||
|
|
||||||
|
DROP TABLE logintokens;
|
||||||
|
|
||||||
|
DROP TABLE vms;
|
||||||
|
|
||||||
|
DROP TABLE accounts;
|
||||||
|
|
||||||
|
UPDATE schemaversion SET version = 1;
|
28
capsulflask/schema_migrations/02_up_accounts_vms_etc.sql
Normal file
28
capsulflask/schema_migrations/02_up_accounts_vms_etc.sql
Normal 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;
|
Loading…
Reference in New Issue
Block a user