Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@ env:
PY_COLORS: 1

jobs:
black:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- uses: psf/black@stable
with:
options: "--check ."
- uses: astral-sh/ruff-action@v3
- run: ruff check .
- run: ruff format --check .
commitlint:
runs-on: ubuntu-latest
steps:
Expand All @@ -33,7 +30,7 @@ jobs:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:18.1
image: postgres:18.3
env:
POSTGRES_HOST_AUTH_METHOD: trust
# Set health checks to wait until postgres has started
Expand All @@ -45,11 +42,11 @@ jobs:
ports:
- 5432:5432
memcached:
image: memcached:1.6.40-alpine
image: memcached:1.6.41-alpine
ports:
- 11211:11211
redis:
image: redis:8.4.0-alpine
image: redis:8.6.1-alpine
ports:
- 6379:6379
steps:
Expand All @@ -61,7 +58,7 @@ jobs:
python-version: "3.13"
- uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7
with:
version: '0.8.2'
version: '0.10.9'
enable-cache: false
- uses: actions/setup-node@v6
with:
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
path = deps/sentry
url = https://github.com/getsentry/sentry.git
# This is here for renovate
branch = 26.2.0
branch = 26.2.1
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.13.5
3.13
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
postgres:
image: postgres:18.1
image: postgres:18.3
environment:
POSTGRES_HOST_AUTH_METHOD: trust
# Set health checks to wait until postgres has started
Expand All @@ -12,10 +12,10 @@ services:
ports:
- 5432:5432
memcached:
image: memcached:1.6.40-alpine
image: memcached:1.6.41-alpine
ports:
- 11211:11211
redis:
image: redis:8.4.0-alpine
image: redis:8.6.1-alpine
ports:
- 6379:6379
4 changes: 1 addition & 3 deletions oidc/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
USERINFO_ENDPOINT = getattr(settings, "OIDC_USERINFO_ENDPOINT", None)
SCOPE = getattr(settings, "OIDC_SCOPE", "openid email")
WELL_KNOWN_SCHEME = "/.well-known/openid-configuration"
ERR_INVALID_RESPONSE = (
"Unable to fetch user information from provider. Please check the log."
)
ERR_INVALID_RESPONSE = "Unable to fetch user information from provider. Please check the log."
ISSUER = None

DATA_VERSION = "1"
Expand Down
13 changes: 4 additions & 9 deletions oidc/provider.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from __future__ import annotations

from collections.abc import Callable

from django.http import HttpRequest

import time
from collections.abc import Callable

import requests
from django.http import HttpRequest
from sentry.auth.provider import MigratingIdentityId
from sentry.auth.providers.oauth2 import OAuth2Callback, OAuth2Login, OAuth2Provider
from sentry.auth.services.auth.model import RpcAuthProvider
Expand Down Expand Up @@ -60,10 +58,7 @@ def __init__(self, domain=None, domains=None, version=None, **config):
# this is a bit complex in Sentry's SSO implementation as we don't
# provide a great way to get initial state for new setup pipelines
# vs missing state in case of migrations.
if domains is None:
version = DATA_VERSION
else:
version = None
version = DATA_VERSION if domains is None else None
self.version = version
super().__init__(**config)

Expand Down Expand Up @@ -100,7 +95,7 @@ def get_user_info(self, bearer_token):
bearer_auth = "Bearer " + bearer_token
retry_codes = [429, 500, 502, 503, 504]
for retry in range(10):
if 10 < retry:
if retry > 10:
return {}
r = requests.get(
endpoint + "?schema=openid",
Expand Down
18 changes: 7 additions & 11 deletions oidc/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

from django.http import HttpRequest
from rest_framework.response import Response

from sentry.auth.services.auth.model import RpcAuthProvider
from sentry.auth.view import AuthView
from sentry.utils import json
from sentry.organizations.services.organization.model import RpcOrganization
from sentry.plugins.base.response import DeferredResponse
from sentry.utils import json
from sentry.utils.signing import urlsafe_b64decode

from .constants import ERR_INVALID_RESPONSE, ISSUER
Expand All @@ -32,38 +31,35 @@ def dispatch(self, request: HttpRequest, **kwargs) -> Response: # type: ignore
pipeline = kwargs["helper"]
else:
raise TypeError(
f"FetchUser.dispatch() is missing either the `pipeline` or the `helper` keyword argument."
"FetchUser.dispatch() is missing either the `pipeline` or the `helper` keyword argument."
)

data = pipeline.fetch_state("data")

try:
id_token = data["id_token"]
except KeyError:
logger.error("Missing id_token in OAuth response: %s" % data)
logger.error(f"Missing id_token in OAuth response: {data}")
return pipeline.error(ERR_INVALID_RESPONSE)

try:
_, payload, _ = map(urlsafe_b64decode, id_token.split(".", 2))
except Exception as exc:
logger.error("Unable to decode id_token: %s" % exc, exc_info=True)
logger.error(f"Unable to decode id_token: {exc}", exc_info=True)
return pipeline.error(ERR_INVALID_RESPONSE)

try:
payload = json.loads(payload)
except Exception as exc:
logger.error("Unable to decode id_token payload: %s" % exc, exc_info=True)
logger.error(f"Unable to decode id_token payload: {exc}", exc_info=True)
return pipeline.error(ERR_INVALID_RESPONSE)

if not payload.get("email"):
logger.error("Missing email in id_token payload: %s" % id_token)
logger.error(f"Missing email in id_token payload: {id_token}")
return pipeline.error(ERR_INVALID_RESPONSE)

# support legacy style domains with pure domain regexp
if self.version is None:
domain = extract_domain(payload["email"])
else:
domain = payload.get("hd")
domain = extract_domain(payload["email"]) if self.version is None else payload.get("hd")

pipeline.bind_state("domain", domain)
pipeline.bind_state("user", payload)
Expand Down
35 changes: 27 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ oidc = "oidc.apps.Config"

[dependency-groups]
dev = [
"black>=26.0.0,<27",
"isort>=7.0.0,<8",
"flake8>=7.0.0,<8",
"ruff>=0.10.0,<1",
]
test = [
"codecov>=2.1.12,<3",
Expand All @@ -39,8 +37,32 @@ test = [
"xmlsec>=1.3.14",
]

[tool.black]
extend-exclude = "deps"
[tool.ruff]
line-length = 100
extend-exclude = ["deps"]

[tool.ruff.lint]
extend-ignore = [
"E402",
"E501",
"E731",
]
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
# isort
"I",
]

[tool.ruff.format]

[tool.uv]
default-groups = [
Expand All @@ -56,8 +78,5 @@ module-root = ""
requires = ["uv_build>=0.10.4,<0.11.0"]
build-backend = "uv_build"

[tool.isort]
profile = "black"

[tool.pytest.ini_options]
testpaths = ["tests"]
5 changes: 0 additions & 5 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,3 @@ universal = 1
python_files = test*.py
addopts = --tb=native -p no:doctest
norecursedirs = bin dist docs htmlcov script hooks node_modules .* {args}

[flake8]
ignore = F999,E501,E128,E124,E402,W503,E731,C901
max-line-length = 100
exclude = .tox,.git,*/migrations/*,node_modules/*,docs/*
Loading