From 8d69e57be9d7023691d8fcbc8ba36fcbd641b1b7 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Thu, 22 Feb 2024 17:33:27 +0100 Subject: [PATCH] refactor: adapt dependency management for v24 --- .github/workflows/publish.yml | 2 +- .github/workflows/test.yml | 12 ++++---- .gitignore | 3 ++ .python-version | 2 +- Makefile | 22 +++++++------- conftest.py | 8 ----- docker-compose.yml | 21 +++++++++++++ oidc/provider.py | 12 ++------ poetry.lock | 55 +++++++++++++++++++++++------------ pyproject.toml | 12 ++++++-- tests/test_provider.py | 40 ++++++++++--------------- 11 files changed, 106 insertions(+), 83 deletions(-) delete mode 100644 conftest.py create mode 100644 docker-compose.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 11b64d8..97032df 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - uses: abatilo/actions-poetry@v2 - name: Publish package run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 132f98d..e63c89c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - uses: psf/black@stable with: options: "--check ." @@ -56,7 +56,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - uses: abatilo/actions-poetry@v2 - uses: actions/setup-node@v3 with: @@ -65,8 +65,6 @@ jobs: run: yarn set version 1.22.21 - run: | sudo apt-get update && sudo apt-get install -y libxmlsec1-dev libmaxminddb-dev - python3 -m venv venv - . venv/bin/activate - venv/bin/pip3 install -U wheel - make develop - make test + poetry install --with test + make deps + poetry run pytest diff --git a/.gitignore b/.gitignore index 98f501a..d631ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ venv .venv .coverage .vscode/ +# Fetched from upstream +requirements-sentry.txt +tests/conftest.py diff --git a/.python-version b/.python-version index 9919bf8..b6d8b76 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.10.13 +3.11.8 diff --git a/Makefile b/Makefile index b3c0090..dcc8ee1 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,17 @@ SENTRY_VERSION := 24.2.0 -.PHONY: clean develop test +.PHONY: clean deps -develop: - pip3 install -e git+https://github.com/getsentry/sentry.git@$(SENTRY_VERSION)#egg=sentry[dev] - poetry install -n --no-dev - poetry build && pip3 install -U dist/*.whl - pip3 install -U codecov pytest freezegun fixtures - -test: - @echo "--> Running Python tests" - python -m pytest tests || exit 1 - @echo "" +# Upstream no longer tracks its own dependencies in the package as dev extras, +# so we cannot resolve them here as transitive dependencies. Instead we fetch +# their locked development dependencies. +# Likewise, their root-level conftest is not provided as a pytest plugin for +# use outside their own tests, but we need their fixtures. We fetch them into +# our own namespace here. +deps: + curl -L -o requirements-sentry.txt https://github.com/getsentry/sentry/raw/$(SENTRY_VERSION)/requirements-dev-frozen.txt + curl -L -o tests/conftest.py https://github.com/getsentry/sentry/raw/$(SENTRY_VERSION)/tests/conftest.py + poetry run pip install -r requirements-sentry.txt clean: rm -rf *.egg-info src/*.egg-info diff --git a/conftest.py b/conftest.py deleted file mode 100644 index b34a1ce..0000000 --- a/conftest.py +++ /dev/null @@ -1,8 +0,0 @@ -import os -import sys - -os.environ.setdefault("DB", "postgres") - -sys.path.insert(0, os.path.join(os.path.dirname(__file__))) - -pytest_plugins = ["sentry.testutils.pytest"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..84047e2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +services: + postgres: + image: postgres:14.11 + environment: + POSTGRES_HOST_AUTH_METHOD: trust + # Set health checks to wait until postgres has started + healthcheck: + test: ["CMD-SHELL", “pg_isready”] + interval: 10s + timeout: 5s + retries: 5 + ports: + - 5432:5432 + memcached: + image: memcached:1.6.23-alpine + ports: + - 11211:11211 + redis: + image: redis:6.2.14-alpine + ports: + - 6379:6379 diff --git a/oidc/provider.py b/oidc/provider.py index da28113..749dec6 100644 --- a/oidc/provider.py +++ b/oidc/provider.py @@ -68,26 +68,20 @@ def get_configure_view(self): def get_auth_pipeline(self): return [ - OIDCLogin(self.get_client_id(), domains=self.domains), + OIDCLogin(domains=self.domains, client_id=self.get_client_id()), OAuth2Callback( access_token_url=TOKEN_ENDPOINT, client_id=self.get_client_id(), client_secret=self.get_client_secret(), ), - FetchUser( - domains=self.domains, - version=self.version, - ), + FetchUser(domains=self.domains, version=self.version), ] def get_refresh_token_url(self): return TOKEN_ENDPOINT def build_config(self, state): - return { - "domains": [state["domain"]], - "version": DATA_VERSION, - } + return {"domains": [state["domain"]], "version": DATA_VERSION} def get_user_info(self, bearer_token): endpoint = USERINFO_ENDPOINT diff --git a/poetry.lock b/poetry.lock index 1baae1d..f6bc787 100644 --- a/poetry.lock +++ b/poetry.lock @@ -26,7 +26,6 @@ click = ">=8.0.0" mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -249,18 +248,23 @@ files = [ toml = ["tomli"] [[package]] -name = "exceptiongroup" -version = "1.2.0" -description = "Backport of PEP 654 (exception groups)" +name = "fixtures" +version = "4.1.0" +description = "Fixtures, reusable state for writing clean tests and more." optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "fixtures-4.1.0-py3-none-any.whl", hash = "sha256:a43a55da406c37651aa86dd1ba6c3983a09d36d60fe5f72242872c8a4eeeb710"}, + {file = "fixtures-4.1.0.tar.gz", hash = "sha256:82b1c5e69f615526ef6c067188a1e6c6067df7f88332509c99f8b8fdbb9776f3"}, ] +[package.dependencies] +pbr = ">=5.7.0" + [package.extras] -test = ["pytest (>=6)"] +docs = ["docutils"] +streams = ["testtools"] +test = ["mock", "testtools"] [[package]] name = "flake8" @@ -358,6 +362,17 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +[[package]] +name = "pbr" +version = "6.0.0" +description = "Python Build Reasonableness" +optional = false +python-versions = ">=2.6" +files = [ + {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, + {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, +] + [[package]] name = "platformdirs" version = "4.2.0" @@ -423,11 +438,9 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] @@ -454,15 +467,19 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" +name = "sentry" +version = "24.2.0" +description = "A realtime logging and aggregation server." optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] +python-versions = ">=3.8" +files = [] +develop = false + +[package.source] +type = "git" +url = "https://github.com/getsentry/sentry.git" +reference = "24.2.0" +resolved_reference = "cfcff1f4fda857dcddc9401efb689b6af92a3214" [[package]] name = "urllib3" @@ -483,5 +500,5 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" -python-versions = "^3.10" -content-hash = "02daee215ddae2f6a8a3bdce83fb30a7af8cb83d332b3ea77aec1895fe03685e" +python-versions = "^3.11" +content-hash = "44f9daad82de055130ebbee3c77ee3a0862d0cbd7ebee2b663b15a41f08f8957" diff --git a/pyproject.toml b/pyproject.toml index f201a57..f61bf9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,11 @@ name = "sentry-auth-oidc" version = "8.0.0" description = "OpenID Connect authentication provider for Sentry" -authors = ["Max Wittig , Diego Louzán "] +authors = [ + "Max Wittig ", + "Diego Louzán ", + "Nejc Habjan ", +] license = "Apache 2.0" readme = "README.rst" classifiers = [ @@ -16,14 +20,18 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.10" +python = "^3.11" [tool.poetry.dev-dependencies] black = "^22.8.0" isort = "^5.7.0" flake8 = "^3.8.4" + +[tool.poetry.group.test.dependencies] codecov = "^2.1.12" pytest = "^7.1.3" +sentry = {git = "https://github.com/getsentry/sentry.git", rev = "24.2.0"} +fixtures = "^4.1.0" [tool.isort] profile = "black" diff --git a/tests/test_provider.py b/tests/test_provider.py index b56bd82..fa5331d 100644 --- a/tests/test_provider.py +++ b/tests/test_provider.py @@ -2,55 +2,48 @@ from sentry import auth from sentry.auth.exceptions import IdentityNotValid from sentry.models import AuthIdentity, AuthProvider -from sentry.testutils import TestCase +from sentry.testutils.cases import TestCase +from sentry.testutils.silo import control_silo_test from oidc.constants import DATA_VERSION from oidc.provider import OIDCProvider +@control_silo_test class OIDCProviderTest(TestCase): def setUp(self): - self.user = self.create_user("foo@example.com") - self.org = self.create_organization(owner=self.user) - self.auth_provider = AuthProvider.objects.create( - provider="oidc", - organization=self.org, + self.auth_provider_inst = AuthProvider.objects.create( + provider="oidc", organization_id=self.organization.id ) auth.register("oidc", OIDCProvider) - super(OIDCProviderTest, self).setUp() + super().setUp() def test_refresh_identity_without_refresh_token(self): auth_identity = AuthIdentity.objects.create( - auth_provider=self.auth_provider, + auth_provider=self.auth_provider_inst, user=self.user, - data={ - "access_token": "access_token", - }, + data={"access_token": "access_token"}, ) - provider = self.auth_provider.get_provider() + provider = self.auth_provider_inst.get_provider() with pytest.raises(IdentityNotValid): provider.refresh_identity(auth_identity) def test_handles_multiple_domains(self): - self.auth_provider.update( - config={"domains": ["example.com"]}, - ) + self.auth_provider_inst.update(config={"domains": ["example.com"]}) - provider = self.auth_provider.get_provider() + provider = self.auth_provider_inst.get_provider() assert provider.domains == ["example.com"] def test_handles_legacy_single_domain(self): - self.auth_provider.update( - config={"domain": "example.com"}, - ) + self.auth_provider_inst.update(config={"domain": "example.com"}) - provider = self.auth_provider.get_provider() + provider = self.auth_provider_inst.get_provider() assert provider.domains == ["example.com"] def test_build_config(self): - provider = self.auth_provider.get_provider() + provider = self.auth_provider_inst.get_provider() state = { "domain": "example.com", "user": { @@ -67,7 +60,4 @@ def test_build_config(self): }, } result = provider.build_config(state) - assert result == { - "domains": ["example.com"], - "version": DATA_VERSION, - } + assert result == {"domains": ["example.com"], "version": DATA_VERSION}