From 6186362642da9e46b7a7c8353792b1ae09e63935 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Fri, 18 Aug 2023 02:07:35 +0200 Subject: [PATCH 01/11] Up --- src/ska/bin/ska-sign-url | 7 ------- 1 file changed, 7 deletions(-) delete mode 100755 src/ska/bin/ska-sign-url diff --git a/src/ska/bin/ska-sign-url b/src/ska/bin/ska-sign-url deleted file mode 100755 index 375d99b..0000000 --- a/src/ska/bin/ska-sign-url +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -# We should have absolute imports here -from ska.generate_signed_url import main - -if __name__ == "__main__": - main() From de90e9a1e8b1ee47531cf2269de951816caf3223 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 00:21:23 +0200 Subject: [PATCH 02/11] Update constance code. Blackify, isortify, upgrade requirements --- CHANGELOG.rst | 10 + docs/conf.py | 3 +- examples/requirements/common.txt | 4 +- examples/requirements/constance_django_4_1.in | 5 + examples/requirements/constance_django_4_2.in | 4 + examples/requirements/debug.in | 5 +- examples/requirements/debug.txt | 10 +- examples/requirements/deployment.txt | 4 +- examples/requirements/dev.in | 2 +- examples/requirements/dev.txt | 404 ++++++++++-------- examples/requirements/django_3_2.txt | 146 ++++--- examples/requirements/django_4_1.in | 6 + examples/requirements/django_4_1.txt | 172 ++++++++ examples/requirements/django_4_2.in | 7 + examples/requirements/django_4_2.txt | 178 ++++++++ examples/requirements/docs.in | 2 +- examples/requirements/docs.txt | 4 +- examples/requirements/documentation.in | 2 +- examples/requirements/documentation.txt | 256 ++++++----- .../requirements/rest_framework_django_4_1.in | 2 + .../requirements/rest_framework_django_4_2.in | 2 + examples/requirements/style_checkers.in | 1 - examples/requirements/test.in | 21 +- examples/requirements/test.txt | 127 +++--- examples/requirements/testing.in | 2 +- examples/requirements/testing.txt | 246 ++++++----- examples/simple/constance_urls.py | 4 +- examples/simple/factories/auth_group.py | 7 +- examples/simple/factories/auth_user.py | 9 +- .../simple/factories/constance_constance.py | 5 +- examples/simple/factories/factory_faker.py | 4 +- examples/simple/factories/foo_fooitem.py | 5 +- examples/simple/foo/serializers.py | 1 - examples/simple/foo/urls.py | 5 +- examples/simple/foo/views.py | 9 +- examples/simple/settings/base.py | 44 +- .../simple/settings/constance_settings.py | 1 + examples/simple/urls.py | 6 +- monkeytype_config.py | 2 +- pyproject.toml | 76 +++- pytest.ini | 2 +- scripts/compile_requirements.sh | 22 +- setup.py | 35 +- src/ska/__init__.py | 32 +- src/ska/base.py | 4 +- src/ska/contrib/django/ska/backends/base.py | 9 +- .../django/ska/backends/constance_backend.py | 9 +- .../django/ska/backends/default_backends.py | 9 +- src/ska/contrib/django/ska/decorators.py | 15 +- .../templatetags/ska_constance_tags.py | 5 +- .../ska/integration/drf/permissions/base.py | 8 +- .../drf/permissions/constance_permissions.py | 10 +- .../drf/permissions/default_permissions.py | 12 +- .../ska/integration/drf/views/jwt_token.py | 5 +- .../django/ska/templatetags/ska_tags.py | 5 +- src/ska/contrib/django/ska/tests/helpers.py | 3 +- .../test_constance_authentication_backend.py | 17 +- .../django/ska/tests/test_decorators.py | 12 +- .../test_default_authentication_backend.py | 15 +- .../tests/test_drf_integration_permissions.py | 11 +- .../test_drf_integration_view_jwt_token.py | 10 +- .../django/ska/tests/test_templatetags.py | 4 +- .../django/ska/views/constance_views.py | 1 - src/ska/generate_signed_url.py | 16 +- src/ska/helpers.py | 6 +- src/ska/shortcuts.py | 4 +- src/ska/signatures/hmac_md5.py | 2 +- src/ska/signatures/hmac_sha1.py | 2 +- src/ska/signatures/hmac_sha224.py | 2 +- src/ska/signatures/hmac_sha256.py | 2 +- src/ska/signatures/hmac_sha384.py | 2 +- src/ska/signatures/hmac_sha512.py | 2 +- src/ska/tests/base.py | 2 +- src/ska/tests/test_commands.py | 3 +- src/ska/tests/test_core.py | 24 +- src/ska/tests/test_integration.py | 22 +- src/ska/utils.py | 8 +- tox.ini | 19 +- 78 files changed, 1359 insertions(+), 815 deletions(-) create mode 100644 examples/requirements/constance_django_4_1.in create mode 100644 examples/requirements/constance_django_4_2.in create mode 100755 examples/requirements/django_4_1.in create mode 100644 examples/requirements/django_4_1.txt create mode 100755 examples/requirements/django_4_2.in create mode 100644 examples/requirements/django_4_2.txt create mode 100644 examples/requirements/rest_framework_django_4_1.in create mode 100644 examples/requirements/rest_framework_django_4_2.in diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e66f3cc..7e19adc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,16 @@ are used for versioning (schema follows below): 0.3.4 to 0.4). - All backwards incompatible changes are mentioned in this document. +1.10 +---- +2023-08-17 + +- Tested against Python 3.11. +- Mark `django-nine` as optional dependency. +- Drop support for Python < 3.7. +- Drop support for Django < 2.2, 3.0 and 3.1. +- Tested against Django 4.1 and 4.2. + 1.9.1 ----- 2021-11-18 diff --git a/docs/conf.py b/docs/conf.py index 9592ae9..ec8c618 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,9 +21,10 @@ sys.path.insert(0, os.path.abspath("../examples")) sys.path.insert(0, os.path.abspath(os.path.join("..", "examples", "simple"))) try: - import ska from simple import settings as docs_settings + import ska + version = ska.__version__ project = ska.__title__ copyright = ska.__copyright__ diff --git a/examples/requirements/common.txt b/examples/requirements/common.txt index feccd38..320a278 100644 --- a/examples/requirements/common.txt +++ b/examples/requirements/common.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile common.in # diff --git a/examples/requirements/constance_django_4_1.in b/examples/requirements/constance_django_4_1.in new file mode 100644 index 0000000..5f08566 --- /dev/null +++ b/examples/requirements/constance_django_4_1.in @@ -0,0 +1,5 @@ +django-constance==2.8.0 +django-json-widget==1.1.1 +django-picklefield==3.0.1 +#jsonfield2==3.0.1 +redis==3.0.1 diff --git a/examples/requirements/constance_django_4_2.in b/examples/requirements/constance_django_4_2.in new file mode 100644 index 0000000..bf544fb --- /dev/null +++ b/examples/requirements/constance_django_4_2.in @@ -0,0 +1,4 @@ +django-constance +django-json-widget +django-picklefield +redis diff --git a/examples/requirements/debug.in b/examples/requirements/debug.in index 0c91234..1275f6a 100644 --- a/examples/requirements/debug.in +++ b/examples/requirements/debug.in @@ -1,3 +1,2 @@ -ipdb==0.8.1 -ipython==7.0.1 -ipython-genutils==0.1.0 +ipython +ipython-genutils diff --git a/examples/requirements/debug.txt b/examples/requirements/debug.txt index c737628..89644c8 100644 --- a/examples/requirements/debug.txt +++ b/examples/requirements/debug.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile debug.in # @@ -10,12 +10,8 @@ decorator==5.0.9 # via # ipython # traitlets -ipdb==0.8.1 - # via -r debug.in ipython==7.0.1 - # via - # -r debug.in - # ipdb + # via -r debug.in ipython-genutils==0.1.0 # via # -r debug.in diff --git a/examples/requirements/deployment.txt b/examples/requirements/deployment.txt index 6316db4..a19544a 100644 --- a/examples/requirements/deployment.txt +++ b/examples/requirements/deployment.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile deployment.in # diff --git a/examples/requirements/dev.in b/examples/requirements/dev.in index b3ee84c..f3cceba 100644 --- a/examples/requirements/dev.in +++ b/examples/requirements/dev.in @@ -1,4 +1,4 @@ --r django_3_2.in +-r django_4_2.in -r deployment.in -r debug.in -r docs.in diff --git a/examples/requirements/dev.txt b/examples/requirements/dev.txt index 6ac4187..9c724f6 100644 --- a/examples/requirements/dev.txt +++ b/examples/requirements/dev.txt @@ -1,354 +1,418 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile dev.in # -alabaster==0.7.12 +alabaster==0.7.13 # via sphinx -appdirs==1.4.4 - # via - # black - # virtualenv -asgiref==3.3.4 +asgiref==3.7.2 # via django -astroid==2.5.6 +astroid==2.15.6 # via pylint -attrs==21.2.0 - # via pytest -babel==2.9.1 +asttokens==2.2.1 + # via stack-data +async-timeout==4.0.3 + # via redis +attrs==23.1.0 + # via + # outcome + # trio +babel==2.12.1 # via sphinx backcall==0.2.0 # via ipython -beautifulsoup4==4.7.1 +beautifulsoup4==4.12.2 # via -r test.in -black==21.5b2 +black==23.7.0 # via -r style_checkers.in -bleach==3.3.0 +bleach==6.0.0 # via readme-renderer -build==0.4.0 - # via check-manifest -certifi==2021.5.30 - # via requests -cffi==1.14.5 +build==0.10.0 + # via + # check-manifest + # pip-tools +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via + # requests + # selenium +cffi==1.15.1 # via cryptography -cfgv==3.3.0 +cfgv==3.4.0 # via pre-commit -chardet==4.0.0 +chardet==5.2.0 + # via tox +charset-normalizer==3.2.0 # via requests -check-manifest==0.46 +check-manifest==0.49 # via -r style_checkers.in -click==8.0.1 +click==8.1.7 # via # black # pip-tools -colorama==0.4.4 - # via twine -coverage[toml]==5.5 + # typer +colorama==0.4.6 + # via + # tox + # typer +commonmark==0.9.1 + # via rich +coverage[toml]==7.3.0 # via # -r test.in # pytest-cov -cryptography==3.4.7 +cryptography==41.0.3 # via # pyjwt # secretstorage -decorator==5.0.9 - # via - # ipython - # traitlets -distlib==0.3.2 +decorator==5.1.1 + # via ipython +dill==0.3.7 + # via pylint +distlib==0.3.7 # via virtualenv -django==3.2.4 +django==4.2.4 # via - # -r django_3_2.in + # -r django_4_2.in # django-picklefield # djangorestframework # drf-jwt -django-constance==2.8.0 - # via -r constance_django_3_2.in +django-constance==3.1.0 + # via -r constance_django_4_2.in django-json-widget==1.1.1 - # via -r constance_django_3_2.in -django-picklefield==3.0.1 - # via -r constance_django_3_2.in -djangorestframework==3.12.4 + # via -r constance_django_4_2.in +django-picklefield==3.1 + # via + # -r constance_django_4_2.in + # django-constance +djangorestframework==3.14.0 # via - # -r rest_framework_django_3_2.in + # -r rest_framework_django_4_2.in # drf-jwt -docutils==0.17.1 +docutils==0.19 # via # -r docs.in # readme-renderer # restview - # rstcheck + # rstcheck-core # sphinx -drf-jwt==1.19.1 - # via -r rest_framework_django_3_2.in -factory_boy==2.11.1 +drf-jwt==1.19.2 + # via -r rest_framework_django_4_2.in +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +executing==1.2.0 + # via stack-data +factory-boy==3.3.0 # via -r test.in -faker==8.1.4 +faker==19.3.1 # via # -r test.in # factory-boy -filelock==3.0.12 +filelock==3.12.2 # via # tox # virtualenv -flake8==3.9.2 +flake8==6.1.0 # via -r style_checkers.in -future==0.18.2 +future==0.18.3 # via django-json-widget -identify==2.2.10 +h11==0.14.0 + # via wsproto +identify==2.5.27 # via pre-commit -idna==2.10 - # via requests -imagesize==1.2.0 +idna==3.4 + # via + # requests + # trio +imagesize==1.4.1 # via sphinx -importlib-metadata==4.5.0 +importlib-metadata==6.8.0 # via # keyring # twine -ipdb==0.8.1 +iniconfig==2.0.0 + # via pytest +ipython==8.14.0 # via -r debug.in -ipython==7.0.1 - # via - # -r debug.in - # ipdb -ipython-genutils==0.1.0 - # via - # -r debug.in - # traitlets -isort==5.8.0 +ipython-genutils==0.2.0 + # via -r debug.in +isort==5.12.0 # via # -r style_checkers.in # pylint -jedi==0.18.0 +jaraco-classes==3.3.0 + # via keyring +jedi==0.19.0 # via ipython -jeepney==0.6.0 +jeepney==0.8.0 # via # keyring # secretstorage -jinja2==3.0.1 +jinja2==3.1.2 # via # -r docs.in # sphinx -keyring==23.0.1 +keyring==24.2.0 # via twine -lazy-object-proxy==1.6.0 +lazy-object-proxy==1.9.0 # via astroid -libcst==0.3.19 +libcst==1.0.1 # via monkeytype -markupsafe==2.0.1 +markupsafe==2.1.3 # via # -r docs.in # jinja2 -mccabe==0.6.1 +matplotlib-inline==0.1.6 + # via ipython +mccabe==0.7.0 # via # flake8 # pylint -mock==4.0.3 +mock==5.1.0 # via -r test.in -monkeytype==21.5.0 +monkeytype==23.3.0 # via pytest-monkeytype -more-itertools==8.8.0 - # via pytest -mypy-extensions==0.4.3 +more-itertools==10.1.0 + # via jaraco-classes +mypy-extensions==1.0.0 # via # black # monkeytype # typing-inspect -nodeenv==1.6.0 +nodeenv==1.8.0 # via pre-commit -packaging==20.9 +outcome==1.2.0 + # via trio +packaging==23.1 # via - # bleach + # black # build + # pyproject-api # pytest # sphinx # tox -parso==0.8.2 +parso==0.8.3 # via jedi -pathspec==0.8.1 +pathspec==0.11.2 # via black -pep517==0.10.0 - # via - # build - # pip-tools pexpect==4.8.0 # via ipython pickleshare==0.7.5 # via ipython -pip-tools==6.1.0 +pip-tools==7.3.0 # via -r deployment.in -pkginfo==1.7.0 +pkginfo==1.9.6 # via twine -pluggy==0.13.1 +platformdirs==3.10.0 + # via + # black + # pylint + # tox + # virtualenv +pluggy==1.2.0 # via # pytest # tox -pre-commit==2.13.0 +pre-commit==3.3.3 # via -r style_checkers.in -prompt-toolkit==2.0.10 +prompt-toolkit==3.0.39 # via ipython ptyprocess==0.7.0 # via pexpect -py==1.10.0 - # via - # -r test.in - # pytest - # tox -pycodestyle==2.7.0 +pure-eval==0.2.2 + # via stack-data +py==1.11.0 + # via -r test.in +pycodestyle==2.11.0 # via flake8 -pycparser==2.20 +pycparser==2.21 # via cffi -pydocstyle==6.1.1 +pydantic==1.10.12 + # via rstcheck-core +pydocstyle==6.3.0 # via -r style_checkers.in -pyflakes==2.3.1 +pyflakes==3.1.0 # via flake8 -pygments==2.9.0 +pygments==2.16.1 # via # ipython # readme-renderer # restview + # rich # sphinx -pyjwt[crypto]==2.1.0 +pyjwt[crypto]==2.8.0 # via drf-jwt -pylint==2.8.3 +pylint==2.17.5 # via -r style_checkers.in -pyparsing==2.4.7 - # via packaging -pytest==5.4.3 ; python_version < "3.10" +pyproject-api==1.5.4 + # via tox +pyproject-hooks==1.0.0 + # via build +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" # via # -r test.in # pytest-cov # pytest-django # pytest-monkeytype # pytest-ordering - # pytest-pythonpath -pytest-cov==2.12.0 +pytest-cov==4.1.0 # via -r test.in -pytest-django==4.3.0 +pytest-django==4.5.2 # via -r test.in pytest-monkeytype==1.1.0 # via -r test.in pytest-ordering==0.6 # via -r test.in -pytest-pythonpath==0.7.3 - # via -r test.in -python-dateutil==2.8.1 +python-dateutil==2.8.2 # via faker -pytz==2021.1 - # via - # babel - # django -pyyaml==5.4.1 +pytz==2023.3 + # via djangorestframework +pyyaml==6.0.1 # via # libcst # pre-commit radar==0.3 # via -r test.in -readme-renderer==29.0 +readme-renderer==36.0 # via # restview # twine -redis==3.0.1 - # via -r constance_django_3_2.in -regex==2021.4.4 - # via black -requests==2.25.1 +redis==5.0.0 + # via -r constance_django_4_2.in +requests==2.31.0 # via # requests-toolbelt # sphinx # twine -requests-toolbelt==0.9.1 +requests-toolbelt==1.0.0 # via twine -restview==2.9.2 +restview==3.0.1 # via -r style_checkers.in -rfc3986==1.5.0 +rfc3986==2.0.0 # via twine -rstcheck==3.3.1 +rich==12.6.0 + # via + # twine + # typer +rstcheck==6.1.2 # via -r docs.in -secretstorage==3.3.1 +rstcheck-core==1.0.3 + # via rstcheck +secretstorage==3.3.3 # via keyring -selenium==3.141.0 +selenium==4.11.2 # via -r test.in -simplegeneric==0.8.1 - # via ipython +shellingham==1.5.3 + # via typer six==1.16.0 # via + # asttokens # bleach - # prompt-toolkit # python-dateutil - # readme-renderer - # tox - # traitlets - # virtualenv -snowballstemmer==2.1.0 +sniffio==1.3.0 + # via trio +snowballstemmer==2.2.0 # via # pydocstyle # sphinx -soupsieve==1.8 +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 # via # -r test.in # beautifulsoup4 -sphinx==4.0.2 - # via -r docs.in -sphinxcontrib-applehelp==1.0.2 +sphinx==7.2.3 + # via + # -r docs.in + # sphinxcontrib-applehelp + # sphinxcontrib-devhelp + # sphinxcontrib-htmlhelp + # sphinxcontrib-qthelp + # sphinxcontrib-serializinghtml +sphinxcontrib-applehelp==1.0.7 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==1.0.5 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.0.4 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==1.0.6 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==1.1.9 # via sphinx -sqlparse==0.4.1 +sqlparse==0.4.4 # via django -text-unidecode==1.3 - # via faker -toml==0.10.2 +stack-data==0.6.2 + # via ipython +tomli==2.0.1 # via # black # build # check-manifest # coverage - # pep517 - # pre-commit + # pip-tools # pylint + # pyproject-api + # pyproject-hooks + # pytest # tox -tox==3.23.1 +tomlkit==0.12.1 + # via pylint +tox==4.10.0 # via -r test.in -tqdm==4.61.0 - # via twine -traitlets==4.3.3 - # via ipython -twine==3.4.1 - # via -r deployment.in -typing-extensions==3.10.0.0 +traitlets==5.9.0 # via + # ipython + # matplotlib-inline +trio==0.22.2 + # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +twine==4.0.2 + # via -r deployment.in +typer[all]==0.7.0 + # via rstcheck +types-docutils==0.19.1.9 + # via rstcheck-core +typing-extensions==4.7.1 + # via + # asgiref + # astroid # libcst + # pydantic # typing-inspect -typing-inspect==0.7.1 +typing-inspect==0.9.0 # via libcst -urllib3==1.26.5 +urllib3[socks]==2.0.4 # via # requests # selenium -virtualenv==20.4.7 + # twine +virtualenv==20.24.3 # via # pre-commit # tox -wcwidth==0.2.5 - # via - # prompt-toolkit - # pytest +wcwidth==0.2.6 + # via prompt-toolkit webencodings==0.5.1 # via bleach -wrapt==1.12.1 +wheel==0.41.2 + # via pip-tools +wrapt==1.15.0 # via astroid -zipp==3.4.1 +wsproto==1.2.0 + # via trio-websocket +zipp==3.16.2 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/examples/requirements/django_3_2.txt b/examples/requirements/django_3_2.txt index e29d92e..f54358c 100644 --- a/examples/requirements/django_3_2.txt +++ b/examples/requirements/django_3_2.txt @@ -1,28 +1,36 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile django_3_2.in # -appdirs==1.4.4 - # via virtualenv -asgiref==3.3.4 +asgiref==3.7.2 # via django -attrs==21.2.0 - # via pytest -beautifulsoup4==4.7.1 +attrs==23.1.0 + # via + # outcome + # trio +beautifulsoup4==4.12.2 # via -r test.in -cffi==1.14.5 +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via selenium +cffi==1.15.1 # via cryptography -coverage[toml]==5.5 +chardet==5.2.0 + # via tox +colorama==0.4.6 + # via tox +coverage[toml]==7.3.0 # via # -r test.in # pytest-cov -cryptography==3.4.7 +cryptography==41.0.3 # via pyjwt -distlib==0.3.2 +distlib==0.3.7 # via virtualenv -django==3.2.4 +django==3.2.20 # via # -r django_3_2.in # django-picklefield @@ -38,109 +46,129 @@ djangorestframework==3.12.4 # via # -r rest_framework_django_3_2.in # drf-jwt -drf-jwt==1.19.1 +drf-jwt==1.19.2 # via -r rest_framework_django_3_2.in -factory_boy==2.11.1 +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +factory-boy==3.3.0 # via -r test.in -faker==8.1.4 +faker==19.3.1 # via # -r test.in # factory-boy -filelock==3.0.12 +filelock==3.12.2 # via # tox # virtualenv -future==0.18.2 +future==0.18.3 # via django-json-widget -libcst==0.3.19 +h11==0.14.0 + # via wsproto +idna==3.4 + # via trio +iniconfig==2.0.0 + # via pytest +libcst==1.0.1 # via monkeytype -mock==4.0.3 +mock==5.1.0 # via -r test.in -monkeytype==21.5.0 +monkeytype==23.3.0 # via pytest-monkeytype -more-itertools==8.8.0 - # via pytest -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via # monkeytype # typing-inspect -packaging==20.9 +outcome==1.2.0 + # via trio +packaging==23.1 # via + # pyproject-api # pytest # tox -pluggy==0.13.1 +platformdirs==3.10.0 # via - # pytest # tox -py==1.10.0 + # virtualenv +pluggy==1.2.0 # via - # -r test.in # pytest # tox -pycparser==2.20 +py==1.11.0 + # via -r test.in +pycparser==2.21 # via cffi -pyjwt[crypto]==2.1.0 +pyjwt[crypto]==2.8.0 # via drf-jwt -pyparsing==2.4.7 - # via packaging -pytest==5.4.3 ; python_version < "3.10" +pyproject-api==1.5.4 + # via tox +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" # via # -r test.in # pytest-cov # pytest-django # pytest-monkeytype # pytest-ordering - # pytest-pythonpath -pytest-cov==2.12.0 +pytest-cov==4.1.0 # via -r test.in -pytest-django==4.3.0 +pytest-django==4.5.2 # via -r test.in pytest-monkeytype==1.1.0 # via -r test.in pytest-ordering==0.6 # via -r test.in -pytest-pythonpath==0.7.3 - # via -r test.in -python-dateutil==2.8.1 +python-dateutil==2.8.2 # via faker -pytz==2021.1 +pytz==2023.3 # via django -pyyaml==5.4.1 +pyyaml==6.0.1 # via libcst radar==0.3 # via -r test.in redis==3.0.1 # via -r constance_django_3_2.in -selenium==3.141.0 +selenium==4.11.2 # via -r test.in six==1.16.0 - # via - # python-dateutil - # tox - # virtualenv -soupsieve==1.8 + # via python-dateutil +sniffio==1.3.0 + # via trio +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 # via # -r test.in # beautifulsoup4 -sqlparse==0.4.1 +sqlparse==0.4.4 # via django -text-unidecode==1.3 - # via faker -toml==0.10.2 +tomli==2.0.1 # via # coverage + # pyproject-api + # pytest # tox -tox==3.23.1 +tox==4.10.0 # via -r test.in -typing-extensions==3.10.0.0 +trio==0.22.2 # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +typing-extensions==4.7.1 + # via + # asgiref # libcst # typing-inspect -typing-inspect==0.7.1 +typing-inspect==0.9.0 # via libcst -urllib3==1.26.5 +urllib3[socks]==2.0.4 # via selenium -virtualenv==20.4.7 +virtualenv==20.24.3 # via tox -wcwidth==0.2.5 - # via pytest +wsproto==1.2.0 + # via trio-websocket diff --git a/examples/requirements/django_4_1.in b/examples/requirements/django_4_1.in new file mode 100755 index 0000000..bd9f20d --- /dev/null +++ b/examples/requirements/django_4_1.in @@ -0,0 +1,6 @@ +-r common.in +-r test.in +-r constance_django_4_1.in +-r rest_framework_django_4_1.in + +Django>=4.1,<4.2 diff --git a/examples/requirements/django_4_1.txt b/examples/requirements/django_4_1.txt new file mode 100644 index 0000000..43555dc --- /dev/null +++ b/examples/requirements/django_4_1.txt @@ -0,0 +1,172 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile django_4_1.in +# +asgiref==3.7.2 + # via django +attrs==23.1.0 + # via + # outcome + # trio +beautifulsoup4==4.12.2 + # via -r test.in +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via selenium +cffi==1.15.1 + # via cryptography +chardet==5.2.0 + # via tox +colorama==0.4.6 + # via tox +coverage[toml]==7.3.0 + # via + # -r test.in + # pytest-cov +cryptography==41.0.3 + # via pyjwt +distlib==0.3.7 + # via virtualenv +django==4.1.10 + # via + # -r django_4_1.in + # django-picklefield + # djangorestframework + # drf-jwt +django-constance==2.8.0 + # via -r constance_django_4_1.in +django-json-widget==1.1.1 + # via -r constance_django_4_1.in +django-picklefield==3.0.1 + # via -r constance_django_4_1.in +djangorestframework==3.12.4 + # via + # -r rest_framework_django_4_1.in + # drf-jwt +drf-jwt==1.19.2 + # via -r rest_framework_django_4_1.in +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +factory-boy==3.3.0 + # via -r test.in +faker==19.3.1 + # via + # -r test.in + # factory-boy +filelock==3.12.2 + # via + # tox + # virtualenv +future==0.18.3 + # via django-json-widget +h11==0.14.0 + # via wsproto +idna==3.4 + # via trio +iniconfig==2.0.0 + # via pytest +libcst==1.0.1 + # via monkeytype +mock==5.1.0 + # via -r test.in +monkeytype==23.3.0 + # via pytest-monkeytype +mypy-extensions==1.0.0 + # via + # monkeytype + # typing-inspect +outcome==1.2.0 + # via trio +packaging==23.1 + # via + # pyproject-api + # pytest + # tox +platformdirs==3.10.0 + # via + # tox + # virtualenv +pluggy==1.2.0 + # via + # pytest + # tox +py==1.11.0 + # via -r test.in +pycparser==2.21 + # via cffi +pyjwt[crypto]==2.8.0 + # via drf-jwt +pyproject-api==1.5.4 + # via tox +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" + # via + # -r test.in + # pytest-cov + # pytest-django + # pytest-monkeytype + # pytest-ordering +pytest-cov==4.1.0 + # via -r test.in +pytest-django==4.5.2 + # via -r test.in +pytest-monkeytype==1.1.0 + # via -r test.in +pytest-ordering==0.6 + # via -r test.in +python-dateutil==2.8.2 + # via faker +pyyaml==6.0.1 + # via libcst +radar==0.3 + # via -r test.in +redis==3.0.1 + # via -r constance_django_4_1.in +selenium==4.11.2 + # via -r test.in +six==1.16.0 + # via python-dateutil +sniffio==1.3.0 + # via trio +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 + # via + # -r test.in + # beautifulsoup4 +sqlparse==0.4.4 + # via django +tomli==2.0.1 + # via + # coverage + # pyproject-api + # pytest + # tox +tox==4.10.0 + # via -r test.in +trio==0.22.2 + # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +typing-extensions==4.7.1 + # via + # asgiref + # libcst + # typing-inspect +typing-inspect==0.9.0 + # via libcst +urllib3[socks]==2.0.4 + # via selenium +virtualenv==20.24.3 + # via tox +wsproto==1.2.0 + # via trio-websocket diff --git a/examples/requirements/django_4_2.in b/examples/requirements/django_4_2.in new file mode 100755 index 0000000..a051f01 --- /dev/null +++ b/examples/requirements/django_4_2.in @@ -0,0 +1,7 @@ +-r common.in +-r test.in +-r constance_django_4_2.in +-r rest_framework_django_4_2.in + +Django>=4.2,<5.0 + diff --git a/examples/requirements/django_4_2.txt b/examples/requirements/django_4_2.txt new file mode 100644 index 0000000..eba02f2 --- /dev/null +++ b/examples/requirements/django_4_2.txt @@ -0,0 +1,178 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile django_4_2.in +# +asgiref==3.7.2 + # via django +async-timeout==4.0.3 + # via redis +attrs==23.1.0 + # via + # outcome + # trio +beautifulsoup4==4.12.2 + # via -r test.in +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via selenium +cffi==1.15.1 + # via cryptography +chardet==5.2.0 + # via tox +colorama==0.4.6 + # via tox +coverage[toml]==7.3.0 + # via + # -r test.in + # pytest-cov +cryptography==41.0.3 + # via pyjwt +distlib==0.3.7 + # via virtualenv +django==4.2.4 + # via + # -r django_4_2.in + # django-picklefield + # djangorestframework + # drf-jwt +django-constance==3.1.0 + # via -r constance_django_4_2.in +django-json-widget==1.1.1 + # via -r constance_django_4_2.in +django-picklefield==3.1 + # via + # -r constance_django_4_2.in + # django-constance +djangorestframework==3.14.0 + # via + # -r rest_framework_django_4_2.in + # drf-jwt +drf-jwt==1.19.2 + # via -r rest_framework_django_4_2.in +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +factory-boy==3.3.0 + # via -r test.in +faker==19.3.1 + # via + # -r test.in + # factory-boy +filelock==3.12.2 + # via + # tox + # virtualenv +future==0.18.3 + # via django-json-widget +h11==0.14.0 + # via wsproto +idna==3.4 + # via trio +iniconfig==2.0.0 + # via pytest +libcst==1.0.1 + # via monkeytype +mock==5.1.0 + # via -r test.in +monkeytype==23.3.0 + # via pytest-monkeytype +mypy-extensions==1.0.0 + # via + # monkeytype + # typing-inspect +outcome==1.2.0 + # via trio +packaging==23.1 + # via + # pyproject-api + # pytest + # tox +platformdirs==3.10.0 + # via + # tox + # virtualenv +pluggy==1.2.0 + # via + # pytest + # tox +py==1.11.0 + # via -r test.in +pycparser==2.21 + # via cffi +pyjwt[crypto]==2.8.0 + # via drf-jwt +pyproject-api==1.5.4 + # via tox +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" + # via + # -r test.in + # pytest-cov + # pytest-django + # pytest-monkeytype + # pytest-ordering +pytest-cov==4.1.0 + # via -r test.in +pytest-django==4.5.2 + # via -r test.in +pytest-monkeytype==1.1.0 + # via -r test.in +pytest-ordering==0.6 + # via -r test.in +python-dateutil==2.8.2 + # via faker +pytz==2023.3 + # via djangorestframework +pyyaml==6.0.1 + # via libcst +radar==0.3 + # via -r test.in +redis==5.0.0 + # via -r constance_django_4_2.in +selenium==4.11.2 + # via -r test.in +six==1.16.0 + # via python-dateutil +sniffio==1.3.0 + # via trio +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 + # via + # -r test.in + # beautifulsoup4 +sqlparse==0.4.4 + # via django +tomli==2.0.1 + # via + # coverage + # pyproject-api + # pytest + # tox +tox==4.10.0 + # via -r test.in +trio==0.22.2 + # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +typing-extensions==4.7.1 + # via + # asgiref + # libcst + # typing-inspect +typing-inspect==0.9.0 + # via libcst +urllib3[socks]==2.0.4 + # via selenium +virtualenv==20.24.3 + # via tox +wsproto==1.2.0 + # via trio-websocket diff --git a/examples/requirements/docs.in b/examples/requirements/docs.in index 8278c96..c0dc233 100644 --- a/examples/requirements/docs.in +++ b/examples/requirements/docs.in @@ -2,4 +2,4 @@ Jinja2 MarkupSafe Sphinx docutils -rstcheck==3.3.1 +rstcheck diff --git a/examples/requirements/docs.txt b/examples/requirements/docs.txt index f61ae0d..36ad768 100644 --- a/examples/requirements/docs.txt +++ b/examples/requirements/docs.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile docs.in # diff --git a/examples/requirements/documentation.in b/examples/requirements/documentation.in index 340cd39..2c72e87 100644 --- a/examples/requirements/documentation.in +++ b/examples/requirements/documentation.in @@ -1,2 +1,2 @@ --r django_3_2.in +-r django_4_2.in -r docs.in diff --git a/examples/requirements/documentation.txt b/examples/requirements/documentation.txt index d769c7e..3bb382d 100644 --- a/examples/requirements/documentation.txt +++ b/examples/requirements/documentation.txt @@ -1,201 +1,253 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile documentation.in # -alabaster==0.7.12 +alabaster==0.7.13 # via sphinx -appdirs==1.4.4 - # via virtualenv -asgiref==3.3.4 +asgiref==3.7.2 # via django -attrs==21.2.0 - # via pytest -babel==2.9.1 +async-timeout==4.0.3 + # via redis +attrs==23.1.0 + # via + # outcome + # trio +babel==2.12.1 # via sphinx -beautifulsoup4==4.7.1 +beautifulsoup4==4.12.2 # via -r test.in -certifi==2021.5.30 - # via requests -cffi==1.14.5 +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via + # requests + # selenium +cffi==1.15.1 # via cryptography -chardet==4.0.0 +chardet==5.2.0 + # via tox +charset-normalizer==3.2.0 # via requests -coverage[toml]==5.5 +click==8.1.7 + # via typer +colorama==0.4.6 + # via + # tox + # typer +commonmark==0.9.1 + # via rich +coverage[toml]==7.3.0 # via # -r test.in # pytest-cov -cryptography==3.4.7 +cryptography==41.0.3 # via pyjwt -distlib==0.3.2 +distlib==0.3.7 # via virtualenv -django==3.2.4 +django==4.2.4 # via - # -r django_3_2.in + # -r django_4_2.in # django-picklefield # djangorestframework # drf-jwt -django-constance==2.8.0 - # via -r constance_django_3_2.in +django-constance==3.1.0 + # via -r constance_django_4_2.in django-json-widget==1.1.1 - # via -r constance_django_3_2.in -django-picklefield==3.0.1 - # via -r constance_django_3_2.in -djangorestframework==3.12.4 + # via -r constance_django_4_2.in +django-picklefield==3.1 + # via + # -r constance_django_4_2.in + # django-constance +djangorestframework==3.14.0 # via - # -r rest_framework_django_3_2.in + # -r rest_framework_django_4_2.in # drf-jwt -docutils==0.17.1 +docutils==0.19 # via # -r docs.in - # rstcheck + # rstcheck-core # sphinx -drf-jwt==1.19.1 - # via -r rest_framework_django_3_2.in -factory_boy==2.11.1 +drf-jwt==1.19.2 + # via -r rest_framework_django_4_2.in +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +factory-boy==3.3.0 # via -r test.in -faker==8.1.4 +faker==19.3.1 # via # -r test.in # factory-boy -filelock==3.0.12 +filelock==3.12.2 # via # tox # virtualenv -future==0.18.2 +future==0.18.3 # via django-json-widget -idna==2.10 - # via requests -imagesize==1.2.0 +h11==0.14.0 + # via wsproto +idna==3.4 + # via + # requests + # trio +imagesize==1.4.1 # via sphinx -jinja2==3.0.1 +iniconfig==2.0.0 + # via pytest +jinja2==3.1.2 # via # -r docs.in # sphinx -libcst==0.3.19 +libcst==1.0.1 # via monkeytype -markupsafe==2.0.1 +markupsafe==2.1.3 # via # -r docs.in # jinja2 -mock==4.0.3 +mock==5.1.0 # via -r test.in -monkeytype==21.5.0 +monkeytype==23.3.0 # via pytest-monkeytype -more-itertools==8.8.0 - # via pytest -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via # monkeytype # typing-inspect -packaging==20.9 +outcome==1.2.0 + # via trio +packaging==23.1 # via + # pyproject-api # pytest # sphinx # tox -pluggy==0.13.1 +platformdirs==3.10.0 # via - # pytest # tox -py==1.10.0 + # virtualenv +pluggy==1.2.0 # via - # -r test.in # pytest # tox -pycparser==2.20 +py==1.11.0 + # via -r test.in +pycparser==2.21 # via cffi -pygments==2.9.0 - # via sphinx -pyjwt[crypto]==2.1.0 +pydantic==1.10.12 + # via rstcheck-core +pygments==2.16.1 + # via + # rich + # sphinx +pyjwt[crypto]==2.8.0 # via drf-jwt -pyparsing==2.4.7 - # via packaging -pytest==5.4.3 ; python_version < "3.10" +pyproject-api==1.5.4 + # via tox +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" # via # -r test.in # pytest-cov # pytest-django # pytest-monkeytype # pytest-ordering - # pytest-pythonpath -pytest-cov==2.12.0 +pytest-cov==4.1.0 # via -r test.in -pytest-django==4.3.0 +pytest-django==4.5.2 # via -r test.in pytest-monkeytype==1.1.0 # via -r test.in pytest-ordering==0.6 # via -r test.in -pytest-pythonpath==0.7.3 - # via -r test.in -python-dateutil==2.8.1 +python-dateutil==2.8.2 # via faker -pytz==2021.1 - # via - # babel - # django -pyyaml==5.4.1 +pytz==2023.3 + # via djangorestframework +pyyaml==6.0.1 # via libcst -radar==0.3 - # via -r test.in -redis==3.0.1 - # via -r constance_django_3_2.in -requests==2.25.1 +redis==5.0.0 + # via -r constance_django_4_2.in +requests==2.31.0 # via sphinx -rstcheck==3.3.1 +rich==12.6.0 + # via typer +rstcheck==6.1.2 # via -r docs.in -selenium==3.141.0 +rstcheck-core==1.0.3 + # via rstcheck +selenium==4.11.2 # via -r test.in +shellingham==1.5.3 + # via typer six==1.16.0 - # via - # python-dateutil - # tox - # virtualenv -snowballstemmer==2.1.0 + # via python-dateutil +sniffio==1.3.0 + # via trio +snowballstemmer==2.2.0 # via sphinx -soupsieve==1.8 +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 # via # -r test.in # beautifulsoup4 -sphinx==4.0.2 - # via -r docs.in -sphinxcontrib-applehelp==1.0.2 +sphinx==7.2.3 + # via + # -r docs.in + # sphinxcontrib-applehelp + # sphinxcontrib-devhelp + # sphinxcontrib-htmlhelp + # sphinxcontrib-qthelp + # sphinxcontrib-serializinghtml +sphinxcontrib-applehelp==1.0.7 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==1.0.5 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.0.4 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==1.0.6 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==1.1.9 # via sphinx -sqlparse==0.4.1 +sqlparse==0.4.4 # via django -text-unidecode==1.3 - # via faker -toml==0.10.2 +tomli==2.0.1 # via # coverage + # pyproject-api + # pytest # tox -tox==3.23.1 +tox==4.10.0 # via -r test.in -typing-extensions==3.10.0.0 +trio==0.22.2 # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +typer[all]==0.7.0 + # via rstcheck +types-docutils==0.19.1.9 + # via rstcheck-core +typing-extensions==4.7.1 + # via + # asgiref # libcst + # pydantic # typing-inspect -typing-inspect==0.7.1 +typing-inspect==0.9.0 # via libcst -urllib3==1.26.5 +urllib3[socks]==2.0.4 # via # requests # selenium -virtualenv==20.4.7 +virtualenv==20.24.3 # via tox -wcwidth==0.2.5 - # via pytest - -# The following packages are considered to be unsafe in a requirements file: -# setuptools +wsproto==1.2.0 + # via trio-websocket diff --git a/examples/requirements/rest_framework_django_4_1.in b/examples/requirements/rest_framework_django_4_1.in new file mode 100644 index 0000000..0c9b6fe --- /dev/null +++ b/examples/requirements/rest_framework_django_4_1.in @@ -0,0 +1,2 @@ +djangorestframework==3.12.4 +drf-jwt diff --git a/examples/requirements/rest_framework_django_4_2.in b/examples/requirements/rest_framework_django_4_2.in new file mode 100644 index 0000000..d298546 --- /dev/null +++ b/examples/requirements/rest_framework_django_4_2.in @@ -0,0 +1,2 @@ +djangorestframework +drf-jwt diff --git a/examples/requirements/style_checkers.in b/examples/requirements/style_checkers.in index b8a7a15..38f5ace 100644 --- a/examples/requirements/style_checkers.in +++ b/examples/requirements/style_checkers.in @@ -1,4 +1,3 @@ - # Style checkers black check-manifest diff --git a/examples/requirements/test.in b/examples/requirements/test.in index 88f5008..b26e987 100644 --- a/examples/requirements/test.in +++ b/examples/requirements/test.in @@ -1,19 +1,16 @@ selenium -beautifulsoup4==4.7.1 +beautifulsoup4 mock -radar -soupsieve==1.8 +soupsieve - -Faker==8.1.4 -coverage>=4.5.4 -factory_boy==2.11.1 +Faker +coverage +factory_boy py -pytest-cov==2.12.0 +pytest-cov pytest-monkeytype -pytest-django==4.3.0 -pytest-ordering==0.6 -pytest-pythonpath +pytest-django +pytest-ordering pytest>=6.2.5; python_version >= '3.10' pytest; python_version < '3.10' -tox==3.23.1 +tox diff --git a/examples/requirements/test.txt b/examples/requirements/test.txt index 49d45bc..5a729a4 100644 --- a/examples/requirements/test.txt +++ b/examples/requirements/test.txt @@ -1,110 +1,135 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile test.in # -appdirs==1.4.4 - # via virtualenv -attrs==21.2.0 - # via pytest -beautifulsoup4==4.7.1 +attrs==23.1.0 + # via + # outcome + # trio +beautifulsoup4==4.12.2 # via -r test.in -coverage[toml]==5.5 +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via selenium +chardet==5.2.0 + # via tox +colorama==0.4.6 + # via tox +coverage[toml]==7.3.0 # via # -r test.in # pytest-cov -distlib==0.3.2 +distlib==0.3.7 # via virtualenv -factory_boy==2.11.1 +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +factory-boy==3.3.0 # via -r test.in -faker==8.1.4 +faker==19.3.1 # via # -r test.in # factory-boy -filelock==3.0.12 +filelock==3.12.2 # via # tox # virtualenv -libcst==0.3.19 +h11==0.14.0 + # via wsproto +idna==3.4 + # via trio +iniconfig==2.0.0 + # via pytest +libcst==1.0.1 # via monkeytype -mock==4.0.3 +mock==5.1.0 # via -r test.in -monkeytype==21.5.0 +monkeytype==23.3.0 # via pytest-monkeytype -more-itertools==8.8.0 - # via pytest -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via # monkeytype # typing-inspect -packaging==20.9 +outcome==1.2.0 + # via trio +packaging==23.1 # via + # pyproject-api # pytest # tox -pluggy==0.13.1 +platformdirs==3.10.0 # via - # pytest # tox -py==1.10.0 + # virtualenv +pluggy==1.2.0 # via - # -r test.in # pytest # tox -pyparsing==2.4.7 - # via packaging -pytest==5.4.3 ; python_version < "3.10" +py==1.11.0 + # via -r test.in +pyproject-api==1.5.4 + # via tox +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" # via # -r test.in # pytest-cov # pytest-django # pytest-monkeytype # pytest-ordering - # pytest-pythonpath -pytest-cov==2.12.0 +pytest-cov==4.1.0 # via -r test.in -pytest-django==4.3.0 +pytest-django==4.5.2 # via -r test.in pytest-monkeytype==1.1.0 # via -r test.in pytest-ordering==0.6 # via -r test.in -pytest-pythonpath==0.7.3 - # via -r test.in -python-dateutil==2.8.1 +python-dateutil==2.8.2 # via faker -pyyaml==5.4.1 +pyyaml==6.0.1 # via libcst -radar==0.3 - # via -r test.in -selenium==3.141.0 +selenium==4.11.2 # via -r test.in six==1.16.0 - # via - # python-dateutil - # tox - # virtualenv -soupsieve==1.8 + # via python-dateutil +sniffio==1.3.0 + # via trio +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 # via # -r test.in # beautifulsoup4 -text-unidecode==1.3 - # via faker -toml==0.10.2 +tomli==2.0.1 # via # coverage + # pyproject-api + # pytest # tox -tox==3.23.1 +tox==4.10.0 # via -r test.in -typing-extensions==3.10.0.0 +trio==0.22.2 + # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +typing-extensions==4.7.1 # via # libcst # typing-inspect -typing-inspect==0.7.1 +typing-inspect==0.9.0 # via libcst -urllib3==1.26.5 +urllib3[socks]==2.0.4 # via selenium -virtualenv==20.4.7 +virtualenv==20.24.3 # via tox -wcwidth==0.2.5 - # via pytest +wsproto==1.2.0 + # via trio-websocket diff --git a/examples/requirements/testing.in b/examples/requirements/testing.in index 256ae18..a184d14 100644 --- a/examples/requirements/testing.in +++ b/examples/requirements/testing.in @@ -1,3 +1,3 @@ --r django_3_2.in +-r django_4_2.in -r test.in -r style_checkers.in diff --git a/examples/requirements/testing.txt b/examples/requirements/testing.txt index 8f399fb..7f5e276 100644 --- a/examples/requirements/testing.txt +++ b/examples/requirements/testing.txt @@ -1,230 +1,262 @@ # -# This file is autogenerated by pip-compile with python 3.8 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile testing.in # -appdirs==1.4.4 - # via - # black - # virtualenv -asgiref==3.3.4 +asgiref==3.7.2 # via django -astroid==2.5.6 +astroid==2.15.6 # via pylint -attrs==21.2.0 - # via pytest -beautifulsoup4==4.7.1 +async-timeout==4.0.3 + # via redis +attrs==23.1.0 + # via + # outcome + # trio +beautifulsoup4==4.12.2 # via -r test.in -black==21.5b2 +black==23.7.0 # via -r style_checkers.in -bleach==3.3.0 +bleach==6.0.0 # via readme-renderer -build==0.4.0 +build==0.10.0 # via check-manifest -cffi==1.14.5 +cachetools==5.3.1 + # via tox +certifi==2023.7.22 + # via selenium +cffi==1.15.1 # via cryptography -cfgv==3.3.0 +cfgv==3.4.0 # via pre-commit -check-manifest==0.46 +chardet==5.2.0 + # via tox +check-manifest==0.49 # via -r style_checkers.in -click==8.0.1 +click==8.1.7 # via black -coverage[toml]==5.5 +colorama==0.4.6 + # via tox +coverage[toml]==7.3.0 # via # -r test.in # pytest-cov -cryptography==3.4.7 +cryptography==41.0.3 # via pyjwt -distlib==0.3.2 +dill==0.3.7 + # via pylint +distlib==0.3.7 # via virtualenv -django==3.2.4 +django==4.2.4 # via - # -r django_3_2.in + # -r django_4_2.in # django-picklefield # djangorestframework # drf-jwt -django-constance==2.8.0 - # via -r constance_django_3_2.in +django-constance==3.1.0 + # via -r constance_django_4_2.in django-json-widget==1.1.1 - # via -r constance_django_3_2.in -django-picklefield==3.0.1 - # via -r constance_django_3_2.in -djangorestframework==3.12.4 + # via -r constance_django_4_2.in +django-picklefield==3.1 + # via + # -r constance_django_4_2.in + # django-constance +djangorestframework==3.14.0 # via - # -r rest_framework_django_3_2.in + # -r rest_framework_django_4_2.in # drf-jwt -docutils==0.17.1 +docutils==0.20.1 # via # readme-renderer # restview -drf-jwt==1.19.1 - # via -r rest_framework_django_3_2.in -factory_boy==2.11.1 +drf-jwt==1.19.2 + # via -r rest_framework_django_4_2.in +exceptiongroup==1.1.3 + # via + # pytest + # trio + # trio-websocket +factory-boy==3.3.0 # via -r test.in -faker==8.1.4 +faker==19.3.1 # via # -r test.in # factory-boy -filelock==3.0.12 +filelock==3.12.2 # via # tox # virtualenv -flake8==3.9.2 +flake8==6.1.0 # via -r style_checkers.in -future==0.18.2 +future==0.18.3 # via django-json-widget -identify==2.2.10 +h11==0.14.0 + # via wsproto +identify==2.5.27 # via pre-commit -isort==5.8.0 +idna==3.4 + # via trio +iniconfig==2.0.0 + # via pytest +isort==5.12.0 # via # -r style_checkers.in # pylint -lazy-object-proxy==1.6.0 +lazy-object-proxy==1.9.0 # via astroid -libcst==0.3.19 +libcst==1.0.1 # via monkeytype -mccabe==0.6.1 +mccabe==0.7.0 # via # flake8 # pylint -mock==4.0.3 +mock==5.1.0 # via -r test.in -monkeytype==21.5.0 +monkeytype==23.3.0 # via pytest-monkeytype -more-itertools==8.8.0 - # via pytest -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via # black # monkeytype # typing-inspect -nodeenv==1.6.0 +nodeenv==1.8.0 # via pre-commit -packaging==20.9 +outcome==1.2.0 + # via trio +packaging==23.1 # via - # bleach + # black # build + # pyproject-api # pytest # tox -pathspec==0.8.1 +pathspec==0.11.2 # via black -pep517==0.10.0 - # via build -pluggy==0.13.1 +platformdirs==3.10.0 # via - # pytest + # black + # pylint # tox -pre-commit==2.13.0 - # via -r style_checkers.in -py==1.10.0 + # virtualenv +pluggy==1.2.0 # via - # -r test.in # pytest # tox -pycodestyle==2.7.0 +pre-commit==3.3.3 + # via -r style_checkers.in +py==1.11.0 + # via -r test.in +pycodestyle==2.11.0 # via flake8 -pycparser==2.20 +pycparser==2.21 # via cffi -pydocstyle==6.1.1 +pydocstyle==6.3.0 # via -r style_checkers.in -pyflakes==2.3.1 +pyflakes==3.1.0 # via flake8 -pygments==2.9.0 +pygments==2.16.1 # via # readme-renderer # restview -pyjwt[crypto]==2.1.0 +pyjwt[crypto]==2.8.0 # via drf-jwt -pylint==2.8.3 +pylint==2.17.5 # via -r style_checkers.in -pyparsing==2.4.7 - # via packaging -pytest==5.4.3 ; python_version < "3.10" +pyproject-api==1.5.4 + # via tox +pyproject-hooks==1.0.0 + # via build +pysocks==1.7.1 + # via urllib3 +pytest==7.4.0 ; python_version >= "3.10" # via # -r test.in # pytest-cov # pytest-django # pytest-monkeytype # pytest-ordering - # pytest-pythonpath -pytest-cov==2.12.0 +pytest-cov==4.1.0 # via -r test.in -pytest-django==4.3.0 +pytest-django==4.5.2 # via -r test.in pytest-monkeytype==1.1.0 # via -r test.in pytest-ordering==0.6 # via -r test.in -pytest-pythonpath==0.7.3 - # via -r test.in -python-dateutil==2.8.1 +python-dateutil==2.8.2 # via faker -pytz==2021.1 - # via django -pyyaml==5.4.1 +pytz==2023.3 + # via djangorestframework +pyyaml==6.0.1 # via # libcst # pre-commit -radar==0.3 - # via -r test.in -readme-renderer==29.0 +readme-renderer==36.0 # via restview -redis==3.0.1 - # via -r constance_django_3_2.in -regex==2021.4.4 - # via black -restview==2.9.2 +redis==5.0.0 + # via -r constance_django_4_2.in +restview==3.0.1 # via -r style_checkers.in -selenium==3.141.0 +selenium==4.11.2 # via -r test.in six==1.16.0 # via # bleach # python-dateutil - # readme-renderer - # tox - # virtualenv -snowballstemmer==2.1.0 +sniffio==1.3.0 + # via trio +snowballstemmer==2.2.0 # via pydocstyle -soupsieve==1.8 +sortedcontainers==2.4.0 + # via trio +soupsieve==2.4.1 # via # -r test.in # beautifulsoup4 -sqlparse==0.4.1 +sqlparse==0.4.4 # via django -text-unidecode==1.3 - # via faker -toml==0.10.2 +tomli==2.0.1 # via # black # build # check-manifest # coverage - # pep517 - # pre-commit # pylint + # pyproject-api + # pyproject-hooks + # pytest # tox -tox==3.23.1 +tomlkit==0.12.1 + # via pylint +tox==4.10.0 # via -r test.in -typing-extensions==3.10.0.0 +trio==0.22.2 + # via + # selenium + # trio-websocket +trio-websocket==0.10.3 + # via selenium +typing-extensions==4.7.1 # via + # asgiref + # astroid # libcst # typing-inspect -typing-inspect==0.7.1 +typing-inspect==0.9.0 # via libcst -urllib3==1.26.5 +urllib3[socks]==2.0.4 # via selenium -virtualenv==20.4.7 +virtualenv==20.24.3 # via # pre-commit # tox -wcwidth==0.2.5 - # via pytest webencodings==0.5.1 # via bleach -wrapt==1.12.1 +wrapt==1.15.0 # via astroid +wsproto==1.2.0 + # via trio-websocket # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/examples/simple/constance_urls.py b/examples/simple/constance_urls.py index 5b008ef..7e53f97 100644 --- a/examples/simple/constance_urls.py +++ b/examples/simple/constance_urls.py @@ -30,6 +30,4 @@ if settings.DEBUG: urlpatterns += staticfiles_urlpatterns() - urlpatterns += static( - settings.MEDIA_URL, document_root=settings.MEDIA_ROOT - ) + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/examples/simple/factories/auth_group.py b/examples/simple/factories/auth_group.py index 035d9e8..2b2b43c 100644 --- a/examples/simple/factories/auth_group.py +++ b/examples/simple/factories/auth_group.py @@ -1,11 +1,8 @@ import random from django.contrib.auth.models import Group - -from factory import ( - DjangoModelFactory, - LazyAttribute, -) +from factory import LazyAttribute +from factory.django import DjangoModelFactory from faker import Faker as OriginalFaker from .factory_faker import Faker diff --git a/examples/simple/factories/auth_user.py b/examples/simple/factories/auth_user.py index 8aa2d15..06d2f60 100644 --- a/examples/simple/factories/auth_user.py +++ b/examples/simple/factories/auth_user.py @@ -1,19 +1,18 @@ import random from django.conf import settings - from factory import ( - DjangoModelFactory, + LazyAttribute, PostGenerationMethodCall, Sequence, + SubFactory, post_generation, - LazyAttribute, ) +from factory.django import DjangoModelFactory from faker import Faker as OriginalFaker -from factory import SubFactory -from .factory_faker import Faker from .auth_group import LimitedGroupFactory +from .factory_faker import Faker __all__ = ( "AbstractUserFactory", diff --git a/examples/simple/factories/constance_constance.py b/examples/simple/factories/constance_constance.py index 8059ddc..ebedfd6 100644 --- a/examples/simple/factories/constance_constance.py +++ b/examples/simple/factories/constance_constance.py @@ -1,8 +1,7 @@ import json -from factory import DjangoModelFactory - -from constance.backends.database.models import Constance +from constance.models import Constance +from factory.django import DjangoModelFactory from .factory_faker import Faker diff --git a/examples/simple/factories/factory_faker.py b/examples/simple/factories/factory_faker.py index 9c37a1c..d53c2e2 100644 --- a/examples/simple/factories/factory_faker.py +++ b/examples/simple/factories/factory_faker.py @@ -4,10 +4,10 @@ import uuid from factory import Faker as OriginalFaker -from faker.providers.phone_number import Provider as PhoneNumberProvider +from faker.providers.company import Provider as CompanyProvider from faker.providers.internet import Provider as InternetProvider from faker.providers.person import Provider as PersonProvider -from faker.providers.company import Provider as CompanyProvider +from faker.providers.phone_number import Provider as PhoneNumberProvider localized = True diff --git a/examples/simple/factories/foo_fooitem.py b/examples/simple/factories/foo_fooitem.py index f50b6ff..1322060 100644 --- a/examples/simple/factories/foo_fooitem.py +++ b/examples/simple/factories/foo_fooitem.py @@ -1,10 +1,9 @@ import random from django.utils.text import slugify - -from factory import DjangoModelFactory, LazyAttribute +from factory import LazyAttribute +from factory.django import DjangoModelFactory from factory.fuzzy import FuzzyChoice - from foo.models import FooItem from .factory_faker import Faker diff --git a/examples/simple/foo/serializers.py b/examples/simple/foo/serializers.py index e2af24f..05db0ef 100644 --- a/examples/simple/foo/serializers.py +++ b/examples/simple/foo/serializers.py @@ -12,7 +12,6 @@ class FooItemSerializer(serializers.ModelSerializer): """FooItem model serializer.""" class Meta(object): - model = FooItem fields = ( "title", diff --git a/examples/simple/foo/urls.py b/examples/simple/foo/urls.py index 155e20f..d773628 100644 --- a/examples/simple/foo/urls.py +++ b/examples/simple/foo/urls.py @@ -1,14 +1,13 @@ from django.urls import include, re_path as url - from rest_framework.routers import DefaultRouter from .views import ( FooDetailView, - browse_view, authenticate_view, + browse_view, + detail_view, drf_view, logged_in_view, - detail_view, ) from .viewsets import ( FooItemConstanceProviderSignedRequestRequiredViewSet, diff --git a/examples/simple/foo/views.py b/examples/simple/foo/views.py index 88d1125..57df5f9 100644 --- a/examples/simple/foo/views.py +++ b/examples/simple/foo/views.py @@ -1,18 +1,17 @@ from django.http import Http404 from django.shortcuts import render -from django.views.generic.base import View from django.urls import reverse +from django.views.generic.base import View +from foo.models import FooItem from ska import sign_url from ska.contrib.django.ska.decorators import ( - validate_signed_request, m_validate_signed_request, + validate_signed_request, ) -from ska.contrib.django.ska.settings import SECRET_KEY, PROVIDERS +from ska.contrib.django.ska.settings import PROVIDERS, SECRET_KEY from ska.defaults import DEFAULT_PROVIDER_PARAM -from foo.models import FooItem - def browse_view(request, template_name="foo/browse.html"): """Foo items listing. diff --git a/examples/simple/settings/base.py b/examples/simple/settings/base.py index d064a9b..9dee1ec 100644 --- a/examples/simple/settings/base.py +++ b/examples/simple/settings/base.py @@ -163,7 +163,7 @@ # 'django.contrib.admindocs', # For django-constance "constance", - "constance.backends.database", # Only if ``DatabaseBackend`` is used + # "constance.backends.database", # Only if ``DatabaseBackend`` is used "django_json_widget", # For djangorestframework "rest_framework", @@ -265,56 +265,32 @@ "filters": { "require_debug_false": {"()": "django.utils.log.RequireDebugFalse"} }, + "root": { + "level": "INFO", + "handlers": ["console"], + }, "formatters": { "verbose": { - "format": "%(levelname)s %(asctime)s [%(pathname)s:%(lineno)s] " + "format": "\n%(levelname)s %(asctime)s [%(pathname)s:%(lineno)s] " "%(message)s" }, - "simple": {"format": "%(levelname)s %(message)s"}, }, "handlers": { - "mail_admins": { - "level": "ERROR", - "filters": ["require_debug_false"], - "class": "django.utils.log.AdminEmailHandler", - }, "console": { - "level": "DEBUG", + "level": "INFO", "class": "logging.StreamHandler", "formatter": "verbose", }, - "django_log": { - "level": "DEBUG", - "class": "logging.handlers.RotatingFileHandler", - "filename": PROJECT_DIR("../../logs/django.log"), - "maxBytes": 1048576, - "backupCount": 99, - "formatter": "verbose", - }, - "ska_log": { - "level": "DEBUG", - "class": "logging.handlers.RotatingFileHandler", - "filename": PROJECT_DIR("../../logs/ska.log"), - "maxBytes": 1048576, - "backupCount": 99, - "formatter": "verbose", - }, }, "loggers": { - "django": { - "handlers": ["django_log"], - "level": "ERROR", - "propagate": True, - }, - "ska": { - "handlers": ["console", "ska_log"], + "": { + "handlers": ["console"], "level": "DEBUG", - "propagate": True, + "propagate": False, }, }, } - # Do not put any settings below this line try: from .local_settings import * diff --git a/examples/simple/settings/constance_settings.py b/examples/simple/settings/constance_settings.py index 92b06f5..a7f9534 100644 --- a/examples/simple/settings/constance_settings.py +++ b/examples/simple/settings/constance_settings.py @@ -1,4 +1,5 @@ import json + from .base import * INSTALLED_APPS += ( diff --git a/examples/simple/urls.py b/examples/simple/urls.py index 17bd749..5f8a4e8 100644 --- a/examples/simple/urls.py +++ b/examples/simple/urls.py @@ -1,8 +1,8 @@ from django.conf import settings from django.conf.urls.static import static from django.contrib import admin -from django.urls import include, re_path as url from django.contrib.staticfiles.urls import staticfiles_urlpatterns +from django.urls import include, re_path as url from django.views.generic import TemplateView admin.autodiscover() @@ -31,6 +31,4 @@ if settings.DEBUG: urlpatterns += staticfiles_urlpatterns() - urlpatterns += static( - settings.MEDIA_URL, document_root=settings.MEDIA_ROOT - ) + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/monkeytype_config.py b/monkeytype_config.py index b5e6186..5e09c73 100644 --- a/monkeytype_config.py +++ b/monkeytype_config.py @@ -1,6 +1,6 @@ import os -from contextlib import contextmanager import sys +from contextlib import contextmanager from typing import Iterator from monkeytype.config import DefaultConfig diff --git a/pyproject.toml b/pyproject.toml index 3d9d15d..75f87b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,8 @@ # character. [tool.black] -line-length = 79 -target-version = ['py36', 'py37', 'py38', 'py39'] +line-length = 80 +target-version = ['py37', 'py38', 'py39', 'py310', 'py311'] include = '\.pyi?$' extend-exclude = ''' /( @@ -19,10 +19,78 @@ extend-exclude = ''' )/ ''' - # Build system information below. # NOTE: You don't need this in your own Black configuration. - [build-system] requires = ["setuptools>=41.0", "setuptools-scm", "wheel"] build-backend = "setuptools.build_meta" + +[tool.isort] +profile = "black" +combine_as_imports = true +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +ensure_newline_before_comments = true +line_length = 80 +known_first_party = "faker_file" +known_third_party = ["django", "factory"] +skip = ["wsgi.py",] + +[tool.ruff] +line-length = 80 + +# Enable Pyflakes `E` and `F` codes by default. +select = ["E", "F"] +ignore = [] + +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "venv", + "examples/django_example/project/wsgi.py", +] +per-file-ignores = {} + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +# Assume Python 3.10. +target-version = "py310" + +[tool.pyright] +include = ["src"] +exclude = ["**/node_modules", + "**/__pycache__", + "tmp", + "src/faker_file.egg-info", + "src/faker_file/tests" +] +ignore = ["src/oldstuff"] +defineConstant = { DEBUG = true } +stubPath = "src/stubs" + +reportMissingImports = true +reportMissingTypeStubs = false + +pythonVersion = "3.10" +pythonPlatform = "Linux" +verboseOutput = true diff --git a/pytest.ini b/pytest.ini index c9bc1b8..752b940 100644 --- a/pytest.ini +++ b/pytest.ini @@ -12,7 +12,7 @@ norecursedirs= python_files = test_*.py tests.py -python_paths = +pythonpath = src examples/simple DJANGO_SETTINGS_MODULE=settings.testing diff --git a/scripts/compile_requirements.sh b/scripts/compile_requirements.sh index 23215e2..ada150d 100755 --- a/scripts/compile_requirements.sh +++ b/scripts/compile_requirements.sh @@ -13,18 +13,24 @@ pip-compile deployment.in "$@" echo "pip-compile deployment.in" pip-compile dev.in "$@" -echo "pip-compile django_2_2.in" -pip-compile django_2_2.in "$@" - -echo "pip-compile django_3_0.in" -pip-compile django_3_0.in "$@" - -echo "pip-compile django_3_1.in" -pip-compile django_3_1.in "$@" +#echo "pip-compile django_2_2.in" +#pip-compile django_2_2.in "$@" +# +#echo "pip-compile django_3_0.in" +#pip-compile django_3_0.in "$@" +# +#echo "pip-compile django_3_1.in" +#pip-compile django_3_1.in "$@" echo "pip-compile django_3_2.in" pip-compile django_3_2.in "$@" +echo "pip-compile django_4_1.in" +pip-compile django_4_1.in "$@" + +echo "pip-compile django_4_2.in" +pip-compile django_4_2.in "$@" + echo "pip-compile docs.in" pip-compile docs.in "$@" diff --git a/setup.py b/setup.py index 1ff4f07..9500c11 100644 --- a/setup.py +++ b/setup.py @@ -1,20 +1,13 @@ import os -from setuptools import setup, find_packages + +from setuptools import find_packages, setup try: readme = open(os.path.join(os.path.dirname(__file__), "README.rst")).read() except: readme = "" -version = "1.9.1" - -exec_dirs = [ - "src/ska/bin/", -] - -execs = [] -for exec_dir in exec_dirs: - execs += [os.path.join(exec_dir, f) for f in os.listdir(exec_dir)] +version = "1.10" setup( name="ska", @@ -25,11 +18,11 @@ classifiers=[ "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Security :: Cryptography", "Environment :: Web Environment", "Intended Audience :: Developers", @@ -47,10 +40,6 @@ url="https://github.com/barseghyanartur/ska", package_dir={"": "src"}, packages=find_packages(where="./src"), - include_package_data=True, - package_data={ - "ska": execs, - }, project_urls={ "Bug Tracker": "https://github.com/barseghyanartur/ska/issues", "Documentation": "https://ska.readthedocs.io/", @@ -58,21 +47,21 @@ "Changelog": "https://ska.readthedocs.io/" "en/latest/changelog.html", }, license="GPL-2.0-only OR LGPL-2.1-or-later", - scripts=["src/ska/bin/ska-sign-url"], - install_requires=[ - "django-nine>=0.2.4", - ], + entry_points={ + "console_scripts": ["ska-sign-url = ska.generate_signed_url:main"] + }, + install_requires=[], extras_require={ - "django-constance": ["django-constance"], - "djangorestframework": ["djangorestframework"], - "drf-jwt": ["drf-jwt"], + "django": ["django-nine>=0.2.4"], + "django-constance": ["django-constance", "django-nine>=0.2.4"], + "djangorestframework": ["djangorestframework", "django-nine>=0.2.4"], + "drf-jwt": ["drf-jwt", "django-nine>=0.2.4"], }, tests_require=[ "factory_boy", "faker", "pytest", "pytest-django", - "radar", "mock", "beautifulsoup4", "soupsieve", diff --git a/src/ska/__init__.py b/src/ska/__init__.py index e2450ac..c90d3cd 100644 --- a/src/ska/__init__.py +++ b/src/ska/__init__.py @@ -1,35 +1,35 @@ -from .base import SignatureValidationResult, AbstractSignature +from .base import AbstractSignature, SignatureValidationResult from .defaults import ( - SIGNATURE_LIFETIME, - TIMESTAMP_FORMAT, - DEFAULT_URL_SUFFIX, - DEFAULT_SIGNATURE_PARAM, DEFAULT_AUTH_USER_PARAM, - DEFAULT_VALID_UNTIL_PARAM, DEFAULT_EXTRA_PARAM, + DEFAULT_SIGNATURE_PARAM, + DEFAULT_URL_SUFFIX, + DEFAULT_VALID_UNTIL_PARAM, + SIGNATURE_LIFETIME, + TIMESTAMP_FORMAT, +) +from .shortcuts import ( + extract_signed_request_data, + sign_url, + signature_to_dict, + validate_signed_request_data, ) from .signatures import ( - Signature, HMACMD5Signature, HMACSHA1Signature, HMACSHA224Signature, HMACSHA256Signature, HMACSHA384Signature, HMACSHA512Signature, -) -from .shortcuts import ( - sign_url, - signature_to_dict, - validate_signed_request_data, - extract_signed_request_data, + Signature, ) from .utils import RequestHelper __title__ = "ska" -__version__ = "1.9.1" +__version__ = "1.10" __author__ = "Artur Barseghyan " -__copyright__ = "2013-2021 Artur Barseghyan" -__license__ = "GPL 2.0/LGPL 2.1" +__copyright__ = "2013-2023 Artur Barseghyan" +__license__ = "GPL-2.0-only OR LGPL-2.1-or-later" __all__ = ( "sign_url", "signature_to_dict", diff --git a/src/ska/base.py b/src/ska/base.py index 7a2221d..8934f56 100644 --- a/src/ska/base.py +++ b/src/ska/base.py @@ -1,7 +1,7 @@ +import time from base64 import b64encode from datetime import datetime, timedelta -import time -from typing import Any, Dict, List, Optional, Union, Callable +from typing import Any, Callable, Dict, List, Optional, Union from . import error_codes from .defaults import SIGNATURE_LIFETIME, TIMESTAMP_FORMAT diff --git a/src/ska/contrib/django/ska/backends/base.py b/src/ska/contrib/django/ska/backends/base.py index 2547e7f..4e8c3e1 100644 --- a/src/ska/contrib/django/ska/backends/base.py +++ b/src/ska/contrib/django/ska/backends/base.py @@ -1,23 +1,22 @@ import logging from typing import Dict, Optional, Union -from django.core.exceptions import PermissionDenied from django.contrib.auth.hashers import make_password from django.contrib.auth.models import User +from django.core.exceptions import PermissionDenied from django.db import IntegrityError from django.http import HttpRequest from rest_framework.request import Request from ..... import Signature, extract_signed_request_data -from .....helpers import get_callback_func from .....defaults import ( - DEFAULT_SIGNATURE_PARAM, DEFAULT_AUTH_USER_PARAM, - DEFAULT_VALID_UNTIL_PARAM, DEFAULT_EXTRA_PARAM, + DEFAULT_SIGNATURE_PARAM, + DEFAULT_VALID_UNTIL_PARAM, ) from .....exceptions import ImproperlyConfigured, InvalidData - +from .....helpers import get_callback_func from ..models import Signature as SignatureModel from ..settings import ( DB_PERFORM_SIGNATURE_CHECK, diff --git a/src/ska/contrib/django/ska/backends/constance_backend.py b/src/ska/contrib/django/ska/backends/constance_backend.py index 107e88b..89fe07d 100644 --- a/src/ska/contrib/django/ska/backends/constance_backend.py +++ b/src/ska/contrib/django/ska/backends/constance_backend.py @@ -2,7 +2,6 @@ from typing import Dict, Optional, Union from constance import config - from django.conf import settings from django.http import HttpRequest from rest_framework.request import Request @@ -20,9 +19,7 @@ class SkaAuthenticationConstanceBackend(BaseSkaAuthenticationBackend): def get_settings( self, - request_data: Optional[ - Dict[str, Union[bytes, str, float, int]] - ] = None, + request_data: Optional[Dict[str, Union[bytes, str, float, int]]] = None, request: Optional[Union[Request, HttpRequest]] = None, **kwargs, ) -> Dict[str, Dict[str, str]]: @@ -43,9 +40,7 @@ def get_settings( def get_secret_key( self, - request_data: Optional[ - Dict[str, Union[bytes, str, float, int]] - ] = None, + request_data: Optional[Dict[str, Union[bytes, str, float, int]]] = None, request: Optional[Union[Request, HttpRequest]] = None, **kwargs, ) -> str: diff --git a/src/ska/contrib/django/ska/backends/default_backends.py b/src/ska/contrib/django/ska/backends/default_backends.py index 882c7e4..e3ba705 100644 --- a/src/ska/contrib/django/ska/backends/default_backends.py +++ b/src/ska/contrib/django/ska/backends/default_backends.py @@ -1,4 +1,5 @@ from typing import Any, Dict, Optional, Union + from django.http import HttpRequest from rest_framework.request import Request @@ -15,9 +16,7 @@ class SkaAuthenticationBackend(BaseSkaAuthenticationBackend): def get_settings( self, - request_data: Optional[ - Dict[str, Union[bytes, str, float, int]] - ] = None, + request_data: Optional[Dict[str, Union[bytes, str, float, int]]] = None, request: Optional[Union[Request, HttpRequest]] = None, **kwargs, ) -> Dict[Any, Any]: @@ -29,9 +28,7 @@ def get_settings( def get_secret_key( self, - request_data: Optional[ - Dict[str, Union[bytes, str, float, int]] - ] = None, + request_data: Optional[Dict[str, Union[bytes, str, float, int]]] = None, request: Optional[Union[Request, HttpRequest]] = None, **kwargs, ) -> None: diff --git a/src/ska/contrib/django/ska/decorators.py b/src/ska/contrib/django/ska/decorators.py index 0962188..c9ef801 100644 --- a/src/ska/contrib/django/ska/decorators.py +++ b/src/ska/contrib/django/ska/decorators.py @@ -32,26 +32,25 @@ :param str valid_until_param: Name of the GET param name which would hold the ``valid_until`` value. """ -from typing import Callable, Dict, Union, Optional +from typing import Callable, Dict, Optional, Union from django.http import HttpRequest from django.shortcuts import render from django.utils.translation import gettext, gettext_lazy as _ -from .... import validate_signed_request_data, sign_url as ska_sign_url +from .... import sign_url as ska_sign_url, validate_signed_request_data from ....defaults import ( - SIGNATURE_LIFETIME, - DEFAULT_URL_SUFFIX, - DEFAULT_SIGNATURE_PARAM, DEFAULT_AUTH_USER_PARAM, - DEFAULT_VALID_UNTIL_PARAM, DEFAULT_EXTRA_PARAM, + DEFAULT_SIGNATURE_PARAM, + DEFAULT_URL_SUFFIX, + DEFAULT_VALID_UNTIL_PARAM, + SIGNATURE_LIFETIME, ) - from .http import HttpResponseUnauthorized from .settings import ( - SECRET_KEY, AUTH_USER, + SECRET_KEY, UNAUTHORISED_REQUEST_ERROR_MESSAGE, UNAUTHORISED_REQUEST_ERROR_TEMPLATE, ) diff --git a/src/ska/contrib/django/ska/integration/constance_integration/templatetags/ska_constance_tags.py b/src/ska/contrib/django/ska/integration/constance_integration/templatetags/ska_constance_tags.py index a4652de..58e087b 100644 --- a/src/ska/contrib/django/ska/integration/constance_integration/templatetags/ska_constance_tags.py +++ b/src/ska/contrib/django/ska/integration/constance_integration/templatetags/ska_constance_tags.py @@ -1,11 +1,10 @@ -from typing import Optional, Type, Union, Dict +from typing import Dict, Optional, Type, Union +from constance import config from django import template from django.core.exceptions import ImproperlyConfigured from django.template.context import RequestContext -from constance import config - from ....... import sign_url as ska_sign_url from .......base import AbstractSignature from .......defaults import ( diff --git a/src/ska/contrib/django/ska/integration/drf/permissions/base.py b/src/ska/contrib/django/ska/integration/drf/permissions/base.py index da8b552..8608025 100644 --- a/src/ska/contrib/django/ska/integration/drf/permissions/base.py +++ b/src/ska/contrib/django/ska/integration/drf/permissions/base.py @@ -1,5 +1,5 @@ -from typing import Dict, Optional, Union import logging +from typing import Dict, Optional, Union from django.db.models import Model from rest_framework import permissions @@ -8,16 +8,14 @@ from ....... import validate_signed_request_data from .......defaults import ( - DEFAULT_SIGNATURE_PARAM, DEFAULT_AUTH_USER_PARAM, - DEFAULT_VALID_UNTIL_PARAM, DEFAULT_EXTRA_PARAM, + DEFAULT_SIGNATURE_PARAM, + DEFAULT_VALID_UNTIL_PARAM, ) from .......exceptions import ImproperlyConfigured, InvalidData - from ....utils import get_provider_data - __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" __license__ = "GPL 2.0/LGPL 2.1" diff --git a/src/ska/contrib/django/ska/integration/drf/permissions/constance_permissions.py b/src/ska/contrib/django/ska/integration/drf/permissions/constance_permissions.py index 7d962ad..abaa56f 100644 --- a/src/ska/contrib/django/ska/integration/drf/permissions/constance_permissions.py +++ b/src/ska/contrib/django/ska/integration/drf/permissions/constance_permissions.py @@ -1,15 +1,11 @@ from typing import Dict, Optional, Union from constance import config - from django.db.models import Model from rest_framework.request import Request from rest_framework.viewsets import GenericViewSet -from .base import ( - BaseProviderSignedRequestRequired, - BaseSignedRequestRequired, -) +from .base import BaseProviderSignedRequestRequired, BaseSignedRequestRequired __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" @@ -35,9 +31,7 @@ def get_settings( } -class ConstanceProviderSignedRequestRequired( - BaseProviderSignedRequestRequired -): +class ConstanceProviderSignedRequestRequired(BaseProviderSignedRequestRequired): """Provider signed request required permission.""" def get_settings( diff --git a/src/ska/contrib/django/ska/integration/drf/permissions/default_permissions.py b/src/ska/contrib/django/ska/integration/drf/permissions/default_permissions.py index 250e616..41842d2 100644 --- a/src/ska/contrib/django/ska/integration/drf/permissions/default_permissions.py +++ b/src/ska/contrib/django/ska/integration/drf/permissions/default_permissions.py @@ -4,16 +4,8 @@ from rest_framework.request import Request from rest_framework.viewsets import GenericViewSet -from ....settings import ( - SECRET_KEY, - PROVIDERS, -) - -from .base import ( - BaseProviderSignedRequestRequired, - BaseSignedRequestRequired, -) - +from ....settings import PROVIDERS, SECRET_KEY +from .base import BaseProviderSignedRequestRequired, BaseSignedRequestRequired __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" diff --git a/src/ska/contrib/django/ska/integration/drf/views/jwt_token.py b/src/ska/contrib/django/ska/integration/drf/views/jwt_token.py index 525e5a6..4b99c8f 100644 --- a/src/ska/contrib/django/ska/integration/drf/views/jwt_token.py +++ b/src/ska/contrib/django/ska/integration/drf/views/jwt_token.py @@ -1,11 +1,10 @@ from typing import Optional from django.contrib.auth import authenticate - -from rest_framework.views import APIView +from rest_framework.exceptions import AuthenticationFailed from rest_framework.request import Request from rest_framework.response import Response -from rest_framework.exceptions import AuthenticationFailed +from rest_framework.views import APIView from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER diff --git a/src/ska/contrib/django/ska/templatetags/ska_tags.py b/src/ska/contrib/django/ska/templatetags/ska_tags.py index 2fd48e5..7669546 100644 --- a/src/ska/contrib/django/ska/templatetags/ska_tags.py +++ b/src/ska/contrib/django/ska/templatetags/ska_tags.py @@ -1,4 +1,4 @@ -from typing import Optional, Type, Dict, Union +from typing import Dict, Optional, Type, Union from django import template from django.core.exceptions import ImproperlyConfigured @@ -16,8 +16,7 @@ SIGNATURE_LIFETIME, ) from .....signatures import Signature -from ..settings import SECRET_KEY, PROVIDERS - +from ..settings import PROVIDERS, SECRET_KEY __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" diff --git a/src/ska/contrib/django/ska/tests/helpers.py b/src/ska/contrib/django/ska/tests/helpers.py index e0219f1..2535c73 100644 --- a/src/ska/contrib/django/ska/tests/helpers.py +++ b/src/ska/contrib/django/ska/tests/helpers.py @@ -2,9 +2,8 @@ import os import random -import pytest - import factories +import pytest __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" diff --git a/src/ska/contrib/django/ska/tests/test_constance_authentication_backend.py b/src/ska/contrib/django/ska/tests/test_constance_authentication_backend.py index b731c24..cfe3935 100644 --- a/src/ska/contrib/django/ska/tests/test_constance_authentication_backend.py +++ b/src/ska/contrib/django/ska/tests/test_constance_authentication_backend.py @@ -1,25 +1,20 @@ import datetime import time +import factories +import mock +import pytest from constance import config from constance.test import override_config - from django.core import mail from django.core.management import call_command from django.test import Client, TransactionTestCase, override_settings -import mock - -import pytest - from ska import sign_url -from ska.contrib.django.ska.models import Signature from ska.contrib.django.ska import settings as ska_settings - +from ska.contrib.django.ska.models import Signature from ska.defaults import DEFAULT_PROVIDER_PARAM -import factories - from .helpers import log_info __author__ = "Artur Barseghyan " @@ -353,9 +348,7 @@ def test_06_purge_stored_signatures_data(self): # Manually set valid_until to no longer valid so that we can # test - invalid_until = datetime.datetime.now() - datetime.timedelta( - minutes=20 - ) + invalid_until = datetime.datetime.now() - datetime.timedelta(minutes=20) Signature.objects.update(valid_until=invalid_until) # Call purge command diff --git a/src/ska/contrib/django/ska/tests/test_decorators.py b/src/ska/contrib/django/ska/tests/test_decorators.py index e1875d5..f2876c3 100644 --- a/src/ska/contrib/django/ska/tests/test_decorators.py +++ b/src/ska/contrib/django/ska/tests/test_decorators.py @@ -1,14 +1,8 @@ -from django.test import Client, TransactionTestCase - -import pytest - import factories +import pytest +from django.test import Client, TransactionTestCase -from .helpers import ( - generate_data, - log_info, - NUM_ITEMS, -) +from .helpers import NUM_ITEMS, generate_data, log_info __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" diff --git a/src/ska/contrib/django/ska/tests/test_default_authentication_backend.py b/src/ska/contrib/django/ska/tests/test_default_authentication_backend.py index 2c834d8..c12907d 100644 --- a/src/ska/contrib/django/ska/tests/test_default_authentication_backend.py +++ b/src/ska/contrib/django/ska/tests/test_default_authentication_backend.py @@ -2,21 +2,18 @@ import logging import time +import factories +import mock +import pytest from django.core import mail from django.core.management import call_command from django.test import Client, TransactionTestCase, override_settings -import mock - -import pytest - from ska import sign_url -from ska.contrib.django.ska.models import Signature from ska.contrib.django.ska import settings as ska_settings +from ska.contrib.django.ska.models import Signature from ska.defaults import DEFAULT_PROVIDER_PARAM -import factories - from .helpers import log_info __author__ = "Artur Barseghyan " @@ -291,9 +288,7 @@ def test_06_purge_stored_signatures_data(self): # Manually set valid_until to no longer valid so that we can # test - invalid_until = datetime.datetime.now() - datetime.timedelta( - minutes=20 - ) + invalid_until = datetime.datetime.now() - datetime.timedelta(minutes=20) Signature.objects.update(valid_until=invalid_until) # Call purge command diff --git a/src/ska/contrib/django/ska/tests/test_drf_integration_permissions.py b/src/ska/contrib/django/ska/tests/test_drf_integration_permissions.py index 982cd7c..d80aa85 100644 --- a/src/ska/contrib/django/ska/tests/test_drf_integration_permissions.py +++ b/src/ska/contrib/django/ska/tests/test_drf_integration_permissions.py @@ -4,19 +4,18 @@ import logging +import factories +import pytest from constance import config from django.test import TransactionTestCase, override_settings from django.urls import reverse -import pytest from rest_framework import status from rest_framework.test import APIClient from ska import sign_url -from ska.contrib.django.ska.settings import SECRET_KEY, PROVIDERS +from ska.contrib.django.ska.settings import PROVIDERS, SECRET_KEY from ska.defaults import DEFAULT_PROVIDER_PARAM -import factories - __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" __license__ = "GPL 2.0/LGPL 2.1" @@ -168,9 +167,7 @@ def test_permissions_provider_detail_request_not_signed_fail(self): :return: """ - self._test_permissions_request_not_signed_fail( - self.provider_detail_url - ) + self._test_permissions_request_not_signed_fail(self.provider_detail_url) def test_permissions_list_request_not_signed_fail(self): """Fail test permissions list request not signed. diff --git a/src/ska/contrib/django/ska/tests/test_drf_integration_view_jwt_token.py b/src/ska/contrib/django/ska/tests/test_drf_integration_view_jwt_token.py index 49df776..bc16ff0 100644 --- a/src/ska/contrib/django/ska/tests/test_drf_integration_view_jwt_token.py +++ b/src/ska/contrib/django/ska/tests/test_drf_integration_view_jwt_token.py @@ -5,20 +5,18 @@ import logging import unittest +import factories +import pytest from constance import config -from django.urls import reverse from django.test import TransactionTestCase, override_settings - -import pytest +from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient from ska import sign_url -from ska.contrib.django.ska.settings import SECRET_KEY, PROVIDERS +from ska.contrib.django.ska.settings import PROVIDERS, SECRET_KEY from ska.defaults import DEFAULT_PROVIDER_PARAM -import factories - __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" __license__ = "GPL 2.0/LGPL 2.1" diff --git a/src/ska/contrib/django/ska/tests/test_templatetags.py b/src/ska/contrib/django/ska/tests/test_templatetags.py index f5b17c4..91f20b2 100644 --- a/src/ska/contrib/django/ska/tests/test_templatetags.py +++ b/src/ska/contrib/django/ska/tests/test_templatetags.py @@ -1,10 +1,8 @@ +import factories from bs4 import BeautifulSoup - from django.test import Client, TransactionTestCase, override_settings from django.urls import reverse -import factories - from .helpers import log_info __author__ = "Artur Barseghyan " diff --git a/src/ska/contrib/django/ska/views/constance_views.py b/src/ska/contrib/django/ska/views/constance_views.py index 9ccdaae..c8d483a 100644 --- a/src/ska/contrib/django/ska/views/constance_views.py +++ b/src/ska/contrib/django/ska/views/constance_views.py @@ -1,5 +1,4 @@ from constance import config - from django.contrib import messages from django.contrib.auth import authenticate, login as auth_login from django.http import HttpResponseForbidden, HttpResponseRedirect diff --git a/src/ska/generate_signed_url.py b/src/ska/generate_signed_url.py index 411db86..26da235 100644 --- a/src/ska/generate_signed_url.py +++ b/src/ska/generate_signed_url.py @@ -3,7 +3,7 @@ from .shortcuts import sign_url __author__ = "Artur Barseghyan " -__copyright__ = "2013-2021 Artur Barseghyan" +__copyright__ = "2013-2023 Artur Barseghyan" __license__ = "GPL 2.0/LGPL 2.1" __all__ = ("main",) @@ -13,11 +13,19 @@ def main(): :example: - python src/ska/generate_signature.py -au user -sk test + python src/ska/generate_signature.py -u http://example.com -au user -sk test + + :example: + + ska-sign-url -u http://example.com -au user -sk test """ parser = argparse.ArgumentParser( description=""" Generates signed URL. + + Example: + + ska-sign-url -u http://example.com -au user -sk test """ ) @@ -125,7 +133,3 @@ def main(): print(signed_url) except Exception as err: print(err) - - -if __name__ == "__main__": - main() diff --git a/src/ska/helpers.py b/src/ska/helpers.py index a017ad1..8ebbaad 100644 --- a/src/ska/helpers.py +++ b/src/ska/helpers.py @@ -1,8 +1,8 @@ -from datetime import datetime, timedelta -from importlib import import_module import json import time -from typing import Callable, Dict, List, Tuple, Union, Optional +from datetime import datetime, timedelta +from importlib import import_module +from typing import Callable, Dict, List, Optional, Tuple, Union from urllib.parse import quote from .defaults import SIGNATURE_LIFETIME diff --git a/src/ska/shortcuts.py b/src/ska/shortcuts.py index a918a50..00bff3e 100644 --- a/src/ska/shortcuts.py +++ b/src/ska/shortcuts.py @@ -1,6 +1,6 @@ -from typing import Dict, Optional, Type, Union, Callable +from typing import Callable, Dict, Optional, Type, Union -from .base import SignatureValidationResult, AbstractSignature +from .base import AbstractSignature, SignatureValidationResult from .defaults import ( DEFAULT_AUTH_USER_PARAM, DEFAULT_EXTRA_PARAM, diff --git a/src/ska/signatures/hmac_md5.py b/src/ska/signatures/hmac_md5.py index a8b379c..0d7baeb 100644 --- a/src/ska/signatures/hmac_md5.py +++ b/src/ska/signatures/hmac_md5.py @@ -1,6 +1,6 @@ import hashlib import hmac -from typing import Union, Optional, Dict, Callable +from typing import Callable, Dict, Optional, Union from ..base import AbstractSignature diff --git a/src/ska/signatures/hmac_sha1.py b/src/ska/signatures/hmac_sha1.py index 6cefd70..d2b436e 100644 --- a/src/ska/signatures/hmac_sha1.py +++ b/src/ska/signatures/hmac_sha1.py @@ -1,6 +1,6 @@ import hashlib import hmac -from typing import Union, Optional, Dict, Callable +from typing import Callable, Dict, Optional, Union from ..base import AbstractSignature diff --git a/src/ska/signatures/hmac_sha224.py b/src/ska/signatures/hmac_sha224.py index 0514784..2f53bd6 100644 --- a/src/ska/signatures/hmac_sha224.py +++ b/src/ska/signatures/hmac_sha224.py @@ -1,6 +1,6 @@ import hashlib import hmac -from typing import Union, Optional, Dict, Callable +from typing import Callable, Dict, Optional, Union from ..base import AbstractSignature diff --git a/src/ska/signatures/hmac_sha256.py b/src/ska/signatures/hmac_sha256.py index c8d79ab..550ebf9 100644 --- a/src/ska/signatures/hmac_sha256.py +++ b/src/ska/signatures/hmac_sha256.py @@ -1,6 +1,6 @@ import hashlib import hmac -from typing import Union, Optional, Dict, Callable +from typing import Callable, Dict, Optional, Union from ..base import AbstractSignature diff --git a/src/ska/signatures/hmac_sha384.py b/src/ska/signatures/hmac_sha384.py index d8598aa..f02d6e0 100644 --- a/src/ska/signatures/hmac_sha384.py +++ b/src/ska/signatures/hmac_sha384.py @@ -1,6 +1,6 @@ import hashlib import hmac -from typing import Union, Optional, Dict, Callable +from typing import Callable, Dict, Optional, Union from ..base import AbstractSignature diff --git a/src/ska/signatures/hmac_sha512.py b/src/ska/signatures/hmac_sha512.py index 9eac0bd..8093847 100644 --- a/src/ska/signatures/hmac_sha512.py +++ b/src/ska/signatures/hmac_sha512.py @@ -1,6 +1,6 @@ import hashlib import hmac -from typing import Union, Optional, Dict, Callable +from typing import Callable, Dict, Optional, Union from ..base import AbstractSignature diff --git a/src/ska/tests/base.py b/src/ska/tests/base.py index 3fe7ca1..8c757ee 100644 --- a/src/ska/tests/base.py +++ b/src/ska/tests/base.py @@ -1,6 +1,6 @@ import datetime import logging -from urllib.parse import urlparse, parse_qs +from urllib.parse import parse_qs, urlparse from .. import TIMESTAMP_FORMAT diff --git a/src/ska/tests/test_commands.py b/src/ska/tests/test_commands.py index 0f56ba7..3a102c4 100644 --- a/src/ska/tests/test_commands.py +++ b/src/ska/tests/test_commands.py @@ -1,7 +1,6 @@ -import unittest - import shlex import subprocess +import unittest from urllib import parse from ..shortcuts import validate_signed_request_data diff --git a/src/ska/tests/test_core.py b/src/ska/tests/test_core.py index 059d241..3cc81ff 100644 --- a/src/ska/tests/test_core.py +++ b/src/ska/tests/test_core.py @@ -1,25 +1,23 @@ -from copy import copy import datetime -from decimal import Decimal import unittest +from copy import copy +from decimal import Decimal from .. import ( - Signature, - RequestHelper, HMACMD5Signature, HMACSHA1Signature, HMACSHA224Signature, HMACSHA256Signature, HMACSHA384Signature, HMACSHA512Signature, -) -from .. import ( + RequestHelper, + Signature, + error_codes, sign_url, - validate_signed_request_data, signature_to_dict, - error_codes, + validate_signed_request_data, ) -from .base import log_info, timestamp_to_human_readable, parse_url_params +from .base import log_info, parse_url_params, timestamp_to_human_readable __title__ = "ska.tests.test_core" __author__ = "Artur Barseghyan " @@ -300,9 +298,7 @@ def __test_05_fail_signature_test_validation_result_class( self.assertIsInstance(validation_result.errors, list) self.assertIsInstance(validation_result.message, str) self.assertIsInstance(" ".join(validation_result.reason), str) - self.assertIsInstance( - " ".join(map(str, validation_result.errors)), str - ) + self.assertIsInstance(" ".join(map(str, validation_result.errors)), str) flow.append(validation_result.message) @@ -382,9 +378,7 @@ def test_01_signature_to_url(self): """Signature test.""" flow = [] for signature_cls in self.signature_classes: - flow += self.__test_01_signature_to_url( - signature_cls=signature_cls - ) + flow += self.__test_01_signature_to_url(signature_cls=signature_cls) return flow @log_info diff --git a/src/ska/tests/test_integration.py b/src/ska/tests/test_integration.py index 956b6b0..fa8490c 100644 --- a/src/ska/tests/test_integration.py +++ b/src/ska/tests/test_integration.py @@ -1,18 +1,16 @@ import unittest -from .. import Signature, HMACSHA256Signature, HMACSHA512Signature +from .. import HMACSHA256Signature, HMACSHA512Signature, Signature from ..helpers import ( - sorted_urlencode, javascript_quoter, javascript_value_dumper, + sorted_urlencode, ) __author__ = "Artur Barseghyan " __copyright__ = "2013-2021 Artur Barseghyan" __license__ = "GPL 2.0/LGPL 2.1" -__all__ = ( - "IntegrationTest", -) +__all__ = ("IntegrationTest",) SECRET_KEY = "UxuhnPaO4vKA" @@ -52,19 +50,13 @@ def test_get_base(self, signature_cls=Signature): """ # Test case 1 - base1 = signature_cls.get_base( - AUTH_USER, - VALID_UNTIL, - {} - ) + base1 = signature_cls.get_base(AUTH_USER, VALID_UNTIL, {}) expected_base1 = b"1628717009.0_me@example.com" self.assertEqual(base1, expected_base1) # Test case 2 base2 = signature_cls.get_base( - AUTH_USER, - VALID_UNTIL, - {"one": "1", "two": "2"} + AUTH_USER, VALID_UNTIL, {"one": "1", "two": "2"} ) expected_base2 = b"1628717009.0_me@example.com_one%3D1%26two%3D2" self.assertEqual(base2, expected_base2) @@ -75,7 +67,7 @@ def test_get_base(self, signature_cls=Signature): VALID_UNTIL, {"one": "â"}, value_dumper=javascript_value_dumper, - quoter=javascript_quoter + quoter=javascript_quoter, ) expected_base3 = b"1628717009.0_me@example.com_one%3D%C3%A2" self.assertEqual(base3, expected_base3) @@ -86,7 +78,7 @@ def test_get_base(self, signature_cls=Signature): VALID_UNTIL, {"one": {"value": "â"}}, value_dumper=javascript_value_dumper, - quoter=javascript_quoter + quoter=javascript_quoter, ) expected_base4 = b"1628717009.0_me@example.com_one%3D%7B%22value%22%3A%22%5Cu00e2%22%7D" self.assertEqual(base4, expected_base4) diff --git a/src/ska/utils.py b/src/ska/utils.py index d673954..4d3718a 100644 --- a/src/ska/utils.py +++ b/src/ska/utils.py @@ -1,15 +1,15 @@ -from typing import Dict, Optional, Union, Type, Callable +from typing import Callable, Dict, Optional, Type, Union from urllib.parse import urlencode from .base import AbstractSignature, SignatureValidationResult from .defaults import ( - DEFAULT_URL_SUFFIX, + DEFAULT_AUTH_USER_PARAM, DEFAULT_EXTRA_PARAM, DEFAULT_SIGNATURE_PARAM, - DEFAULT_AUTH_USER_PARAM, + DEFAULT_URL_SUFFIX, DEFAULT_VALID_UNTIL_PARAM, ) -from .exceptions import InvalidData, ImproperlyConfigured +from .exceptions import ImproperlyConfigured, InvalidData from .helpers import dict_keys, extract_signed_data as extract_signed_data from .signatures import Signature diff --git a/tox.ini b/tox.ini index e8be749..7826f7a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,18 @@ [tox] envlist = - py{36,37,38,39,310}-django{22,30,31,32} +; py{36,37,38,39,310}-django{22,30,31,32} + py{38,39,310,311}-django{32,41,42} [testenv] envlogdir = examples/logs/ examples/db/ - passenv = * - +allowlist_externals=* deps = - django22: -r{toxinidir}/examples/requirements/django_2_2.txt - django30: -r{toxinidir}/examples/requirements/django_3_0.txt - django31: -r{toxinidir}/examples/requirements/django_3_1.txt django32: -r{toxinidir}/examples/requirements/django_3_2.txt - + django31: -r{toxinidir}/examples/requirements/django_4_1.txt + django42: -r{toxinidir}/examples/requirements/django_4_2.txt commands = coverage erase pip install -e . @@ -22,3 +20,10 @@ commands = ; pip install -r src/ska/contrib/django/ska/requirements.txt ; {envpython} example/example/manage.py syncdb --noinput --traceback -v 3 ; {envpython} example/example/manage.py test ska --traceback -v 3 + +[gh-actions] +python = + 3.8: py38 + 3.9: py39 + 3.10: py310 + 3.11: py311 From e426ebd376eb5a87282a92181ef3e73918333a89 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 00:55:31 +0200 Subject: [PATCH 03/11] Fixing django 3.2 compat --- examples/simple/factories/constance_constance.py | 6 +++++- examples/simple/settings/base.py | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/simple/factories/constance_constance.py b/examples/simple/factories/constance_constance.py index ebedfd6..ca24680 100644 --- a/examples/simple/factories/constance_constance.py +++ b/examples/simple/factories/constance_constance.py @@ -1,10 +1,14 @@ import json -from constance.models import Constance from factory.django import DjangoModelFactory from .factory_faker import Faker +try: + from constance.models import Constance # noqa +except ImportError: + from constance.backends.database.models import Constance # noqa + __all__ = ( "ConstanceFactory", "SkaProvidersConstanceFactory", diff --git a/examples/simple/settings/base.py b/examples/simple/settings/base.py index 9dee1ec..721fd5a 100644 --- a/examples/simple/settings/base.py +++ b/examples/simple/settings/base.py @@ -2,6 +2,8 @@ import os import sys +from django_nine import versions + from .core import PROJECT_DIR DEBUG = False @@ -174,6 +176,11 @@ "foo", # Our example app ) +if versions.DJANGO_GTE_3_2: + INSTALLED_APPS += ( + "constance.backends.database", + ) # Only if ``DatabaseBackend`` is used + # *************************************************************************** # ************************** ska config ************************************* # *************************************************************************** From 51279ed12e1381bb07a11246a0ccff9af03e24f8 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 01:01:16 +0200 Subject: [PATCH 04/11] Fixes --- examples/requirements/dev.txt | 6 ++++-- examples/requirements/django_3_2.in | 1 + examples/requirements/django_3_2.txt | 6 ++++-- examples/requirements/django_4_1.in | 1 + examples/requirements/django_4_1.txt | 6 ++++-- examples/requirements/django_4_2.in | 2 +- examples/requirements/django_4_2.txt | 6 ++++-- examples/requirements/documentation.txt | 4 ++++ examples/requirements/testing.txt | 4 ++++ 9 files changed, 27 insertions(+), 9 deletions(-) diff --git a/examples/requirements/dev.txt b/examples/requirements/dev.txt index 9c724f6..8da2b3d 100644 --- a/examples/requirements/dev.txt +++ b/examples/requirements/dev.txt @@ -76,6 +76,7 @@ distlib==0.3.7 django==4.2.4 # via # -r django_4_2.in + # django-nine # django-picklefield # djangorestframework # drf-jwt @@ -83,6 +84,8 @@ django-constance==3.1.0 # via -r constance_django_4_2.in django-json-widget==1.1.1 # via -r constance_django_4_2.in +django-nine==0.2.7 + # via -r django_4_2.in django-picklefield==3.1 # via # -r constance_django_4_2.in @@ -192,6 +195,7 @@ packaging==23.1 # via # black # build + # django-nine # pyproject-api # pytest # sphinx @@ -278,8 +282,6 @@ pyyaml==6.0.1 # via # libcst # pre-commit -radar==0.3 - # via -r test.in readme-renderer==36.0 # via # restview diff --git a/examples/requirements/django_3_2.in b/examples/requirements/django_3_2.in index 5985aa2..b44d902 100755 --- a/examples/requirements/django_3_2.in +++ b/examples/requirements/django_3_2.in @@ -4,3 +4,4 @@ -r rest_framework_django_3_2.in Django>=3.2,<4.0 +django-nine diff --git a/examples/requirements/django_3_2.txt b/examples/requirements/django_3_2.txt index f54358c..35d4228 100644 --- a/examples/requirements/django_3_2.txt +++ b/examples/requirements/django_3_2.txt @@ -33,6 +33,7 @@ distlib==0.3.7 django==3.2.20 # via # -r django_3_2.in + # django-nine # django-picklefield # djangorestframework # drf-jwt @@ -40,6 +41,8 @@ django-constance==2.8.0 # via -r constance_django_3_2.in django-json-widget==1.1.1 # via -r constance_django_3_2.in +django-nine==0.2.7 + # via -r django_3_2.in django-picklefield==3.0.1 # via -r constance_django_3_2.in djangorestframework==3.12.4 @@ -85,6 +88,7 @@ outcome==1.2.0 # via trio packaging==23.1 # via + # django-nine # pyproject-api # pytest # tox @@ -127,8 +131,6 @@ pytz==2023.3 # via django pyyaml==6.0.1 # via libcst -radar==0.3 - # via -r test.in redis==3.0.1 # via -r constance_django_3_2.in selenium==4.11.2 diff --git a/examples/requirements/django_4_1.in b/examples/requirements/django_4_1.in index bd9f20d..498d853 100755 --- a/examples/requirements/django_4_1.in +++ b/examples/requirements/django_4_1.in @@ -4,3 +4,4 @@ -r rest_framework_django_4_1.in Django>=4.1,<4.2 +django-nine diff --git a/examples/requirements/django_4_1.txt b/examples/requirements/django_4_1.txt index 43555dc..bb4d000 100644 --- a/examples/requirements/django_4_1.txt +++ b/examples/requirements/django_4_1.txt @@ -33,6 +33,7 @@ distlib==0.3.7 django==4.1.10 # via # -r django_4_1.in + # django-nine # django-picklefield # djangorestframework # drf-jwt @@ -40,6 +41,8 @@ django-constance==2.8.0 # via -r constance_django_4_1.in django-json-widget==1.1.1 # via -r constance_django_4_1.in +django-nine==0.2.7 + # via -r django_4_1.in django-picklefield==3.0.1 # via -r constance_django_4_1.in djangorestframework==3.12.4 @@ -85,6 +88,7 @@ outcome==1.2.0 # via trio packaging==23.1 # via + # django-nine # pyproject-api # pytest # tox @@ -125,8 +129,6 @@ python-dateutil==2.8.2 # via faker pyyaml==6.0.1 # via libcst -radar==0.3 - # via -r test.in redis==3.0.1 # via -r constance_django_4_1.in selenium==4.11.2 diff --git a/examples/requirements/django_4_2.in b/examples/requirements/django_4_2.in index a051f01..10bb05f 100755 --- a/examples/requirements/django_4_2.in +++ b/examples/requirements/django_4_2.in @@ -4,4 +4,4 @@ -r rest_framework_django_4_2.in Django>=4.2,<5.0 - +django-nine diff --git a/examples/requirements/django_4_2.txt b/examples/requirements/django_4_2.txt index eba02f2..7bf87e1 100644 --- a/examples/requirements/django_4_2.txt +++ b/examples/requirements/django_4_2.txt @@ -35,6 +35,7 @@ distlib==0.3.7 django==4.2.4 # via # -r django_4_2.in + # django-nine # django-picklefield # djangorestframework # drf-jwt @@ -42,6 +43,8 @@ django-constance==3.1.0 # via -r constance_django_4_2.in django-json-widget==1.1.1 # via -r constance_django_4_2.in +django-nine==0.2.7 + # via -r django_4_2.in django-picklefield==3.1 # via # -r constance_django_4_2.in @@ -89,6 +92,7 @@ outcome==1.2.0 # via trio packaging==23.1 # via + # django-nine # pyproject-api # pytest # tox @@ -131,8 +135,6 @@ pytz==2023.3 # via djangorestframework pyyaml==6.0.1 # via libcst -radar==0.3 - # via -r test.in redis==5.0.0 # via -r constance_django_4_2.in selenium==4.11.2 diff --git a/examples/requirements/documentation.txt b/examples/requirements/documentation.txt index 3bb382d..4382e21 100644 --- a/examples/requirements/documentation.txt +++ b/examples/requirements/documentation.txt @@ -49,6 +49,7 @@ distlib==0.3.7 django==4.2.4 # via # -r django_4_2.in + # django-nine # django-picklefield # djangorestframework # drf-jwt @@ -56,6 +57,8 @@ django-constance==3.1.0 # via -r constance_django_4_2.in django-json-widget==1.1.1 # via -r constance_django_4_2.in +django-nine==0.2.7 + # via -r django_4_2.in django-picklefield==3.1 # via # -r constance_django_4_2.in @@ -120,6 +123,7 @@ outcome==1.2.0 # via trio packaging==23.1 # via + # django-nine # pyproject-api # pytest # sphinx diff --git a/examples/requirements/testing.txt b/examples/requirements/testing.txt index 7f5e276..f7924d3 100644 --- a/examples/requirements/testing.txt +++ b/examples/requirements/testing.txt @@ -51,6 +51,7 @@ distlib==0.3.7 django==4.2.4 # via # -r django_4_2.in + # django-nine # django-picklefield # djangorestframework # drf-jwt @@ -58,6 +59,8 @@ django-constance==3.1.0 # via -r constance_django_4_2.in django-json-widget==1.1.1 # via -r constance_django_4_2.in +django-nine==0.2.7 + # via -r django_4_2.in django-picklefield==3.1 # via # -r constance_django_4_2.in @@ -128,6 +131,7 @@ packaging==23.1 # via # black # build + # django-nine # pyproject-api # pytest # tox From 18641d96c0ff6f2eb3dc9b8bfeff5cc6e96e7dcf Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 01:13:38 +0200 Subject: [PATCH 05/11] Fixes --- .github/workflows/test.yml | 74 ++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7244944..807c459 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,54 +7,11 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false max-parallel: 4 matrix: include: - - python-version: '3.6' - requirements: django_2_2 - tox_env: py36-django22 - - python-version: '3.7' - requirements: django_2_2 - tox_env: py37-django22 - - python-version: '3.8' - requirements: django_2_2 - tox_env: py38-django22 - - python-version: '3.9' - requirements: django_2_2 - tox_env: py39-django22 - - - python-version: '3.6' - requirements: django_3_0 - tox_env: py36-django30 - - python-version: '3.7' - requirements: django_3_0 - tox_env: py37-django30 - - python-version: '3.8' - requirements: django_3_0 - tox_env: py38-django30 - - python-version: '3.9' - requirements: django_3_0 - tox_env: py39-django30 - - python-version: '3.6' - requirements: django_3_1 - tox_env: py36-django31 - - python-version: '3.7' - requirements: django_3_1 - tox_env: py37-django31 - - python-version: '3.8' - requirements: django_3_1 - tox_env: py38-django31 - - python-version: '3.9' - requirements: django_3_1 - tox_env: py39-django31 - - - python-version: '3.6' - requirements: django_3_2 - tox_env: py36-django32 - - python-version: '3.7' - requirements: django_3_2 - tox_env: py37-django32 - python-version: '3.8' requirements: django_3_2 tox_env: py38-django32 @@ -64,6 +21,35 @@ jobs: - python-version: '3.10' requirements: django_3_2 tox_env: py310-django32 + - python-version: '3.11`' + requirements: django_3_2 + tox_env: py311-django32 + + - python-version: '3.8' + requirements: django_4_1 + tox_env: py38-django41 + - python-version: '3.9' + requirements: django_4_1 + tox_env: py39-django41 + - python-version: '3.10' + requirements: django_4_1 + tox_env: py310-django41 + - python-version: '3.11' + requirements: django_4_1 + tox_env: py311-django41 + + - python-version: '3.8' + requirements: django_4_2 + tox_env: py38-django42 + - python-version: '3.9' + requirements: django_4_2 + tox_env: py39-django42 + - python-version: '3.10' + requirements: django_4_2 + tox_env: py310-django42 + - python-version: '3.11' + requirements: django_4_2 + tox_env: py311-django42 steps: - uses: actions/checkout@v2 From 4497c99d235a82292d86b9741fa91a3b9887365c Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 01:16:26 +0200 Subject: [PATCH 06/11] Fixes --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 807c459..ed98a58 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: - python-version: '3.10' requirements: django_3_2 tox_env: py310-django32 - - python-version: '3.11`' + - python-version: '3.11' requirements: django_3_2 tox_env: py311-django32 From 4897216bc5ea6f5ffcf03f51960f8ba271c92561 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 01:39:15 +0200 Subject: [PATCH 07/11] Fixes --- examples/requirements/dev.txt | 4 +++- examples/requirements/django_3_2.in | 1 + examples/requirements/django_3_2.txt | 4 +++- examples/requirements/django_4_1.in | 1 + examples/requirements/django_4_1.txt | 2 ++ examples/requirements/django_4_2.in | 1 + examples/requirements/django_4_2.txt | 4 +++- examples/requirements/documentation.txt | 4 +++- examples/requirements/testing.txt | 4 +++- 9 files changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/requirements/dev.txt b/examples/requirements/dev.txt index 8da2b3d..3f208bd 100644 --- a/examples/requirements/dev.txt +++ b/examples/requirements/dev.txt @@ -277,7 +277,9 @@ pytest-ordering==0.6 python-dateutil==2.8.2 # via faker pytz==2023.3 - # via djangorestframework + # via + # -r django_4_2.in + # djangorestframework pyyaml==6.0.1 # via # libcst diff --git a/examples/requirements/django_3_2.in b/examples/requirements/django_3_2.in index b44d902..01298d3 100755 --- a/examples/requirements/django_3_2.in +++ b/examples/requirements/django_3_2.in @@ -5,3 +5,4 @@ Django>=3.2,<4.0 django-nine +pytz diff --git a/examples/requirements/django_3_2.txt b/examples/requirements/django_3_2.txt index 35d4228..29b5f39 100644 --- a/examples/requirements/django_3_2.txt +++ b/examples/requirements/django_3_2.txt @@ -128,7 +128,9 @@ pytest-ordering==0.6 python-dateutil==2.8.2 # via faker pytz==2023.3 - # via django + # via + # -r django_3_2.in + # django pyyaml==6.0.1 # via libcst redis==3.0.1 diff --git a/examples/requirements/django_4_1.in b/examples/requirements/django_4_1.in index 498d853..b63339d 100755 --- a/examples/requirements/django_4_1.in +++ b/examples/requirements/django_4_1.in @@ -5,3 +5,4 @@ Django>=4.1,<4.2 django-nine +pytz diff --git a/examples/requirements/django_4_1.txt b/examples/requirements/django_4_1.txt index bb4d000..3b39071 100644 --- a/examples/requirements/django_4_1.txt +++ b/examples/requirements/django_4_1.txt @@ -127,6 +127,8 @@ pytest-ordering==0.6 # via -r test.in python-dateutil==2.8.2 # via faker +pytz==2023.3 + # via -r django_4_1.in pyyaml==6.0.1 # via libcst redis==3.0.1 diff --git a/examples/requirements/django_4_2.in b/examples/requirements/django_4_2.in index 10bb05f..c56e7c7 100755 --- a/examples/requirements/django_4_2.in +++ b/examples/requirements/django_4_2.in @@ -5,3 +5,4 @@ Django>=4.2,<5.0 django-nine +pytz diff --git a/examples/requirements/django_4_2.txt b/examples/requirements/django_4_2.txt index 7bf87e1..b14cbd4 100644 --- a/examples/requirements/django_4_2.txt +++ b/examples/requirements/django_4_2.txt @@ -132,7 +132,9 @@ pytest-ordering==0.6 python-dateutil==2.8.2 # via faker pytz==2023.3 - # via djangorestframework + # via + # -r django_4_2.in + # djangorestframework pyyaml==6.0.1 # via libcst redis==5.0.0 diff --git a/examples/requirements/documentation.txt b/examples/requirements/documentation.txt index 4382e21..f5a064a 100644 --- a/examples/requirements/documentation.txt +++ b/examples/requirements/documentation.txt @@ -170,7 +170,9 @@ pytest-ordering==0.6 python-dateutil==2.8.2 # via faker pytz==2023.3 - # via djangorestframework + # via + # -r django_4_2.in + # djangorestframework pyyaml==6.0.1 # via libcst redis==5.0.0 diff --git a/examples/requirements/testing.txt b/examples/requirements/testing.txt index f7924d3..4a86c6a 100644 --- a/examples/requirements/testing.txt +++ b/examples/requirements/testing.txt @@ -191,7 +191,9 @@ pytest-ordering==0.6 python-dateutil==2.8.2 # via faker pytz==2023.3 - # via djangorestframework + # via + # -r django_4_2.in + # djangorestframework pyyaml==6.0.1 # via # libcst From c5713ff8318db8690c9c663b9299529de1fda6c1 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sat, 26 Aug 2023 23:27:34 +0200 Subject: [PATCH 08/11] Fix reqs --- examples/requirements/constance_django_4_1.in | 9 ++++----- examples/requirements/django_4_1.txt | 14 +++++++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/requirements/constance_django_4_1.in b/examples/requirements/constance_django_4_1.in index 5f08566..bf544fb 100644 --- a/examples/requirements/constance_django_4_1.in +++ b/examples/requirements/constance_django_4_1.in @@ -1,5 +1,4 @@ -django-constance==2.8.0 -django-json-widget==1.1.1 -django-picklefield==3.0.1 -#jsonfield2==3.0.1 -redis==3.0.1 +django-constance +django-json-widget +django-picklefield +redis diff --git a/examples/requirements/django_4_1.txt b/examples/requirements/django_4_1.txt index 3b39071..8f3b2e0 100644 --- a/examples/requirements/django_4_1.txt +++ b/examples/requirements/django_4_1.txt @@ -6,6 +6,8 @@ # asgiref==3.7.2 # via django +async-timeout==4.0.3 + # via redis attrs==23.1.0 # via # outcome @@ -37,14 +39,16 @@ django==4.1.10 # django-picklefield # djangorestframework # drf-jwt -django-constance==2.8.0 +django-constance==3.1.0 # via -r constance_django_4_1.in django-json-widget==1.1.1 # via -r constance_django_4_1.in django-nine==0.2.7 # via -r django_4_1.in -django-picklefield==3.0.1 - # via -r constance_django_4_1.in +django-picklefield==3.1 + # via + # -r constance_django_4_1.in + # django-constance djangorestframework==3.12.4 # via # -r rest_framework_django_4_1.in @@ -96,7 +100,7 @@ platformdirs==3.10.0 # via # tox # virtualenv -pluggy==1.2.0 +pluggy==1.3.0 # via # pytest # tox @@ -131,7 +135,7 @@ pytz==2023.3 # via -r django_4_1.in pyyaml==6.0.1 # via libcst -redis==3.0.1 +redis==5.0.0 # via -r constance_django_4_1.in selenium==4.11.2 # via -r test.in From ce9a82bd5c109e047f6ecc79124f6c4cabad0e80 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sun, 27 Aug 2023 00:53:26 +0200 Subject: [PATCH 09/11] Up docs --- docs/changelog.rst | 370 +------- docs/documentation.rst | 13 + docs/documentation.rst.distrib | 18 - docs/index.rst | 1478 +------------------------------- docs/index.rst.distrib | 2 + docs/package.rst | 15 + scripts/build_docs.sh | 5 - scripts/clean_up.sh | 2 +- scripts/prepare_docs.sh | 3 - scripts/rebuild_docs.sh | 6 +- 10 files changed, 36 insertions(+), 1876 deletions(-) create mode 100644 docs/documentation.rst delete mode 100644 docs/documentation.rst.distrib create mode 100644 docs/index.rst.distrib create mode 100644 docs/package.rst delete mode 100755 scripts/prepare_docs.sh diff --git a/docs/changelog.rst b/docs/changelog.rst index e66f3cc..565b052 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,369 +1 @@ -Release history and notes -========================= -`Sequence based identifiers -`_ -are used for versioning (schema follows below): - -.. code-block:: none - - major.minor[.revision] - -- It's always safe to upgrade within the same minor version (for example, from - 0.3 to 0.3.4). -- Minor version changes might be backwards incompatible. Read the - release notes carefully before upgrading (for example, when upgrading from - 0.3.4 to 0.4). -- All backwards incompatible changes are mentioned in this document. - -1.9.1 ------ -2021-11-18 - -- Tested against Python 3.10. - -1.9 ------ -2021-08-18 - -- Add `value_dumper` to most of the functions/methods related to signature - generation/validation. It's aimed to make signatures generated in languages - better compatible with `ska`. -- Add `quoter` to most of the functions/methods related to signature - generation/validation. It's aimed to make signatures generated in languages - better compatible with `ska`. - -1.8.2 ------ -2021-06-18 - -- Add typing to most of the code parts. - -1.8.1 ------ -2021-06-10 - -- Wipe out old flavour from code. -- Blackify. - -1.8 ---- -2021-06-10 - -*Additions to the Django contrib app* - -- Drop Python 2.7 and 3.5 support. -- Tested against Django 2.2, 3.0, 3.1 and 3.2. -- Tested against Python 3.8 and 3.9. -- ``django-constance`` specific template tags have been moved to - ``ska.contrib.django.ska.integration.constance_integration``. Update your - Django settings accordingly. -- ``django-constance`` specific authentication backend has been moved to - ``'ska.contrib.django.ska.backends.constance_backend.SkaAuthenticationConstanceBackend``. - Update your Django settings accordingly. -- ``django-constance`` specific DRF permission - classes (``ConstanceSignedRequestRequired`` - and ``ConstanceProviderSignedRequestRequired``) have been moved to - ``ska.contrib.django.ska.integration.drf.permissions.constance_permissions``. - Update your Django settings accordingly. - -1.7.5 ------ -2019-05-15 - -- Fixes in ska-sign-url on Python 3.5. - -1.7.4 ------ -2019-05-12 - -*Minor additions to the Django contrib app* - -- Introduce ``SKA_CONSTANCE_SETTINGS_PARSE_FROM_JSON`` directive for - parsing the data stored in ``django-constance`` (instead of treating it - as ``dict``). Default value is ``False``. - -1.7.3 ------ -2019-03-13 - -*Fixes in the Django contrib app* - -- Handle cases when `request` is not passed to the authentication backend. - -1.7.2 ------ -2019-02-23 - -*Additions to the Django contrib app* - -- Added `provider_sign_url` template tag to the existing `ska_tags` template - tags module. -- Added a new `ska_constance_tags` template tags module (to be used in - combination with `django-constance`). - -1.7.1 ------ -2019-01-22 - -*Additions to the Django contrib app* - -- Added Django REST framework JWT token obtain view (for authentication). -- Fixes in the authentication backend `SkaAuthenticationConstanceBackend`. - -1.7 ---- -2018-12-28 - -*Additions to the Django contrib app* - -- Added Django REST framework integration (for signing ViewSets). - -1.6.12 ------- -2018-12-25 - -*Additions to the Django contrib app* - -- Added additional callback ``USER_VALIDATE_CALLBACK`` to the authentication - backends which is fired right after the signature validation to allow custom - validation logic for the incoming authentication requests. - -1.6.11 ------- -2018-12-20 - -*Additions to the Django contrib app* - -- Authentication backend has been made customisable. Most of the code is - moved to the ``BaseSkaAuthenticationBackend``. Introduced new authentication - backend ``SkaAuthenticationConstanceBackend`` to be used in combination with - ``django-constance``. - -1.6.10 ------- -2018-12-16 - -*Additions to the Django contrib app* - -- Fixes in the callbacks import of the Django contrib app. -- Testing shell commands; minor fixes in tests. - -1.6.9 ------ -2018-12-07 - -- Tested against Python 3.7. -- Add initial migrations for Django contrib package. - -1.6.8 ------ -2018-12-03 - -.. note:: - - Release dedicated to Charles Aznavour. Rest in peace, maestro. - -- Django 2.0 and 2.1 compatibility. -- Upgrade test suite. -- Fixes in docs. -- Python 3.4 is removed from support matrix (however, it might still work). - -1.6.7 ------ -2017-02-09 - -- Tested against Python 3.6 and Django 1.11 (alpha). - -1.6.6 ------ -2016-12-21 - -- Minor fixes. - -1.6.5 ------ -2016-12-06 - -- Fixed in docs. - -1.6.4 ------ -2016-12-06 - -- Added template tags library for Django integration. - -1.6.3 ------ -2016-12-04 - -- Fixes in django ska decorators. - -1.6.2 ------ -2016-12-03 - -- Fixed broken example installer. - -1.6.1 ------ -2016-12-03 - -- Fixes in tests of django-ska package. -- Add shell.py command for easy debugging. -- Minor fixes. -- Clean up docs. - -1.6 ---- -2016-12-02 - -- Django 1.8, 1.9 and 1.10 compatibility. -- pep8 fixes. -- The ``six`` package requirement increased to six >= 1.9. -- Drop support of Django < 1.8 (it still may work, but no longer guaranteed). -- Drop support of Python 2.6.x. -- Fix broken Django authentication backend, due to deprecation of - ``request.REQUEST``. - -1.5 ---- -2014-06-04 - -- Introducing abstract signature class in order to make it possible to define - more hash algorithms. -- Added HMAC MD5, HMAC SHA-224, HMAC SHA-256, HMAC SHA-384 and HMAC SHA-512 - hash algorythms. HMAC SHA-1 remains a default. - -1.4.4 ------ -2014-05-06 - -- Add ``ska-sign-url`` terminal command (Linux only). - -1.4.3 ------ -2014-02-28 - -- The ``ValidationResult`` class is slightly changed. The ``reason`` property - is replaced with ``errors`` (while ``reason`` is left mainly for backwards - compatibility). For getting human readable message you're encouraged to use - the ``message`` property (string) instead of joining strings manually. - Additionally, each error got a separate object (see ``error_codes`` module): - ``INVALID_SIGNATURE`` and ``SIGNATURE_TIMESTAMP_EXPIRED``. -- Minor documentation improvements. - -1.4.2 ------ -2013-12-25 - -- Minor fixes. -- Added authentication backend tests. -- Added tumpering tests. -- Minor documentation improvements. - -1.4.1 ------ -2013-12-23 - -- Armenian, Dutch and Russian translations added for Django app. -- Documentation improved. - -1.4 ---- -2013-12-21 - -- Providers concept implemented. It's now possible to handle multiple secret - keys and define custom callbacks and redirect URLs per provider. See the - docs for more. -- Better example project. -- Better documentation. - -1.3 ---- -2013-12-21 - -- Make it possible to add additional data to the signed request by providing - an additional ``extra`` argument. -- Reflect the new functionality in Django app. -- Better documentation. - -1.2 ---- -2013-12-17 - -- Optionally storing the authentication tokens into the database, when used - with Django auth backend. -- Optionally checking, if signature token has already been used to log into - Django. If so, ignoring the login attempt. A management command is added to - purge old signature data. -- Demo (quick installer) added. - -1.1 ---- -2013-12-14 - -- Class based views validation decorator added. -- Authentication backend for Django based on authentication tokens generated - with ``ska``. - -1.0 ---- -2013-12-13 - -- Lowered ``six`` version requirement to 1.1.0. - -0.9 ---- -2013-10-16 - -- Lowered ``six`` version requirement to 1.4.0. - -0.8 ---- -2013-10-12 - -- Contrib package ``ska.contrib.django.ska`` added for better Django - integration. - -0.7 ---- -2013-09-12 - -- Pinned version requirement of ``six`` package to 1.4.1. - -0.6 ---- -2013-09-06 - -- Python 2.6.8 and 3.3 support addeded. - -0.5 ---- -2013-09-05 - -- Stable release. - -0.4 ---- -2013-09-04 - -- Adding shortcuts for handling dictionaries. -- Improved documentation. - -0.3 ---- -2013-09-04 - -- Adding commands to generate the URLs. - -0.2 ---- -2013-09-02 - -- Fixed docs. - -0.1 ---- -2013-09-01 - -- Initial beta release. +.. include:: ../CHANGELOG.rst diff --git a/docs/documentation.rst b/docs/documentation.rst new file mode 100644 index 0000000..401ce1d --- /dev/null +++ b/docs/documentation.rst @@ -0,0 +1,13 @@ + +Project documentation +===================== +Contents: + +.. contents:: Table of Contents + +.. toctree:: + :maxdepth: 20 + + index + changelog + package diff --git a/docs/documentation.rst.distrib b/docs/documentation.rst.distrib deleted file mode 100644 index 090ad86..0000000 --- a/docs/documentation.rst.distrib +++ /dev/null @@ -1,18 +0,0 @@ - -Documentation -=================================================== -Contents: - -.. toctree:: - :maxdepth: 20 - - ska - index - changelog - -Indices and tables -=================================================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/index.rst b/docs/index.rst index aa67357..8683071 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,1476 +1,2 @@ -=== -ska -=== -Lets you easily sign data, using symmetric-key algorithm encryption. Allows -you to validate signed data and identify possible validation errors. Uses -sha-(1, 224, 256, 385 and 512)/hmac for signature encryption. Allows to use -custom hash algorithms. Comes with shortcut functions for signing (and -validating) dictionaries and URLs. - -.. image:: https://img.shields.io/pypi/v/ska.svg - :target: https://pypi.python.org/pypi/ska - :alt: PyPI Version - -.. image:: https://img.shields.io/pypi/pyversions/ska.svg - :target: https://pypi.python.org/pypi/ska/ - :alt: Supported Python versions - -.. image:: https://github.com/barseghyanartur/ska/workflows/test/badge.svg - :target: https://github.com/barseghyanartur/ska/actions - :alt: Build Status - -.. image:: https://readthedocs.org/projects/ska/badge/?version=latest - :target: http://ska.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - -.. image:: https://img.shields.io/badge/license-GPL--2.0--only%20OR%20LGPL--2.1--or--later-blue.svg - :target: https://github.com/barseghyanartur/ska/#License - :alt: GPL-2.0-only OR LGPL-2.1-or-later - -.. image:: https://coveralls.io/repos/github/barseghyanartur/ska/badge.svg?branch=master&service=github - :target: https://coveralls.io/github/barseghyanartur/ska?branch=master - :alt: Coverage - -Key concepts -============ -Hosts, that communicate with each other, share the Secret Key, which is used -to sign data (requests). Secret key is never sent around. - -One of the cases is signing of HTTP requests. Each (HTTP) request is signed -on the sender side using the shared Secret Key and as an outcome produces the -triple (``signature``, ``auth_user``, ``valid_until``) which are used to sign -the requests. - -- ``signature`` (``str``): Signature generated. -- ``auth_user`` (``str``): User making the request. Can be anything. -- ``valid_until`` (``float`` or ``str``): Signature expiration time (Unix timestamp). - -On the recipient side, (HTTP request) data is validated using the shared -Secret Key. It's being checked whether signature is valid and not expired. - -.. code-block:: text - - ┌─────────────┐ Data ┌─────────────┐ - │ Host 1 ├────────────────────────────>│ Host 2 │ - │ ─────────── │ │ ─────────── │ - │ secret key │ │ secret key │ - │ 'my-secret' │<────────────────────────────┤ 'my-secret' │ - └─────────────┘ Data └─────────────┘ - -Features -======== -Core `ska` module ------------------ -- Sign dictionaries. -- Validate signed dictionaries. -- Sign URLs. Append and sign additional URL data. -- Validate URLs. -- Use one of the built-in algorythms (HMAC SHA-1, HMAC SHA-224, HMAC SHA-256, - HMAC SHA-384 or HMAC SHA-512) or define a custom one. - -Django `ska` module (`ska.contrib.django.ska`) ----------------------------------------------- -- Model decorators for signing absolute URLs. View (including class-based - views) decorators for protecting views to authorised parties only (no - authentication required). -- Authentication backend for Django based on the signatures (tokens) generated - using `ska`, which allows you to get a password-less login to Django web - site. Multiple Secret Keys (per provider) supported. Comes with handy - callbacks (possible to customise per provider) for various states of - authentication. -- Template tags for signing URLs from within templates. -- `django-constance` integration (for password-less authentication). -- `Django REST Framework integration`_ (for protecting ViewSets, obtaining - JWT tokens for authentication). - -Prerequisites -============= -Present -------- -- Core ``ska`` module requires Python 3.6, 3.7, 3.8, 3.9 or 3.10. -- Django ``ska`` module (``ska.contrib.django.ska``) requires the mentioned - above plus Django 2.2, 3.0, 3.1 or 3.2. Additionally, certain - versions of `django-constance` and `djangorestframework` are required. - Specific version requirement primarily depends on the used Django version. - Check the `example requirements - `_ - to find out which versions of `django-constance` and `djangorestframework` - have been tested with specific Django versions. - -Past ----- -.. note:: - - In future releases (any time) compatibility with no-longer-supported - versions might/will be wiped out. - -- Dropping support of Python 2.7 and 3.5 has been announced in version 1.8. - As of 1.7.5 everything still worked. -- Dropping support of Python 3.4 has been announced in version 1.6.8. As of - 1.6.8 everything still worked. -- Dropping support of Django 1.5, 1.6 and 1.7 has been announced in version - 1.6. As of 1.6 everything is still backwards compatible with mentioned - versions. -- Dropping support of Python 2.6 and 3.3 has been announced in version 1.6. - As of 1.6 everything is still backwards compatible (as much as it's possible - within this package) with mentioned versions. - -Eco-system -========== -Need ``ska`` for other languages? Check the following affiliated projects: - -- `skajs `_: ``ska`` implementation - for NodeJS (both CommonJS and ESM are supported, Node >= 14). -- `skaphp `_: ``ska`` implementation - for PHP (>= 7.2). - -Generated signatures are intercompatible between Python, NodeJS and PHP -implementations. - -Installation -============ -Latest stable version from PyPI: - -.. code-block:: sh - - pip install ska - -or latest development version from GitHub. - -.. code-block:: sh - - pip install https://github.com/barseghyanartur/ska/archive/master.tar.gz - -Usage examples -============== -For integration with Django, see the `Django integration`_ section. - -Basic usage ------------ -Pure Python usage. - -Sender side -~~~~~~~~~~~ -Signing URLs is as simple as follows. - -Required imports. - -.. code-block:: python - - from ska import sign_url - -Producing a signed URL. - -.. code-block:: python - - signed_url = sign_url( - auth_user='user', - secret_key='your-secret_key', - url='http://e.com/api/' - ) - -.. code-block:: text - - GET http://e.com/api/?valid_until=1378045287.0&auth_user=user&signature=YlZpLFsjUKBalL4x5trhkeEgqE8%3D - -Default lifetime of a signature is 10 minutes (600 seconds). If you want it -to be different, provide a ``lifetime`` argument to ``sign_url`` function. - -Default name of the (GET) param holding the generated signature value -is ``signature``. If you want it to be different, provide a ``signature_param`` -argument to ``sign_url`` function. - -Default name of the (GET) param holding the ``auth_user`` value is -``auth_user``. If you want it to be different, provide a ``auth_user_param`` -argument to ``sign_url`` function. - -Default name of the (GET) param holding the ``valid_until`` value is -`valid_until`. If you want it to be different, provide a ``valid_until_param`` -argument to ``sign_url`` function. - -Note, that by default a suffix '?' is added after the given ``url`` and -generated signature params. If you want that suffix to be custom, provide a -``suffix`` argument to the ``sign_url`` function. If you want it to be gone, -set its' value to empty string. - -With all customisations, it would look as follows: - -.. code-block:: python - - from ska import HMACSHA512Signature # Use HMAC SHA-512 algorithm - - signed_url = sign_url( - auth_user='user', - secret_key='your-secret_key', - lifetime=120, - url='http://e.com/api/', - signature_param='signature', - auth_user_param='auth_user', - valid_until_param='valid_until', - signature_cls=HMACSHA512Signature - ) - -It's also possible to add additional data to the signature by providing a -``extra`` argument (dict). Note, that additional data is signed as well. -If request is somehow tampered (values vary from originally provided ones), -signature becomes invalid. - -.. code-block:: python - - sign_url( - auth_user='user', - secret_key='your-secret_key', - url='http://e.com/api/', - extra={ - 'email': 'doe@example.com', - 'last_name': 'Doe', - 'first_name': 'Joe' - } - ) - -You may now proceed with the signed URL request. If you use the famous -``requests`` library, it would be as follows. - -.. code-block:: python - - import requests - requests.get(signed_url) - -If you want to use POST method instead, you would likely want to get a -dictionary back, in order to append it to the POST data later. - -Required imports. - -.. code-block:: python - - from ska import signature_to_dict - -Producing a dictionary containing the signature data, ready to be put into -the request (for example POST) data. All customisations mentioned above for -the ``sign_url`` function, also apply to the ``signature_to_dict``: - -.. code-block:: python - - signature_dict = signature_to_dict( - auth_user='user', - secret_key='your-secret_key' - ) - -.. code-block:: text - - { - 'signature': 'YlZpLFsjUKBalL4x5trhkeEgqE8=', - 'auth_user': 'user', - 'valid_until': '1378045287.0' - } - -Adding of additional data to the signature works in the same way: - -.. code-block:: python - - signature_dict = signature_to_dict( - auth_user='user', - secret_key='your-secret_key', - extra={ - 'email': 'john.doe@mail.example.com', - 'first_name': 'John', - 'last_name': 'Doe' - } - ) - -.. code-block:: text - - { - 'auth_user': 'user', - 'email': 'john.doe@mail.example.com', - 'extra': 'email,first_name,last_name', - 'first_name': 'John', - 'last_name': 'Doe', - 'signature': 'cnSoU/LnJ/ZhfLtDLzab3a3gkug=', - 'valid_until': 1387616469.0 - } - -If you for some reason prefer a lower level implementation, read the same -section in the `Advanced usage (low-level)`_ chapter. - -Recipient side -~~~~~~~~~~~~~~ -Validating the signed request data is as simple as follows. - -Required imports. - -.. code-block:: python - - from ska import validate_signed_request_data - -Validating the signed request data. Note, that ``data`` value is expected to -be a dictionary; ``request.GET`` is given as an example. It will most likely -vary from what's used in your framework (unless you use Django). - -.. code-block:: python - - validation_result = validate_signed_request_data( - data=request.GET, # Note, that ``request.GET`` is given as example. - secret_key='your-secret_key' - ) - -The ``validate_signed_request_data`` produces a -``ska.SignatureValidationResult`` object, which holds the following data. - -- ``result`` (``bool``): True if data is valid. False otherwise. -- ``reason`` (``list``): List of strings, indicating validation errors. Empty list - in case if ``result`` is True. - -Default name of the (GET) param holding the signature value is ``signature``. -If you want it to be different, provide a ``signature_param`` argument to -``validate_signed_request_data`` function. - -Default name of the (GET) param holding the ``auth_user`` value is -``auth_user``. If you want it to be different, provide a ``auth_user_param`` -argument to ``validate_signed_request_data`` function. - -Default name of the (GET) param holding the ``valid_until`` value is -``valid_until``. If you want it to be different, provide a -``valid_until_param`` argument to ``validate_signed_request_data`` function. - -With all customisations, it would look as follows. Note, that -``request.GET`` is given as example. - -.. code-block:: python - - from ska import HMACSHA256Signature # Use HMAC SHA-256 algorithm - - validation_result = validate_signed_request_data( - data=request.GET, - secret_key='your-secret_key', - signature_param='signature', - auth_user_param='auth_user', - valid_until_param='valid_until', - signature_cls=HMACSHA256Signature - ) - -If you for some reason prefer a lower level implementation, read the same -section in the `Advanced usage (low-level)`_ chapter. - -Command line usage ------------------- -It's possible to generate a signed URL from command line using the -``ska.generate_signed_url`` module. - -:Arguments: - -.. code-block:: text - - -h, --help show this help message and exit - - -au AUTH_USER, --auth-user AUTH_USER - `auth_user` value - - -sk SECRET_KEY, --secret-key SECRET_KEY - `secret_key` value - - -vu VALID_UNTIL, --valid-until VALID_UNTIL - `valid_until` value - - -l LIFETIME, --lifetime LIFETIME - `lifetime` value - - -u URL, --url URL URL to sign - - -sp SIGNATURE_PARAM, --signature-param SIGNATURE_PARAM - (GET) param holding the `signature` value - - -aup AUTH_USER_PARAM, --auth-user-param AUTH_USER_PARAM - (GET) param holding the `auth_user` value - - -vup VALID_UNTIL_PARAM, --valid-until-param VALID_UNTIL_PARAM - (GET) param holding the `auth_user` value - -:Example: - -.. code-block:: sh - - ska-sign-url -au user -sk your-secret-key --url http://example.com - -Advanced usage (low-level) --------------------------- -Sender side -~~~~~~~~~~~ - -Required imports. - -.. code-block:: python - - from ska import Signature, RequestHelper - -Generate a signature. - -.. code-block:: python - - signature = Signature.generate_signature( - auth_user='user', - secret_key='your-secret-key' - ) - -Default lifetime of a signature is 10 minutes (600 seconds). If you want it to -be different, provide a ``lifetime`` argument to ``generate_signature`` -method. - -.. code-block:: python - - signature = Signature.generate_signature( - auth_user='user', - secret_key='your-secret-key', - lifetime=120 # Signature lifetime set to 120 seconds. - ) - -Adding of additional data to the signature works in the same way as in -``sign_url``. - -.. code-block:: python - - signature = Signature.generate_signature( - auth_user='user', - secret_key='your-secret-key', - extra={ - 'email': 'doe@example.com', - 'last_name': 'Doe', - 'first_name': 'Joe' - } - ) - -For HMAC SHA-384 algorithm it would look as follows. - -.. code-block:: python - - from ska import HMACSHA384Signature - - signature = HMACSHA384Signature.generate_signature( - auth_user='user', - secret_key='your-secret-key' - ) - -Your endpoint operates with certain param names and you need to wrap generated -signature params into the URL. In order to have the job done in an easy way, -create a request helper. Feed names of the (GET) params to the request helper -and let it make a signed endpoint URL for you. - -.. code-block:: python - - request_helper = RequestHelper( - signature_param='signature', - auth_user_param='auth_user', - valid_until_param='valid_until' - ) - -Append signature params to the endpoint URL. - -.. code-block:: python - - signed_url = request_helper.signature_to_url( - signature=signature, - endpoint_url='http://e.com/api/' - ) - -.. code-block:: text - - GET http://e.com/api/?valid_until=1378045287.0&auth_user=user&signature=YlZpLFsjUKBalL4x5trhkeEgqE8%3D - -Make a request. - -.. code-block:: python - - import requests - r = requests.get(signed_url) - - -For HMAC SHA-384 algorithm it would look as follows. - -.. code-block:: python - - from ska import HMACSHA384Signature - - request_helper = RequestHelper( - signature_param='signature', - auth_user_param='auth_user', - valid_until_param='valid_until', - signature_cls=HMACSHA384Signature - ) - - signed_url = request_helper.signature_to_url( - signature=signature, - endpoint_url='http://e.com/api/' - ) - -Recipient side -~~~~~~~~~~~~~~ -Required imports. - -.. code-block:: python - - from ska import RequestHelper - -Create a request helper. Your endpoint operates with certain param names. In -order to have the job done in an easy way, we feed those params to the -request helper and let it extract data from signed request for us. - -.. code-block:: python - - request_helper = RequestHelper( - signature_param='signature', - auth_user_param='auth_user', - valid_until_param='valid_until' - ) - -Validate the request data. Note, that ``request.GET`` is given just as an -example. - -.. code-block:: python - - validation_result = request_helper.validate_request_data( - data=request.GET, - secret_key='your-secret-key' - ) - -Your implementation further depends on you, but may look as follows. - -.. code-block:: python - - if validation_result.result: - # Validated, proceed further - # ... - else: - # Validation not passed. - raise Http404(validation_result.reason) - -You can also just validate the signature by calling ``validate_signature`` -method of the ``ska.Signature``. - -.. code-block:: python - - Signature.validate_signature( - signature='EBS6ipiqRLa6TY5vxIvZU30FpnM=', - auth_user='user', - secret_key='your-secret-key', - valid_until='1377997396.0' - ) - -Django integration ------------------- -``ska`` comes with Django model- and view-decorators for producing signed URLs -and and validating the endpoints, as well as with authentication backend, -which allows password-less login into Django web site using ``ska`` generated -signature tokens. There's also a template tag for signing URLs. - -Demo -~~~~ -In order to be able to quickly evaluate the ``ska``, a demo app (with a quick -installer) has been created (works on Ubuntu/Debian, may work on other Linux -systems as well, although not guaranteed). Follow the instructions below for -having the demo running within a minute. - -Grab the latest ``ska_example_app_installer.sh`` and execute it: - -.. code-block:: sh - - wget -O - https://raw.github.com/barseghyanartur/ska/stable/examples/ska_example_app_installer.sh | bash - -Open your browser and test the app. - -Foo listing (ska protected views): - -- URL: http://127.0.0.1:8001/foo/ - -Authentication page (ska authentication backend): - -- URL: http://127.0.0.1:8001/foo/authenticate/ - -Django admin interface: - -- URL: http://127.0.0.1:8001/admin/ -- Admin username: test_admin -- Admin password: test - -Configuration -~~~~~~~~~~~~~ -Secret key (``str``) must be defined in ``settings`` module of your project. - -.. code-block:: python - - SKA_SECRET_KEY = 'my-secret-key' - -The following variables can be overridden in ``settings`` module of your -project. - -- ``SKA_UNAUTHORISED_REQUEST_ERROR_MESSAGE`` (``str``): Plain text error message. - Defaults to "Unauthorised request. {0}". -- ``SKA_UNAUTHORISED_REQUEST_ERROR_TEMPLATE`` (``str``): Path to 401 template that - should be rendered in case of 401 - responses. Defaults to empty string (not provided). -- ``SKA_AUTH_USER`` (``str``): The ``auth_user`` argument for ``ska.sign_url`` - function. Defaults to "ska-auth-user". - -See the working `example project -`_. - -Multiple secret keys -~~~~~~~~~~~~~~~~~~~~ -Imagine, you have a site to which you want to offer a password-less login for -various clients/senders and you don't want them all to have one shared secret -key, but rather have their own one. Moreover, you specifically want to execute -very custom callbacks not only for each separate client/sender, but also for -different sort of users authenticating. - -.. code-block:: text - - ┌────────────────┐ - │ Site providing │ - │ authentication │ - │ ────────────── │ - │ custom secret │ - │ keys per │ - │ client │ - │ ────────────── │ - │ Site 1: 'sk-1' │ - ┌───────────>│ Site 2: 'sk-2' │<───────────┐ - │ │ Site 3: 'sk-3' │ │ - │ ┌────>│ Site 4: 'sk-4' │<────┐ │ - │ │ └────────────────┘ │ │ - │ │ │ │ - │ │ │ │ - ┌────────────┴─┐ ┌─┴────────────┐ ┌────────────┴─┐ ┌─┴────────────┐ - │ Site 1 │ │ Site 2 │ │ Site 3 │ │ Site 4 │ - │ ──────────── │ │ ──────────── │ │ ──────────── │ │ ──────────── │ - │ secret key │ │ secret key │ │ secret key │ │ secret key │ - │ 'sk-1' │ │ 'sk-2' │ │ 'sk-3' │ │ 'sk-4' │ - └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ - -In order to make the stated above possible, the concept of providers is -introduced. You can define a secret key, callbacks or redirect URL. See an -example below. Note, that keys of the ``SKA_PROVIDERS`` ("client_1", -"client_2", etc.) are the provider keys. - -.. code-block:: python - - SKA_PROVIDERS = { - # ******************************************************** - # ******************** Basic gradation ******************* - # ******************************************************** - # Site 1 - 'client_1': { - 'SECRET_KEY': 'sk-1', - }, - - # Site 2 - 'client_2': { - 'SECRET_KEY': 'sk-2', - }, - - # Site 3 - 'client_3': { - 'SECRET_KEY': 'sk-3', - }, - - # Site 4 - 'client_4': { - 'SECRET_KEY': 'sk-4', - }, - - # ******************************************************** - # ******* You make gradation as complex as you wish ****** - # ******************************************************** - # Client 1, group users - 'client_1.users': { - 'SECRET_KEY': 'client-1-users-secret-key', - }, - - # Client 1, group power_users - 'client_1.power_users': { - 'SECRET_KEY': 'client-1-power-users-secret-key', - 'USER_CREATE_CALLBACK': 'foo.ska_callbacks.client1_power_users_create', - }, - - # Client 1, group admins - 'client_1.admins': { - 'SECRET_KEY': 'client-1-admins-secret-key', - 'USER_CREATE_CALLBACK': 'foo.ska_callbacks.client1_admins_create', - 'REDIRECT_AFTER_LOGIN': '/admin/' - }, - } - -See the `Callbacks`_ section for the list of callbacks. Note, that callbacks -defined in the ``SKA_PROVIDERS`` are overrides. If a certain callback isn't -defined in the ``SKA_PROVIDERS``, authentication backend falls back to the -respective default callback function. - -Obviously, server would have to have the full list of providers defined. On -the client side you would only have to store the general secret key and of -course the provider UID(s). - -When making a signed URL on the sender side, you should be providing the -``provider`` key in the ``extra`` argument. See the example below for how you -would do it for ``client_1.power_users``. - -.. code-block:: python - - from ska import sign_url - from ska.defaults import DEFAULT_PROVIDER_PARAM - - server_ska_login_url = 'https://server-url.com/ska/login/' - - signed_remote_ska_login_url = sign_url( - auth_user='test_ska_user', - # Using provider-specific secret key. This value shall be equal to - # the value of SKA_PROVIDERS['client_1.power_users']['SECRET_KEY'], - # defined in your projects' Django settings module. - secret_key='client-1-power-users-secret-key', - url=server_ska_login_url, - extra={ - 'email': 'test_ska_user@mail.example.com', - 'first_name': 'John', - 'last_name': 'Doe', - # Using provider specific string. This value shall be equal to - # the key string "client_1.power_users" of SKA_PROVIDERS, - # defined in your projcts' Django settings module. - DEFAULT_PROVIDER_PARAM: 'client_1.power_users', - } - ) - -Django model method decorator ``sign_url`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This is most likely be used in module ``models`` (models.py). - -Imagine, you have a some objects listing and you want to protect the URLs to -be viewed by authorised parties only. You would then use -``get_signed_absolute_url`` method when rendering the listing (HTML). - -.. code-block:: python - - from django.db import models - from django.utils.translation import ugettext_lazy as _ - from django.core.urlresolvers import reverse - - from ska.contrib.django.ska.decorators import sign_url - - - class FooItem(models.Model): - - title = models.CharField(_("Title"), max_length=100) - slug = models.SlugField(unique=True, verbose_name=_("Slug")) - body = models.TextField(_("Body")) - - # Unsigned absolute URL, which goes to the foo item detail page. - def get_absolute_url(self): - return reverse('foo.detail', kwargs={'slug': self.slug}) - - # Signed absolute URL, which goes to the foo item detail page. - @sign_url() - def get_signed_absolute_url(self): - return reverse('foo.detail', kwargs={'slug': self.slug}) - -Note, that ``sign_url`` decorator accepts the following optional arguments. - -- ``auth_user`` (``str``): Username of the user making the request. -- ``secret_key``: The shared secret key. If set, overrides - the ``SKA_SECRET_KEY`` variable set in the ``settings`` module of your - project. -- ``valid_until`` (``float`` or ``str``): Unix timestamp. If not given, generated - automatically (now + lifetime). -- ``lifetime`` (``int``): Signature lifetime in seconds. -- ``suffix`` (``str``): Suffix to add after the ``endpoint_url`` and before the - appended signature params. -- ``signature_param`` (``str``): Name of the GET param name which would hold the - generated signature value. -- ``auth_user_param`` (``str``): Name of the GET param name which would hold - the ``auth_user`` value. -- ``valid_until_param`` (``str``): Name of the GET param name which would hold - the ``valid_until`` value. - -Django view decorator ``validate_signed_request`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To be used to protect views (file views.py). Should be applied to -views (endpoints) that require signed requests. If checks are not successful, -a ``ska.contrib.django.ska.http.HttpResponseUnauthorized`` is returned, which -is a subclass of Django's ``django.http.HttpResponse``. You can provide your -own template for 401 error. Simply point the -``SKA_UNAUTHORISED_REQUEST_ERROR_TEMPLATE`` in ``settings`` module to the right -template. See ``ska/contrib/django/ska/templates/ska/401.html`` as a template -example. - -.. code-block:: python - - from ska.contrib.django.ska.decorators import validate_signed_request - - # Your view that shall be protected - @validate_signed_request() - def detail(request, slug, template_name='foo/detail.html'): - # Your code - -Note, that ``validate_signed_request`` decorator accepts the following optional -arguments. - -- ``secret_key`` (``str``) : The shared secret key. If set, overrides - the ``SKA_SECRET_KEY`` variable set in the ``settings`` module of your - project. -- ``signature_param`` (``str``): Name of the (for example GET or POST) param name - which holds the ``signature`` value. -- ``auth_user_param`` (``str``): Name of the (for example GET or POST) param name - which holds the ``auth_user`` value. -- ``valid_until_param`` (``str``): Name of the (foe example GET or POST) param - name which holds the ``valid_until`` value. - -If you're using class based views, use the ``m_validate_signed_request`` -decorator instead of ``validate_signed_request``. - -Template tags -~~~~~~~~~~~~~ -There are two template tags modules: ``ska_tags`` and ``ska_constance_tags``. -They are functionally identical, although ``ska_constance_tags`` is tied to -``django-constance``. - -For standard settings configurations, template tags shall be loaded as follows: - -.. code-block:: html - - {% load ska_tags %} - -For ``django-constance`` based settings configurations, template tags shall be -loaded as follows: - -.. code-block:: html - - {% load ska_constance_tags %} - -Note, that if you want to use ``ska_constance_tags``, add -the ``ska.contrib.django.ska.integration.constance_integration`` line to -your``INSTALLED_APPS``: - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'ska.contrib.django.ska.integration.constance_integration', - # ... - ) - -sign_url -++++++++ -The ``sign_url`` template tag accepts template context and the following -params: - -- ``url`` -- ``auth_user``: If not given, ``request.user.get_username()`` is used. -- ``secret_key``: If not given, the secret key from settings is used. -- ``valid_until``: If not given, calculated from ``lifetime``. -- ``lifetime``: Defaults to ``ska.defaults.SIGNATURE_LIFETIME``. -- ``suffix``: Defaults to ``ska.defaults.DEFAULT_URL_SUFFIX``. -- ``signature_param``: Defaults to ``ska.defaultsDEFAULT_SIGNATURE_PARAM``. -- ``auth_user_param``: Defaults to ``ska.defaults.DEFAULT_AUTH_USER_PARAM``. -- ``valid_until_param``: Defaults to ``ska.defaults.DEFAULT_VALID_UNTIL_PARAM``. -- ``signature_cls``: Defaults to ``ska.signatures.Signature``. - -Usage example: - -.. code-block:: html - - {% load ska_tags %} - - {% for item in items%} - - {% sign_url item.get_absolute_url as item_signed_absolute_url %} - {{ item }} - - {% endfor %} - -provider_sign_url -+++++++++++++++++ -The ``provider_sign_url`` template tag accepts template context and the -following params: - -- ``url`` -- ``provider``: Provider name. -- ``auth_user``: If not given, ``request.user.get_username()`` is used. -- ``valid_until``: If not given, calculated from ``lifetime``. -- ``lifetime``: Defaults to ``ska.defaults.SIGNATURE_LIFETIME``. -- ``suffix``: Defaults to ``ska.defaults.DEFAULT_URL_SUFFIX``. -- ``signature_param``: Defaults to ``ska.defaultsDEFAULT_SIGNATURE_PARAM``. -- ``auth_user_param``: Defaults to ``ska.defaults.DEFAULT_AUTH_USER_PARAM``. -- ``valid_until_param``: Defaults to ``ska.defaults.DEFAULT_VALID_UNTIL_PARAM``. -- ``signature_cls``: Defaults to ``ska.signatures.Signature``. -- ``fail_silently``: Defaults to False. - -Usage example: - -.. code-block:: html - - {% load ska_tags %} - - {% for item in items%} - - {% provider_sign_url url=item.get_absolute_url provider='client_1.users' as item_signed_absolute_url %} - {{ item }} - - {% endfor %} - -Authentication backends -~~~~~~~~~~~~~~~~~~~~~~~ -Allows you to get a password-less login to Django web site. - -At the moment there are two backends implemented: - -- `SkaAuthenticationBackend`_: Uses standard Django settings. -- `SkaAuthenticationConstanceBackend`_: Relies on dynamic settings - functionality provided by ``django-constance``. - -By default, number of logins using the same token is not limited. If you wish -that single tokens become invalid after first use, set the following variables -to True in your projects' Django settings module. - -.. code-block:: python - - SKA_DB_STORE_SIGNATURES = True - SKA_DB_PERFORM_SIGNATURE_CHECK = True - -SkaAuthenticationBackend -++++++++++++++++++++++++ -``SkaAuthenticationBackend`` uses standard Django settings. - -Recipient side -^^^^^^^^^^^^^^ -Recipient is the host (Django site), to which the sender tries to get -authenticated (log in). On the recipient side the following shall be present. - -settings.py -*********** -.. code-block:: python - - AUTHENTICATION_BACKENDS = ( - 'ska.contrib.django.ska.backends.SkaAuthenticationBackend', - 'django.contrib.auth.backends.ModelBackend', - ) - - INSTALLED_APPS = ( - # ... - 'ska.contrib.django.ska', - # ... - ) - - SKA_SECRET_KEY = 'secret-key' - SKA_UNAUTHORISED_REQUEST_ERROR_TEMPLATE = 'ska/401.html' - SKA_REDIRECT_AFTER_LOGIN = '/foo/logged-in/' - -urls.py -******* -.. code-block:: python - - urlpatterns = [ - url(r'^ska/', include('ska.contrib.django.ska.urls')), - url(r'^admin/', include(admin.site.urls)), - ] - -Callbacks -********* -There are several callbacks implemented for authentication backend. - -- ``USER_VALIDATE_CALLBACK`` (``str``): Validate request callback. Created to - allow adding custom logic to the incoming authentication requests. The main - purpose is to provide a flexible way of raising exceptions if the incoming - authentication request shall be blocked (for instance, email or username is - in black-list or right the opposite - not in the white list). The only aim of - the ``USER_VALIDATE_CALLBACK`` is to raise a ``django.core.PermissionDenied`` - exception if request data is invalid. In that case authentication flow will - halt. All other exceptions would simply be ignored (but logged) and if no - exception raised, the normal flow would be continued. -- ``USER_GET_CALLBACK`` (``str``): Fired if user was successfully fetched from - database (existing user). -- ``USER_CREATE_CALLBACK`` (``str``): Fired right after user has been - created (user didn't exist). -- ``USER_INFO_CALLBACK`` (``str``): Fired upon successful authentication. - -Example of a callback function (let's say, it resides in module -``my_app.ska_callbacks``): - -.. code-block:: python - - def my_callback(user, request, signed_request_data) - # Your code - -...where: - -- ``user`` is ``django.contrib.auth.models.User`` instance. -- ``request`` is ``django.http.HttpRequest`` instance. -- ``signed_request_data`` is dictionary with signed request data. - -For example, if you need to assign user to some local Django group, you could -specify the group name on the client side (add it to the ``extra`` dictionary) -and based on that, add the user to the group in the callback. - -The callback is a path qualifier of the callback function. Considering the -example above, it would be ``my_app.ska_callbacks.my_callback``. - -Prefix names of each callback variable with ``SKA_`` in your projects' settings -module. - -Example: - -.. code-block:: python - - SKA_USER_GET_CALLBACK = 'my_app.ska_callbacks.my_get_callback' - SKA_USER_CREATE_CALLBACK = 'my_app.ska_callbacks.my_create_callback' - -Sender side -^^^^^^^^^^^ -Sender is the host (another Django web site) from which users authenticate to -the Recipient using signed URLs. - -On the sender side, the only thing necessary to be present is the ``ska`` -module for Django and of course the same ``SECRET_KEY`` as on the server side. -Further, the server ``ska`` login URL (in our case "/ska/login/") shall be -signed using ``ska`` (for example, using ``sign_url`` function). The -``auth_user`` param would be used as a Django username. See the example below. - -.. code-block:: python - - from ska import sign_url - from ska.contrib.django.ska.settings import SECRET_KEY - - server_ska_login_url = 'https://server-url.com/ska/login/' - - signed_url = sign_url( - auth_user='test_ska_user_0', - secret_key=SECRET_KEY, - url=server_ska_login_url, - extra={ - 'email': 'john.doe@mail.example.com', - 'first_name': 'John', - 'last_name': 'Doe', - } - ) - -Note, that you ``extra`` dictionary is optional! If ``email``, ``first_name`` -and ``last_name`` keys are present, upon successful validation, the data -would be saved into users' profile. - -Put this code, for instance, in your view and then make the generated URL -available in template context and render it as a URL so that user can click -on it for authenticating to the server. - -.. code-block:: python - - def auth_to_server(request, template_name='auth_to_server.html'): - # Some code + obtaining the `signed_url` (code shown above) - context = {'signed_url': signed_url} - - return render(request, template_name, context) - -SkaAuthenticationConstanceBackend -+++++++++++++++++++++++++++++++++ -Relies on dynamic settings functionality provided by -`django-constance `_. - -*Only differences with `SkaAuthenticationBackend` are mentioned.* - -.. note:: - - Additional requirements shall be installed. See the `constance.txt - `_ - file for additional requirements (``django-constance``, - ``django-json-widget``, ``django-picklefield``, ``jsonfield2`` and - ``redis``). - -settings.py -^^^^^^^^^^^ - -.. code-block:: python - - AUTHENTICATION_BACKENDS = ( - 'ska.contrib.django.ska.backends.constance_backend.SkaAuthenticationConstanceBackend', - 'django.contrib.auth.backends.ModelBackend', - ) - - INSTALLED_APPS = ( - # ... - 'constance', # django-constance - 'ska.contrib.django.ska', - 'django_json_widget', # For nice admin JSON widget - # ... - ) - - CONSTANCE_CONFIG = { - 'SKA_PROVIDERS': ( - {}, # The default value - 'JSON data', # Help text in admin - 'JSONField_config', # Field config - ) - } - - CONSTANCE_ADDITIONAL_FIELDS = { - 'JSONField_config': [ - # `jsonfield2` package might be used for storing the JSON field, - # however, at the moment of writing it has a bug which makes - # the JSON invalid after the first save. To avoid that, it has - # been patched and resides in examples/simple/jsonfield2_addons/ - # module. - 'jsonfield2_addons.forms.JSONField', - { - 'widget': 'django_json_widget.widgets.JSONEditorWidget', - } - ], - } - - CONSTANCE_BACKEND = 'constance.backends.redisd.RedisBackend' - - CONSTANCE_REDIS_CONNECTION = { - 'host': 'localhost', - 'port': 6379, - 'db': 0, - } - -.. note:: - - In very tiny bits, although not required, the - `jsonfield2 `_ and - `django-json-widget `_ - packages are used for editing of the ``SKA_PROVIDERS`` setting in Django - admin. - -.. note:: - - In the example shown above, the ``RedisBackend`` of ``django-constance`` - is used. You could also use ``DatabaseBackend``. Study the - `documentation `_ - for more. - -.. note:: - - If your `SKA_PROVIDERS` settings are stored in the constance as ``str`` - instead of ``dict``, set the setting - ``SKA_CONSTANCE_SETTINGS_PARSE_FROM_JSON`` to ``True``. - -With ``DatabaseBackend`` it would look as follows: - -.. code-block:: python - - CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend' - - INSTALLED_APPS = ( - # ... - 'constance.backends.database', - # ... - ) - -**Quick demo of the dynamic backend** - -- Clone this project: - -.. code-block:: sh - - git clone git@github.com:barseghyanartur/ska.git - -- Install/migrate: - -.. code-block:: sh - - ./scripts/install.sh - pip install -r examples/requirements/django_2_1.txt - ./scripts/migrate.sh --settings=settings.constance_settings - -- Run: - -.. code-block:: sh - - ./scripts/runserver.sh --settings=settings.constance_settings - -- Go to `http://localhost:8000/admin/constance/config/ - `_. - -- Paste the following code: - -.. code-block:: javascript - - { - "client_1.users":{ - "SECRET_KEY":"client-1-users-secret-key" - }, - "client_1.power_users":{ - "SECRET_KEY":"client-1-power-users-secret-key", - "USER_CREATE_CALLBACK":"foo.ska_callbacks.client1_power_users_create" - }, - "client_1.admins":{ - "SECRET_KEY":"client-1-admins-secret-key", - "USER_CREATE_CALLBACK":"foo.ska_callbacks.client1_admins_create", - "USER_GET_CALLBACK":"foo.ska_callbacks.client1_admins_get", - "USER_INFO_CALLBACK":"foo.ska_callbacks.client1_admins_info_constance", - "REDIRECT_AFTER_LOGIN":"/admin/auth/user/" - } - } - -- Open `http://localhost:8000/foo/authenticate/ - `_ in another browser and navigate - to the ``Log in - client_1.admins`` link in the ``Success`` table column of - the ``By provider`` section. Upon clicking, you should be logged in. - You have used the dynamic settings. - -urls.py -^^^^^^^ -``django-constance`` specific views and urls are used. See -`ska.contrib.django.ska.views.constance_views -`_ -and `ska.contrib.django.ska.urls.constance_urls -`_ -for the reference. - -.. code-block:: python - - urlpatterns = [ - url(r'^ska/', include('ska.contrib.django.ska.urls.constance_urls')), - url(r'^admin/', include(admin.site.urls)), - ] - -Custom authentication backend -+++++++++++++++++++++++++++++ -To implement alternative authentication backend, see the following example: - -.. code-block:: python - - from constance import config - - from ska.contrib.django.backends import BaseSkaAuthenticationBackend - - class SkaAuthenticationConstanceBackend(BaseSkaAuthenticationBackend): - """Authentication backend.""" - - def get_settings(self): - """ - - :return: - """ - return config.SKA_PROVIDERS - -That's it. The only thing the ``get_settings`` method shall return is ``dict`` -with providers data (see the `Multiple secret keys`_ for the reference; -return value of the ``get_settings` is ``SKA_PROVIDERS`` dict). - -Purging of old signature data -+++++++++++++++++++++++++++++ -If you have lots of visitors and the ``SKA_DB_STORE_SIGNATURES`` set to True, -your database grows. If you wish to get rid of old signature token data, you -may want to execute the following command using a cron job. - -.. code-block:: sh - - ./manage.py ska_purge_stored_signature_data - -Security notes -++++++++++++++ -From point of security, you should be serving the following pages via HTTP -secure connection: - -- The server login page (/ska/login/). -- The client page containing the authentication links. - -Django REST Framework integration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Permission classes -++++++++++++++++++ -For protecting views without actually being authenticated into the system, -specific permission classes are implemented (for both plan settings and -provider settings, as well as both plain- and provider-settings work in -combination with ``django-constance`` package). - -The following permission classes are implemented: - -- ``SignedRequestRequired`` -- ``ProviderSignedRequestRequired`` -- ``ConstanceSignedRequestRequired`` -- ``ConstanceProviderSignedRequestRequired`` - -**ProviderSignedRequestRequired example** - -.. code-block:: python - - from rest_framework.viewsets import ModelViewSet - - from ska.contrib.django.ska.integration.drf.permissions import ( - ProviderSignedRequestRequired - ) - - from .models import FooItem - from .serializers import FooItemSerializer - - class FooItemViewSet(ModelViewSet): - """FooItem model viewset.""" - - permission_classes = (ProviderSignedRequestRequired,) - queryset = FooItem.objects.all() - serializer_class = FooItemSerializer - -**Signing requests** - -Requests are signed the same way. Sample code: - -.. code-block:: python - - # Given that we have `auth_user`, `auth_user_email`, `provider_name` - # (and the rest), the code would look as follows: - - from ska import sign_url - from ska.defaults import DEFAULT_PROVIDER_PARAM - - extra = { - 'email': auth_user_email, - 'first_name': first_name, - 'last_name': last_name, - } - - if provider_name: - extra.update({DEFAULT_PROVIDER_PARAM: provider_name}) - - signed_url = sign_url( - auth_user=auth_user, - secret_key=secret_key, - url=url, - extra=extra - ) - -JWT tokens for authentication -+++++++++++++++++++++++++++++ -For obtaining JWT tokens for authentication. Also works with -``django-constance``. - -**settings example** - -.. code-block:: python - - REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', - 'rest_framework.authentication.SessionAuthentication', - 'rest_framework.authentication.BasicAuthentication', - ), - } - -**urls example** - -.. code-block:: python - - urlpatterns = [ - # ... - url( - r'^ska-rest/', - include('ska.contrib.django.ska.integration.drf.urls.jwt_token') - ), - ] - -**Sample request** - -.. code-block:: text - - http://localhost:8008/ska-rest/obtain-jwt-token/ - ?signature=P92KWDDe0U84Alvu0tvmYoi8e8s%3D - &auth_user=test_ska_user - &valid_until=1548195246.0 - &extra=email%2Cfirst_name%2Clast_name - &email=test_ska_user%40mail.example.com - &first_name=John - &last_name=Doe - -**Sample response** - -.. code-block:: text - - HTTP 200 OK - Allow: GET, HEAD, OPTIONS - Content-Type: application/json - Vary: Accept - -.. code-block:: javascript - - { - "token": "eyJ0eXAiO.eyJ1c2VyX2lkIjo.m_saOvyKBO3" - } - -Testing -======= -Simply type: - -.. code-block:: sh - - pytest - -Or use tox: - -.. code-block:: sh - - tox - -Or use tox to check specific env: - -.. code-block:: sh - - tox -e py39 - -Or run Django tests: - -.. code-block:: sh - - python examples/simple/manage.py test ska --settings=settings.testing - -Writing documentation -===================== -Keep the following hierarchy. - -.. code-block:: text - - ===== - title - ===== - - header - ====== - - sub-header - ---------- - - sub-sub-header - ~~~~~~~~~~~~~~ - - sub-sub-sub-header - ++++++++++++++++++ - - sub-sub-sub-sub-header - ^^^^^^^^^^^^^^^^^^^^^^ - - sub-sub-sub-sub-sub-header - ************************** - -License -======= -GPL-2.0-only OR LGPL-2.1-or-later - -Support -======= -For any issues contact me at the e-mail given in the `Author`_ section. - -Author -====== -Artur Barseghyan - -Documentation -=================================================== -Contents: - -.. toctree:: - :maxdepth: 20 - - ska - index - changelog - -Indices and tables -=================================================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +.. include:: ../README.rst +.. include:: documentation.rst.distrib diff --git a/docs/index.rst.distrib b/docs/index.rst.distrib new file mode 100644 index 0000000..8683071 --- /dev/null +++ b/docs/index.rst.distrib @@ -0,0 +1,2 @@ +.. include:: ../README.rst +.. include:: documentation.rst.distrib diff --git a/docs/package.rst b/docs/package.rst new file mode 100644 index 0000000..4ec2365 --- /dev/null +++ b/docs/package.rst @@ -0,0 +1,15 @@ + +Package +======= + +.. toctree:: + :maxdepth: 20 + + ska + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/scripts/build_docs.sh b/scripts/build_docs.sh index c8077bd..31c0bb5 100755 --- a/scripts/build_docs.sh +++ b/scripts/build_docs.sh @@ -1,8 +1,3 @@ #!/usr/bin/env bash -./scripts/uninstall.sh -#reset -./scripts/install.sh -#reset -cat README.rst docs/documentation.rst.distrib > docs/index.rst sphinx-build -n -a -b html docs builddocs cd builddocs && zip -r ../builddocs.zip . -x ".*" && cd .. diff --git a/scripts/clean_up.sh b/scripts/clean_up.sh index a6e8c65..6246764 100755 --- a/scripts/clean_up.sh +++ b/scripts/clean_up.sh @@ -9,4 +9,4 @@ rm -rf build/ rm -rf dist/ rm -rf src/ska.egg-info/ rm -rf .cache/ -rm -rf htmlcov/ \ No newline at end of file +rm -rf htmlcov/ diff --git a/scripts/prepare_docs.sh b/scripts/prepare_docs.sh deleted file mode 100755 index 0d8d273..0000000 --- a/scripts/prepare_docs.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -cat README.rst docs/documentation.rst.distrib > docs/index.rst -cat CHANGELOG.rst > docs/changelog.rst diff --git a/scripts/rebuild_docs.sh b/scripts/rebuild_docs.sh index 20a5781..39dbd54 100755 --- a/scripts/rebuild_docs.sh +++ b/scripts/rebuild_docs.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash -./scripts/uninstall.sh -./scripts/install.sh -rm docs/*.rst -rm -rf builddocs/ +./scripts/clean_up.sh sphinx-apidoc src/ska --full -o docs -H 'ska' -A 'Artur Barseghyan ' -f -d 20 cp docs/conf.py.distrib docs/conf.py +cp docs/index.rst.distrib docs/index.rst From ffb2b199de884bba75b89ea6df9fbf0148cf649a Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sun, 27 Aug 2023 01:03:09 +0200 Subject: [PATCH 10/11] Up docs --- CHANGELOG.rst | 6 ++++-- README.rst | 25 +++++++++++++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7e19adc..5a99d00 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,13 +17,15 @@ are used for versioning (schema follows below): 1.10 ---- -2023-08-17 +2023-08-27 - Tested against Python 3.11. - Mark `django-nine` as optional dependency. - Drop support for Python < 3.7. -- Drop support for Django < 2.2, 3.0 and 3.1. +- Drop support for Django < 3.2 and 4.0. - Tested against Django 4.1 and 4.2. +- Upgrade relevant contrib code to support both ``django-constance`` >= 2.8.x and + 3.x. 1.9.1 ----- diff --git a/README.rst b/README.rst index 657dd6d..01ba7db 100644 --- a/README.rst +++ b/README.rst @@ -27,8 +27,8 @@ validating) dictionaries and URLs. :target: https://github.com/barseghyanartur/ska/#License :alt: GPL-2.0-only OR LGPL-2.1-or-later -.. image:: https://coveralls.io/repos/github/barseghyanartur/ska/badge.svg?branch=master&service=github - :target: https://coveralls.io/github/barseghyanartur/ska?branch=master +.. image:: https://coveralls.io/repos/github/barseghyanartur/ska/badge.svg?branch=main&service=github + :target: https://coveralls.io/github/barseghyanartur/ska?branch=main :alt: Coverage Key concepts @@ -87,13 +87,13 @@ Prerequisites ============= Present ------- -- Core ``ska`` module requires Python 3.6, 3.7, 3.8, 3.9 or 3.10. +- Core ``ska`` module requires Python 3.8, 3.9, 3.10 and 3.11. - Django ``ska`` module (``ska.contrib.django.ska``) requires the mentioned - above plus Django 2.2, 3.0, 3.1 or 3.2. Additionally, certain + above plus Django 3.2, 4.1 or 4.2. Additionally, certain versions of `django-constance` and `djangorestframework` are required. Specific version requirement primarily depends on the used Django version. Check the `example requirements - `_ + `_ to find out which versions of `django-constance` and `djangorestframework` have been tested with specific Django versions. @@ -104,10 +104,15 @@ Past In future releases (any time) compatibility with no-longer-supported versions might/will be wiped out. +- Dropping support of Python 3.6 and 3.7 has been announced in version 1.10. + As of 1.9.1 everything still worked. - Dropping support of Python 2.7 and 3.5 has been announced in version 1.8. As of 1.7.5 everything still worked. - Dropping support of Python 3.4 has been announced in version 1.6.8. As of 1.6.8 everything still worked. +- Dropping support of Django 2.2, 3.0, 3.1 and 4.0 has been announced in + version 1.10. As of 1.9.1 everything is still backwards compatible with + mentioned versions. - Dropping support of Django 1.5, 1.6 and 1.7 has been announced in version 1.6. As of 1.6 everything is still backwards compatible with mentioned versions. @@ -124,7 +129,7 @@ Need ``ska`` for other languages? Check the following affiliated projects: - `skaphp `_: ``ska`` implementation for PHP (>= 7.2). -Generated signatures are intercompatible between Python, NodeJS and PHP +Generated signatures are inter-compatible between Python, NodeJS and PHP implementations. Installation @@ -139,7 +144,7 @@ or latest development version from GitHub. .. code-block:: sh - pip install https://github.com/barseghyanartur/ska/archive/master.tar.gz + pip install https://github.com/barseghyanartur/ska/archive/main.tar.gz Usage examples ============== @@ -1073,7 +1078,7 @@ Relies on dynamic settings functionality provided by .. note:: Additional requirements shall be installed. See the `constance.txt - `_ + `_ file for additional requirements (``django-constance``, ``django-json-widget``, ``django-picklefield``, ``jsonfield2`` and ``redis``). @@ -1215,9 +1220,9 @@ urls.py ^^^^^^^ ``django-constance`` specific views and urls are used. See `ska.contrib.django.ska.views.constance_views -`_ +`_ and `ska.contrib.django.ska.urls.constance_urls -`_ +`_ for the reference. .. code-block:: python From 4c3bd3e0d9f4d3a2edee6117eb4d08bd16e45b58 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Sun, 27 Aug 2023 01:08:05 +0200 Subject: [PATCH 11/11] Clean up --- MANIFEST.in | 3 +-- examples/ska_example_app_installer.sh | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 9375461..c9a8ab5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,9 +1,8 @@ include README.rst include LICENSE_GPL2.0.txt include LICENSE_LGPL_2.1.txt -include src/ska/contrib/django/ska/requirements.txt +include CHANGELOG.rst include src/ska/contrib/django/ska/templates/ska/401.html recursive-include src/ska/contrib/django/ska/locale/hy * recursive-include src/ska/contrib/django/ska/locale/nl * recursive-include src/ska/contrib/django/ska/locale/ru * -include src/ska/bin/ska-sign-url diff --git a/examples/ska_example_app_installer.sh b/examples/ska_example_app_installer.sh index c218dd9..d33cbea 100755 --- a/examples/ska_example_app_installer.sh +++ b/examples/ska_example_app_installer.sh @@ -1,12 +1,13 @@ -wget -O ska_example_app_installer.tar.gz https://github.com/barseghyanartur/ska/archive/stable.tar.gz +wget -O ska_example_app_installer.tar.gz https://github.com/barseghyanartur/ska/archive/main.tar.gz virtualenv ska source ska/bin/activate mkdir ska_example_app_installer/ tar -xvf ska_example_app_installer.tar.gz -C ska_example_app_installer cd ska_example_app_installer/ska-stable/examples/simple/ #cd ska_example_app_installer/ska-master/examples/simple/ -pip install -r ../../src/ska/contrib/django/ska/requirements.txt -pip install https://github.com/barseghyanartur/ska/archive/stable.tar.gz +#pip install -r ../../src/ska/contrib/django/ska/requirements.txt +pip install -r ../../examples/requirements/django_4_2.txt +pip install https://github.com/barseghyanartur/ska/archive/main.tar.gz mkdir ../media/ mkdir ../media/static/ mkdir ../static/