From 52c63cddb3f7860862af6a2185a728baf7593cc7 Mon Sep 17 00:00:00 2001 From: citrons Date: Fri, 6 Aug 2021 01:35:37 +0000 Subject: fix roles even more; forum creation and configuration --- apioforum/db.py | 3 ++ apioforum/forum.py | 78 ++++++++++++++++++++++++++++++-- apioforum/roles.py | 9 +++- apioforum/static/style.css | 2 +- apioforum/templates/common.html | 4 ++ apioforum/templates/edit_forum.html | 27 +++++++++++ apioforum/templates/role_assignment.html | 2 +- apioforum/templates/view_forum.html | 20 ++++++-- apioforum/templates/view_unlisted.html | 24 ++++++++++ apioforum/user.py | 7 ++- 10 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 apioforum/templates/edit_forum.html create mode 100644 apioforum/templates/view_unlisted.html diff --git a/apioforum/db.py b/apioforum/db.py index d501159..899c6b4 100644 --- a/apioforum/db.py +++ b/apioforum/db.py @@ -146,6 +146,9 @@ CREATE TABLE role_assignments ( """, """ ALTER TABLE posts ADD COLUMN deleted NOT NULL DEFAULT 0; +""", +""" +ALTER TABLE forums ADD COLUMN unlisted NOT NULL DEFAULT 0; """ ] diff --git a/apioforum/forum.py b/apioforum/forum.py index f86629d..410bee5 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -98,7 +98,7 @@ def view_forum(forum): subforums_rows = db.execute(""" SELECT max(threads.updated) as updated, forums.* FROM forums LEFT OUTER JOIN threads ON threads.forum=forums.id - WHERE parent = ? + WHERE parent = ? AND unlisted = 0 GROUP BY forums.id ORDER BY name ASC """,(forum['id'],)).fetchall() @@ -109,12 +109,19 @@ def view_forum(forum): if a['updated'] is not None: a['updated'] = datetime.datetime.fromisoformat(a['updated']) subforums.append(a) + + bureaucrats = db.execute(""" + SELECT user FROM role_assignments + WHERE role = 'bureaucrat' AND forum = ? + """,(forum['id'],)).fetchall() + bureaucrats = [b[0] for b in bureaucrats] return render_template("view_forum.html", forum=forum, subforums=subforums, threads=threads, thread_tags=thread_tags, + bureaucrats=bureaucrats ) @forum_route("create_thread",methods=("GET","POST")) @@ -232,15 +239,18 @@ def edit_user_role(forum, username): return redirect(url_for('forum.edit_user_role', username=username,forum_id=forum['id'])) if not is_bureaucrat(forum['id'],g.user) and role != "approved" and role != "": + # only bureaucrats can assign arbitrary roles abort(403) - existing = db.execute("SELECT * FROM role_assignments WHERE user = ?;",(username,)).fetchone() + existing = db.execute( + "SELECT * FROM role_assignments WHERE user = ? AND forum = ?;", + (username,forum['id'])).fetchone() if existing: - db.execute("DELETE FROM role_assignments WHERE user = ?;",(username,)) + db.execute("DELETE FROM role_assignments WHERE user = ? AND forum = ?;",(username,forum['id'])) if role != "": db.execute( "INSERT INTO role_assignments (user,role,forum) VALUES (?,?,?);", (username,role,forum['id'])) - db.commit() + db.commit() flash("role assigned assignedly") return redirect(url_for('forum.view_forum',forum_id=forum['id'])) else: @@ -249,7 +259,8 @@ def edit_user_role(forum, username): return render_template("role_assignment.html", forum=forum,user=username,invalid_user=True) r = db.execute( - "SELECT role FROM role_assignments WHERE user = ?;",(username,)).fetchone() + "SELECT role FROM role_assignments WHERE user = ? AND forum = ?;", + (username,forum['id'])).fetchone() if not r: assigned_role = "" else: @@ -265,6 +276,63 @@ def edit_user_role(forum, username): forum=forum,user=username,role=role, assigned_role=assigned_role,forum_roles=roles) +def forum_config_page(forum, create=False): + db = get_db() + if request.method == "POST": + name = request.form["name"] + desc = request.form["description"] + unlisted = "unlisted" in request.form + if len(name) > 100 or len(name.strip()) == 0: + flash("invalid name") + return redirect(url_for('forum.edit_forum',forum_id=forum['id'])) + elif len(desc) > 6000: + flash("invalid description") + return redirect(url_for('forum.edit_forum',forum_id=forum['id'])) + if not create: + db.execute("UPDATE forums SET name = ?, description = ?, unlisted = ? WHERE id = ?", + (name,desc,forum['id'])) + fid = forum['id'] + else: + cur = db.cursor() + cur.execute( + "INSERT INTO forums (name,description,parent,unlisted) VALUES (?,?,?,?)", + (name,desc,forum['id'],unlisted)) + new = cur.lastrowid + # creator becomes bureaucrat of new forum + db.execute("INSERT INTO role_assignments (role,user,forum) VALUES (?,?,?)", + ("bureaucrat",g.user,new)) + fid = new + db.commit() + return redirect(url_for('forum.view_forum',forum_id=fid)) + else: + if create: + name = "" + desc = "" + else: + name = forum['name'] + desc = forum['description'] + cancel_link = url_for('forum.view_forum',forum_id=forum['id']) + return render_template("edit_forum.html",create=create, + name=name,description=desc,cancel_link=cancel_link) + +@forum_route("edit",methods=["GET","POST"]) +@requires_bureaucrat +def edit_forum(forum): + return forum_config_page(forum) + +@forum_route("create",methods=["GET","POST"]) +@requires_permission("p_create_subforum") +def create_forum(forum): + return forum_config_page(forum,create=True) + +@forum_route("unlisted") +@requires_bureaucrat +def view_unlisted(forum): + db = get_db() + unlisted = db.execute( + "SELECT * FROM forums WHERE unlisted = 1 AND parent = ?",(forum['id'],)) + return render_template('view_unlisted.html',forum=forum,unlisted=unlisted) + @bp.route("/search") def search(): db = get_db() diff --git a/apioforum/roles.py b/apioforum/roles.py index bda6704..ae47e31 100644 --- a/apioforum/roles.py +++ b/apioforum/roles.py @@ -40,11 +40,16 @@ def get_user_role(forum_id, user): fid = forum_id the = None - while the == None and fid != None: - the = db.execute(""" + while fid != None: + r = db.execute(""" SELECT * FROM role_assignments WHERE forum = ? AND user = ?; """,(fid,user)).fetchone() + # the user's role is equal to the role assignnment of the closest + # ancestor unless the user's role is "bureaucrat" in any ancestor + # in which case, the users role is "bureaucrat" + if the == None or (r and r['role'] == "bureaucrat"): + the = r fid = db.execute(""" SELECT * FROM forums WHERE id = ? """,(fid,)).fetchone()['parent'] diff --git a/apioforum/static/style.css b/apioforum/static/style.css index 931ac9a..2ed2e7a 100644 --- a/apioforum/static/style.css +++ b/apioforum/static/style.css @@ -188,7 +188,7 @@ nav#navbar .links { display: flex; } } .actionbutton { color:blue } -.new-post-box { +.new-post-box, .forum-desc-box { height:20em; resize:vertical; width:100%; diff --git a/apioforum/templates/common.html b/apioforum/templates/common.html index 9e60e81..7144667 100644 --- a/apioforum/templates/common.html +++ b/apioforum/templates/common.html @@ -67,6 +67,10 @@ {{the_tag.name}} {%- endmacro %} +{% macro ab(name,href) -%} +{{name}} +{%- endmacro %} + {% macro breadcrumb() %}