summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--apioforum/db.py6
-rw-r--r--apioforum/forum.py43
-rw-r--r--apioforum/roles.py41
-rw-r--r--apioforum/templates/edit_permissions.html28
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 %}