diff options
-rw-r--r-- | apioforum/db.py | 6 | ||||
-rw-r--r-- | apioforum/forum.py | 43 | ||||
-rw-r--r-- | apioforum/roles.py | 41 | ||||
-rw-r--r-- | 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("/<int:forum_id>/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. </p> <p> - 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. </p> <form method="post" id="role_config"> @@ -23,11 +21,11 @@ {% macro perm(p, description, tooltip) %} <input type="checkbox" - id="{{role_config.role}}_{{p}}" - name="{{role_config.role}}_{{p}}" + id="perm_{{role_config.role}}_{{p}}" + name="perm_{{role_config.role}}_{{p}}" {% if role_config[p] %}checked{% endif %} /> - <label for="{{role_config.role}}_{{p}}" title="{{tooltip}}"> + <label for="perm_{{role_config.role}}_{{p}}" title="{{tooltip}}"> {{- description -}} </label> <br/> @@ -47,15 +45,23 @@ {{perm("p_create_subforum","create subforæ", "allow users with the role to create subforæ in this forum. " + "they will automatically become a bureaucrat in this subforum.")}} + <input type="hidden" name="roleconfig_{{role_config.role}}" value="present"/> {% if role_config.role != "other" %} {{perm("p_approve","approve others", "allow users with the role to assign the 'approved' role to those with the 'other' role")}} {% endif %} </fieldset> {% endfor %} - +{% if role_configs %} + <p>confirm changes?</p> + <p> + <input type="submit" value="confirm"> + <a href="{{url_for('forum.view_forum',forum_id=forum.id)}}">cancel</a> + </p> +{% endif %} </form> + <fieldset> <legend>add role</legend> <ul> @@ -68,16 +74,12 @@ </li> {% endfor %} <li> - <form action="{{url_for('forum.add_role',forum_id=forum.id,role_name=role)}}" method="POST" style="display:inline"> - <input type="text" name="role" class="role-input" placeholder="role name"/> + <form action="{{url_for('forum.add_role',forum_id=forum.id)}}" method="POST" style="display:inline"> + <input type="text" name="role" class="role-input" placeholder="role name" maxlength="32"/> <input type="submit" value="add" /> </form> </li> </ul> </fieldset> -<p>confirm changes?</p> -<input type="submit" value="confirm" form="role_config"> -<a href="{{url_for('forum.view_forum',forum_id=forum.id)}}">cancel</a> - {% endblock %} |