Skip to content

Commit cea204f

Browse files
committed
fix(libsecret): Treat lack of libsecret as unsupported
This changes cargo-credential-libsecret to report `UrlNotSupported` errors when `libsecret` can't be loaded. The goal with this change is to make it easier to support a cross-platform, cross-machine config file. Before, someone couldn't enable `libsecret` for the machines that supported it and then fallback to something else on machines that don't. After this change, we should be able to fallback to other providers. To help with debugability, we preserve the "`libsecret` can't be loaded" message by reporting the first "rich" `UrlNotSupported` error message. This is a newly invented construct as part of this PR. This was discussed on [zulip](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/reg.20auth.20and.20libsecret) and in the cargo team meeting. This is to improve the cross-platform config support in an effort to deprecate having config be unset as part of #13343
1 parent 19e2165 commit cea204f

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

credential/cargo-credential-libsecret/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,12 @@ mod linux {
115115
let secret_password_store_sync: Symbol<'_, SecretPasswordStoreSync>;
116116
let secret_password_clear_sync: Symbol<'_, SecretPasswordClearSync>;
117117
unsafe {
118-
lib = Library::new("libsecret-1.so").context(
119-
"failed to load libsecret: try installing the `libsecret` \
118+
lib = Library::new("libsecret-1.so")
119+
.context(
120+
"failed to load libsecret: try installing the `libsecret` \
120121
or `libsecret-1-0` package with the system package manager",
121-
)?;
122+
)
123+
.map_err(|err| Error::from(err).with_kind(ErrorKind::UrlNotSupported))?;
122124
secret_password_lookup_sync = lib
123125
.get(b"secret_password_lookup_sync\0")
124126
.map_err(Box::new)?;

credential/cargo-credential/src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ impl Error {
3737
pub fn kind(&self) -> ErrorKind {
3838
self.kind
3939
}
40+
41+
pub fn as_inner(&self) -> Option<&(dyn StdError + Sync + Send)> {
42+
use std::ops::Deref as _;
43+
self.inner.as_ref().map(|e| e.0.deref())
44+
}
4045
}
4146

4247
impl StdError for Error {

src/cargo/util/auth/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ fn credential_action(
513513
};
514514
let providers = credential_provider(gctx, sid, require_cred_provider_config, true)?;
515515
let mut any_not_found = false;
516+
let mut custom_not_supported = None;
516517
for provider in providers {
517518
let args: Vec<&str> = provider
518519
.iter()
@@ -553,7 +554,20 @@ fn credential_action(
553554
match provider.perform(&registry, &action, &args[1..]) {
554555
Ok(response) => return Ok(response),
555556
Err(e) => match e.kind() {
556-
cargo_credential::ErrorKind::UrlNotSupported => {}
557+
cargo_credential::ErrorKind::UrlNotSupported => {
558+
if e.as_inner().is_some() {
559+
custom_not_supported.get_or_insert_with(|| {
560+
Err::<(), _>(e)
561+
.with_context(|| {
562+
format!(
563+
"credential provider `{}` could not handle the request",
564+
args.join(" ")
565+
)
566+
})
567+
.unwrap_err()
568+
});
569+
}
570+
}
557571
cargo_credential::ErrorKind::NotFound => any_not_found = true,
558572
_ => {
559573
return Err(e).with_context(|| {
@@ -568,6 +582,8 @@ fn credential_action(
568582
}
569583
if any_not_found {
570584
Err(cargo_credential::ErrorKind::NotFound.into())
585+
} else if let Some(custom_not_supported) = custom_not_supported {
586+
Err(custom_not_supported)
571587
} else {
572588
anyhow::bail!("no credential providers could handle the request")
573589
}

0 commit comments

Comments
 (0)