From 96fcef98d7bc0fd8940959077c009016aae56fd0 Mon Sep 17 00:00:00 2001 From: citrons Date: Sun, 18 Jul 2021 06:11:26 +0000 Subject: role config UI --- apioforum/db.py | 6 +++++ apioforum/forum.py | 43 ++++++++++++++++++++++++++++--- apioforum/roles.py | 41 +++++++++++++++++++++++++++++ apioforum/templates/edit_permissions.html | 28 ++++++++++---------- 4 files changed, 102 insertions(+), 16 deletions(-) diff --git a/apioforum/db.py b/apioforum/db.py index 5ffd5d9..d94a707 100644 --- a/apioforum/db.py +++ b/apioforum/db.py @@ -135,6 +135,12 @@ CREATE TABLE role_config ( INSERT INTO role_config (role,forum) VALUES ("approved",1); INSERT INTO role_config (role,forum) VALUES ("other",1); +""", +""" +CREATE TABLE role_assignments ( + user NOT NULL REFERENCES users(username), + forum NOT NULL REFERENCES forums(id) +); """ ] diff --git a/apioforum/forum.py b/apioforum/forum.py index 4b7522c..ed7e2b7 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -8,7 +8,8 @@ from flask import ( from .db import get_db from .mdrender import render -from .roles import forum_perms, overridden_perms +from .roles import get_forum_roles +from .roles import permissions as role_permissions from sqlite3 import OperationalError import datetime @@ -127,15 +128,51 @@ def edit_roles(forum_id): "SELECT * FROM role_config WHERE forum = ? ORDER BY ID ASC", (forum_id,)).fetchall() + if request.method == "POST": + for config in role_configs: + if 'roleconfig_' + config['role'] in request.form: + for p in role_permissions: + permission_setting =\ + f"perm_{config['role']}_{p}" in request.form + db.execute(f""" + UPDATE role_config SET {p} = ? + WHERE forum = ? AND role = ?; + """, + (permission_setting,forum_id, config['role'])) + db.commit() + flash('roles sucessfully enroled') + return redirect(url_for('forum.view_forum',forum_id=forum_id)) + + role_config_roles = [c['role'] for c in role_configs] + other_roles = [role for role in get_forum_roles(forum_id) if not role in role_config_roles] + return render_template("edit_permissions.html", forum=forum, role_configs=role_configs, - other_roles=["the","test","placeholder"], + other_roles=other_roles ) @bp.route("//roles/new",methods=["POST"]) def add_role(forum_id): - return "placeholder" + name = request.form['role'].strip() + if not all(c in (" ","-","_") or c.isalnum() for c in name) \ + or len(name) > 32: + flash("role name must contain no special characters") + return redirect(url_for('forum.edit_roles',forum_id=forum_id)) + if name == "bureaucrat": + flash("cannot configure permissions for bureaucrat") + return redirect(url_for('forum.edit_roles',forum_id=forum_id)) + + db = get_db() + + existing_config = db.execute(""" + SELECT * FROM role_config WHERE forum = ? AND role = ? + """,(forum_id,name)).fetchone() + if not existing_config: + db.execute("INSERT INTO role_config (forum,role) VALUES (?,?)", + (forum_id,name)) + db.commit() + return redirect(url_for('forum.edit_roles',forum_id=forum_id)) @bp.route("/search") def search(): diff --git a/apioforum/roles.py b/apioforum/roles.py index 71efcbd..ae193a7 100644 --- a/apioforum/roles.py +++ b/apioforum/roles.py @@ -23,4 +23,45 @@ def get_role_config(forum_id, role): WHERE forum = ? AND role = ?; """, (fid,role)).fetchone() fid = db.execute(""" + SELECT * FROM forums WHERE id = ? + """(fid,)).fetchone()['parent'] + if the == None: + if role == "other": + raise(RuntimeError( + "unable to find permissions for role 'other', " + + "which should have associated permissions in all contexts.")) + else: + return get_role_config(forum_id, "other") + return the + +def get_user_role(forum_id, user): + db = get_db() + + fid = forum_id + the = None + while the == None and fid != None: + the = db.execute(""" + SELECT * FROM role_assignments + WHERE forum = ? AND user = ?; + """, (fid,role)).fetchone() + fid = db.execute(""" + SELECT * FROM forums WHERE id = ? """).fetchone()['parent'] + return the['role'] if the != None else 'other' + +def get_forum_roles(forum_id): + db = get_db() + + ancestors = db.execute(""" + WITH RECURSIVE fs AS + (SELECT * FROM forums WHERE id = ? + UNION ALL + SELECT forums.* FROM forums, fs WHERE fs.parent=forums.id) + SELECT * FROM fs; + """,(forum_id,)).fetchall() + configs = [] + for a in ancestors: + configs += db.execute(""" + SELECT * FROM role_config WHERE forum = ? + """,(a['id'],)).fetchall() + return set(r['role'] for r in configs) diff --git a/apioforum/templates/edit_permissions.html b/apioforum/templates/edit_permissions.html index e79c0c7..1e4e848 100644 --- a/apioforum/templates/edit_permissions.html +++ b/apioforum/templates/edit_permissions.html @@ -9,11 +9,9 @@ everyone's role is "other" by default.

- here a set of permissions may be associated with any role. + here, a set of permissions may be associated with any role. if a role does not have any permissions configured for this forum, the permissions set for the role in closest ancestor forum are used. - if no permissions are set for the role in any ancestor forum, - the permissions for the role "other" are used.

@@ -23,11 +21,11 @@ {% macro perm(p, description, tooltip) %} -