summaryrefslogtreecommitdiff
path: root/app/modules
diff options
context:
space:
mode:
Diffstat (limited to 'app/modules')
-rw-r--r--app/modules/__init__.py4
-rw-r--r--app/modules/auth/forms.py34
-rw-r--r--app/modules/auth/routes.py73
-rw-r--r--app/modules/common.py75
4 files changed, 186 insertions, 0 deletions
diff --git a/app/modules/__init__.py b/app/modules/__init__.py
new file mode 100644
index 0000000..fcd1d43
--- /dev/null
+++ b/app/modules/__init__.py
@@ -0,0 +1,4 @@
+# -*- mode: python; -*-
+
+from .common import common
+from .auth.routes import auth
diff --git a/app/modules/auth/forms.py b/app/modules/auth/forms.py
new file mode 100644
index 0000000..a4b4555
--- /dev/null
+++ b/app/modules/auth/forms.py
@@ -0,0 +1,34 @@
+# -*- mode: python; -*-
+
+
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ BooleanField,
+)
+from wtforms.validators import (
+ InputRequired,
+ Length,
+ ValidationError,
+)
+
+
+class LoginForm(FlaskForm):
+ username = StringField("Username", validators=[InputRequired()])
+ password = PasswordField("Password", validators=[InputRequired()])
+ remember = BooleanField("Remember")
+ submit = SubmitField("Login")
+
+
+class RegisterForm(LoginForm):
+ def validate_invite_code(self, field):
+ if field.data != "mdltesters2022":
+ raise ValidationError("Invitation code does not match")
+
+ invitation_code = StringField("Invitation code", validators=[InputRequired()])
+ name_first = StringField("First name", validators=[InputRequired()])
+ name_last = StringField("Last name", validators=[InputRequired()])
+ submit = SubmitField("Register")
diff --git a/app/modules/auth/routes.py b/app/modules/auth/routes.py
new file mode 100644
index 0000000..db59bf1
--- /dev/null
+++ b/app/modules/auth/routes.py
@@ -0,0 +1,73 @@
+# -*- mode: python; -*-
+
+from flask import Blueprint, render_template, redirect, url_for, request, flash
+from flask_login import login_user, login_required, logout_user
+from werkzeug.security import generate_password_hash, check_password_hash
+
+from ... import db
+from ...models import User
+from .forms import LoginForm, RegisterForm
+
+
+auth = Blueprint("auth", __name__)
+
+
+@auth.route("/login", methods=["GET", "POST"])
+def login():
+ form = LoginForm()
+ if form.validate_on_submit():
+ req = request.form
+ # print(req["remember"])
+ remember = True if req.get("remember") else False
+ user = User.query.filter_by(username=req["username"]).first()
+ if user is None:
+ flash("User not registered.", "error")
+ return redirect(url_for("auth.register"))
+ if check_password_hash(user.hashed_password, req["password"]) is False:
+ flash("Wrong password.", "error")
+ return redirect(url_for("auth.login"))
+ login_user(user, remember=remember)
+ flash(
+ f"Logged in as user {user.username} successfully. "
+ + f"You will{' not ' if remember is False else ' '}be remembered next time!"
+ )
+ return redirect(url_for("main.home"))
+ return render_template("modules/login.html", form=form)
+
+
+@auth.route("/register", methods=["GET", "POST"])
+def register():
+ form = RegisterForm()
+ if form.validate_on_submit():
+ req = request.form
+ user_already_exists = User.query.filter_by(
+ name_first=req["name_first"],
+ name_last=req["name_last"],
+ ).first()
+ if user_already_exists:
+ flash(
+ f"User {req['name_first']} {req['name_last']} already exists.", "error"
+ )
+ return redirect(url_for("auth.login"))
+ if req["invitation_code"] != "mdltesters2022":
+ flash("Wrong invitation code.", "error")
+ return redirect(url_for("auth.register"))
+ new_user = User(
+ username=req["username"],
+ hashed_password=generate_password_hash(req["password"], method="sha256"),
+ name_first=req["name_first"],
+ name_last=req["name_last"],
+ )
+ db.session.add(new_user)
+ db.session.commit()
+ flash(f"Created user {req['name_first']} {req['name_last']} successfully.")
+ return redirect(url_for("main.home"))
+ return render_template("modules/register.html", form=form)
+
+
+@auth.route("/logout")
+@login_required
+def logout():
+ logout_user()
+ flash(f"Logged out successfully.")
+ return redirect(url_for("main.home"))
diff --git a/app/modules/common.py b/app/modules/common.py
new file mode 100644
index 0000000..1250878
--- /dev/null
+++ b/app/modules/common.py
@@ -0,0 +1,75 @@
+# -*- mode: python; -*-
+
+import inspect
+from flask import Blueprint, request, render_template, redirect, flash, jsonify
+from flask_login import login_required, current_user
+
+from .. import db
+from .. import models
+# from . import forms
+
+from wtforms import SelectField
+
+
+common = Blueprint("common", __name__)
+
+
+@common.route("/modules/<module>/add/<table>", methods=["GET", "POST"])
+@login_required
+def add_item(module, table):
+ """Add new item to table accessible via module."""
+ # print("db table keys are", db.metadata.tables.keys())
+ if table not in db.metadata.tables.keys():
+ return render_template("errors/item-not-found.html", table=table)
+ form = getattr(forms, f"Add{table}")()
+ if form.validate_on_submit():
+ model = getattr(models, table)
+ table_fields = inspect.signature(model).parameters
+ form_values = {key: request.form.get(key) for key in table_fields}
+ print(f"Ready to insert in {table} from {module} {form_values}")
+ record = model(**form_values)
+ db.session.add(record)
+ db.session.commit()
+ item_pk = model.query.order_by(model.primary_key.desc()).first().primary_key
+ flash(f"Successfully added item #{item_pk} to {table} table.", "info")
+ return redirect(f"/modules/{module}")
+ return render_template("modules/add-item.html", table=table, form=form)
+
+
+@common.route("/modules/<module>/edit/<table>/<int:pk>", methods=["GET", "POST"])
+@login_required
+def edit_item(module, table, pk):
+ """Edit existing item in table accessible via module."""
+ if table not in db.metadata.tables.keys():
+ return render_template("errors/item-not-found.html", table=table)
+ model = getattr(models, table)
+ item = model.query.filter_by(primary_key=pk).first()
+ # Instantiate form with selected item's field values.
+ form = getattr(forms, f"Add{table}")(**item.__dict__)
+ if form.validate_on_submit():
+ table_fields = inspect.signature(model).parameters
+ form_values = {key: request.form.get(key) for key in table_fields}
+ print(f"Ready to update {form_values}")
+ model.query.filter_by(primary_key=pk).update(form_values)
+ db.session.commit()
+ flash(f"Successfully edited item #{pk} in {table} table.", "info")
+ return redirect(f"/modules/{module}")
+ return render_template("modules/edit-item.html", table=table, pk=pk, form=form)
+
+
+@common.route("/modules/<module>/delete/<table>/<int:pk>", methods=["POST"])
+@login_required
+def delete_item(module, table, pk):
+ """Delete item with Primary Key = pk from table in module."""
+ model = getattr(models, table)
+ record = model.query.filter_by(primary_key=pk).first()
+ db.session.delete(record)
+ db.session.commit()
+ flash(f"Successfully removed item #{pk} from {table} table.", "info")
+ return redirect(f"/modules/{module}")
+
+
+@common.route("/modules/settings")
+@login_required
+def settings():
+ return render_template("modules/settings.html", user=current_user)
Copyright 2019--2024 Marius PETER