• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive / 25211490103
65%

Build:
DEFAULT BRANCH: main
Ran 01 May 2026 10:46AM UTC
Jobs 1
Files 709
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

01 May 2026 10:40AM UTC coverage: 64.302% (-0.02%) from 64.32%
25211490103

push

github

web-flow
Carry forward upstream refresh token on re-authorization (#5132)

* Add GetLatestUpstreamTokensForUser to storage

Introduces a secondary upstream-token lookup keyed on (userID, providerID)
on the UpstreamTokenStorage interface. The OAuth callback handler will use
this in a follow-on commit to preserve a previously-issued refresh token
when the upstream IdP omits refresh_token on re-authorization (e.g. Google
without prompt=consent), which today silently clobbers the prior good RT
and forces a refresh-token-orphaning loop.

This commit only adds the interface surface plus stub implementations on
both backends that return ErrNotFound. The real Memory and Redis logic, the
callback wiring, and tests land in subsequent commits so each diff stays
small and independently reviewable. The godoc explicitly calls out the
liveness contract (expired rows are returned, callers handle it) and the
cross-identity caller responsibility (verify UpstreamSubject before reusing
the prior RT) so future callers cannot misuse the lookup.

Refs #5047

* Implement GetLatestUpstreamTokensForUser for memory

Replaces the Step 1 stub on MemoryStorage with the real lookup. Iterates
the upstream-tokens map under RLock, filters by (UserID, ProviderID), and
picks the row with the highest ExpiresAt. Expired access tokens are
intentionally returned (matching the interface contract) so the OAuth
callback can carry forward a still-valid refresh token even when the
access token is dead.

Returns a defensive deep copy on hit and the same wrapped ErrNotFound
shape that GetUpstreamTokens uses on miss, so callers cannot accidentally
mutate stored state through the returned pointer.

Adds a 7-case table-driven test covering: no match, one match (with a
deep-copy mutation assertion), latest-by-ExpiresAt across three rows,
different-user/different-provider misses, expired-row tolerance, and
zero-ExpiresAt losing to non-zero.

Refs #5047

* Implement GetLatestUpstreamTokensForUser for redis

Repl... (continued)

153 of 188 new or added lines in 4 files covered. (81.38%)

40 existing lines in 5 files now uncovered.

61310 of 95347 relevant lines covered (64.3%)

59.11 hits per line

Uncovered Changes

Lines Coverage ∆ File
22
82.79
-0.99% pkg/authserver/storage/redis.go
11
61.53
0.74% pkg/authserver/storage/mocks/mock_storage.go
2
96.58
0.21% pkg/authserver/storage/memory.go

Coverage Regressions

Lines Coverage ∆ File
12
75.09
-4.33% pkg/client/config.go
12
67.9
-14.81% pkg/client/discovery.go
8
23.56
-4.6% pkg/client/manager.go
6
76.15
-5.5% pkg/secrets/keyring/keyctl_linux.go
2
82.29
-0.21% pkg/vmcp/composer/workflow_engine.go
Jobs
ID Job ID Ran Files Coverage
1 25211490103.1 01 May 2026 10:46AM UTC 709
64.3
GitHub Action Run
Source Files on build 25211490103
  • Tree
  • List 709
  • Changed 10
  • Source Changed 5
  • Coverage Changed 9
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #25211490103
  • 31e03074 on github
  • Prev Build on main (#25173777081)
  • Next Build on main (#25213578349)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc