diff --git a/app.py b/app.py index 79cd4ca..f0f6340 100644 --- a/app.py +++ b/app.py @@ -4,6 +4,8 @@ import sqlite3 from flask import Flask, render_template, request, url_for, flash, redirect from werkzeug.exceptions import abort +import db +import auth def get_db_connection(): conn = sqlite3.connect('database.db') @@ -21,15 +23,18 @@ def get_post(post_id): app = Flask(__name__) -# app.config['SECRET_KEY'] = 'hello' +app.config['SECRET_KEY'] = '\xacI4\x077\x16?Q\xb4")\xdb\x066\x95\x11i\x0b\x0c&\xb6rP\'' +app.teardown_appcontext(db.close_db) +app.cli.add_command(db.init_db_command) +app.register_blueprint(auth.bp) @app.route('/') +@auth.login_required def index(): - events= calendar_interface.get_future_calendar_events().get("value") + events = calendar_interface.get_future_calendar_events().get("value") calendar_interface.convert_datetimes(events) - if events is None: abort(404) else: diff --git a/auth.py b/auth.py new file mode 100644 index 0000000..f0acc4f --- /dev/null +++ b/auth.py @@ -0,0 +1,99 @@ +import functools + +from flask import ( + Blueprint, flash, g, redirect, render_template, request, session, url_for +) +from werkzeug.security import check_password_hash, generate_password_hash + +from db import get_db + +bp = Blueprint('auth', __name__, url_prefix='/auth') + +@bp.route('/register', methods=('GET', 'POST')) +def register(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + email = request.form['email'] + + db = get_db() + error = None + + if not username: + error = 'Username is required.' + elif not password: + error = 'Password is required.' + elif not email: + error = 'Email is required.' + + if error is None: + try: + db.execute( + "INSERT INTO user (username, email, password) VALUES (?, ?, ?)", + (username, email, generate_password_hash(password)), + ) + db.commit() + except db.IntegrityError: + error = f"User mit email {email} existiert bereits." + else: + return redirect(url_for("auth.login")) + + flash(error) + + return render_template('auth/register.html') + + +@bp.route('/login', methods=('GET', 'POST')) +def login(): + if request.method == 'POST': + password = request.form['password'] + email = request.form['email'] + + db = get_db() + error = None + user = db.execute( + 'SELECT * FROM user WHERE email = ?', (email,) + ).fetchone() + + if email is None: + error = 'Email existiert nicht.' + elif not check_password_hash(user['password'], password): + error = 'Incorrect password.' + + if error is None: + session.clear() + session['user_id'] = user['id'] + return redirect(url_for('index')) + + flash(error) + + return render_template('auth/login.html') + + +@bp.before_app_request +def load_logged_in_user(): + user_id = session.get('user_id') + + if user_id is None: + g.user = None + else: + g.user = get_db().execute( + 'SELECT * FROM user WHERE id = ?', (user_id,) + ).fetchone() + + +@bp.route('/logout') +def logout(): + session.clear() + return redirect(url_for('index')) + + +def login_required(view): # use this as decorator + @functools.wraps(view) + def wrapped_view(**kwargs): + if g.user is None: + return redirect(url_for('auth.login')) + + return view(**kwargs) + + return wrapped_view \ No newline at end of file diff --git a/db.py b/db.py new file mode 100644 index 0000000..fbca571 --- /dev/null +++ b/db.py @@ -0,0 +1,40 @@ +import sqlite3 + +import click +from flask import current_app, g +from flask.cli import with_appcontext + +DATABASE_PATH = "users.db" + +def get_db(): + if 'db' not in g: + g.db = sqlite3.connect( + DATABASE_PATH, + detect_types=sqlite3.PARSE_DECLTYPES + ) + g.db.row_factory = sqlite3.Row + + return g.db + +def close_db(e=None): + db = g.pop('db', None) + + if db is not None: + db.close() + +def init_db(): + db = get_db() + + with current_app.open_resource('schema.sql') as f: + db.executescript(f.read().decode('utf8')) + +@click.command('init-db') +@with_appcontext +def init_db_command(): + """Clear the existing data and create new tables.""" + init_db() + click.echo('Initialized the database.') + +def init_app(app): + app.teardown_appcontext(close_db) + app.cli.add_command(init_db_command) \ No newline at end of file diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..6d08916 --- /dev/null +++ b/schema.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS user; + +CREATE TABLE user ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + password TEXT NOT NULL +); diff --git a/templates/auth/login.html b/templates/auth/login.html new file mode 100644 index 0000000..2631dcc --- /dev/null +++ b/templates/auth/login.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} + +{% block header %} +