Repository navigation
feat(oauth): add OAuth revoke/clear and use PKCE in the authorization flow - #616
Merged
Merged
Conversation
… flow
- Add `OAuth.revoke()` (RFC 7009) and `OAuth.clear()` to every SDK layer
(Rust, C, C++, Java, Node.js, Python), plus `TokenStorage::delete` and
`OAuthError::{RevokeFailed, TokenFileDelete}`.
- `clear()` deletes the persisted token first and clears memory only on
success; `revoke()` rejects `from_token` clients with a clear error.
- `TokenStorage::delete` defaults to an error so `clear()` never reports
success for a backend it cannot wipe.
- C: NULL handles passed to `lb_oauth_revoke` / `lb_oauth_clear` are reported
through the callback instead of crashing.
- Python: blocking `revoke()` / `clear()` release the GIL and reuse the shared
Tokio runtime.
- Use PKCE (S256) in the browser authorization flow; the server requires it
for public clients.
- Mark `OAuthError` as `#[non_exhaustive]`.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BJcMMB4GdF4MgepE5mW2K
hogan-yuan
added a commit
to longbridge/openapi-go
that referenced
this pull request
Nov 4, 2026
… flow (#140) ## Summary Ports longbridge/openapi#616 to the Go SDK. - **`OAuth.Revoke(ctx)`** revokes the current token on the server (RFC 7009, `POST /oauth2/revoke`): the refresh token when present, otherwise the access token. It only contacts the server. The request matches what the Rust `oauth2` crate sends (`token`, `token_type_hint`, `client_id` in the form body; `Accept: application/json`). Failures carry the server's `error: error_description`. It uses the `*http.Client` stored in `ctx` under `oauth2.HTTPClient` when present (as token refreshes do), otherwise a client with a 30s timeout. - **`OAuth.Clear()`** drops the token locally: deletes `~/.longbridge/openapi/tokens/<client_id>` first (a missing file is not an error) and clears the in-memory token only when that succeeds. - **Concurrency:** `AccessToken` and `Build` release the lock during network I/O. A generation counter now makes a refresh or authorization that was in flight when `Clear` ran get discarded instead of re-saving the token (`Build` returns an error; `AccessToken` returns the replacement token if one was stored, otherwise an error). - **PKCE (RFC 7636, `S256`)** in the browser authorization flow: the authorization URL carries `code_challenge`, and the code exchange sends the matching `code_verifier`. The server requires PKCE for `public` clients. Not ported: `from_token` / `TokenStorage` handling, which do not exist in the Go SDK. ## Test plan - [x] `go test ./oauth/ -race -count=1`: new tests cover the PKCE authorize URL, `code_verifier` in the exchange, `Revoke` (refresh-token preference, access-token fallback, server error, no token), `Clear` (memory + file, missing file, delete failure keeps the token), and a refresh in flight in `AccessToken` / `Build` being discarded after `Clear` - [x] `go vet ./oauth/`, `go build ./...` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
5 tasks done
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
OAuth.revoke()/OAuth.clear()in every SDK layer (Rust, C, C++, Java, Node.js, Python).revoke()revokes the current token on the server (RFC 7009): the refresh token when present, otherwise the access token. It only contacts the server.clear()drops the token locally: it deletes the persisted token first and clears the in-memory copy only when that succeeds. It does not contact the server, so callrevoke()first to fully disconnect.TokenStorage::delete(default implementation returns an error, so existing custom backends still compile butclear()fails loudly instead of reporting success),OAuthError::RevokeFailedandOAuthError::TokenFileDelete.revoke()on afrom_tokenclient (no client ID) fails with a clearRevokeFailedmessage.lb_oauth_revoke/lb_oauth_clearis reported through the callback instead of crashing (this also covers a moved-from C++OAuth).S256) in the browser authorization flow. The server requires PKCE forpublicclients, which previously failed withOAuth authorization failed: server_error.Breaking changes
OAuthErroris now#[non_exhaustive](and gains two variants). Exhaustivematches outside the crate need a wildcard arm.Test plan
cargo test -p longbridge-oauth(30 unit tests + 2 doctests), including new tests for the PKCE authorize URL,revoke_error_message,from_tokenrevoke, andclear()when the storage delete fails or is unsupportedcargo clippyonlongbridge-oauthandlongbridge-c(no new warnings);longbridge-python,longbridge-javaandlongbridge-nodejscompileOAuth::revoke/OAuth::clear; all Java sources compile withjavac --release 9; Node.jsnpm run build:debugsucceeds and the generatedOAuth/OAuthBuilderdeclarations match the committedindex.d.tscargo +nightly fmt --all -- --checkreports no diff🤖 Generated with Claude Code
https://claude.ai/code/session_017BJcMMB4GdF4MgepE5mW2K