diff options
Diffstat (limited to 'apioforum/roles.py')
-rw-r--r-- | apioforum/roles.py | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/apioforum/roles.py b/apioforum/roles.py new file mode 100644 index 0000000..aa1d239 --- /dev/null +++ b/apioforum/roles.py @@ -0,0 +1,97 @@ + +from .db import get_db +from .permissions import is_admin + +permissions = [ + "p_create_threads", + "p_reply_threads", + "p_manage_threads", + "p_delete_posts", + "p_view_threads", + "p_vote", + "p_create_polls", + "p_approve", + "p_create_subforum", + "p_view_forum" +] + +def get_role_config(forum_id, role): + db = get_db() + + fid = forum_id + the = None + while the == None and fid != None: + the = db.execute(""" + SELECT * FROM role_config + 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, username): + db = get_db() + user = db.execute('SELECT * FROM users WHERE username = ?', + (username,)).fetchone() + if user == None: return "other" + if user['admin']: return "bureaucrat" + + fid = forum_id + the = None + while fid != None: + r = db.execute(""" + SELECT * FROM role_assignments + WHERE forum = ? AND user = ?; + """,(fid,username)).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'] + 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) + +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] + +def is_bureaucrat(forum_id, user): + if user == None: return False + return get_user_role(forum_id, user) == "bureaucrat" |