diff options
-rw-r--r-- | apioforum/db.py | 3 | ||||
-rw-r--r-- | apioforum/forum.py | 44 | ||||
-rw-r--r-- | apioforum/roles.py | 17 | ||||
-rw-r--r-- | apioforum/templates/edit_forum.html | 2 | ||||
-rw-r--r-- | apioforum/templates/edit_permissions.html | 2 | ||||
-rw-r--r-- | apioforum/templates/role_assignment.html | 4 |
6 files changed, 43 insertions, 29 deletions
diff --git a/apioforum/db.py b/apioforum/db.py index 5c3d2eb..c0c8c7e 100644 --- a/apioforum/db.py +++ b/apioforum/db.py @@ -204,6 +204,9 @@ ALTER TABLE posts ADD COLUMN deleted NOT NULL DEFAULT 0; """ ALTER TABLE forums ADD COLUMN unlisted NOT NULL DEFAULT 0; """, +""" +ALTER TABLE role_config ADD COLUMN p_view_forum INT NOT NULL DEFAULT 1; +""" ] def init_db(): diff --git a/apioforum/forum.py b/apioforum/forum.py index 084c75d..2931df9 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -10,6 +10,7 @@ from flask import ( from .db import get_db from .mdrender import render from .roles import get_forum_roles,has_permission,is_bureaucrat,get_user_role, permissions as role_permissions +from .permissions import is_admin from sqlite3 import OperationalError import datetime import functools @@ -63,11 +64,11 @@ def forum_route(relative_path, **kwargs): return decorator -def requires_permission(permission): +def requires_permission(permission, login_required=True): def decorator(f): @functools.wraps(f) def wrapper(forum, *args, **kwargs): - if not has_permission(forum['id'], g.user, permission): + if not has_permission(forum['id'],g.user,permission,login_required): abort(403) return f(forum, *args, **kwargs) return wrapper @@ -75,6 +76,7 @@ def requires_permission(permission): def requires_bureaucrat(f): @functools.wraps(f) + @requires_permission("p_view_forum") def wrapper(forum, *args, **kwargs): if not is_bureaucrat(forum['id'], g.user): abort(403) @@ -82,12 +84,8 @@ def requires_bureaucrat(f): return wrapper @forum_route("") +@requires_permission("p_view_forum", login_required=False) def view_forum(forum): - # user should not be able to see anything about the forum if it is unlisted - # and the user does not have permission to see things - if forum['unlisted'] and not has_permission(forum['id'], g.user, "p_view_threads"): - abort(403) - db = get_db() threads = db.execute( """SELECT @@ -154,7 +152,8 @@ def view_forum(forum): a.update(s) if a['updated'] is not None: a['updated'] = datetime.datetime.fromisoformat(a['updated']) - subforums.append(a) + if has_permission(a['id'],g.user,"p_view_forum",login_required=False): + subforums.append(a) bureaucrats = db.execute(""" SELECT user FROM role_assignments @@ -174,6 +173,7 @@ def view_forum(forum): @forum_route("create_thread",methods=("GET","POST")) @requires_permission("p_create_threads") +@requires_permission("p_view_forum") def create_thread(forum): db = get_db() forum = db.execute("SELECT * FROM forums WHERE id = ?",(forum['id'],)).fetchone() @@ -247,6 +247,7 @@ def edit_roles(forum): ) @forum_route("roles/new",methods=["POST"]) +@requires_bureaucrat def add_role(forum): name = request.form['role'].strip() if not all(c in (" ","-","_") or c.isalnum() for c in name) \ @@ -334,7 +335,6 @@ def forum_config_page(forum, create=False): 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'])) @@ -342,14 +342,14 @@ def forum_config_page(forum, create=False): 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,unlisted,forum['id'])) + db.execute("UPDATE forums SET name = ?, description = ? 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)) + "INSERT INTO forums (name,description,parent) VALUES (?,?,?)", + (name,desc,forum['id'])) new = cur.lastrowid # creator becomes bureaucrat of new forum db.execute("INSERT INTO role_assignments (role,user,forum) VALUES (?,?,?)", @@ -361,14 +361,12 @@ def forum_config_page(forum, create=False): if create: name = "" desc = "" - unlisted = False else: name = forum['name'] desc = forum['description'] - unlisted = forum['unlisted'] cancel_link = url_for('forum.view_forum',forum_id=forum['id']) return render_template("edit_forum.html",create=create, - name=name,description=desc,unlisted=unlisted,cancel_link=cancel_link) + name=name,description=desc,cancel_link=cancel_link) @forum_route("edit",methods=["GET","POST"]) @requires_bureaucrat @@ -380,13 +378,13 @@ def edit_forum(forum): 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) +#@forum_route("unlisted") +#def view_unlisted(forum): +# if not is_admin: abort(403) # why doesn't this fucking work +# 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(): diff --git a/apioforum/roles.py b/apioforum/roles.py index d8e59ba..aa1d239 100644 --- a/apioforum/roles.py +++ b/apioforum/roles.py @@ -1,5 +1,6 @@ from .db import get_db +from .permissions import is_admin permissions = [ "p_create_threads", @@ -10,7 +11,8 @@ permissions = [ "p_vote", "p_create_polls", "p_approve", - "p_create_subforum" + "p_create_subforum", + "p_view_forum" ] def get_role_config(forum_id, role): @@ -76,9 +78,16 @@ def get_forum_roles(forum_id): """,(a['id'],)).fetchall() return set(r['role'] for r in configs) -def has_permission(forum_id, user, permission, login_required=True): - if user == None and login_required: return False - role = get_user_role(forum_id, user) if user else "other" +def has_permission(forum_id, username, permission, login_required=True): + db = get_db() + forum = db.execute("SELECT * FROM forums WHERE id = ?",(forum_id,)).fetchone() + user = db.execute('SELECT * FROM users WHERE username = ?', + (username,)).fetchone() if username else None + + if forum['unlisted'] and not (user and user['admin']): return False + if username == None and login_required: return False + + role = get_user_role(forum_id, username) if username else "other" if role == "bureaucrat": return True config = get_role_config(forum_id, role) return config[permission] diff --git a/apioforum/templates/edit_forum.html b/apioforum/templates/edit_forum.html index 32bfaf1..f165676 100644 --- a/apioforum/templates/edit_forum.html +++ b/apioforum/templates/edit_forum.html @@ -17,8 +17,6 @@ maxlength="6000" required >{{description}}</textarea> - <input type="checkbox" id="unlisted" name="unlisted" {% if unlisted %}checked{% endif %}/> - <label for="unlisted">unlisted?</label> <p> <input type="submit" value="confirm"> <a href="{{cancel_link}}">cancel</a> diff --git a/apioforum/templates/edit_permissions.html b/apioforum/templates/edit_permissions.html index c92c9a9..59c9093 100644 --- a/apioforum/templates/edit_permissions.html +++ b/apioforum/templates/edit_permissions.html @@ -29,6 +29,8 @@ </label> <br/> {% endmacro %} + {{perm("p_view_forum","view the forum", + "allow users with the role to see the forum in listings and view information about it")}} {{perm("p_create_threads","create threads", "allow users with the role to create a thread in the forum")}} {{perm("p_reply_threads","reply to threads", diff --git a/apioforum/templates/role_assignment.html b/apioforum/templates/role_assignment.html index 74dc3cd..8309506 100644 --- a/apioforum/templates/role_assignment.html +++ b/apioforum/templates/role_assignment.html @@ -1,4 +1,5 @@ {% extends 'base.html' %} +{% from 'common.html' import ab %} {% block header %}<h1>{% block title %}configure user role in '{{forum.name}}'{% endblock %}</h1>{% endblock %} {% block content %} <p> @@ -12,6 +13,9 @@ you are only allowed to approve members in this forum. </p> {% endif %} + +{# <p>{{ab("role assignment list",url_for("forum.role_list_select",forum_id=forum.id))}}</p> #} + <form method="post" action="{{url_for('forum.view_user_role',forum_id=forum.id)}}"> <label for="user">role settings for user: </label> <input type="text" class="name-input" id="user" name="user" value="{{user}}"/> |