Skip to content

Activate descriptor-backed PKCE refresh - #449

Merged
jodal merged 1 commit into
mainfrom
oauth-runtime-integration
Oct 5, 2026
Merged

jodal merged 1 commit into
mainfrom
oauth-runtime-integration

Conversation

@adamcik

@adamcik adamcik commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

The authorization store and refresh policies are already on main; this PR connects them to the running Web client. Playback authorization is unchanged.

  • Prefer stored PKCE authorization over configured bridge credentials.
  • Allow bridge fallback when authorization is missing or cleared, but never after PKCE rejection or an unreadable manifest.
  • Preserve authorization on transient failures. A permanent PKCE rejection requires reauthorization.
  • Reject stale refresh results after logout or reauthorization; persist the transition before installing its access token.
  • Keep HTTP retries, response validation, and access-token expiry in the shared OAuth client. Providers handle grant-specific eligibility, requests, and response processing.

Review path

  1. backend.py wires the store, PKCE provider, and bridge provider into SpotifyAccessTokenSource.
  2. oauth/source.py owns the refresh transaction shown below. The network request runs without the store lock. Selecting a provider is the only opportunity for fallback; a failed exchange does not try another grant.
  3. oauth/providers.py contains the grant differences: PKCE retains or rotates its refresh token; the bridge uses configured credentials and ignores refresh tokens in its response. web.py installs the access token only after the source returns successfully.
flowchart TD
    A[Load authorization snapshot] --> B[Select provider]
    B -->|PKCE authorized| C[PKCE request]
    B -->|Missing, cleared, or bridge state| D[Bridge request if configured]
    B -->|PKCE rejected or no provider| X[Stop without an exchange]
    C --> E[Exchange and validate response]
    D --> E
    E --> F[Provider processes response]
    F -->|Transient failure| G[Preserve state; report failure]
    F -->|Success or permanent rejection| H{Snapshot still current?}
    H -->|No| I[Discard stale result]
    H -->|Yes| J[Persist proposed state]
    J -->|Success| K[Install access token]
    J -->|Permanent rejection| L[Report rejection]
Loading

Compatibility caveat: every refresh retries a permanently rejected bridge configuration, even if its credentials are unchanged. This allows corrected configuration to recover without clearing the manifest. A separate credential-fingerprint follow-up will distinguish changed credentials from repeated attempts with the rejected pair.

Tests exercise provider precedence, token rotation, transient and permanent failures, and logout/reauthorization during an in-flight refresh. #450 documents the architecture; #451 handles separate playback authorization.

@adamcik
adamcik added this pull request to stack #453 September 23, 2026 15:14
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from 20108ea to f1d6c4c Compare September 23, 2026 21:30
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from f1d6c4c to f55eec5 Compare September 24, 2026 18:54
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from f55eec5 to 3df9eef Compare September 24, 2026 20:57
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from 3df9eef to b3b6f26 Compare September 24, 2026 21:09
@adamcik
adamcik force-pushed the oauth-runtime-integration branch 2 times, most recently from 67b95fd to d2073c5 Compare September 24, 2026 21:53
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from d2073c5 to db2d819 Compare September 24, 2026 22:08
@adamcik
adamcik force-pushed the oauth-runtime-integration branch 2 times, most recently from 8c1d155 to ef0212d Compare September 26, 2026 22:53
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from ef0212d to b61f586 Compare September 26, 2026 23:06
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from b61f586 to 91b2c7c Compare September 26, 2026 23:10
@adamcik
adamcik force-pushed the oauth-runtime-integration branch 4 times, most recently from 7e5d24b to 4134396 Compare September 27, 2026 10:24
@adamcik
adamcik force-pushed the oauth-runtime-integration branch 2 times, most recently from f4e47cd to 2e2aca3 Compare September 27, 2026 11:36
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from 2e2aca3 to 6967dd8 Compare September 27, 2026 11:54
@adamcik
adamcik force-pushed the oauth-runtime-integration branch 2 times, most recently from 695a46c to 7d23b07 Compare October 3, 2026 12:12
@jodal
jodal force-pushed the oauth-runtime-integration branch 3 times, most recently from 08fe2d6 to 7b845fd Compare October 3, 2026 12:26
Base automatically changed from oauth-refresh-policy to main October 3, 2026 12:28
@jodal
jodal force-pushed the oauth-runtime-integration branch from 7b845fd to 69cfc4f Compare October 3, 2026 12:28
@adamcik
adamcik force-pushed the oauth-runtime-integration branch 2 times, most recently from 1386fbe to 9ada8b7 Compare October 4, 2026 19:29
Load resolved authorization snapshots at runtime and persist provider transitions with compare-and-set semantics. Preserve legacy bridge fallback while preventing stale refresh responses from overwriting newer authorization.
@adamcik
adamcik force-pushed the oauth-runtime-integration branch from 9ada8b7 to a188c50 Compare October 4, 2026 19:59
@adamcik
adamcik marked this pull request as ready for review October 4, 2026 20:01
@adamcik
adamcik removed this pull request from stack #453 October 4, 2026 20:28
@adamcik
adamcik added this pull request to stack #455 October 4, 2026 20:30
@jodal
jodal merged commit 5223303 into main Oct 5, 2026
8 checks passed
@jodal
jodal deleted the oauth-runtime-integration branch October 5, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants