Revised the documentation.
This commit is contained in:
@ -26,6 +26,13 @@ from hashlib import md5
|
||||
|
||||
def make_password_hash(realm: str, username: str, password: str) -> str:
|
||||
"""Calculates the password hash for the HTTP digest authentication.
|
||||
Use this function to set the password for the user.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
user.password = make_password_hash(realm, username, password)
|
||||
|
||||
:param realm: The realm.
|
||||
:param username: The username.
|
||||
|
@ -58,6 +58,16 @@ class DigestAuth:
|
||||
def login_required(self, view) -> t.Callable:
|
||||
"""The view decorator for HTTP digest authentication.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
@auth.login_required
|
||||
def admin():
|
||||
return f"Hello, {g.user.username}!"
|
||||
|
||||
The logged-in user can be retrieved at ``g.user``.
|
||||
|
||||
:param view: The view.
|
||||
:return: The login-protected view.
|
||||
"""
|
||||
@ -212,7 +222,16 @@ class DigestAuth:
|
||||
|
||||
def register_get_password(self, func: t.Callable[[str], t.Optional[str]])\
|
||||
-> None:
|
||||
"""Registers the callback to obtain the password hash.
|
||||
"""The decorator to register the callback to obtain the password hash.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
@auth.register_get_password
|
||||
def get_password_hash(username: str) -> Optional[str]:
|
||||
user = User.query.filter(User.username == username).first()
|
||||
return None if user is None else user.password
|
||||
|
||||
:param func: The callback that given the username, returns the password
|
||||
hash, or None if the user does not exist.
|
||||
@ -235,7 +254,15 @@ class DigestAuth:
|
||||
|
||||
def register_get_user(self, func: t.Callable[[str], t.Optional[t.Any]])\
|
||||
-> None:
|
||||
"""Registers the callback to obtain the user.
|
||||
"""The decorator to register the callback to obtain the user.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
@auth.register_get_user
|
||||
def get_user(username: str) -> Optional[User]:
|
||||
return User.query.filter(User.username == username).first()
|
||||
|
||||
:param func: The callback that given the username, returns the user,
|
||||
or None if the user does not exist.
|
||||
@ -257,7 +284,15 @@ class DigestAuth:
|
||||
self.__get_user = UserGetter()
|
||||
|
||||
def register_on_login(self, func: t.Callable[[t.Any], None]) -> None:
|
||||
"""Registers the callback when the user logs in.
|
||||
"""The decorator to register the callback to run when the user logs in.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
@auth.register_on_login
|
||||
def on_login(user: User) -> None:
|
||||
user.visits = user.visits + 1
|
||||
|
||||
:param func: The callback given the logged-in user.
|
||||
:return: None.
|
||||
@ -280,6 +315,15 @@ class DigestAuth:
|
||||
def init_app(self, app: Flask) -> None:
|
||||
"""Initializes the Flask application.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
app: flask = Flask(__name__)
|
||||
auth: DigestAuth = DigestAuth()
|
||||
auth.realm = "My Admin"
|
||||
auth.init_app(app)
|
||||
|
||||
:param app: The Flask application.
|
||||
:return: None.
|
||||
"""
|
||||
@ -335,6 +379,16 @@ class DigestAuth:
|
||||
This actually causes the next authentication to fail, which forces
|
||||
the browser to ask the user for the username and password again.
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
@app.post("/logout")
|
||||
@auth.login_required
|
||||
def logout():
|
||||
auth.logout()
|
||||
return redirect(request.form.get("next"))
|
||||
|
||||
:return: None.
|
||||
"""
|
||||
if "user" in session:
|
||||
|
@ -29,7 +29,54 @@ from flask_digest_auth.algo import calc_response, make_password_hash
|
||||
|
||||
|
||||
class Client(WerkzeugClient):
|
||||
"""The test client with HTTP digest authentication enabled."""
|
||||
"""The test client with HTTP digest authentication enabled.
|
||||
|
||||
For unittest example:
|
||||
|
||||
::
|
||||
|
||||
class MyTestCase(flask_testing.TestCase):
|
||||
|
||||
def create_app(self):
|
||||
app: Flask = create_app({
|
||||
"SECRET_KEY": token_urlsafe(32),
|
||||
"TESTING": True
|
||||
})
|
||||
app.test_client_class = Client
|
||||
return app
|
||||
|
||||
def test_admin(self):
|
||||
response = self.client.get("/admin")
|
||||
self.assertEqual(response.status_code, 401)
|
||||
response = self.client.get(
|
||||
"/admin", digest_auth=("my_name", "my_pass"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
For pytest example:
|
||||
|
||||
::
|
||||
|
||||
@pytest.fixture()
|
||||
def app():
|
||||
app: Flask = create_app({
|
||||
"SECRET_KEY": token_urlsafe(32),
|
||||
"TESTING": True
|
||||
})
|
||||
app.test_client_class = Client
|
||||
yield app
|
||||
|
||||
@pytest.fixture()
|
||||
def client(app):
|
||||
return app.test_client()
|
||||
|
||||
def test_admin(app: Flask, client: Client):
|
||||
with app.app_context():
|
||||
response = self.client.get("/admin")
|
||||
assert response.status_code == 401
|
||||
response = self.client.get(
|
||||
"/admin", digest_auth=("my_name", "my_pass"))
|
||||
assert response.status_code == 200
|
||||
"""
|
||||
|
||||
def open(self, *args, digest_auth: t.Optional[t.Tuple[str, str]] = None,
|
||||
**kwargs) -> TestResponse:
|
||||
|
Reference in New Issue
Block a user