fix(oauth): normalize OAuth sub claim to str to prevent PostgreSQL type mismatch

GitHub's /user API returns 'id' as a JSON number. When this numeric value
reaches get_user_by_oauth_sub(), the PostgreSQL query
  User.oauth[provider].cast(JSONB)['sub'].astext == sub
compares TEXT against INTEGER, raising:
  psycopg.errors.UndefinedFunction: operator does not exist: text = integer

The SQLite path has the mirror-image problem: json_contains with an int sub
never matches a record stored with a string sub, causing silent lookup misses.

Fix: convert the extracted sub to str immediately after extraction, before it
is stored in oauth_data or passed to any lookup/signup function. This is
consistent with OIDC providers where 'sub' is already a string per RFC 7519.

Closes #27760
This commit is contained in:
loulanyue 2026-08-01 18:48:44 +08:00
parent 52145eede9
commit 2b52b18faa

View file

@ -1834,6 +1834,10 @@ class OAuthManager:
if not sub:
log.warning(f'OAuth callback failed, sub is missing: {user_data}')
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
# Normalize to str: some providers (e.g. GitHub) return a numeric id.
# Without this, PostgreSQL fails with "operator does not exist: text = integer"
# and SQLite containment checks silently miss (int vs str mismatch).
sub = str(sub)
oauth_data = {}
oauth_data[provider] = {