diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000..4e751977 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,20 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v3 diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index fe654d9f..f50e8aa9 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -8,20 +8,15 @@ jobs: - uses: actions/setup-python@v4 with: python-version: 3.x + check-latest: true - run: pip install --upgrade pip setuptools wheel - - run: pip install bandit black codespell flake8 flake8-2020 flake8-bugbear - flake8-comprehensions isort mypy pytest pyupgrade safety - - run: bandit --recursive --skip B101,B105,B106,B107,B324 . + - run: pip install black codespell mypy pytest ruff safety + - run: ruff --format=github . - run: black --check . || true - - run: codespell || true # --ignore-words-list="" --skip="*.css,*.js,*.lock" - - run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - - run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 - --show-source --statistics - - run: isort --check-only --profile black . || true - - run: pip install -r requirements.txt || pip install --editable . || true + - run: codespell # --ignore-words-list="" --skip="*.css,*.js,*.lock" + - run: pip install -r requirements-test.txt + - run: pip install --editable . - run: mkdir --parents --verbose .mypy_cache - run: mypy --ignore-missing-imports --install-types --non-interactive . || true - - run: pytest . || true - - run: pytest --doctest-modules . || true - - run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true + - run: pytest - run: safety check diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index c7af97ad..0f7ddf1b 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -1,19 +1,21 @@ name: Python Tests run-name: Run Tests by ${{ github.actor }} -on: [push] +on: [push, pull_request, workflow_dispatch] jobs: tests: env: + FORCE_COLOR: 1 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} strategy: matrix: - python: ["3.8", "3.9", "3.10", "3.11"] + python: ["3.8", "3.9", "3.10", "3.11", "3.12"] runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} + allow-prereleases: true - name: Check out repository code uses: actions/checkout@v3 - name: Install prereq diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 89262709..43417ee5 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -7,6 +7,7 @@ on: jobs: pypi-publish: if: | + github.repository_owner == 'oauthlib' && ${{ github.event.workflow_run.conclusion == 'success' }} && ${{ github.ref_type == 'tag' }} name: Upload release to PyPI diff --git a/Makefile b/Makefile index 2d2e1ed7..28081659 100644 --- a/Makefile +++ b/Makefile @@ -34,11 +34,11 @@ clean-build: @rm -fr dist/ @rm -fr *.egg-info -format fmt: - isort --recursive oauthlib tests +format fmt black: + black . -lint: - isort --recursive --check-only --diff oauthlib tests +lint ruff: + ruff . test: tox @@ -81,4 +81,4 @@ dance: .DEFAULT_GOAL := all .PHONY: clean test bottle dance django flask requests -all: test bottle dance django flask requests +all: lint test bottle dance django flask requests diff --git a/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py b/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py index ce33df0e..43bf55ac 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py +++ b/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py @@ -101,6 +101,9 @@ def validate_token_request(self, request): if not self.request_validator.authenticate_client(request): log.debug('Invalid client (%r), denying access.', request) raise errors.InvalidClientError(request=request) + # Ensure that request.client_id is set. + if request.client_id is None and request.client is not None: + request.client_id = request.client.client_id elif not self.request_validator.authenticate_client_id(request.client_id, request): log.debug('Client authentication failed, %r.', request) raise errors.InvalidClientError(request=request) diff --git a/setup.py b/setup.py index b5c2eebc..4043db0f 100755 --- a/setup.py +++ b/setup.py @@ -56,6 +56,7 @@ def fread(fn): 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: Implementation', 'Programming Language :: Python :: Implementation :: CPython', diff --git a/tests/oauth1/rfc5849/test_utils.py b/tests/oauth1/rfc5849/test_utils.py index 013c71a9..22128908 100644 --- a/tests/oauth1/rfc5849/test_utils.py +++ b/tests/oauth1/rfc5849/test_utils.py @@ -53,11 +53,11 @@ def test_filter_params(self): # The following is an isolated test function used to test the filter_params decorator. @filter_params def special_test_function(params, realm=None): - """ I am a special test function """ + """I am a special test function""" return 'OAuth ' + ','.join(['='.join([k, v]) for k, v in params]) # check that the docstring got through - self.assertEqual(special_test_function.__doc__, " I am a special test function ") + self.assertEqual(special_test_function.__doc__, "I am a special test function") # Check that the decorator filtering works as per design. # Any param that does not start with 'oauth' diff --git a/tests/oauth2/rfc6749/grant_types/test_refresh_token.py b/tests/oauth2/rfc6749/grant_types/test_refresh_token.py index 581f2a4d..0a4ddd9a 100644 --- a/tests/oauth2/rfc6749/grant_types/test_refresh_token.py +++ b/tests/oauth2/rfc6749/grant_types/test_refresh_token.py @@ -130,6 +130,22 @@ def test_authentication_required(self): self.request) self.mock_validator.client_authentication_required.assert_called_once_with(self.request) + + def test_authentication_required_populate_client_id(self): + """ + Make sure that request.client_id is populated from + request.client.client_id if None. + + """ + self.mock_validator.client_authentication_required.return_value = True + self.mock_validator.authenticate_client.return_value = True + # self.mock_validator.authenticate_client_id.return_value = False + # self.request.code = 'waffles' + self.request.client_id = None + self.request.client.client_id = 'foobar' + self.auth.validate_token_request(self.request) + self.request.client_id = 'foobar' + def test_invalid_grant_type(self): self.request.grant_type = 'wrong_type' self.assertRaises(errors.UnsupportedGrantTypeError, diff --git a/tox.ini b/tox.ini index 3195c771..fb476a12 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ # require tox>=4 [tox] -envlist = py38,py39,py310,py311,pypy3,docs,readme,bandit,isort +envlist = py38,py39,py310,py311,py312,pypy3,docs,readme,ruff [testenv] deps= @@ -9,7 +9,6 @@ commands= pytest --cov=oauthlib tests/ # tox -e docs to mimic readthedocs build. -# as of today, RTD is using python3.7 and doesn't run "setup.py install" [testenv:docs] basepython=python3.11 skipsdist=True @@ -28,16 +27,8 @@ allowlist_externals=echo commands= twine check .tox/.pkg/dist/* -[testenv:bandit] -basepython=python3.11 -skipsdist=True -deps=bandit -commands=bandit -b bandit.json -r oauthlib/ -allowlist_externals=bandit - -[testenv:isort] -basepython = python3.8 -usedevelop = false -deps = isort -changedir = {toxinidir} -commands = isort --recursive --check-only --diff oauthlib tests +[testenv:ruff] +deps=ruff +allowlist_externals=ruff +skip_install=true +commands=ruff .