Compare commits
7 Commits
v0.4.0
...
769ca7dddd
Author | SHA1 | Date | |
---|---|---|---|
769ca7dddd | |||
33eb81f368 | |||
5faf51c49b | |||
d5a8bb3acd | |||
27d27127f6 | |||
5ebdea6d0a | |||
ea31bb9579 |
40
.readthedocs.yaml
Normal file
40
.readthedocs.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# The Flask HTTP Digest Authentication Project.
|
||||||
|
# Author: imacat@mail.imacat.idv.tw (imacat), 2023/4/5
|
||||||
|
|
||||||
|
# Copyright (c) 2023 imacat.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# .readthedocs.yaml
|
||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
# Required
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
# Set the version of Python and other tools you might need
|
||||||
|
build:
|
||||||
|
os: ubuntu-22.04
|
||||||
|
tools:
|
||||||
|
python: "3.7"
|
||||||
|
|
||||||
|
# Build documentation in the docs/ directory with Sphinx
|
||||||
|
|
||||||
|
# If using Sphinx, optionally build your docs in additional formats such as PDF
|
||||||
|
formats: all
|
||||||
|
|
||||||
|
# Optionally declare the Python requirements required to build your docs
|
||||||
|
python:
|
||||||
|
install:
|
||||||
|
- method: pip
|
||||||
|
path: .
|
@ -15,8 +15,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
include docs/*
|
recursive-include docs *
|
||||||
include docs/source/*
|
recursive-exclude docs/build *
|
||||||
include docs/source/_static/*
|
recursive-include tests *
|
||||||
include docs/source/_templates/*
|
recursive-exclude tests *.pyc
|
||||||
include tests/*
|
|
||||||
|
19
README.rst
19
README.rst
@ -52,6 +52,13 @@ You may also install the latest source from the
|
|||||||
pip install git+https://github.com/imacat/flask-digestauth.git
|
pip install git+https://github.com/imacat/flask-digestauth.git
|
||||||
|
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
=============
|
||||||
|
|
||||||
|
Flask-DigestAuth takes the configuration ``DIGEST_AUTH_REALM`` as the
|
||||||
|
realm. The default realm is ``Login Required``.
|
||||||
|
|
||||||
|
|
||||||
Setting the Password
|
Setting the Password
|
||||||
====================
|
====================
|
||||||
|
|
||||||
@ -89,7 +96,7 @@ In your ``my_app.py``:
|
|||||||
app: flask = Flask(__name__)
|
app: flask = Flask(__name__)
|
||||||
... (Configure the Flask application) ...
|
... (Configure the Flask application) ...
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm="Admin")
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -128,7 +135,6 @@ In your ``my_app/__init__.py``:
|
|||||||
app: flask = Flask(__name__)
|
app: flask = Flask(__name__)
|
||||||
... (Configure the Flask application) ...
|
... (Configure the Flask application) ...
|
||||||
|
|
||||||
auth.realm = app.config["REALM"]
|
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -207,7 +213,7 @@ In your ``my_app.py``:
|
|||||||
def load_user(user_id: str) -> t.Optional[User]:
|
def load_user(user_id: str) -> t.Optional[User]:
|
||||||
... (Load the user with the username) ...
|
... (Load the user with the username) ...
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm="Admin")
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -251,7 +257,6 @@ In your ``my_app/__init__.py``:
|
|||||||
def load_user(user_id: str) -> t.Optional[User]:
|
def load_user(user_id: str) -> t.Optional[User]:
|
||||||
... (Load the user with the username) ...
|
... (Load the user with the username) ...
|
||||||
|
|
||||||
auth.realm = app.config["REALM"]
|
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -340,8 +345,9 @@ A unittest Test Case
|
|||||||
|
|
||||||
def create_app(self):
|
def create_app(self):
|
||||||
app: Flask = create_app({
|
app: Flask = create_app({
|
||||||
|
"TESTING": True,
|
||||||
"SECRET_KEY": token_urlsafe(32),
|
"SECRET_KEY": token_urlsafe(32),
|
||||||
"TESTING": True
|
"DIGEST_AUTH_REALM": "admin",
|
||||||
})
|
})
|
||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
return app
|
return app
|
||||||
@ -367,8 +373,9 @@ A pytest Test
|
|||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def app():
|
def app():
|
||||||
app: Flask = create_app({
|
app: Flask = create_app({
|
||||||
|
"TESTING": True,
|
||||||
"SECRET_KEY": token_urlsafe(32),
|
"SECRET_KEY": token_urlsafe(32),
|
||||||
"TESTING": True
|
"DIGEST_AUTH_REALM": "admin",
|
||||||
})
|
})
|
||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
yield app
|
yield app
|
||||||
|
@ -1 +0,0 @@
|
|||||||
flask
|
|
@ -13,7 +13,7 @@ sys.path.insert(0, os.path.abspath('../../src/'))
|
|||||||
project = 'Flask-DigestAuth'
|
project = 'Flask-DigestAuth'
|
||||||
copyright = '2022-2023, imacat'
|
copyright = '2022-2023, imacat'
|
||||||
author = 'imacat'
|
author = 'imacat'
|
||||||
release = '0.4.0'
|
release = '0.5.0'
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||||
|
@ -17,7 +17,7 @@ In your ``my_app.py``:
|
|||||||
app: flask = Flask(__name__)
|
app: flask = Flask(__name__)
|
||||||
... (Configure the Flask application) ...
|
... (Configure the Flask application) ...
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm="Admin")
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -58,7 +58,6 @@ In your ``my_app/__init__.py``:
|
|||||||
app: flask = Flask(__name__)
|
app: flask = Flask(__name__)
|
||||||
... (Configure the Flask application) ...
|
... (Configure the Flask application) ...
|
||||||
|
|
||||||
auth.realm = app.config["REALM"]
|
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -118,7 +117,7 @@ In your ``my_app.py``:
|
|||||||
def load_user(user_id: str) -> t.Optional[User]:
|
def load_user(user_id: str) -> t.Optional[User]:
|
||||||
... (Load the user with the username) ...
|
... (Load the user with the username) ...
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm="Admin")
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -164,7 +163,6 @@ In your ``my_app/__init__.py``:
|
|||||||
def load_user(user_id: str) -> t.Optional[User]:
|
def load_user(user_id: str) -> t.Optional[User]:
|
||||||
... (Load the user with the username) ...
|
... (Load the user with the username) ...
|
||||||
|
|
||||||
auth.realm = app.config["REALM"]
|
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
@auth.register_get_password
|
@auth.register_get_password
|
||||||
@ -219,8 +217,9 @@ A unittest Test Case
|
|||||||
|
|
||||||
def create_app(self):
|
def create_app(self):
|
||||||
app: Flask = create_app({
|
app: Flask = create_app({
|
||||||
|
"TESTING": True,
|
||||||
"SECRET_KEY": token_urlsafe(32),
|
"SECRET_KEY": token_urlsafe(32),
|
||||||
"TESTING": True
|
"DIGEST_AUTH_REALM": "admin",
|
||||||
})
|
})
|
||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
return app
|
return app
|
||||||
@ -249,8 +248,9 @@ A pytest Test
|
|||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def app():
|
def app():
|
||||||
app: Flask = create_app({
|
app: Flask = create_app({
|
||||||
|
"TESTING": True,
|
||||||
"SECRET_KEY": token_urlsafe(32),
|
"SECRET_KEY": token_urlsafe(32),
|
||||||
"TESTING": True
|
"DIGEST_AUTH_REALM": "admin",
|
||||||
})
|
})
|
||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
yield app
|
yield app
|
||||||
|
@ -46,6 +46,13 @@ You may also install the latest source from the
|
|||||||
pip install git+https://github.com/imacat/flask-digestauth.git
|
pip install git+https://github.com/imacat/flask-digestauth.git
|
||||||
|
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Flask-DigestAuth takes the configuration ``DIGEST_AUTH_REALM`` as the
|
||||||
|
realm. The default realm is ``Login Required``.
|
||||||
|
|
||||||
|
|
||||||
Setting the Password
|
Setting the Password
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# The Flask HTTP Digest Authentication Project.
|
# The Flask HTTP Digest Authentication Project.
|
||||||
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/11/23
|
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/11/23
|
||||||
|
|
||||||
# Copyright (c) 2022 imacat.
|
# Copyright (c) 2022-2023 imacat.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -15,6 +15,39 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "Flask-DigestAuth"
|
||||||
|
version = "0.5.0"
|
||||||
|
description = "The Flask HTTP Digest Authentication project."
|
||||||
|
readme = "README.rst"
|
||||||
|
requires-python = ">=3.7"
|
||||||
|
authors = [
|
||||||
|
{name = "imacat", email = "imacat@mail.imacat.idv.tw"},
|
||||||
|
]
|
||||||
|
keywords = ["flask", "digest-authentication"]
|
||||||
|
classifiers = [
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: Apache Software License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
"Framework :: Flask",
|
||||||
|
"Topic :: System :: Systems Administration :: Authentication/Directory",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"flask",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
test = [
|
||||||
|
"unittest",
|
||||||
|
"flask-testing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
"Documentation" = "https://flask-digestauth.readthedocs.io"
|
||||||
|
"Repository" = "https://github.com/imacat/flask-digestauth"
|
||||||
|
"Bug Tracker" = "https://github.com/imacat/flask-digestauth/issues"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=42"]
|
requires = ["setuptools>=42"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
53
setup.cfg
53
setup.cfg
@ -1,53 +0,0 @@
|
|||||||
# The Flask HTTP Digest Authentication Project.
|
|
||||||
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/11/23
|
|
||||||
|
|
||||||
# Copyright (c) 2022-2023 imacat.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
name = Flask-DigestAuth
|
|
||||||
version = 0.4.0
|
|
||||||
author = imacat
|
|
||||||
author_email = imacat@mail.imacat.idv.tw
|
|
||||||
description = The Flask HTTP Digest Authentication project.
|
|
||||||
long_description = file: README.rst
|
|
||||||
long_description_content_type = text/x-rst
|
|
||||||
url = https://github.com/imacat/flask-digestauth
|
|
||||||
project_urls =
|
|
||||||
Bug Tracker = https://github.com/imacat/flask-digestauth/issues
|
|
||||||
classifiers =
|
|
||||||
Programming Language :: Python :: 3
|
|
||||||
License :: OSI Approved :: Apache Software License
|
|
||||||
Operating System :: OS Independent
|
|
||||||
Framework :: Flask
|
|
||||||
Topic :: System :: Systems Administration :: Authentication/Directory
|
|
||||||
Intended Audience :: Developers
|
|
||||||
|
|
||||||
[options]
|
|
||||||
package_dir =
|
|
||||||
= src
|
|
||||||
packages = find:
|
|
||||||
python_requires = >=3.7
|
|
||||||
install_requires =
|
|
||||||
flask
|
|
||||||
tests_require =
|
|
||||||
unittest
|
|
||||||
flask-testing
|
|
||||||
|
|
||||||
[options.packages.find]
|
|
||||||
where = src
|
|
||||||
|
|
||||||
[options.extras_require]
|
|
||||||
flask_login =
|
|
||||||
flask-login
|
|
@ -46,8 +46,8 @@ class DigestAuth:
|
|||||||
self.__serializer: URLSafeTimedSerializer \
|
self.__serializer: URLSafeTimedSerializer \
|
||||||
= URLSafeTimedSerializer(token_urlsafe(32))
|
= URLSafeTimedSerializer(token_urlsafe(32))
|
||||||
"""The serializer to generate and validate the nonce and opaque."""
|
"""The serializer to generate and validate the nonce and opaque."""
|
||||||
self.realm: str = "" if realm is None else realm
|
self.realm: str = "Login Required" if realm is None else realm
|
||||||
"""The realm. Default is an empty string."""
|
"""The realm. Default is "Login Required"."""
|
||||||
self.algorithm: t.Optional[t.Literal["MD5", "MD5-sess"]] = None
|
self.algorithm: t.Optional[t.Literal["MD5", "MD5-sess"]] = None
|
||||||
"""The algorithm, either None, ``MD5``, or ``MD5-sess``. Default is
|
"""The algorithm, either None, ``MD5``, or ``MD5-sess``. Default is
|
||||||
None."""
|
None."""
|
||||||
@ -336,13 +336,14 @@ class DigestAuth:
|
|||||||
|
|
||||||
app: flask = Flask(__name__)
|
app: flask = Flask(__name__)
|
||||||
auth: DigestAuth = DigestAuth()
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.realm = "My Admin"
|
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
:param app: The Flask application.
|
:param app: The Flask application.
|
||||||
:return: None.
|
:return: None.
|
||||||
"""
|
"""
|
||||||
app.extensions["digest_auth"] = self
|
app.extensions["digest_auth"] = self
|
||||||
|
if "DIGEST_AUTH_REALM" in app.config:
|
||||||
|
self.realm = app.config["DIGEST_AUTH_REALM"]
|
||||||
|
|
||||||
if hasattr(app, "login_manager"):
|
if hasattr(app, "login_manager"):
|
||||||
from flask_login import LoginManager, login_user
|
from flask_login import LoginManager, login_user
|
||||||
@ -381,8 +382,7 @@ class DigestAuth:
|
|||||||
raise UnauthorizedException(
|
raise UnauthorizedException(
|
||||||
"Not an HTTP digest authorization")
|
"Not an HTTP digest authorization")
|
||||||
self.__authenticate(request._digest_auth_state)
|
self.__authenticate(request._digest_auth_state)
|
||||||
user = login_manager.user_callback(
|
user = login_manager.user_callback(authorization.username)
|
||||||
authorization.username)
|
|
||||||
login_user(user)
|
login_user(user)
|
||||||
self.__on_login(user)
|
self.__on_login(user)
|
||||||
return user
|
return user
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# The Flask HTTP Digest Authentication Project.
|
# The Flask HTTP Digest Authentication Project.
|
||||||
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/10/22
|
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/10/22
|
||||||
|
|
||||||
# Copyright (c) 2022 imacat.
|
# Copyright (c) 2022-2023 imacat.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -57,12 +57,13 @@ class AuthenticationTestCase(TestCase):
|
|||||||
"""
|
"""
|
||||||
app: Flask = Flask(__name__)
|
app: Flask = Flask(__name__)
|
||||||
app.config.from_mapping({
|
app.config.from_mapping({
|
||||||
|
"TESTING": True,
|
||||||
"SECRET_KEY": token_urlsafe(32),
|
"SECRET_KEY": token_urlsafe(32),
|
||||||
"TESTING": True
|
"DIGEST_AUTH_REALM": _REALM,
|
||||||
})
|
})
|
||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm=_REALM)
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
self.user: User = User(_USERNAME, _PASSWORD)
|
self.user: User = User(_USERNAME, _PASSWORD)
|
||||||
user_db: t.Dict[str, User] = {_USERNAME: self.user}
|
user_db: t.Dict[str, User] = {_USERNAME: self.user}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# The Flask HTTP Digest Authentication Project.
|
# The Flask HTTP Digest Authentication Project.
|
||||||
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/11/23
|
# Author: imacat@mail.imacat.idv.tw (imacat), 2022/11/23
|
||||||
|
|
||||||
# Copyright (c) 2022 imacat.
|
# Copyright (c) 2022-2023 imacat.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -77,8 +77,9 @@ class FlaskLoginTestCase(TestCase):
|
|||||||
"""
|
"""
|
||||||
app: Flask = Flask(__name__)
|
app: Flask = Flask(__name__)
|
||||||
app.config.from_mapping({
|
app.config.from_mapping({
|
||||||
|
"TESTING": True,
|
||||||
"SECRET_KEY": token_urlsafe(32),
|
"SECRET_KEY": token_urlsafe(32),
|
||||||
"TESTING": True
|
"DIGEST_AUTH_REALM": _REALM,
|
||||||
})
|
})
|
||||||
app.test_client_class = Client
|
app.test_client_class = Client
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ class FlaskLoginTestCase(TestCase):
|
|||||||
login_manager: flask_login.LoginManager = flask_login.LoginManager()
|
login_manager: flask_login.LoginManager = flask_login.LoginManager()
|
||||||
login_manager.init_app(app)
|
login_manager.init_app(app)
|
||||||
|
|
||||||
auth: DigestAuth = DigestAuth(realm=_REALM)
|
auth: DigestAuth = DigestAuth()
|
||||||
auth.init_app(app)
|
auth.init_app(app)
|
||||||
|
|
||||||
self.user: User = User(_USERNAME, _PASSWORD)
|
self.user: User = User(_USERNAME, _PASSWORD)
|
||||||
|
Reference in New Issue
Block a user