Skip to content

Commit 8d54a17

Browse files
committed
Sketch of improved error messages.
1 parent a4bd03c commit 8d54a17

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/cargo/sources/registry/http_remote.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ pub struct HttpRegistry<'gctx> {
100100
/// Should we include the authorization header?
101101
auth_required: bool,
102102

103+
/// The scheme of the included authorization header, if any.
104+
authorization_scheme: Option<auth::AuthorizationScheme>,
105+
103106
/// Url to get a token for the registry.
104107
login_url: Option<Url>,
105108

@@ -231,6 +234,7 @@ impl<'gctx> HttpRegistry<'gctx> {
231234
fetch_started: false,
232235
registry_config: None,
233236
auth_required: false,
237+
authorization_scheme: None,
234238
login_url: None,
235239
auth_error_headers: vec![],
236240
quiet: false,
@@ -604,6 +608,7 @@ impl<'gctx> RegistryData for HttpRegistry<'gctx> {
604608
self.source_id,
605609
self.login_url.clone(),
606610
auth::AuthorizationErrorReason::TokenRejected,
611+
self.authorization_scheme.clone(),
607612
)?;
608613
return Poll::Ready(err.context(auth_error));
609614
} else {
@@ -663,6 +668,12 @@ impl<'gctx> RegistryData for HttpRegistry<'gctx> {
663668
self.auth_error_headers.clone(),
664669
true,
665670
)?;
671+
let (scheme, _token) = authorization.split_once(" ").unwrap_or(("", &authorization));
672+
self.authorization_scheme = match scheme.to_ascii_lowercase().as_str() {
673+
"Basic" => Some(auth::AuthorizationScheme::Basic),
674+
"Bearer" => Some(auth::AuthorizationScheme::Bearer),
675+
_ => Some(auth::AuthorizationScheme::Unrecognized),
676+
};
666677
headers.append(&format!("Authorization: {}", authorization))?;
667678
trace!(target: "network", "including authorization for {}", full_url);
668679
}

src/cargo/util/auth/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,23 @@ impl fmt::Display for AuthorizationErrorReason {
387387
}
388388
}
389389

390+
#[derive(Clone, Debug, PartialEq)]
391+
pub enum AuthorizationScheme {
392+
Basic,
393+
Bearer,
394+
Unrecognized,
395+
}
396+
397+
impl fmt::Display for AuthorizationScheme {
398+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
399+
match self {
400+
AuthorizationScheme::Basic => write!(f, "Basic"),
401+
AuthorizationScheme::Bearer => write!(f, "Bearer"),
402+
AuthorizationScheme::Unrecognized => write!(f, "unrecognized"),
403+
}
404+
}
405+
}
406+
390407
/// An authorization error from accessing a registry.
391408
#[derive(Debug)]
392409
pub struct AuthorizationError {
@@ -400,6 +417,8 @@ pub struct AuthorizationError {
400417
reason: AuthorizationErrorReason,
401418
/// Should `cargo login` and the `_TOKEN` env var be included when displaying this error?
402419
supports_cargo_token_credential_provider: bool,
420+
/// What authorization scheme was specified in the token, if any?
421+
scheme: Option<AuthorizationScheme>,
403422
}
404423

405424
impl AuthorizationError {
@@ -408,6 +427,7 @@ impl AuthorizationError {
408427
sid: SourceId,
409428
login_url: Option<Url>,
410429
reason: AuthorizationErrorReason,
430+
scheme: Option<AuthorizationScheme>,
411431
) -> CargoResult<Self> {
412432
// Only display the _TOKEN environment variable suggestion if the `cargo:token` credential
413433
// provider is available for the source. Otherwise setting the environment variable will
@@ -422,6 +442,7 @@ impl AuthorizationError {
422442
login_url,
423443
reason,
424444
supports_cargo_token_credential_provider,
445+
scheme,
425446
})
426447
}
427448
}
@@ -461,6 +482,19 @@ impl fmt::Display for AuthorizationError {
461482
"\nYou may need to log in using this registry's credential provider"
462483
)?;
463484
}
485+
if let Some(scheme) = &self.scheme {
486+
write!(
487+
f,
488+
"Your registry token is prefixed with an embedded {} authentication scheme. Is this correct?",
489+
scheme,
490+
)?;
491+
} else {
492+
write!(
493+
f,
494+
"Your registry token is not prefixed with an embedded authorization scheme (e.g. `Bearer `).\n\
495+
Does this registry require an authentication scheme?",
496+
)?;
497+
}
464498
Ok(())
465499
} else if self.reason == AuthorizationErrorReason::TokenMissing {
466500
write!(
@@ -624,6 +658,7 @@ pub fn auth_token(
624658
*sid,
625659
login_url.cloned(),
626660
AuthorizationErrorReason::TokenMissing,
661+
None,
627662
)?
628663
.into()),
629664
}

0 commit comments

Comments
 (0)