2019-02-05 11:30:39 +01:00
|
|
|
from functools import wraps
|
2019-06-05 11:35:54 +02:00
|
|
|
from flask import request, abort
|
2019-02-05 11:30:39 +01:00
|
|
|
from flask_login import current_user
|
|
|
|
from flask_login.config import EXEMPT_METHODS
|
|
|
|
from app import app
|
|
|
|
|
2019-06-05 11:35:54 +02:00
|
|
|
|
2019-02-05 11:30:39 +01:00
|
|
|
def priv_required(*perms):
|
|
|
|
"""
|
2019-02-09 11:32:08 +01:00
|
|
|
Requires the user to be an authenticated member with privileges [perms].
|
|
|
|
Calls :attr:`LoginManager.unauthorized` if the user is not authenticated,
|
|
|
|
and a 403 if some of the privileges are missing.
|
2019-02-05 11:30:39 +01:00
|
|
|
|
2019-02-09 11:32:08 +01:00
|
|
|
Example:
|
2019-02-05 11:30:39 +01:00
|
|
|
@app.route('/admin')
|
review of privileges and forum permissions
* Sorted privileges into categories, similar to the v4.3 style
Added privilege check utilities:
* Forum: is_news(), is_default_accessible() and is_default_postable()
* Member: can_access_forum(), can_post_in_forum(), can_edit_post(),
and can_delete_post()
Unfortunately current_user is not a Guest when logged out, so one
cannot usually write current_user.can_*() without checking for
authentication first, so the checks are still somewhat verbose.
Reviewed forum permissions; the following permission issues have been
fixed (I have tested most but not all of them prior to fixing):
* app/routes/forum/index.py: Users that were not meant to access a
forum could still obtain a listing of the topics
* app/routes/forum/topic.py: Users that were not meant to see topics
could still read them by browsing the URL
* app/routes/forum/topic.py: Authenticated users could post in any
topic, including ones that they should not have access to
* app/routes/posts/edit.py: Users with edit.posts (eg. mods) could edit
and delete messages in forums they can't access (eg. creativecalc)
* app/templates/account/user.html: Users with admin panel access would
see account editing links they can't use (affects developers)
* app/templates/base/navbar/forum.html: The "Forum" tab would list all
forums including ones the user doesn't have access to
* app/templates/forum/index.html: Users would see every single forum,
including ones they can't access
* app/template/widgets/thread.html: Anyone would see Edit/Delete links
on every message, even though most were unusable
Miscellaneous changes:
* app/routes/forum/topic.py: Ordered comments by date as intended,
which I assume worked by chance until now
* Removed the old assets/privs.txt files which is now superseded by the
list implemented in app/data/groups.yaml
This commit changes group and forum information, run master.py with:
@> forums update
@> groups update
2021-02-26 18:29:25 +01:00
|
|
|
@priv_required('forum.access.admin')
|
2019-02-05 11:30:39 +01:00
|
|
|
def admin_board():
|
|
|
|
pass
|
|
|
|
|
|
|
|
It can be convenient to globally turn off authentication when unit testing.
|
2019-02-09 11:32:08 +01:00
|
|
|
Setting the `LOGIN_DISABLED` configuration variable to `True` will silence
|
|
|
|
this decorator.
|
2019-02-05 11:30:39 +01:00
|
|
|
"""
|
|
|
|
def decorated_view(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
if request.method in EXEMPT_METHODS:
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
elif not current_user.is_authenticated:
|
|
|
|
return app.login_manager.unauthorized()
|
|
|
|
else:
|
|
|
|
for p in perms:
|
|
|
|
if not current_user.priv(p):
|
2019-02-09 11:32:08 +01:00
|
|
|
# TODO: Add error message and privilege name
|
2019-02-05 23:21:46 +01:00
|
|
|
abort(403)
|
2019-02-05 11:30:39 +01:00
|
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapped
|
2019-02-05 23:21:46 +01:00
|
|
|
return decorated_view
|
2020-07-21 21:42:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
def guest_only(func):
|
|
|
|
"""
|
|
|
|
Opposite decorator of @login_required
|
|
|
|
"""
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
if current_user.is_authenticated:
|
|
|
|
abort(404)
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapped
|