Make our require_login() optionally redirect to the login page
This mimicks the behaviour of flask_login. In our case, it only redirects when redirect_to_login=True and the user is anonymous. Otheriwse it still results in a 403 Forbidden response.
This commit is contained in:
@@ -266,7 +266,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):
|
||||||
"""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.
|
||||||
@@ -283,8 +284,15 @@ def require_login(require_roles=set(),
|
|||||||
non-empty intersection with the given roles, access is granted.
|
non-empty intersection with the given roles, access is granted.
|
||||||
When True: require the user to have all given roles before access is
|
When True: require the user to have all given roles before access is
|
||||||
granted.
|
granted.
|
||||||
|
:param redirect_to_login: Determines the behaviour when the user is not
|
||||||
|
logged in. When False (the default), a 403 Forbidden response 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
|
||||||
|
requests, and mimicks the flask_login behaviour.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from flask import request, redirect, url_for
|
||||||
|
|
||||||
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}')
|
||||||
|
|
||||||
@@ -308,6 +316,10 @@ def require_login(require_roles=set(),
|
|||||||
# Many browsers first try to see whether authentication is needed
|
# Many browsers first try to see whether authentication is needed
|
||||||
# at all, before sending the password.
|
# at all, before sending the password.
|
||||||
log.debug('Unauthenticated access to %s attempted.', func)
|
log.debug('Unauthenticated access to %s attempted.', func)
|
||||||
|
if redirect_to_login:
|
||||||
|
# Redirect using a 303 See Other, since even a POST
|
||||||
|
# request should cause a GET on the login page.
|
||||||
|
return redirect(url_for('users.login', next=request.url), 303)
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
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):
|
||||||
|
Reference in New Issue
Block a user