From 707b8101b2b513ba7dbd648fd6c4a5dd4a7b18ab Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 28 Apr 2021 15:40:43 -0700 Subject: [PATCH 01/10] remove travis, tox, invoke --- .gitignore | 2 ++ .travis.yml | 54 -------------------------------------------- dev-requirements.txt | 8 ++----- tasks.py | 49 ---------------------------------------- tox.ini | 10 -------- 5 files changed, 4 insertions(+), 119 deletions(-) delete mode 100644 .travis.yml delete mode 100644 tasks.py delete mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 5aca82b..bdf4001 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +venv/ + *.py[cod] # C extensions diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fd2973d..0000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -dist: xenial -language: python -install: - - pip install $DJANGO - - pip install coveralls - - pip install --upgrade -r dev-requirements.txt -script: - - inv test -after_success: - - coveralls -matrix: - include: - - python: "2.7" - name: 'Linter (Python 2.7)' - install: - - pip install --upgrade -r dev-requirements.txt - script: flake8 sudo tests *.py - - python: "3.7" - name: 'Linter (Python 3.7)' - install: - - pip install --upgrade -r dev-requirements.txt - script: flake8 sudo tests *.py - - python: "3.7" - name: 'black' - install: - - pip install black==19.10b0 - script: black --check sudo tests *.py - - python: "2.7" - name: "Python 2.7, Django 1.9" - env: DJANGO="Django>=1.9,<1.10" - - python: "2.7" - name: "Python 2.7, Django 1.10" - env: DJANGO="Django>=1.10,<1.11" - - python: "2.7" - name: "Python 2.7, Django 1.11" - env: DJANGO="Django>=1.11,<1.12" - - python: "3.6" - name: "Python 3.6, Django 1.9" - env: DJANGO="Django>=1.9,<1.10" - - python: "3.6" - name: "Python 3.6, Django 1.10" - env: DJANGO="Django>=1.10,<1.11" - - python: "3.6" - name: "Python 3.6, Django 1.11" - env: DJANGO="Django>=1.11,<1.12" - - python: "3.7" - name: "Python 3.7, Django 1.9" - env: DJANGO="Django>=1.9,<1.10" - - python: "3.7" - name: "Python 3.7, Django 1.10" - env: DJANGO="Django>=1.10,<1.11" - - python: "3.7" - name: "Python 3.7, Django 1.11" - env: DJANGO="Django>=1.11,<1.12" diff --git a/dev-requirements.txt b/dev-requirements.txt index e2913c8..3ece6de 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,11 +1,7 @@ -e . flake8>=3.7.0,<3.8.0 -invoke==1.4.0 pytest==4.6.5 pytest-cov==2.5.1 pytest-django==3.5.1 -sphinx -sphinx_rtd_theme -tox -twine -wheel +#sphinx +#sphinx_rtd_theme diff --git a/tasks.py b/tasks.py deleted file mode 100644 index 497fce7..0000000 --- a/tasks.py +++ /dev/null @@ -1,49 +0,0 @@ -from invoke import run as _run, task -from functools import partial - -# Always echo out the commands -run = partial(_run, echo=True, pty=True) - - -files = "sudo tests *.py" - - -@task -def lint(c, verbose=False): - "Run flake8 linter" - run("flake8 %s %s" % (files, "-v" if verbose else "")) - run("black --check %s" % files) - - -@task -def format(c): - "Run black" - run("black %s" % files) - - -@task -def test(c, verbose=False): - "Run tests using py.test" - run("py.test --cov sudo --cov-report term-missing %s" % ("-v" if verbose else "")) - - -@task -def clean(c): - "Clean working directory" - run("rm -rf *.egg-info *.egg") - run("rm -rf dist build") - - -@task(clean) -def release(c): - "Cut a new release" - version = run("python setup.py --version").stdout.strip() - assert version, "No version found in setup.py?" - - print("### Releasing new version: %s" % version) - run("git tag %s" % version) - run("git push --tags") - - run("python setup.py sdist bdist_wheel") - run("twine check dist/*") - run("twine upload -s dist/*") diff --git a/tox.ini b/tox.ini deleted file mode 100644 index cfa0d3a..0000000 --- a/tox.ini +++ /dev/null @@ -1,10 +0,0 @@ -[tox] -envlist = py27-django{19,110,111}, py36-django{19,110,111}, py37-django{19,110,111} - -[testenv] -deps = - -r dev-requirements.txt - django19: Django >=1.9,<1.10 - django110: Django >=1.10,<1.11 - django111: Django >=1.11,<1.12 -commands = py.test --cov sudo --cov-report term-missing From b3173905fd761b9286a634acb0c2ff2b331af37c Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 28 Apr 2021 15:47:17 -0700 Subject: [PATCH 02/10] basic gha config --- .github/workflows/test.yml | 32 ++++++++++++++++++++++++++++++++ setup.py | 4 +--- 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..485954c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,32 @@ +name: Test + +on: + push: + branches: + - master + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + # todo 3.8 + python-version: [3.6] + # todo more django versions + django-version: [">=1.11,<2"] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip --disable-pip-version-check install -r dev-requirements.txt + pip install "Django${{ matrix.django-version }}" + # todo lint + - name: Run tests + run: | + pytest diff --git a/setup.py b/setup.py index 923800b..0dbafd1 100755 --- a/setup.py +++ b/setup.py @@ -33,11 +33,9 @@ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", + # "Programming Language :: Python :: 3.8", "Programming Language :: Python", "Topic :: Software Development", ], From 571b4b0df1f6e208100385a9242d5a72e669367e Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 28 Apr 2021 16:04:05 -0700 Subject: [PATCH 03/10] bump testing dependencies to good versions --- dev-requirements.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 3ece6de..9181a73 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,6 @@ -e . -flake8>=3.7.0,<3.8.0 -pytest==4.6.5 -pytest-cov==2.5.1 -pytest-django==3.5.1 +flake8==3.8.4 +pytest==6.1.0 +pytest-django==3.10.0 #sphinx #sphinx_rtd_theme From ad55f14f6e5d11b18c26b44ecc32a9c5fbeb5ea4 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 28 Apr 2021 16:15:35 -0700 Subject: [PATCH 04/10] give pytest-django six --- .github/workflows/test.yml | 4 +++- dev-requirements.txt | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 485954c..ce5bcb6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,6 +9,8 @@ on: jobs: build: runs-on: ubuntu-latest + name: Python ${{ matrix.python-version }}, Django${{ matrix.django-version }} + strategy: matrix: # todo 3.8 @@ -18,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} + - name: Install Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} diff --git a/dev-requirements.txt b/dev-requirements.txt index 9181a73..de48c63 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,5 +2,9 @@ flake8==3.8.4 pytest==6.1.0 pytest-django==3.10.0 + +# HACK: pytest-django just assumes six is installed without requiring it. +six==1.15.0 + #sphinx #sphinx_rtd_theme From 26015ee668bad8cd12d48cdfe5adf3fd287b1897 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 28 Apr 2021 16:48:10 -0700 Subject: [PATCH 05/10] resolve deprecations, some tests should fail on 2.1 --- .github/workflows/test.yml | 4 ++-- sudo/utils.py | 4 ++-- sudo/views.py | 4 ++-- tests/base.py | 2 +- tests/utils.py | 34 +++++++++++++--------------------- tests/views.py | 4 ++-- 6 files changed, 22 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ce5bcb6..19d25a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,8 +15,8 @@ jobs: matrix: # todo 3.8 python-version: [3.6] - # todo more django versions - django-version: [">=1.11,<2"] + # todo ">=2.2,<2.3" + django-version: [">=1.11,<2", ">=2.0,<2.1", ">=2.1,<2.2"] steps: - uses: actions/checkout@v2 diff --git a/sudo/utils.py b/sudo/utils.py index d062f2c..b3785fd 100644 --- a/sudo/utils.py +++ b/sudo/utils.py @@ -25,7 +25,7 @@ def grant_sudo_privileges(request, max_age=COOKIE_AGE): if user is None: return - if not user.is_authenticated(): + if not user.is_authenticated: raise ValueError("User needs to be logged in to be elevated to sudo") # Token doesn't need to be unique, @@ -53,7 +53,7 @@ def has_sudo_privileges(request): """ if getattr(request, "_sudo", None) is None: try: - request._sudo = request.user.is_authenticated() and constant_time_compare( + request._sudo = request.user.is_authenticated and constant_time_compare( request.get_signed_cookie( COOKIE_NAME, salt=COOKIE_SALT, max_age=COOKIE_AGE ), diff --git a/sudo/views.py b/sudo/views.py index 5358fd8..4203c4d 100644 --- a/sudo/views.py +++ b/sudo/views.py @@ -48,7 +48,7 @@ def grant_sudo_privileges(self, request, redirect_to): # Restore the redirect destination from the GET request redirect_to = request.session.pop(REDIRECT_TO_FIELD_NAME, redirect_to) # Double check we're not redirecting to other sites - if not is_safe_url(url=redirect_to, host=request.get_host()): + if not is_safe_url(url=redirect_to, allowed_hosts={request.get_host()}): redirect_to = resolve_url(REDIRECT_URL) return HttpResponseRedirect(redirect_to) @@ -60,7 +60,7 @@ def dispatch(self, request): redirect_to = request.GET.get(REDIRECT_FIELD_NAME, REDIRECT_URL) # Make sure we're not redirecting to other sites - if not is_safe_url(url=redirect_to, host=request.get_host()): + if not is_safe_url(url=redirect_to, allowed_hosts={request.get_host()}): redirect_to = resolve_url(REDIRECT_URL) if request.is_sudo(): diff --git a/tests/base.py b/tests/base.py index e49a40c..88a9fb0 100644 --- a/tests/base.py +++ b/tests/base.py @@ -13,7 +13,7 @@ class StubPasswordBackend(object): password = "stub" - def authenticate(self, username, password): + def authenticate(self, username, password, request=None): if password == self.password: return User() diff --git a/tests/utils.py b/tests/utils.py index 67b4c8d..c23449a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -15,7 +15,7 @@ class GrantSudoPrivilegesTestCase(BaseTestCase): def assertRequestHasToken(self, request, max_age): token = request.session[COOKIE_NAME] - self.assertRegexpMatches(token, r"^\w{12}$") + self.assertRegex(token, r"^\w{12}$") self.assertTrue(request._sudo) self.assertEqual(request._sudo_token, token) self.assertEqual(request._sudo_max_age, max_age) @@ -108,25 +108,17 @@ def test_missing_keys(self): class IsSafeUrlTestCase(BaseTestCase): def test_success(self): - urls = ( - ("/", None), - ("/foo/", None), - ("/", "example.com"), - ("http://example.com/foo", "example.com"), - ) - for url in urls: - self.assertTrue(is_safe_url(*url)) + self.assertTrue(is_safe_url("/", allowed_hosts=None)) + self.assertTrue(is_safe_url("/foo/", allowed_hosts=None)) + self.assertTrue(is_safe_url("/", allowed_hosts={"example.com"})) + self.assertTrue(is_safe_url("http://example.com/foo", allowed_hosts={"example.com"})) def test_failure(self): - urls = ( - (None, None), - ("", ""), - ("http://mattrobenolt.com/", "example.com"), - ("///example.com/", None), - ("ftp://example.com", "example.com"), - ("http://example.com\@mattrobenolt.com", "example.com"), # noqa: W605 - ("http:///example.com", "example.com"), - ("\x08//example.com", "example.com"), - ) - for url in urls: - self.assertFalse(is_safe_url(*url)) + self.assertFalse(is_safe_url(None, allowed_hosts=None)) + self.assertFalse(is_safe_url("", allowed_hosts={""})) + self.assertFalse(is_safe_url("http://mattrobenolt.com/", allowed_hosts={"example.com"})) + self.assertFalse(is_safe_url("///example.com/", allowed_hosts=None)) + self.assertFalse(is_safe_url("ftp://example.com", allowed_hosts={"example.com"})) + self.assertFalse(is_safe_url("http://example.com\\@mattrobenolt.com", allowed_hosts={"example.com"})) + self.assertFalse(is_safe_url("http:///example.com", allowed_hosts={"example.com"})) + self.assertFalse(is_safe_url("\x08//example.com", allowed_hosts={"example.com"})) diff --git a/tests/views.py b/tests/views.py index 449dc04..3274a5e 100644 --- a/tests/views.py +++ b/tests/views.py @@ -62,7 +62,7 @@ def test_redirect_fix_bad_url(self): response = sudo(self.request) self.assertEqual(response["Location"], REDIRECT_URL) self.request.GET = { - REDIRECT_FIELD_NAME: "http://%s\@mattrobenolt.com" + REDIRECT_FIELD_NAME: "http://%s\\@mattrobenolt.com" % self.request.get_host(), # noqa: W605 } response = sudo(self.request) @@ -117,7 +117,7 @@ def test_session_based_redirect_bad_url(self): self.assertEqual(response["Location"], REDIRECT_URL) self.assertFalse("redirect_to" in self.request.session) self.request.session[REDIRECT_TO_FIELD_NAME] = ( - "http://%s\@mattrobenolt.com" % self.request.get_host() # noqa: W605 + "http://%s\\@mattrobenolt.com" % self.request.get_host() # noqa: W605 ) response = sudo(self.request) self.assertEqual(response["Location"], REDIRECT_URL) From 9a18db6b795943b21b439fcd268a35fef10da6c6 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Mon, 10 May 2021 15:04:14 -0700 Subject: [PATCH 06/10] use MiddlewareMixin to adapt to MIDDLEWARE --- README.md | 4 ++-- conftest.py | 4 ++-- docs/getting-started/index.rst | 4 ++-- docs/usage/index.rst | 2 +- sudo/middleware.py | 6 ++++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a5821e7..888febb 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ $ pip install django-sudo ## Compatibility -* Django 1.9-1.11 -* Python 2.7, 3.6-3.7 +* Django 1.11 - 2.2 +* Python 3.6 - 3.8 ## Resources diff --git a/conftest.py b/conftest.py index 9cf1b19..c78ba0b 100644 --- a/conftest.py +++ b/conftest.py @@ -5,7 +5,7 @@ "sudo", ] -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ "django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", ] @@ -35,7 +35,7 @@ def pytest_configure(config): DATABASE_NAME=":memory:", TEST_DATABASE_NAME=":memory:", INSTALLED_APPS=INSTALLED_APPS, - MIDDLEWARE_CLASSES=MIDDLEWARE_CLASSES, + MIDDLEWARE=MIDDLEWARE, PASSWORD_HASHERS=["django.contrib.auth.hashers.MD5PasswordHasher"], ROOT_URLCONF="tests.urls", ) diff --git a/docs/getting-started/index.rst b/docs/getting-started/index.rst index 42d4f0b..ac015fa 100644 --- a/docs/getting-started/index.rst +++ b/docs/getting-started/index.rst @@ -20,11 +20,11 @@ will automatically register the ``user_logged_in`` and ``user_logged_out`` signa 'sudo', ) -Now we need to install the required middleware into ``MIDDLEWARE_CLASSES``: +Now we need to install the required middleware into ``MIDDLEWARE``: .. code-block:: python - MIDDLEWARE_CLASSES = ( + MIDDLEWARE = ( # ... 'sudo.middleware.SudoMiddleware', ) diff --git a/docs/usage/index.rst b/docs/usage/index.rst index f38a767..7da8dc9 100644 --- a/docs/usage/index.rst +++ b/docs/usage/index.rst @@ -51,7 +51,7 @@ the :class:`~sudo.middleware.SudoMiddleware`. This is an shortcut for calling .. class:: sudo.middleware.SudoMiddleware - By default, you just need to add this into your ``MIDDLEWARE_CLASSES`` list. + By default, you just need to add this into your ``MIDDLEWARE`` list. .. method:: has_sudo_privileges(self, request) diff --git a/sudo/middleware.py b/sudo/middleware.py index 9c91426..41b5bdb 100644 --- a/sudo/middleware.py +++ b/sudo/middleware.py @@ -15,8 +15,10 @@ ) from sudo.utils import has_sudo_privileges +from django.utils.deprecation import MiddlewareMixin -class SudoMiddleware(object): + +class SudoMiddleware(MiddlewareMixin): """ Middleware that contributes ``request.is_sudo()`` and sets the required cookie for sudo mode to work correctly. @@ -29,7 +31,7 @@ def has_sudo_privileges(self, request): def process_request(self, request): assert hasattr(request, "session"), ( "The Sudo middleware requires session middleware to be installed." - "Edit your MIDDLEWARE_CLASSES setting to insert " + "Edit your MIDDLEWARE setting to insert " "'django.contrib.sessions.middleware.SessionMiddleware' before " "'sudo.middleware.SudoMiddleware'." ) From c0e11d314a333d3cdb9d8b26e9b5ee2553477db0 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 14 May 2021 17:30:59 -0700 Subject: [PATCH 07/10] hmm --- sudo/forms.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sudo/forms.py b/sudo/forms.py index 27b8250..609d342 100644 --- a/sudo/forms.py +++ b/sudo/forms.py @@ -23,6 +23,8 @@ def __init__(self, user, *args, **kwargs): def clean_password(self): username = self.user.get_username() - if auth.authenticate(username=username, password=self.data["password"]): + # I think we need to pass the actual request object. + + if auth.authenticate(request=None, username=username, password=self.data["password"]): return self.data["password"] raise forms.ValidationError(_("Incorrect password")) From bfac98b715b708995efda44fa79dda36e158c4f3 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Tue, 18 May 2021 10:08:18 -0700 Subject: [PATCH 08/10] we did it --- sudo/forms.py | 1 - tests/base.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sudo/forms.py b/sudo/forms.py index 609d342..0a02e74 100644 --- a/sudo/forms.py +++ b/sudo/forms.py @@ -23,7 +23,6 @@ def __init__(self, user, *args, **kwargs): def clean_password(self): username = self.user.get_username() - # I think we need to pass the actual request object. if auth.authenticate(request=None, username=username, password=self.data["password"]): return self.data["password"] diff --git a/tests/base.py b/tests/base.py index 88a9fb0..cbf1376 100644 --- a/tests/base.py +++ b/tests/base.py @@ -13,7 +13,7 @@ class StubPasswordBackend(object): password = "stub" - def authenticate(self, username, password, request=None): + def authenticate(self, request, username, password): if password == self.password: return User() From 2ae5e78aa31cd467c92b8b0899f353a03e5f8f22 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Tue, 18 May 2021 10:09:01 -0700 Subject: [PATCH 09/10] enable more testing --- .github/workflows/test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 19d25a0..ae94f9f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,8 +15,7 @@ jobs: matrix: # todo 3.8 python-version: [3.6] - # todo ">=2.2,<2.3" - django-version: [">=1.11,<2", ">=2.0,<2.1", ">=2.1,<2.2"] + django-version: [">=1.11,<2", ">=2.0,<2.1", ">=2.1,<2.2", ">=2.2,<2.3"] steps: - uses: actions/checkout@v2 From 6221d933d923a85ba039e814d9bb595f28cecedc Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Tue, 18 May 2021 10:22:33 -0700 Subject: [PATCH 10/10] test on 3.7, 3.8, update various things --- .github/workflows/test.yml | 7 ++++--- docs/changelog/index.rst | 5 +++++ docs/index.rst | 5 ++--- setup.py | 3 ++- sudo/forms.py | 7 ++++++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ae94f9f..8fca2fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,8 +13,7 @@ jobs: strategy: matrix: - # todo 3.8 - python-version: [3.6] + python-version: [3.6, 3.7, 3.8] django-version: [">=1.11,<2", ">=2.0,<2.1", ">=2.1,<2.2", ">=2.2,<2.3"] steps: @@ -27,7 +26,9 @@ jobs: run: | pip --disable-pip-version-check install -r dev-requirements.txt pip install "Django${{ matrix.django-version }}" - # todo lint + - name: Run lint + run: | + flake8 sudo/ - name: Run tests run: | pytest diff --git a/docs/changelog/index.rst b/docs/changelog/index.rst index 3bd35d7..3fc2eaa 100644 --- a/docs/changelog/index.rst +++ b/docs/changelog/index.rst @@ -1,6 +1,11 @@ Changelog ========= +4.0.0 (unreleased) +~~~~~~~~~~~~~~~~~~ +* Added support for Django 2.0 - 2.2, Python 3.7 - 3.8 +* Dropped support for Django < 1.11 + 3.1.0 ~~~~~ * Added support for Django 1.11 diff --git a/docs/index.rst b/docs/index.rst index 994c505..566c4ac 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,9 +22,8 @@ Installation Compatibility ~~~~~~~~~~~~~ -* Django 1.4-1.9 -* Python 2.6-3.5 -* pypy +* Django 1.11-2.2 +* Python 3.6-3.8 Contents ~~~~~~~~ diff --git a/setup.py b/setup.py index 0dbafd1..ac76c39 100755 --- a/setup.py +++ b/setup.py @@ -35,7 +35,8 @@ "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", - # "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Programming Language :: Python", "Topic :: Software Development", ], diff --git a/sudo/forms.py b/sudo/forms.py index 0a02e74..5081abf 100644 --- a/sudo/forms.py +++ b/sudo/forms.py @@ -24,6 +24,11 @@ def __init__(self, user, *args, **kwargs): def clean_password(self): username = self.user.get_username() - if auth.authenticate(request=None, username=username, password=self.data["password"]): + if auth.authenticate( + request=None, + username=username, + password=self.data["password"], + ): return self.data["password"] + raise forms.ValidationError(_("Incorrect password"))