fix(sso): tolerate missing active_organization in JWT response (sso_get_token)#1228
Open
fix(sso): tolerate missing active_organization in JWT response (sso_get_token)#1228
Conversation
…ization Restore 0.45.8 behavior at arrow_uploader.py sso_get_token: when the server's JWT response omits (or nulls) active_organization, preserve self.org_name (already populated in __init__ from register(org_name=...) or client_session.org_name) and skip _switch_org instead of raising. This unblocks customers running against site-wide-SSO servers (no per-org binding) — which legitimately omit the field — from upgrading past 0.45.8. The strict raise was introduced in 0.45.10 (PR #832 / #850 cluster). Backwards compatible: when active_organization IS present, behavior is identical to current master (use the supplied slug, call _switch_org). Replaces test_sso_get_token_missing_org_raises (which pinned the bug) with three fallback tests covering: missing field + no caller org_name, missing field + caller org_name preserved, null active_organization. Companion server-side fix: graphistry/graphistry#3002 (already merged); this client-side fix is required for older servers and for defense-in-depth on newer ones. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ArrowUploader.sso_get_tokenraisesException("SSO response missing active organization; ...")when the server's JWT response payload omits (or nulls) theactive_organizationfield. Site-wide-SSO server configurations (no per-org binding) legitimately omit this field, so login fails against any such server.This PR restores the pre-
0.45.10behavior at this site: gracefully fall back to the existingself.org_name(set in__init__fromregister(org_name=...)orclient_session.org_name) and skip_switch_org. Whenactive_organizationIS present, behavior is unchanged.Before / After
Before (
graphistry/arrow_uploader.py:430-439):After:
Backwards-compatibility matrix
active_organization: {"slug": "x", ...}x, switch orgx, switch org (identical)active_organization: Noneself.org_name, no switchactive_organizationabsentself.org_name, no switchactive_organization: {"slug": ""}self.org_name, no switchactive_organization: "non-dict"AttributeErrorself.org_name, no switch (now defensive)The graceful path does not manufacture org access: if the server doesn't bind an org to the session, the client doesn't either — the client merely preserves whatever
org_namethe caller passed toregister()(or whatever the session already had). The next request that needs org context routes through existing_switch_orgpaths.Other read-site audit
active_organizationhas only two production read sites in this repo:arrow_uploader.py:307(_finalize_login, used bylogin()/pkey_login()) — already tolerant via.get('active_organization', {}). Not changed.arrow_uploader.py:430(sso_get_token) — strict raise. This PR.Test changes
The pre-existing
test_sso_get_token_missing_org_raiseswas authored to assert the strict-raise behavior viapytest.raises(Exception); that test pinned the regression in place and is removed. Three replacement tests added intests/test_arrow_uploader.py:test_sso_get_token_missing_active_organization_no_caller_org— payload omits the field, caller passed noorg_name→ no crash,org_namestaysNone,_switch_orgnot called.test_sso_get_token_missing_active_organization_preserves_caller_org— payload omits the field,ArrowUploader(org_name="caller-org")→ caller value preserved,_switch_orgnot called.test_sso_get_token_null_active_organization_falls_back— payload sendsactive_organization: None(vs absent) → same fallback path.The existing happy-path test
test_sso_login_get_sso_token_ok(payload containsactive_organizationwith a validslug) is unmodified and still asserts the unchanged "use slug + call_switch_org" path.Companion server-side fix
graphistry/graphistry#3002ensures the server emitsactive_organizationfor site-wide-SSO signups going forward (already merged). This PR is required regardless: older servers that predate that fix continue to omit the field, and defense-in-depth on newer servers is cheap.Test plan
pytest graphistry/tests/test_arrow_uploader.py graphistry/tests/test_pygraphistry.py graphistry/tests/test_client_session.py -q→ 54 passed./bin/ruff.shclean on changed files./bin/mypy.sh graphistry/arrow_uploader.pyclean🤖 Generated with Claude Code