diff options
-rw-r--r-- | apioforum/forum.py | 37 | ||||
-rw-r--r-- | apioforum/roles.py | 25 | ||||
-rw-r--r-- | apioforum/thread.py | 15 | ||||
-rw-r--r-- | apioforum/user.py | 3 |
4 files changed, 58 insertions, 22 deletions
diff --git a/apioforum/forum.py b/apioforum/forum.py index badbd14..6d3f5cf 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -22,24 +22,35 @@ class Forum(DbWrapper): primary_key = "id" references = {"parent", Forum} + def has_permission(self, user, permission, login_required=True): + return(has_permission(self._key, str(user), permission, login_required)) + + def has_bureaucrat(self, user): + return(is_bureaucraft(self._key, str(user))) + + def get_avail_tags(self): + db = get_db() + return Tag.query_some(""" + WITH RECURSIVE fs AS + (SELECT * FROM forums WHERE id = ? + UNION ALL + SELECT forums.* FROM forums, fs WHERE fs.parent=forums.id) + SELECT * FROM tags + WHERE tags.forum in (SELECT id FROM fs) + ORDER BY id; + """,(self,)) + + def get_forum(self): + return self + +class Tag(DbWrapper): + table = "tags" + references = {"forum": Forum} @bp.route("/") def not_actual_index(): return redirect("/1") -def get_avail_tags(forum_id): - db = get_db() - tags = 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 tags - WHERE tags.forum in (SELECT id FROM fs) - ORDER BY id; - """,(forum_id,)).fetchall() - return tags - def forum_path(forum_id): db = get_db() ancestors = db.execute(""" diff --git a/apioforum/roles.py b/apioforum/roles.py index aa1d239..0e3c4d3 100644 --- a/apioforum/roles.py +++ b/apioforum/roles.py @@ -95,3 +95,28 @@ def has_permission(forum_id, username, permission, login_required=True): def is_bureaucrat(forum_id, user): if user == None: return False return get_user_role(forum_id, user) == "bureaucrat" + +# ^ the above could perhaps be refactored to use the new DB wrappers, but I am +# not focusing on it right now + +# decorators for paths that require certain permissions +# the path must accept an object implementing get_forum +def requires_permission(*a, **k): + def decorator(f): + @functools.wraps(f) + def wrapper(obj, *args, **kwargs): + if not obj.get_forum().has_permission(g.user, *a, **k): + abort(403) + return f(obj, *args, **kwargs) + return wrapper + return decorator + +def requires_bureaucrat(f): + @functools.wraps(f) + @requires_permission("p_view_forum") + def wrapper(obj, *args, **kwargs): + if not obj.get_forum().is_bureaucrat(g.user): + abort(403) + return f(forum, *args, **kwargs) + return wrapper + diff --git a/apioforum/thread.py b/apioforum/thread.py index d0d7e83..3311c4e 100644 --- a/apioforum/thread.py +++ b/apioforum/thread.py @@ -7,8 +7,8 @@ from flask import ( url_for, flash, jsonify ) from .db import get_db, DbWrapper -from .roles import has_permission -from .forum import get_avail_tags, Forum +from .roles import has_permission, requires_permission +from .forum import Forum, Tag from .user import User bp = Blueprint("thread", __name__, url_prefix="/thread") @@ -45,10 +45,6 @@ class Vote(DbWrapper): table = "votes" references = {"poll": Poll, "user": User} -class Tag(DbWrapper): - table = "tags" - references = {"forum": Forum} - class Thread(DbWrapper): table = "threads" references = {"forum": Forum, "poll": Poll} @@ -67,6 +63,9 @@ class Thread(DbWrapper): ORDER BY tags.id """,(self,)) + def get_forum(self): + return self.forum + class Post(DbWrapper): table = "posts" references = {"thread": Thread, "author": User, "vote": Vote} @@ -76,10 +75,9 @@ def post_jump(thread_id, post_id): return url_for("thread.view_thread",thread_id=thread_id)+"#post_"+str(post_id) @bp.route("/<db(Thread):thread>") +@requires_permission("p_view_threads") def view_thread(thread): db = get_db() - if not has_permission(thread['forum'], g.user, "p_view_threads", False): - abort(403) posts = thread.get_posts() tags = thread.get_tags() @@ -100,7 +98,6 @@ def view_thread(thread): posts=posts, thread=thread, tags=tags, - poll=poll, has_voted=has_voted, ) diff --git a/apioforum/user.py b/apioforum/user.py index b92d8b3..3f19a6f 100644 --- a/apioforum/user.py +++ b/apioforum/user.py @@ -16,6 +16,9 @@ class User(DbWrapper): def set_password(self, password): self.password = generate_password_hash(password) + def __str__(self): + return self._key + @bp.route("/<username>") def view_user(username): |