Skip to content

Commit 5bc9a2a

Browse files
author
ironbox
committed
fix(cluster): invalidate current refreshed generation
1 parent d560eed commit 5bc9a2a

4 files changed

Lines changed: 35 additions & 7 deletions

File tree

drivers/115_open/driver.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ func (d *Open115) GetAddition() driver.Additional {
5858

5959
func (d *Open115) Init(ctx context.Context) error {
6060
// This client generation can finish an old request after cluster recovery has
61-
// replaced the storage. Bind auth callbacks to the Addition that configured
62-
// this client so an old 401 cannot revoke the newly installed pair.
63-
observedAddition := d.Storage.Addition
64-
observedModified := d.Storage.Modified
61+
// replaced the storage. The SDK reports the exact access token used by each
62+
// success/failure so callbacks can bind to the current generation.
6563
observedAccessToken := d.Addition.AccessToken
6664
d.client = new115SDKClient(sdk.WithRefreshToken(d.Addition.RefreshToken),
6765
sdk.WithAccessToken(d.Addition.AccessToken),
@@ -91,9 +89,13 @@ func (d *Open115) Init(ctx context.Context) error {
9189
op.NotifyStorageTokenValidWithSnapshot(d, currentAddition, currentModified)
9290
}
9391
}),
94-
sdk.WithOnTokenInvalid(func() {
92+
sdk.WithOnAccessTokenInvalid(func(accessToken string) {
93+
st := d.GetStorage()
94+
if st == nil || d.Addition.AccessToken != accessToken {
95+
return
96+
}
9597
if d.tokenInvalid.CompareAndSwap(false, true) {
96-
op.NotifyStorageTokenInvalidWithSnapshot(d, observedAddition, observedModified)
98+
op.NotifyStorageTokenInvalidWithSnapshot(d, st.Addition, st.Modified)
9799
}
98100
}))
99101
applySDKProxyIfConfigured(d.client)

drivers/115_open/driver_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"slices"
1212
"strings"
1313
"sync"
14+
"sync/atomic"
1415
"testing"
1516
"time"
1617

@@ -326,6 +327,7 @@ func TestOpen115RefreshRestoresErrorStateAndPublishesNewPair(t *testing.T) {
326327
db.Init(database)
327328

328329
var refreshCount int
330+
var rejectFresh atomic.Bool
329331
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
330332
switch r.URL.Path {
331333
case "/open/refreshToken":
@@ -344,6 +346,10 @@ func TestOpen115RefreshRestoresErrorStateAndPublishesNewPair(t *testing.T) {
344346
writeSDKError(t, w, 40140125, "access_token invalid")
345347
return
346348
}
349+
if rejectFresh.Load() {
350+
writeSDKError(t, w, 40140120, "refresh token error")
351+
return
352+
}
347353
writeSDKSuccess(t, w, map[string]any{})
348354
default:
349355
t.Fatalf("unexpected path: %s", r.URL.Path)
@@ -416,6 +422,24 @@ func TestOpen115RefreshRestoresErrorStateAndPublishesNewPair(t *testing.T) {
416422
case <-time.After(time.Second):
417423
t.Fatal("refreshed and proven pair was not published")
418424
}
425+
426+
// The same long-lived driver may fail hours after refreshing. The invalid
427+
// callback must bind to fresh-access, not the pre-refresh generation that
428+
// configured the client.
429+
rejectFresh.Store(true)
430+
if _, err := driver.client.UserInfo(context.Background()); err == nil {
431+
t.Fatal("expected the refreshed generation to become invalid")
432+
}
433+
if driver.Storage.Status == op.WORK {
434+
t.Fatal("refreshed generation 401 did not invalidate the mounted storage")
435+
}
436+
persisted, err = db.GetStorageById(storage.ID)
437+
if err != nil {
438+
t.Fatalf("GetStorageById after invalidation failed: %v", err)
439+
}
440+
if persisted.Status == op.WORK {
441+
t.Fatal("refreshed generation 401 was not persisted for peer recovery")
442+
}
419443
}
420444

421445
func newTestOpen115(t *testing.T, removeWay string, responder http.HandlerFunc) (*Open115, func() []recordedRequest) {

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,6 @@ replace github.com/ProtonMail/go-proton-api => github.com/henrybear327/go-proton
311311

312312
replace github.com/cronokirby/saferith => github.com/Da3zKi7/saferith v0.33.0-fixed
313313

314-
replace github.com/OpenListTeam/115-sdk-go => github.com/Ironboxplus/115-sdk-go v0.2.14
314+
replace github.com/OpenListTeam/115-sdk-go => github.com/Ironboxplus/115-sdk-go v0.2.15
315315

316316
replace github.com/KarpelesLab/reflink => github.com/OpenListTeam/reflink v0.0.0-20260520031008-ed3c0dbe8009

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ github.com/Ironboxplus/115-sdk-go v0.2.13 h1:B815N2mOq2lF2QDyANnkZW3mpmFM7xrBJrq
2727
github.com/Ironboxplus/115-sdk-go v0.2.13/go.mod h1:cfvitk2lwe6036iNi2h+iNxwxWDifKZsSvNtrur5BqU=
2828
github.com/Ironboxplus/115-sdk-go v0.2.14 h1:BN1FjRDbJ/UQiwWwO6mbfoU52L9/46l5oHbyEcWDhSI=
2929
github.com/Ironboxplus/115-sdk-go v0.2.14/go.mod h1:cfvitk2lwe6036iNi2h+iNxwxWDifKZsSvNtrur5BqU=
30+
github.com/Ironboxplus/115-sdk-go v0.2.15 h1:GEFamzPCINsB2aRxjcQyvsqC0SmXuQ6H417Ga7BKUII=
31+
github.com/Ironboxplus/115-sdk-go v0.2.15/go.mod h1:cfvitk2lwe6036iNi2h+iNxwxWDifKZsSvNtrur5BqU=
3032
github.com/KirCute/zip v1.0.1 h1:L/tVZglOiDVKDi9Ud+fN49htgKdQ3Z0H80iX8OZk13c=
3133
github.com/KirCute/zip v1.0.1/go.mod h1:xhF7dCB+Bjvy+5a56lenYCKBsH+gxDNPZSy5Cp+nlXk=
3234
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=

0 commit comments

Comments
 (0)