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:
依瑪貓 2022-11-25 09:14:57 +11:00
parent 65c3322ecc
commit af8c3a484c
3 changed files with 13 additions and 13 deletions

View File

@ -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
------------------------------------------------------------ ------------------------------------------------------------

View File

@ -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:

View File

@ -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)}