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.