@@ -139,7 +139,8 @@ fn load_oauth_tokens_with_store<C: CredentialStore>(
139
139
server_name : & str ,
140
140
url : & str ,
141
141
) -> Result < Option < StoredOAuthTokens > > {
142
- match store. load ( KEYRING_SERVICE , server_name) {
142
+ let key = compute_store_key ( server_name, url) ?;
143
+ match store. load ( KEYRING_SERVICE , & key) {
143
144
Ok ( Some ( serialized) ) => {
144
145
let tokens: StoredOAuthTokens = serde_json:: from_str ( & serialized)
145
146
. context ( "failed to deserialize OAuth tokens from keyring" ) ?;
@@ -167,14 +168,19 @@ fn save_oauth_tokens_with_store<C: CredentialStore>(
167
168
) -> Result < ( ) > {
168
169
let serialized = serde_json:: to_string ( tokens) . context ( "failed to serialize OAuth tokens" ) ?;
169
170
170
- match store. save ( KEYRING_SERVICE , server_name, & serialized) {
171
+ let key = compute_store_key ( server_name, & tokens. url ) ?;
172
+ // DO NOT SUBMIT
173
+ println ! ( "[DEBUG] saving OAuth tokens to keyring: {key}: {serialized}" ) ;
174
+ match store. save ( KEYRING_SERVICE , & key, & serialized) {
171
175
Ok ( ( ) ) => {
172
- if let Err ( error) = delete_oauth_tokens_from_file ( server_name, Some ( & tokens. url ) ) {
176
+ println ! ( "saved OAuth tokens to keyring: {serialized}" ) ;
177
+ if let Err ( error) = delete_oauth_tokens_from_file ( & key) {
173
178
warn ! ( "failed to remove OAuth tokens from fallback storage: {error:?}" ) ;
174
179
}
175
180
Ok ( ( ) )
176
181
}
177
182
Err ( error) => {
183
+ println ! ( "failed to save OAuth tokens to keyring: {error:?}" ) ;
178
184
let message = error. message ( ) ;
179
185
warn ! ( "failed to write OAuth tokens to keyring: {message}" ) ;
180
186
save_oauth_tokens_to_file ( tokens)
@@ -183,16 +189,18 @@ fn save_oauth_tokens_with_store<C: CredentialStore>(
183
189
}
184
190
}
185
191
186
- pub fn delete_oauth_tokens ( server_name : & str ) -> Result < bool > {
192
+ pub fn delete_oauth_tokens ( server_name : & str , url : & str ) -> Result < bool > {
187
193
let store = KeyringCredentialStore ;
188
- delete_oauth_tokens_with_store ( & store, server_name)
194
+ delete_oauth_tokens_with_store ( & store, server_name, url )
189
195
}
190
196
191
197
fn delete_oauth_tokens_with_store < C : CredentialStore > (
192
198
store : & C ,
193
199
server_name : & str ,
200
+ url : & str ,
194
201
) -> Result < bool > {
195
- let keyring_removed = match store. delete ( KEYRING_SERVICE , server_name) {
202
+ let key = compute_store_key ( server_name, url) ?;
203
+ let keyring_removed = match store. delete ( KEYRING_SERVICE , & key) {
196
204
Ok ( removed) => removed,
197
205
Err ( error) => {
198
206
let message = error. message ( ) ;
@@ -201,7 +209,7 @@ fn delete_oauth_tokens_with_store<C: CredentialStore>(
201
209
}
202
210
} ;
203
211
204
- let file_removed = delete_oauth_tokens_from_file ( server_name , None ) ?;
212
+ let file_removed = delete_oauth_tokens_from_file ( & key ) ?;
205
213
Ok ( keyring_removed || file_removed)
206
214
}
207
215
@@ -260,7 +268,8 @@ impl OAuthRuntime {
260
268
None => {
261
269
let mut last_serialized = self . inner . last_credentials . lock ( ) . await ;
262
270
if last_serialized. take ( ) . is_some ( )
263
- && let Err ( error) = delete_oauth_tokens ( & self . inner . server_name )
271
+ && let Err ( error) =
272
+ delete_oauth_tokens ( & self . inner . server_name , & self . inner . url )
264
273
{
265
274
warn ! (
266
275
"failed to remove OAuth tokens for server {}: {error}" ,
@@ -342,8 +351,8 @@ fn load_oauth_tokens_from_file(server_name: &str, url: &str) -> Result<Option<St
342
351
}
343
352
344
353
fn save_oauth_tokens_to_file ( tokens : & StoredOAuthTokens ) -> Result < ( ) > {
345
- let mut store = read_fallback_file ( ) ?. unwrap_or_default ( ) ;
346
354
let key = compute_store_key ( & tokens. server_name , & tokens. url ) ?;
355
+ let mut store = read_fallback_file ( ) ?. unwrap_or_default ( ) ;
347
356
348
357
let token_response = & tokens. token_response . 0 ;
349
358
let refresh_token = token_response
@@ -367,20 +376,13 @@ fn save_oauth_tokens_to_file(tokens: &StoredOAuthTokens) -> Result<()> {
367
376
write_fallback_file ( & store)
368
377
}
369
378
370
- fn delete_oauth_tokens_from_file ( server_name : & str , url : Option < & str > ) -> Result < bool > {
379
+ fn delete_oauth_tokens_from_file ( key : & str ) -> Result < bool > {
371
380
let mut store = match read_fallback_file ( ) ? {
372
381
Some ( store) => store,
373
382
None => return Ok ( false ) ,
374
383
} ;
375
384
376
- let removed = if let Some ( target_url) = url {
377
- let key = compute_store_key ( server_name, target_url) ?;
378
- store. remove ( & key) . is_some ( )
379
- } else {
380
- let original_len = store. len ( ) ;
381
- store. retain ( |_, entry| entry. server_name != server_name) ;
382
- store. len ( ) != original_len
383
- } ;
385
+ let removed = store. remove ( key) . is_some ( ) ;
384
386
385
387
if removed {
386
388
write_fallback_file ( & store) ?;
@@ -642,7 +644,8 @@ mod tests {
642
644
let tokens = sample_tokens ( ) ;
643
645
let expected = tokens. clone ( ) ;
644
646
let serialized = serde_json:: to_string ( & tokens) ?;
645
- store. save ( KEYRING_SERVICE , & tokens. server_name , & serialized) ?;
647
+ let key = super :: compute_store_key ( & tokens. server_name , & tokens. url ) ?;
648
+ store. save ( KEYRING_SERVICE , & key, & serialized) ?;
646
649
647
650
let loaded = super :: load_oauth_tokens_with_store ( & store, & tokens. server_name , & tokens. url ) ?;
648
651
assert_eq ! ( loaded, Some ( expected) ) ;
@@ -670,10 +673,8 @@ mod tests {
670
673
let store = MockCredentialStore :: default ( ) ;
671
674
let tokens = sample_tokens ( ) ;
672
675
let expected = tokens. clone ( ) ;
673
- store. set_error (
674
- & tokens. server_name ,
675
- KeyringError :: Invalid ( "error" . into ( ) , "load" . into ( ) ) ,
676
- ) ;
676
+ let key = super :: compute_store_key ( & tokens. server_name , & tokens. url ) ?;
677
+ store. set_error ( & key, KeyringError :: Invalid ( "error" . into ( ) , "load" . into ( ) ) ) ;
677
678
678
679
super :: save_oauth_tokens_to_file ( & tokens) ?;
679
680
@@ -688,16 +689,15 @@ mod tests {
688
689
let _env = TempCodexHome :: new ( ) ;
689
690
let store = MockCredentialStore :: default ( ) ;
690
691
let tokens = sample_tokens ( ) ;
692
+ let key = super :: compute_store_key ( & tokens. server_name , & tokens. url ) ?;
691
693
692
694
super :: save_oauth_tokens_to_file ( & tokens) ?;
693
695
694
696
super :: save_oauth_tokens_with_store ( & store, & tokens. server_name , & tokens) ?;
695
697
696
698
let fallback_path = super :: fallback_file_path ( ) ?;
697
699
assert ! ( !fallback_path. exists( ) , "fallback file should be removed" ) ;
698
- let stored = store
699
- . saved_value ( & tokens. server_name )
700
- . expect ( "value saved to keyring" ) ;
700
+ let stored = store. saved_value ( & key) . expect ( "value saved to keyring" ) ;
701
701
assert_eq ! ( serde_json:: from_str:: <StoredOAuthTokens >( & stored) ?, tokens) ;
702
702
Ok ( ( ) )
703
703
}
@@ -707,10 +707,8 @@ mod tests {
707
707
let _env = TempCodexHome :: new ( ) ;
708
708
let store = MockCredentialStore :: default ( ) ;
709
709
let tokens = sample_tokens ( ) ;
710
- store. set_error (
711
- & tokens. server_name ,
712
- KeyringError :: Invalid ( "error" . into ( ) , "save" . into ( ) ) ,
713
- ) ;
710
+ let key = super :: compute_store_key ( & tokens. server_name , & tokens. url ) ?;
711
+ store. set_error ( & key, KeyringError :: Invalid ( "error" . into ( ) , "save" . into ( ) ) ) ;
714
712
715
713
super :: save_oauth_tokens_with_store ( & store, & tokens. server_name , & tokens) ?;
716
714
@@ -726,7 +724,7 @@ mod tests {
726
724
entry. access_token,
727
725
tokens. token_response. 0 . access_token( ) . secret( ) . as_str( )
728
726
) ;
729
- assert ! ( store. saved_value( & tokens . server_name ) . is_none( ) ) ;
727
+ assert ! ( store. saved_value( & key ) . is_none( ) ) ;
730
728
Ok ( ( ) )
731
729
}
732
730
@@ -736,30 +734,32 @@ mod tests {
736
734
let store = MockCredentialStore :: default ( ) ;
737
735
let tokens = sample_tokens ( ) ;
738
736
let serialized = serde_json:: to_string ( & tokens) ?;
739
- store. save ( KEYRING_SERVICE , & tokens. server_name , & serialized) ?;
737
+ let key = super :: compute_store_key ( & tokens. server_name , & tokens. url ) ?;
738
+ store. save ( KEYRING_SERVICE , & key, & serialized) ?;
740
739
super :: save_oauth_tokens_to_file ( & tokens) ?;
741
740
742
- let removed = super :: delete_oauth_tokens_with_store ( & store, & tokens. server_name ) ?;
741
+ let removed =
742
+ super :: delete_oauth_tokens_with_store ( & store, & tokens. server_name , & tokens. url ) ?;
743
743
assert ! ( removed) ;
744
- assert ! ( !store. contains( & tokens . server_name ) ) ;
744
+ assert ! ( !store. contains( & key ) ) ;
745
745
assert ! ( !super :: fallback_file_path( ) ?. exists( ) ) ;
746
746
Ok ( ( ) )
747
747
}
748
748
749
749
#[ test]
750
- fn delete_oauth_tokens_propagates_keyring_errors ( ) {
750
+ fn delete_oauth_tokens_propagates_keyring_errors ( ) -> Result < ( ) > {
751
751
let _env = TempCodexHome :: new ( ) ;
752
752
let store = MockCredentialStore :: default ( ) ;
753
753
let tokens = sample_tokens ( ) ;
754
- store. set_error (
755
- & tokens. server_name ,
756
- KeyringError :: Invalid ( "error" . into ( ) , "delete" . into ( ) ) ,
757
- ) ;
754
+ let key = super :: compute_store_key ( & tokens. server_name , & tokens. url ) ?;
755
+ store. set_error ( & key, KeyringError :: Invalid ( "error" . into ( ) , "delete" . into ( ) ) ) ;
758
756
super :: save_oauth_tokens_to_file ( & tokens) . unwrap ( ) ;
759
757
760
- let result = super :: delete_oauth_tokens_with_store ( & store, & tokens. server_name ) ;
758
+ let result =
759
+ super :: delete_oauth_tokens_with_store ( & store, & tokens. server_name , & tokens. url ) ;
761
760
assert ! ( result. is_err( ) ) ;
762
761
assert ! ( super :: fallback_file_path( ) . unwrap( ) . exists( ) ) ;
762
+ Ok ( ( ) )
763
763
}
764
764
765
765
fn assert_tokens_match_without_expiry (
0 commit comments