Files
autotest-ui-public/autotest_ui.py
T
2026-09-17 14:41:22 +01:00

928 lines
28 KiB
Python

import flask
import flask_sqlalchemy
import sqlalchemy
import sqlalchemy_utils
import flask_login
import werkzeug.security
import datetime
import enum
import utils
app = flask.Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///items.db'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECRET_KEY"] = "placeholder_a4b5c6d7"
db = flask_sqlalchemy.SQLAlchemy(app)
login_manager = flask_login.LoginManager()
login_manager.init_app(app)
login_manager.login_view = "route_signin"
class UserRoles(enum.IntEnum):
UNDEFINED = 0
READONLY = 10
DEVELOPER = 20
MAINTAINER = 30
ADMIN = 40
@property
def text(self):
return self.name.title()
@classmethod
def is_valid(cls, role_number: int):
return role_number in cls._value2member_map_
class User(flask_login.UserMixin, db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(
sqlalchemy_utils.StringEncryptedType(db.String(64), app.config["SECRET_KEY"]),
nullable=False)
email = db.Column(
sqlalchemy_utils.StringEncryptedType(db.String(120), app.config["SECRET_KEY"]),
nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
user_role_value = db.Column(db.Integer, nullable=False, default=UserRoles.UNDEFINED)
reports = db.relationship("TestReport", backref="author")
@property
def user_role(self):
try:
return UserRoles(self.user_role_value)
except ValueError:
return UserRoles.UNDEFINED
@property
def password(self):
raise AttributeError("Cannot read password")
@password.setter
def password(self, password):
self.password_hash = werkzeug.security.generate_password_hash(password)
def verify_password(self, password):
return werkzeug.security.check_password_hash(self.password_hash, password)
class BoardFamily(db.Model):
__tablename__ = "board_family"
board_family_id = db.Column(db.Integer, primary_key=True)
board_family_prefix = db.Column(db.String(16), unique=True, nullable=False)
boards = db.relationship("Board", backref="family")
class Board(db.Model):
__tablename__ = "board"
board_id = db.Column(db.Integer, primary_key=True)
board_family_id = db.Column(db.Integer,
db.ForeignKey("board_family.board_family_id"), nullable=False)
board_name = db.Column(db.String(32), unique=True, nullable=False)
test_boards = db.relationship("TestBoards", backref="board")
class OperatingSystem(db.Model):
__tablename__ = "operating_system"
os_id = db.Column(db.Integer, primary_key=True)
os_name = db.Column(db.String(32), unique=True, nullable=False)
test_boards = db.relationship("TestBoards", backref="os")
class TestBoards(db.Model):
__tablename__ = "test_boards"
testboard_id = db.Column(db.Integer, primary_key=True)
board_id = db.Column(db.Integer,
db.ForeignKey("board.board_id"), nullable=False)
os_id = db.Column(db.Integer,
db.ForeignKey("operating_system.os_id"), nullable=True) # an OS is not always installed
_mac_addr = db.Column(db.String(18), nullable=False)
test_boards = db.relationship("TestProduct", backref="testboard")
@property
def mac_addr(self):
return self._mac_addr
@mac_addr.setter
def mac_addr(self, new_addr):
self._mac_addr = new_addr
class Project(db.Model):
__tablename__ = "project"
project_id = db.Column(db.Integer, primary_key=True)
project_name = db.Column(db.String(64), unique=True, nullable=False)
versions = db.relationship("ProjectVersion", backref="project")
class ProjectVersion(db.Model):
__tablename__ = "project_version"
project_version_id = db.Column(db.Integer, primary_key=True)
project_id = db.Column(db.Integer,
db.ForeignKey("project.project_id"), nullable=False)
project_version_major = db.Column(db.Integer, nullable=False)
project_version_minor = db.Column(db.Integer, nullable=False)
project_version_micro = db.Column(db.Integer, nullable=False)
is_hidden = db.Column(db.Boolean, nullable=False)
reports = db.relationship("TestReport", backref="project_version")
__table_args__ = (
sqlalchemy.UniqueConstraint('project_id', 'project_version_major', 'project_version_minor', 'project_version_micro', name='_project_version_uc'),
)
@property
def version_string(self):
return f"v{self.project_version_major}.{self.project_version_minor}.{self.project_version_micro}"
class TestReport(db.Model):
__tablename__ = "test_report"
test_report_id = db.Column(db.Integer, primary_key=True)
author_id = db.Column(db.Integer,
db.ForeignKey("user.id"), nullable=False)
project_version_id = db.Column(db.Integer,
db.ForeignKey("project_version.project_version_id"), nullable=False)
project_version_build = db.Column(db.Integer, nullable=False)
timestamp_start = db.Column(db.DateTime, nullable=False)
timestamp_end = db.Column(db.DateTime, nullable=False)
cached_result_pass = db.Column(db.Integer, nullable=False)
cached_result_fail = db.Column(db.Integer, nullable=False)
tests = db.relationship("TestProduct", backref="report")
class TestProduct(db.Model):
__tablename__ = "test_product"
test_product_id = db.Column(db.Integer, primary_key=True)
test_report_id = db.Column(db.Integer,
db.ForeignKey("test_report.test_report_id"), nullable=False)
testboard_id = db.Column(db.Integer,
db.ForeignKey("test_boards.testboard_id"), nullable=False)
timestamp_start = db.Column(db.DateTime, nullable=False)
timestamp_end = db.Column(db.DateTime, nullable=False)
cached_result_pass = db.Column(db.Integer, nullable=False)
cached_result_fail = db.Column(db.Integer, nullable=False)
test_items = db.relationship("TestItem", backref="test")
class TestItem(db.Model):
__tablename__ = "test_item"
test_item_id = db.Column(db.Integer, primary_key=True)
test_product_id = db.Column(db.Integer,
db.ForeignKey("test_product.test_product_id"), nullable=False)
test_item_name = db.Column(db.String(128), nullable=False)
test_script_version = db.Column(db.String(32), nullable=False)
test_item_result = db.Column(db.Boolean, nullable=False)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@app.before_request
def load_logged_in_user():
user_id = flask.session.get("user_id")
if user_id is None:
flask.g.user = None
else:
flask.g.user = User.query.get(user_id)
@app.route("/")
def route_home():
return flask.render_template("home.html")
@app.route("/signout")
@flask_login.login_required
def route_logout():
flask_login.logout_user()
return flask.redirect("/signin")
@app.route("/signin", methods=["GET", "POST"])
def route_signin():
if flask.request.method == "GET":
return flask.render_template("signin.html")
username = flask.request.form.get("username", "")
password = flask.request.form.get("password", "")
if not username:
flask.flash("Username is blank", "error")
return flask.redirect("/signin")
if not password:
flask.flash("Password is blank", "error")
return flask.redirect("/signin")
if not utils.VALID in (
utils.validation.username(username),
utils.validation.email(username)):
flask.flash("Username contains illegal characters")
return flask.redirect("/signin")
user = User.query.filter_by(username=username).first()
if not user:
user = User.query.filter_by(email=username).first()
if not user:
flask.flash("Incorrect _Username_ or Password", "error")
return flask.render_template("/signin.html")
if not werkzeug.security.check_password_hash(user.password_hash, password):
flask.flash("Incorrect Username or _Password_", "error")
return flask.render_template("/signin.html")
flask_login.login_user(user)
return flask.redirect("/account")
@app.route("/product-setup")
@flask_login.login_required
def route_product_setup():
families = BoardFamily.query.order_by(BoardFamily.board_family_prefix).all()
products_table = []
for family in families:
products_table.append(
Board.query.filter_by(board_family_id=family.board_family_id).order_by(Board.board_name.desc()).all()
)
return flask.render_template("product_setup.html", families=families, products_table=products_table)
@app.route("/product-setup/add-family", methods=["POST"])
def route_product_setup_add_family():
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/product-setup")
family_name = flask.request.form.get("family_name", "").strip()
if not family_name:
flask.flash("Family name is null", "error")
return flask.redirect("/product-setup")
if utils.validation.text_numeric_only(family_name, extra_chars="-") == utils.INVALID:
flask.flash("Family name contains illegal characters", "error")
return flask.redirect("/product-setup")
existing_family = BoardFamily.query.filter_by(board_family_prefix=family_name).first()
if existing_family:
flask.flash("Family name already exists", "error")
return flask.redirect("/product-setup")
new_family = BoardFamily(board_family_prefix=family_name)
db.session.add(new_family)
db.session.commit()
return flask.redirect("/product-setup")
@app.route("/product-setup/add-board", methods=["POST"])
@flask_login.login_required
def route_product_setup_add_board():
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/product-setup")
board_name = flask.request.form.get("board_name", "").strip()
board_family_id = flask.request.form.get("board_family_id", default=0, type=int)
if not board_name:
flask.flash("Board name is null", "error")
return flask.redirect("/product-setup")
if utils.validation.text_numeric_only(board_name) == utils.INVALID:
flask.flash("Board name contains illegal characters", "error")
return flask.redirect("/product-setup")
if board_family_id == 0:
flask.flash("Board family is invalid", "error")
return flask.redirect("/product-setup")
existing_board = Board.query.filter_by(board_name=board_name).first()
if existing_board:
flask.flash("Board name already exists", "error")
return flask.redirect("/product-setup")
new_board = Board(board_family_id=board_family_id, board_name=board_name)
db.session.add(new_board)
db.session.commit()
return flask.redirect("/product-setup")
@app.route("/operating-system-setup")
@flask_login.login_required
def route_operating_system_setup():
operating_systems = OperatingSystem.query.order_by(OperatingSystem.os_name).all()
return flask.render_template("operating_system_setup.html",
operating_systems=operating_systems)
@app.route("/operating-system-setup/add-os", methods=["POST"])
@flask_login.login_required
def route_operating_system_setup_add_os():
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/operating-system-setup")
os_name = flask.request.form.get("os_name", "").strip()
if not os_name:
flask.flash("OS name is invalid", "error")
return flask.redirect("/operating-system-setup")
if utils.validation.text_numeric_only(os_name, extra_chars=" -.") == utils.INVALID:
flask.flash("OS name contains illegal characters", "error")
return flask.redirect("/operating-system-setup")
os = OperatingSystem.query.filter_by(os_name=os_name).first()
if os is not None:
flask.flash(f"OS already exists: {os_name}", "error")
return flask.redirect("/operating-system-setup")
os = OperatingSystem(os_name=os_name)
db.session.add(os)
db.session.commit()
return flask.redirect("/operating-system-setup")
@app.route("/operating-system-setup/delete-os/<int:os_id>", methods=["POST"])
@flask_login.login_required
def route_operating_system_setup_delete_os(os_id):
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/operating-system-setup")
operating_system = OperatingSystem.query.filter_by(os_id=os_id).first()
if operating_system is None:
flask.flash("OS not found", "error")
return flask.redirect("/operating-system-setup")
if len(operating_system.test_boards) != 0:
flask.flash("This OS is still in use by a test board", "error")
return flask.redirect("/operating-system-setup")
db.session.delete(operating_system)
db.session.commit()
return flask.redirect("/operating-system-setup")
@app.route("/test-bench-setup")
@flask_login.login_required
def route_test_bench_setup():
families = BoardFamily.query.order_by(BoardFamily.board_family_prefix).all()
boards = Board.query.order_by(Board.board_name).all()
operating_systems = OperatingSystem.query.order_by(OperatingSystem.os_name).all()
test_boards = TestBoards.query.all()
return flask.render_template("test_bench.html",
families=families, boards=boards,
operating_systems=operating_systems,
test_boards=test_boards)
@app.route("/test-bench-setup/add-board", methods=["POST"])
@flask_login.login_required
def route_test_bench_setup_add_board():
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/test-bench-setup")
board_id = flask.request.form.get("board_id", default=0, type=int)
mac_addr = utils.sanitise.mac_addr(flask.request.form.get("mac_addr", "").strip())
if board_id == 0:
flask.flash("Board ID is invalid", "error")
return flask.redirect("/test-bench-setup")
if not mac_addr:
flask.flash("MAC address is null", "error")
return flask.redirect("/test-bench-setup")
if utils.validation.mac_addr(mac_addr) != utils.VALID:
flask.flash("MAC address is not valid", "error")
return flask.redirect("/test-bench-setup")
new_test_board = TestBoards(board_id=board_id, mac_addr=mac_addr)
db.session.add(new_test_board)
db.session.commit()
return flask.redirect("/test-bench-setup")
@app.route("/test-bench-setup/update-os/<int:testboard_id>", methods=["POST"])
@flask_login.login_required
def route_test_bench_setup_update_os(testboard_id):
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/test-bench-setup")
os_id = flask.request.form.get("os_id", default=0, type=int)
if testboard_id == 0:
flask.flash("Test baord ID is null", "error")
return flask.redirect("/test-bench-setup")
test_board = TestBoards.query.filter_by(testboard_id=testboard_id).first()
if test_board is None:
flask.flash("Test board not found", "error")
return flask.redirect("/test-bench-setup")
# if we are selecting a non-zero OS, we must check it is valid
# 0 indicated a null value - where no OS is installed
if os_id != 0:
os = OperatingSystem.query.filter_by(os_id=os_id).first()
if os is None:
flask.flash("OS is not found", "error")
return flask.redirect("/test-bench-setup")
test_board.os_id = os_id
db.session.commit()
return flask.redirect("/test-bench-setup")
@app.route("/test-bench-setup/delete-test-board/<int:testboard_id>", methods=["POST"])
@flask_login.login_required
def route_test_bench_setup_delete_test_board(testboard_id):
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/test-bench-setup")
if testboard_id == 0:
flask.flash("Test board ID is null", "error")
return flask.redirect("/test-bench-setup")
test_board = TestBoards.query.filter_by(testboard_id=testboard_id).first()
if test_board is None:
flask.flash("Test board is not found", "error")
return flask.redirect("/test-bench-setup")
db.session.delete(test_board)
db.session.commit()
return flask.redirect("/test-bench-setup")
@app.route("/schedule-new-test", methods=["GET", "POST"])
@flask_login.login_required
def route_schedule_new_test():
if flask_login.current_user.user_role < UserRoles.DEVELOPER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/")
if flask.request.method == "GET":
operating_systems = OperatingSystem.query.order_by(OperatingSystem.os_name).all()
test_boards = TestBoards.query.all()
projects = Project.query.all()
projects_dict = {}
for project in projects:
projects_dict[project.project_name] = []
for version in project.versions:
if version.is_hidden:
continue
v_maj = version.project_version_major
v_min = version.project_version_minor
v_mic = version.project_version_micro
ver_str = f"{v_maj}.{v_min}.{v_mic}"
projects_dict[project.project_name].append(ver_str)
return flask.render_template("schedule_new_test.html",
operating_systems=operating_systems, test_boards=test_boards, projects=projects_dict)
# handle post request
project = utils.sanitise.text_input(flask.request.form.get("proj", "").strip())
version = utils.sanitise.text_input(flask.request.form.get("ver", "").strip())
build_num = flask.request.form.get("build", type=int)
test_board_ids = flask.request.form.getlist("test-boards")
# load project id
project_obj = Project.query.filter_by(project_name=project).first()
if project_obj is None:
flask.flash("Cannot load the project", "error")
return flask.redirect("/schedule-new-test")
project_id = project_obj.project_id
generic_version_error_msg = "Version provided is not in the correct format"
# parse project version
if version.count(".") != 2:
flask.flash(generic_version_error_msg, "error")
return flask.redirect("/schedule-new-test")
v_maj, v_min, v_mic = version.split(".")
try:
v_maj = int(v_maj)
v_min = int(v_min)
v_mic = int(v_mic)
except ValueError:
flask.flash(generic_version_error_msg, "error")
return flask.redirect("/schedule-new-test")
version_obj = ProjectVersion.query.filter_by(
project_id=project_id,
project_version_major=v_maj,
project_version_minor=v_min,
project_version_micro=v_mic,
).first()
if version_obj is None:
flask.flash("Cannot load the provided version", "error")
return flask.redirect("/schedule-new-test")
project_version_id = version_obj.project_version_id
# create TestReport record
test_report_obj = TestReport(
author_id = flask_login.current_user.id,
project_version_id = project_version_id,
project_version_build = 4, # placeholder
timestamp_start = datetime.datetime.now(),
timestamp_end = utils.defaults.unix_epoch(),
cached_result_pass = 0, # placeholder
cached_result_fail = 0, # placeholder
)
db.session.add(test_report_obj)
# todo: create TestProduct for each selected board
test_products_objs = []
for test_board_id in test_board_ids:
board_obj = TestBoards.query.filter_by(testboard_id=test_board_id).first()
if board_obj is None:
db.session.rollback()
flask.flash("Cannot cancel this report", "error")
return flask.redirect("/schedule-new-test")
test_board_obj = TestProduct(
test_report_id = test_report_obj.test_report_id,
testboard_id = test_board_id,
timestamp_start = utils.defaults.unix_epoch(),
timestamp_end = utils.defaults.unix_epoch(),
cached_result_pass = 0,
cached_result_fail = 0,
)
test_products_objs.append(test_board_obj)
for test_product in test_products_objs:
db.session.add(test_product)
db.session.commit()
# not fully implemented due to backend relying on internal coporate systems
# this is outside the scope of this assignment
return flask.redirect("/active-tests")
@app.route("/active-tests")
@flask_login.login_required
def route_active_tests():
active_reports = TestReport.query.filter_by(timestamp_end=utils.defaults.unix_epoch()).all()
return flask.render_template("active-tests.html", active_reports=active_reports)
@app.route("/active-tests/delete/<int:report_id>", methods=["POST"])
@flask_login.login_required
def route_active_tests_delete(report_id):
if flask_login.current_user.user_role < UserRoles.DEVELOPER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/active-tests")
report = TestReport.query.filter_by(test_report_id=report_id, timestamp_end=utils.defaults.unix_epoch()).first()
if report is None:
flask.flash("Cannot cancel this report", "error")
return flask.redirect("/active-tests")
# todo: delete child nodes first
child_test_products = TestProduct.query.filter_by(test_report_id=report.test_report_id).all()
for test_product in child_test_products:
db.session.delete(test_product)
db.session.delete(report)
db.session.commit()
return flask.redirect("/active-tests")
@app.route("/active-tests/<int:report_id>")
@flask_login.login_required
def route_active_tests_products(report_id):
test_products = TestProduct.query.filter_by(test_report_id=report_id).all()
if len(test_products) == 0:
flask.flash(f"Invalid test report ID: {report_id}")
return flask.redirect("/active-tests")
return flask.render_template("active-tests-products.html", report_id=report_id, test_products=test_products)
@app.route("/active-tests/delete-product-test/<int:product_test_id>", methods=["POST"])
@flask_login.login_required
def route_active_tests_delete_product_test(product_test_id):
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect(f"/active-tests/{product_test_id}")
test_product = TestProduct.query.filter_by(test_product_id=product_test_id).first()
if test_product is None:
flask.flash("Cannot load record from database")
return flask.redirect(f"/active-tests/{product_test_id}")
test_report_id = test_product.report.test_report_id
db.session.delete(test_product)
db.session.commit()
return flask.redirect(f"/active-tests/{test_report_id}")
@app.route("/test-reports")
@flask_login.login_required
def route_test_reports():
return flask.render_template("test_reports.html")
@app.route("/projects")
@flask_login.login_required
def route_projects():
all_projects = Project.query.order_by(Project.project_name).all()
return flask.render_template("projects.html", projects=all_projects)
@app.route("/projects/add-project", methods=["POST"])
@flask_login.login_required
def route_add_project():
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/projects")
project_name = flask.request.form.get("project_name", "").strip()
if not project_name:
flask.flash("Project name is null", "error")
return flask.redirect("/projects")
if utils.validation.text_numeric_only(project_name, extra_chars=" -") == utils.INVALID:
flask.flash("Project name contains illegal characters", "error")
return flask.redirect("/projects")
existing_project = Project.query.filter_by(project_name=project_name).first()
if existing_project:
flask.flash("Project with that name already exists", "error")
return flask.redirect("/projects")
new_project = Project(project_name=project_name)
db.session.add(new_project)
db.session.commit()
return flask.redirect("/projects")
@app.route("/projects/add-version", methods=["POST"])
@flask_login.login_required
def route_add_project_version():
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/projects")
project_id = flask.request.form.get("project_id", type=int)
version_major = flask.request.form.get("major", type=int)
version_minor = flask.request.form.get("minor", type=int)
version_micro = flask.request.form.get("micro", type=int)
if not project_id:
flask.flash("Project ID is not defined", "error")
return flask.redirect("/projects")
if None in (version_major, version_minor, version_micro):
flask.flash("Not all version levels are defined (major minor micro)", "error")
return flask.redirect("/projects")
existing_version = ProjectVersion.query.filter_by(
project_id=project_id,
project_version_major=version_major,
project_version_minor=version_minor,
project_version_micro=version_micro
).first()
if existing_version:
flask.flash("Version already exists for this project", "error")
return flask.redirect("/projects")
new_version = ProjectVersion(
project_id=project_id,
project_version_major=version_major,
project_version_minor=version_minor,
project_version_micro=version_micro,
is_hidden=False
)
db.session.add(new_version)
db.session.commit()
return flask.redirect("/projects")
@app.route("/projects/toggle-version-hidden/<int:project_version_id>", methods=["POST"])
@flask_login.login_required
def route_toggle_version_hidden(project_version_id):
if flask_login.current_user.user_role < UserRoles.MAINTAINER:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/projects")
version = ProjectVersion.query.filter_by(project_version_id=project_version_id).first()
if not version:
flask.flash("Version cannot be loaded from database", "error")
return flask.redirect("/projects")
version.is_hidden = not version.is_hidden
db.session.commit()
return flask.redirect("/projects")
@app.route("/account")
@flask_login.login_required
def route_accounts():
users = User.query.all()
return flask.render_template("account.html", users=users, UserRoles=UserRoles)
@app.route("/account/new", methods=["GET", "POST"])
@flask_login.login_required
def route_account_new():
if flask_login.current_user.user_role < UserRoles.ADMIN:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/account")
if flask.request.method == "POST":
username = flask.request.form.get("username")
email = flask.request.form.get("email")
password = flask.request.form.get("password")
usertype = flask.request.form.get("user-type", type=int)
if None in (username, email, password):
flask.flash("fields cannot be blank", "error")
return flask.redirect("/account/new")
if utils.INVALID == utils.validation.username(username):
flask.flash("Username contains illegal characters", "error")
return flask.redirect("/account/new")
if utils.INVALID == utils.validation.email(email):
flask.flash("Email contains illegal characters", "error")
return flask.redirect("/account/new")
users_via_username = User.query.filter_by(username=username).first()
users_via_email = User.query.filter_by(email=email).first()
if (users_via_username is not None) or (users_via_email is not None):
flask.flash("That user already exists", "error")
return flask.redirect("/account/new")
if not UserRoles.is_valid(usertype):
flask.flash("Invalid user role")
return flask.redirect("/account/new")
# todo actually create the new user
user = User(
username=username,
email=email,
password=password,
user_role_value=usertype
)
db.session.add(user)
db.session.commit()
return flask.redirect("/account")
return flask.render_template("account-new.html", UserRoles=UserRoles)
@app.route("/account/update", methods=["POST"])
@flask_login.login_required
def route_account_update():
if flask_login.current_user.user_role < UserRoles.ADMIN:
flask.flash("Insufficient privilages", "error")
return flask.redirect("/account")
user_id = flask.request.form.get("user-id", type=int)
userrole = flask.request.form.get("user-type", type=int)
user_obj = User.query.filter_by(id=user_id).first()
if user_obj is None:
flask.flash("Cannot load that user", "error")
return flask.redirect("/account")
if not UserRoles.is_valid(userrole):
flask.flash("User role is not valid", "error")
return flask.redirect("/account")
if user_obj.user_role_value == userrole:
flask.flash("User role has not been changed", "error")
return flask.redirect("/account")
user_obj.user_role_value = userrole
db.session.commit()
with app.app_context():
db.create_all()
# debug create initial account
if not User.query.first():
initial_user = User(
username="admin",
email="admin@localhost",
password="admin",
user_role_value=UserRoles.ADMIN
)
db.session.add(initial_user)
db.session.commit()
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)