@@ -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 ;
@@ -269,98 +270,91 @@ my-registry = {{ index = "{}" }}
269
270
// Store a token in the cache for future calls.
270
271
pub fn cache_token ( config : & Config , sid : & SourceId , token : & str ) {
271
272
let url = sid. canonical_url ( ) ;
272
- config
273
- . credential_cache ( )
274
- . insert ( url. clone ( ) , token. to_string ( ) ) ;
273
+ config. credential_cache ( ) . insert (
274
+ url. clone ( ) ,
275
+ Rc :: new ( RegistryCredentialConfig :: Token ( token. to_string ( ) ) ) ,
276
+ ) ;
275
277
}
276
278
277
279
/// Returns the token to use for the given registry.
278
- /// If a `login_url` is provided and a token is not available, the
279
- /// login_url will be included in the returned error.
280
- pub fn auth_token (
281
- config : & Config ,
282
- sid : & SourceId ,
283
- login_url : Option < & Url > ,
284
- mutation : Option < Mutation < ' _ > > ,
285
- ) -> CargoResult < String > {
286
- match auth_token_optional ( config, sid, mutation. as_ref ( ) ) ? {
287
- Some ( token) => Ok ( token) ,
288
- None => Err ( AuthorizationError {
289
- sid : sid. clone ( ) ,
290
- login_url : login_url. cloned ( ) ,
291
- reason : AuthorizationErrorReason :: TokenMissing ,
292
- }
293
- . into ( ) ) ,
294
- }
295
- }
296
-
297
- /// Returns the token to use for the given registry.
298
- fn auth_token_optional (
299
- config : & Config ,
300
- sid : & SourceId ,
301
- mutation : Option < & ' _ Mutation < ' _ > > ,
302
- ) -> CargoResult < Option < String > > {
280
+ pub fn auth_token ( config : & Config , sid : & SourceId ) -> CargoResult < Rc < RegistryCredentialConfig > > {
303
281
let mut cache = config. credential_cache ( ) ;
304
282
let url = sid. canonical_url ( ) ;
305
283
306
- if mutation. is_none ( ) {
307
- if let Some ( token) = cache. get ( url) {
308
- return Ok ( Some ( token. clone ( ) ) ) ;
309
- }
284
+ if let Some ( token) = cache. get ( url) {
285
+ return Ok ( Rc :: clone ( token) ) ;
310
286
}
311
287
312
- let credential = registry_credential_config ( config, sid) ?;
313
- let token = match credential {
314
- RegistryCredentialConfig :: None => return Ok ( None ) ,
315
- RegistryCredentialConfig :: Token ( config_token) => config_token. to_string ( ) ,
316
- RegistryCredentialConfig :: Process ( process) => {
317
- // todo: PASETO with process
318
- run_command ( config, & process, sid, Action :: Get ) ?. unwrap ( )
319
- }
320
- RegistryCredentialConfig :: Key ( ( private_key, private_key_subject) ) => {
321
- let secret: AsymmetricSecretKey < pasetors:: version3:: V3 > =
322
- private_key. as_str ( ) . try_into ( ) ?;
323
- let public: AsymmetricPublicKey < pasetors:: version3:: V3 > = ( & secret) . try_into ( ) ?;
324
- let public_key_id: pasetors:: paserk:: Id = ( & public) . into ( ) ;
325
- let mut kip = String :: new ( ) ;
326
- FormatAsPaserk :: fmt ( & public_key_id, & mut kip) . unwrap ( ) ;
327
- let iat = OffsetDateTime :: now_utc ( ) ;
328
-
329
- let message = Message {
330
- iat : & iat. format ( & Rfc3339 ) ?,
331
- sub : private_key_subject. as_deref ( ) ,
332
- mutation : mutation. and_then ( |m| m. mutation ) ,
333
- name : mutation. and_then ( |m| m. name ) ,
334
- vers : mutation. and_then ( |m| m. vers ) ,
335
- cksum : mutation. and_then ( |m| m. cksum ) ,
336
- challenge : None , // todo: PASETO with challenges,
337
- v : None ,
338
- } ;
339
- let footer = Footer {
340
- url : & sid. url ( ) . to_string ( ) ,
341
- kip : & kip,
342
- } ;
343
-
344
- pasetors:: version3:: PublicToken :: sign (
345
- & secret,
346
- & public,
347
- serde_json:: to_string ( & message)
348
- . expect ( "cannot serialize" )
349
- . as_bytes ( ) ,
350
- Some (
351
- serde_json:: to_string ( & footer)
288
+ let credential = Rc :: new ( registry_credential_config ( config, sid) ?) ;
289
+
290
+ cache. insert ( url. clone ( ) , Rc :: clone ( & credential) ) ;
291
+ Ok ( credential)
292
+ }
293
+
294
+ impl RegistryCredentialConfig {
295
+ /// If a `login_url` is provided and a token is not available, the
296
+ /// login_url will be included in the returned error.
297
+ pub fn as_header (
298
+ self : & Rc < RegistryCredentialConfig > ,
299
+ config : & Config ,
300
+ sid : & SourceId ,
301
+ login_url : Option < & Url > ,
302
+ mutation : Option < & ' _ Mutation < ' _ > > ,
303
+ ) -> CargoResult < String > {
304
+ Ok ( match & * * self {
305
+ RegistryCredentialConfig :: None => {
306
+ return Err ( AuthorizationError {
307
+ sid : sid. clone ( ) ,
308
+ login_url : login_url. cloned ( ) ,
309
+ reason : AuthorizationErrorReason :: TokenMissing ,
310
+ }
311
+ . into ( ) )
312
+ }
313
+ RegistryCredentialConfig :: Token ( config_token) => config_token. to_string ( ) ,
314
+ RegistryCredentialConfig :: Process ( process) => {
315
+ // todo: PASETO with process
316
+ run_command ( config, & process, sid, Action :: Get ) ?. unwrap ( )
317
+ }
318
+ RegistryCredentialConfig :: Key ( ( private_key, private_key_subject) ) => {
319
+ let secret: AsymmetricSecretKey < pasetors:: version3:: V3 > =
320
+ private_key. as_str ( ) . try_into ( ) ?;
321
+ let public: AsymmetricPublicKey < pasetors:: version3:: V3 > = ( & secret) . try_into ( ) ?;
322
+ let public_key_id: pasetors:: paserk:: Id = ( & public) . into ( ) ;
323
+ let mut kip = String :: new ( ) ;
324
+ FormatAsPaserk :: fmt ( & public_key_id, & mut kip) . unwrap ( ) ;
325
+ let iat = OffsetDateTime :: now_utc ( ) ;
326
+
327
+ let message = Message {
328
+ iat : & iat. format ( & Rfc3339 ) ?,
329
+ sub : private_key_subject. as_deref ( ) ,
330
+ mutation : mutation. and_then ( |m| m. mutation ) ,
331
+ name : mutation. and_then ( |m| m. name ) ,
332
+ vers : mutation. and_then ( |m| m. vers ) ,
333
+ cksum : mutation. and_then ( |m| m. cksum ) ,
334
+ challenge : None , // todo: PASETO with challenges,
335
+ v : None ,
336
+ } ;
337
+ let footer = Footer {
338
+ url : & sid. url ( ) . to_string ( ) ,
339
+ kip : & kip,
340
+ } ;
341
+
342
+ pasetors:: version3:: PublicToken :: sign (
343
+ & secret,
344
+ & public,
345
+ serde_json:: to_string ( & message)
352
346
. expect ( "cannot serialize" )
353
347
. as_bytes ( ) ,
354
- ) ,
355
- None ,
356
- ) ?
357
- }
358
- } ;
359
-
360
- if mutation. is_none ( ) {
361
- cache. insert ( url. clone ( ) , token. clone ( ) ) ;
348
+ Some (
349
+ serde_json:: to_string ( & footer)
350
+ . expect ( "cannot serialize" )
351
+ . as_bytes ( ) ,
352
+ ) ,
353
+ None ,
354
+ ) ?
355
+ }
356
+ } )
362
357
}
363
- Ok ( Some ( token) )
364
358
}
365
359
366
360
pub struct Mutation < ' a > {
0 commit comments