Revised so that you always call digest_auth.init_app(), to avoid confusion. It remembers the current application. The logout() method no longer need current_app for the current application.
This commit is contained in:
parent
65c3322ecc
commit
af8c3a484c
@ -75,6 +75,7 @@ In your ``my_app.py``:
|
|||||||
... (Configure the Flask application) ...
|
... (Configure the Flask application) ...
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm="Admin")
|
auth: DigestAuth = DigestAuth(realm="Admin")
|
||||||
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
def get_password_hash(username: str) -> t.Optional[str]:
|
def get_password_hash(username: str) -> t.Optional[str]:
|
||||||
@ -113,6 +114,7 @@ In your ``my_app/__init__.py``:
|
|||||||
... (Configure the Flask application) ...
|
... (Configure the Flask application) ...
|
||||||
|
|
||||||
auth.realm = app.config["REALM"]
|
auth.realm = app.config["REALM"]
|
||||||
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
def get_password_hash(username: str) -> t.Optional[str]:
|
def get_password_hash(username: str) -> t.Optional[str]:
|
||||||
@ -156,6 +158,9 @@ module that requires log in, without specifying the authentication
|
|||||||
mechanism. The Flask application can specify the actual
|
mechanism. The Flask application can specify the actual
|
||||||
authentication mechanism as it sees fit.
|
authentication mechanism as it sees fit.
|
||||||
|
|
||||||
|
``login_manager.init_app(app)`` must be called before
|
||||||
|
``auth.init_app(app)``.
|
||||||
|
|
||||||
|
|
||||||
Example for Simple Applications with Flask-Login Integration
|
Example for Simple Applications with Flask-Login Integration
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
@ -27,8 +27,7 @@ from functools import wraps
|
|||||||
from random import random
|
from random import random
|
||||||
from secrets import token_urlsafe
|
from secrets import token_urlsafe
|
||||||
|
|
||||||
from flask import g, request, Response, session, abort, Flask, Request, \
|
from flask import g, request, Response, session, abort, Flask, Request
|
||||||
current_app
|
|
||||||
from itsdangerous import URLSafeTimedSerializer, BadData
|
from itsdangerous import URLSafeTimedSerializer, BadData
|
||||||
from werkzeug.datastructures import Authorization
|
from werkzeug.datastructures import Authorization
|
||||||
|
|
||||||
@ -55,6 +54,7 @@ class DigestAuth:
|
|||||||
self.__get_password_hash: t.Callable[[str], t.Optional[str]] \
|
self.__get_password_hash: t.Callable[[str], t.Optional[str]] \
|
||||||
= lambda x: None
|
= lambda x: None
|
||||||
self.__get_user: t.Callable[[str], t.Optional] = lambda x: None
|
self.__get_user: t.Callable[[str], t.Optional] = lambda x: None
|
||||||
|
self.app: t.Optional[Flask] = None
|
||||||
|
|
||||||
def login_required(self, view) -> t.Callable:
|
def login_required(self, view) -> t.Callable:
|
||||||
"""The view decorator for HTTP digest authentication.
|
"""The view decorator for HTTP digest authentication.
|
||||||
@ -205,13 +205,12 @@ class DigestAuth:
|
|||||||
:param app: The Flask application.
|
:param app: The Flask application.
|
||||||
:return: None.
|
:return: None.
|
||||||
"""
|
"""
|
||||||
|
app.digest_auth = self
|
||||||
|
self.app = app
|
||||||
|
|
||||||
try:
|
if hasattr(app, "login_manager"):
|
||||||
from flask_login import LoginManager, login_user
|
from flask_login import LoginManager, login_user
|
||||||
|
|
||||||
if not hasattr(app, "login_manager"):
|
|
||||||
raise AttributeError(
|
|
||||||
"Please run the Flask-Login init-app() first")
|
|
||||||
login_manager: LoginManager = getattr(app, "login_manager")
|
login_manager: LoginManager = getattr(app, "login_manager")
|
||||||
|
|
||||||
@login_manager.unauthorized_handler
|
@login_manager.unauthorized_handler
|
||||||
@ -252,12 +251,7 @@ class DigestAuth:
|
|||||||
app.logger.warning(str(e))
|
app.logger.warning(str(e))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
except ModuleNotFoundError:
|
def logout(self) -> None:
|
||||||
raise ModuleNotFoundError(
|
|
||||||
"init_app() is only for Flask-Login integration")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def logout() -> None:
|
|
||||||
"""Logs out the user.
|
"""Logs out the user.
|
||||||
This actually causes the next authentication to fail, which forces
|
This actually causes the next authentication to fail, which forces
|
||||||
the browser to ask the user for the username and password again.
|
the browser to ask the user for the username and password again.
|
||||||
@ -267,7 +261,7 @@ class DigestAuth:
|
|||||||
if "user" in session:
|
if "user" in session:
|
||||||
del session["user"]
|
del session["user"]
|
||||||
try:
|
try:
|
||||||
if hasattr(current_app, "login_manager"):
|
if hasattr(self.app, "login_manager"):
|
||||||
from flask_login import logout_user
|
from flask_login import logout_user
|
||||||
logout_user()
|
logout_user()
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
|
@ -49,6 +49,7 @@ class AuthenticationTestCase(TestCase):
|
|||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm=_REALM)
|
auth: DigestAuth = DigestAuth(realm=_REALM)
|
||||||
|
auth.init_app(app)
|
||||||
user_db: t.Dict[str, str] \
|
user_db: t.Dict[str, str] \
|
||||||
= {_USERNAME: make_password_hash(_REALM, _USERNAME, _PASSWORD)}
|
= {_USERNAME: make_password_hash(_REALM, _USERNAME, _PASSWORD)}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user