Allow a custom error view with @require_login()
This commit is contained in:
parent
cde86db44e
commit
fee242ad07
@ -279,7 +279,8 @@ def merge_permissions(*args):
|
|||||||
def require_login(*, require_roles=set(),
|
def require_login(*, require_roles=set(),
|
||||||
require_cap='',
|
require_cap='',
|
||||||
require_all=False,
|
require_all=False,
|
||||||
redirect_to_login=False):
|
redirect_to_login=False,
|
||||||
|
error_view=None):
|
||||||
"""Decorator that enforces users to authenticate.
|
"""Decorator that enforces users to authenticate.
|
||||||
|
|
||||||
Optionally only allows access to users with a certain role and/or capability.
|
Optionally only allows access to users with a certain role and/or capability.
|
||||||
@ -301,9 +302,11 @@ def require_login(*, require_roles=set(),
|
|||||||
returned; this is suitable for API calls. When True, the user is
|
returned; this is suitable for API calls. When True, the user is
|
||||||
redirected to the login page; this is suitable for user-facing web
|
redirected to the login page; this is suitable for user-facing web
|
||||||
requests, and mimicks the flask_login behaviour.
|
requests, and mimicks the flask_login behaviour.
|
||||||
|
:param error_view: Callable that returns a Flask response object. This is
|
||||||
|
sent back to the client instead of the default 403 Forbidden.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import request, redirect, url_for
|
from flask import request, redirect, url_for, Response
|
||||||
|
|
||||||
if not isinstance(require_roles, set):
|
if not isinstance(require_roles, set):
|
||||||
raise TypeError(f'require_roles param should be a set, but is {type(require_roles)!r}')
|
raise TypeError(f'require_roles param should be a set, but is {type(require_roles)!r}')
|
||||||
@ -317,6 +320,13 @@ def require_login(*, require_roles=set(),
|
|||||||
if require_all and not require_roles:
|
if require_all and not require_roles:
|
||||||
raise ValueError('require_login(require_all=True) cannot be used with empty require_roles.')
|
raise ValueError('require_login(require_all=True) cannot be used with empty require_roles.')
|
||||||
|
|
||||||
|
def render_error() -> Response:
|
||||||
|
if error_view is None:
|
||||||
|
abort(403)
|
||||||
|
resp: Response = error_view()
|
||||||
|
resp.status_code = 403
|
||||||
|
return resp
|
||||||
|
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
@ -332,17 +342,17 @@ def require_login(*, require_roles=set(),
|
|||||||
# Redirect using a 303 See Other, since even a POST
|
# Redirect using a 303 See Other, since even a POST
|
||||||
# request should cause a GET on the login page.
|
# request should cause a GET on the login page.
|
||||||
return redirect(url_for('users.login', next=request.url), 303)
|
return redirect(url_for('users.login', next=request.url), 303)
|
||||||
abort(403)
|
return render_error()
|
||||||
|
|
||||||
if require_roles and not current_user.matches_roles(require_roles, require_all):
|
if require_roles and not current_user.matches_roles(require_roles, require_all):
|
||||||
log.warning('User %s is authenticated, but does not have required roles %s to '
|
log.warning('User %s is authenticated, but does not have required roles %s to '
|
||||||
'access %s', current_user.user_id, require_roles, func)
|
'access %s', current_user.user_id, require_roles, func)
|
||||||
abort(403)
|
return render_error()
|
||||||
|
|
||||||
if require_cap and not current_user.has_cap(require_cap):
|
if require_cap and not current_user.has_cap(require_cap):
|
||||||
log.warning('User %s is authenticated, but does not have required capability %s to '
|
log.warning('User %s is authenticated, but does not have required capability %s to '
|
||||||
'access %s', current_user.user_id, require_cap, func)
|
'access %s', current_user.user_id, require_cap, func)
|
||||||
abort(403)
|
return render_error()
|
||||||
|
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user