@@ -12,6 +12,7 @@ use std::error::Error;
12
12
use std:: io:: { Read , Write } ;
13
13
use std:: path:: PathBuf ;
14
14
use std:: process:: { Command , Stdio } ;
15
+ use std:: rc:: Rc ;
15
16
use time:: format_description:: well_known:: Rfc3339 ;
16
17
use time:: OffsetDateTime ;
17
18
use url:: Url ;
@@ -295,98 +296,91 @@ my-registry = {{ index = "{}" }}
295
296
// Store a token in the cache for future calls.
296
297
pub fn cache_token ( config : & Config , sid : & SourceId , token : & str ) {
297
298
let url = sid. canonical_url ( ) ;
298
- config
299
- . credential_cache ( )
300
- . insert ( url. clone ( ) , token. to_string ( ) ) ;
299
+ config. credential_cache ( ) . insert (
300
+ url. clone ( ) ,
301
+ Rc :: new ( RegistryCredentialConfig :: Token ( token. to_string ( ) ) ) ,
302
+ ) ;
301
303
}
302
304
303
305
/// Returns the token to use for the given registry.
304
- /// If a `login_url` is provided and a token is not available, the
305
- /// login_url will be included in the returned error.
306
- pub fn auth_token (
307
- config : & Config ,
308
- sid : & SourceId ,
309
- login_url : Option < & Url > ,
310
- mutation : Option < Mutation < ' _ > > ,
311
- ) -> CargoResult < String > {
312
- match auth_token_optional ( config, sid, mutation. as_ref ( ) ) ? {
313
- Some ( token) => Ok ( token) ,
314
- None => Err ( AuthorizationError {
315
- sid : sid. clone ( ) ,
316
- login_url : login_url. cloned ( ) ,
317
- reason : AuthorizationErrorReason :: TokenMissing ,
318
- }
319
- . into ( ) ) ,
320
- }
321
- }
322
-
323
- /// Returns the token to use for the given registry.
324
- fn auth_token_optional (
325
- config : & Config ,
326
- sid : & SourceId ,
327
- mutation : Option < & ' _ Mutation < ' _ > > ,
328
- ) -> CargoResult < Option < String > > {
306
+ pub fn auth_token ( config : & Config , sid : & SourceId ) -> CargoResult < Rc < RegistryCredentialConfig > > {
329
307
let mut cache = config. credential_cache ( ) ;
330
308
let url = sid. canonical_url ( ) ;
331
309
332
- if mutation. is_none ( ) {
333
- if let Some ( token) = cache. get ( url) {
334
- return Ok ( Some ( token. clone ( ) ) ) ;
335
- }
310
+ if let Some ( token) = cache. get ( url) {
311
+ return Ok ( Rc :: clone ( token) ) ;
336
312
}
337
313
338
- let credential = registry_credential_config ( config, sid) ?;
339
- let token = match credential {
340
- RegistryCredentialConfig :: None => return Ok ( None ) ,
341
- RegistryCredentialConfig :: Token ( config_token) => config_token. to_string ( ) ,
342
- RegistryCredentialConfig :: Process ( process) => {
343
- // todo: PASETO with process
344
- run_command ( config, & process, sid, Action :: Get ) ?. unwrap ( )
345
- }
346
- RegistryCredentialConfig :: AsymmetricKey ( ( secret_key, secret_key_subject) ) => {
347
- let secret: AsymmetricSecretKey < pasetors:: version3:: V3 > =
348
- secret_key. as_str ( ) . try_into ( ) ?;
349
- let public: AsymmetricPublicKey < pasetors:: version3:: V3 > = ( & secret) . try_into ( ) ?;
350
- let public_key_id: pasetors:: paserk:: Id = ( & public) . into ( ) ;
351
- let mut kip = String :: new ( ) ;
352
- FormatAsPaserk :: fmt ( & public_key_id, & mut kip) . unwrap ( ) ;
353
- let iat = OffsetDateTime :: now_utc ( ) ;
354
-
355
- let message = Message {
356
- iat : & iat. format ( & Rfc3339 ) ?,
357
- sub : secret_key_subject. as_deref ( ) ,
358
- mutation : mutation. and_then ( |m| m. mutation ) ,
359
- name : mutation. and_then ( |m| m. name ) ,
360
- vers : mutation. and_then ( |m| m. vers ) ,
361
- cksum : mutation. and_then ( |m| m. cksum ) ,
362
- challenge : None , // todo: PASETO with challenges
363
- v : None ,
364
- } ;
365
- let footer = Footer {
366
- url : & sid. url ( ) . to_string ( ) ,
367
- kip : & kip,
368
- } ;
369
-
370
- pasetors:: version3:: PublicToken :: sign (
371
- & secret,
372
- & public,
373
- serde_json:: to_string ( & message)
374
- . expect ( "cannot serialize" )
375
- . as_bytes ( ) ,
376
- Some (
377
- serde_json:: to_string ( & footer)
314
+ let credential = Rc :: new ( registry_credential_config ( config, sid) ?) ;
315
+
316
+ cache. insert ( url. clone ( ) , Rc :: clone ( & credential) ) ;
317
+ Ok ( credential)
318
+ }
319
+
320
+ impl RegistryCredentialConfig {
321
+ /// If a `login_url` is provided and a token is not available, the
322
+ /// login_url will be included in the returned error.
323
+ pub fn as_header (
324
+ self : & Rc < RegistryCredentialConfig > ,
325
+ config : & Config ,
326
+ sid : & SourceId ,
327
+ login_url : Option < & Url > ,
328
+ mutation : Option < & ' _ Mutation < ' _ > > ,
329
+ ) -> CargoResult < String > {
330
+ Ok ( match & * * self {
331
+ RegistryCredentialConfig :: None => {
332
+ return Err ( AuthorizationError {
333
+ sid : sid. clone ( ) ,
334
+ login_url : login_url. cloned ( ) ,
335
+ reason : AuthorizationErrorReason :: TokenMissing ,
336
+ }
337
+ . into ( ) )
338
+ }
339
+ RegistryCredentialConfig :: Token ( config_token) => config_token. to_string ( ) ,
340
+ RegistryCredentialConfig :: Process ( process) => {
341
+ // todo: PASETO with process
342
+ run_command ( config, & process, sid, Action :: Get ) ?. unwrap ( )
343
+ }
344
+ RegistryCredentialConfig :: AsymmetricKey ( ( secret_key, secret_key_subject) ) => {
345
+ let secret: AsymmetricSecretKey < pasetors:: version3:: V3 > =
346
+ secret_key. as_str ( ) . try_into ( ) ?;
347
+ let public: AsymmetricPublicKey < pasetors:: version3:: V3 > = ( & secret) . try_into ( ) ?;
348
+ let public_key_id: pasetors:: paserk:: Id = ( & public) . into ( ) ;
349
+ let mut kip = String :: new ( ) ;
350
+ FormatAsPaserk :: fmt ( & public_key_id, & mut kip) . unwrap ( ) ;
351
+ let iat = OffsetDateTime :: now_utc ( ) ;
352
+
353
+ let message = Message {
354
+ iat : & iat. format ( & Rfc3339 ) ?,
355
+ sub : secret_key_subject. as_deref ( ) ,
356
+ mutation : mutation. and_then ( |m| m. mutation ) ,
357
+ name : mutation. and_then ( |m| m. name ) ,
358
+ vers : mutation. and_then ( |m| m. vers ) ,
359
+ cksum : mutation. and_then ( |m| m. cksum ) ,
360
+ challenge : None , // todo: PASETO with challenges
361
+ v : None ,
362
+ } ;
363
+ let footer = Footer {
364
+ url : & sid. url ( ) . to_string ( ) ,
365
+ kip : & kip,
366
+ } ;
367
+
368
+ pasetors:: version3:: PublicToken :: sign (
369
+ & secret,
370
+ & public,
371
+ serde_json:: to_string ( & message)
378
372
. expect ( "cannot serialize" )
379
373
. as_bytes ( ) ,
380
- ) ,
381
- None ,
382
- ) ?
383
- }
384
- } ;
385
-
386
- if mutation. is_none ( ) {
387
- cache. insert ( url. clone ( ) , token. clone ( ) ) ;
374
+ Some (
375
+ serde_json:: to_string ( & footer)
376
+ . expect ( "cannot serialize" )
377
+ . as_bytes ( ) ,
378
+ ) ,
379
+ None ,
380
+ ) ?
381
+ }
382
+ } )
388
383
}
389
- Ok ( Some ( token) )
390
384
}
391
385
392
386
pub struct Mutation < ' a > {
0 commit comments