mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
rename crate to cargo-credential-libsecret
This commit is contained in:
parent
3d8e8d32cd
commit
763edbab09
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -263,7 +263,7 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"bytesize",
|
"bytesize",
|
||||||
"cargo-credential",
|
"cargo-credential",
|
||||||
"cargo-credential-gnome-secret",
|
"cargo-credential-libsecret",
|
||||||
"cargo-credential-macos-keychain",
|
"cargo-credential-macos-keychain",
|
||||||
"cargo-credential-wincred",
|
"cargo-credential-wincred",
|
||||||
"cargo-platform 0.1.4",
|
"cargo-platform 0.1.4",
|
||||||
@ -355,7 +355,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo-credential-gnome-secret"
|
name = "cargo-credential-libsecret"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -20,7 +20,7 @@ base64 = "0.21.2"
|
|||||||
bytesize = "1.2"
|
bytesize = "1.2"
|
||||||
cargo = { path = "" }
|
cargo = { path = "" }
|
||||||
cargo-credential = { version = "0.3.0", path = "credential/cargo-credential" }
|
cargo-credential = { version = "0.3.0", path = "credential/cargo-credential" }
|
||||||
cargo-credential-gnome-secret = { version = "0.3.1", path = "credential/cargo-credential-gnome-secret" }
|
cargo-credential-libsecret = { version = "0.3.1", path = "credential/cargo-credential-libsecret" }
|
||||||
cargo-credential-wincred = { version = "0.3.0", path = "credential/cargo-credential-wincred" }
|
cargo-credential-wincred = { version = "0.3.0", path = "credential/cargo-credential-wincred" }
|
||||||
cargo-credential-macos-keychain = { version = "0.3.0", path = "credential/cargo-credential-macos-keychain" }
|
cargo-credential-macos-keychain = { version = "0.3.0", path = "credential/cargo-credential-macos-keychain" }
|
||||||
cargo-platform = { path = "crates/cargo-platform", version = "0.1.4" }
|
cargo-platform = { path = "crates/cargo-platform", version = "0.1.4" }
|
||||||
@ -124,7 +124,7 @@ base64.workspace = true
|
|||||||
bytesize.workspace = true
|
bytesize.workspace = true
|
||||||
cargo-platform.workspace = true
|
cargo-platform.workspace = true
|
||||||
cargo-credential.workspace = true
|
cargo-credential.workspace = true
|
||||||
cargo-credential-gnome-secret.workspace = true
|
cargo-credential-libsecret.workspace = true
|
||||||
cargo-credential-macos-keychain.workspace = true
|
cargo-credential-macos-keychain.workspace = true
|
||||||
cargo-credential-wincred.workspace = true
|
cargo-credential-wincred.workspace = true
|
||||||
cargo-util.workspace = true
|
cargo-util.workspace = true
|
||||||
|
@ -153,7 +153,7 @@ fn bump_check(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> Carg
|
|||||||
"--exclude",
|
"--exclude",
|
||||||
"cargo-credential-1password",
|
"cargo-credential-1password",
|
||||||
"--exclude",
|
"--exclude",
|
||||||
"cargo-credential-gnome-secret",
|
"cargo-credential-libsecret",
|
||||||
"--exclude",
|
"--exclude",
|
||||||
"cargo-credential-macos-keychain",
|
"cargo-credential-macos-keychain",
|
||||||
"--exclude",
|
"--exclude",
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#[cfg(target_os = "linux")]
|
|
||||||
mod libsecret;
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
pub use cargo_credential::UnsupportedCredential as GnomeSecret;
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub use libsecret::GnomeSecret;
|
|
@ -1,226 +0,0 @@
|
|||||||
//! Implementation of the libsecret credential helper.
|
|
||||||
|
|
||||||
use anyhow::Context;
|
|
||||||
use cargo_credential::{
|
|
||||||
read_token, Action, CacheControl, Credential, CredentialResponse, Error, RegistryInfo, Secret,
|
|
||||||
};
|
|
||||||
use libloading::{Library, Symbol};
|
|
||||||
use std::ffi::{CStr, CString};
|
|
||||||
use std::os::raw::{c_char, c_int};
|
|
||||||
use std::ptr::{null, null_mut};
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type gchar = c_char;
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type gboolean = c_int;
|
|
||||||
|
|
||||||
type GQuark = u32;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct GError {
|
|
||||||
domain: GQuark,
|
|
||||||
code: c_int,
|
|
||||||
message: *mut gchar,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct GCancellable {
|
|
||||||
_private: [u8; 0],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct SecretSchema {
|
|
||||||
name: *const gchar,
|
|
||||||
flags: SecretSchemaFlags,
|
|
||||||
attributes: [SecretSchemaAttribute; 32],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
struct SecretSchemaAttribute {
|
|
||||||
name: *const gchar,
|
|
||||||
attr_type: SecretSchemaAttributeType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
enum SecretSchemaFlags {
|
|
||||||
None = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
enum SecretSchemaAttributeType {
|
|
||||||
String = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
type SecretPasswordStoreSync = extern "C" fn(
|
|
||||||
schema: *const SecretSchema,
|
|
||||||
collection: *const gchar,
|
|
||||||
label: *const gchar,
|
|
||||||
password: *const gchar,
|
|
||||||
cancellable: *mut GCancellable,
|
|
||||||
error: *mut *mut GError,
|
|
||||||
...
|
|
||||||
) -> gboolean;
|
|
||||||
type SecretPasswordClearSync = extern "C" fn(
|
|
||||||
schema: *const SecretSchema,
|
|
||||||
cancellable: *mut GCancellable,
|
|
||||||
error: *mut *mut GError,
|
|
||||||
...
|
|
||||||
) -> gboolean;
|
|
||||||
type SecretPasswordLookupSync = extern "C" fn(
|
|
||||||
schema: *const SecretSchema,
|
|
||||||
cancellable: *mut GCancellable,
|
|
||||||
error: *mut *mut GError,
|
|
||||||
...
|
|
||||||
) -> *mut gchar;
|
|
||||||
|
|
||||||
pub struct GnomeSecret;
|
|
||||||
|
|
||||||
fn label(index_url: &str) -> CString {
|
|
||||||
CString::new(format!("cargo-registry:{}", index_url)).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn schema() -> SecretSchema {
|
|
||||||
let mut attributes = [SecretSchemaAttribute {
|
|
||||||
name: null(),
|
|
||||||
attr_type: SecretSchemaAttributeType::String,
|
|
||||||
}; 32];
|
|
||||||
attributes[0] = SecretSchemaAttribute {
|
|
||||||
name: b"url\0".as_ptr() as *const gchar,
|
|
||||||
attr_type: SecretSchemaAttributeType::String,
|
|
||||||
};
|
|
||||||
SecretSchema {
|
|
||||||
name: b"org.rust-lang.cargo.registry\0".as_ptr() as *const gchar,
|
|
||||||
flags: SecretSchemaFlags::None,
|
|
||||||
attributes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Credential for GnomeSecret {
|
|
||||||
fn perform(
|
|
||||||
&self,
|
|
||||||
registry: &RegistryInfo,
|
|
||||||
action: &Action,
|
|
||||||
_args: &[&str],
|
|
||||||
) -> Result<CredentialResponse, Error> {
|
|
||||||
// Dynamically load libsecret to avoid users needing to install
|
|
||||||
// additional -dev packages when building this provider.
|
|
||||||
let lib;
|
|
||||||
let secret_password_lookup_sync: Symbol<SecretPasswordLookupSync>;
|
|
||||||
let secret_password_store_sync: Symbol<SecretPasswordStoreSync>;
|
|
||||||
let secret_password_clear_sync: Symbol<SecretPasswordClearSync>;
|
|
||||||
unsafe {
|
|
||||||
lib = Library::new("libsecret-1.so").context(
|
|
||||||
"failed to load libsecret: try installing the `libsecret` \
|
|
||||||
or `libsecret-1-0` package with the system package manager",
|
|
||||||
)?;
|
|
||||||
secret_password_lookup_sync = lib
|
|
||||||
.get(b"secret_password_lookup_sync\0")
|
|
||||||
.map_err(Box::new)?;
|
|
||||||
secret_password_store_sync =
|
|
||||||
lib.get(b"secret_password_store_sync\0").map_err(Box::new)?;
|
|
||||||
secret_password_clear_sync =
|
|
||||||
lib.get(b"secret_password_clear_sync\0").map_err(Box::new)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let index_url_c = CString::new(registry.index_url).unwrap();
|
|
||||||
match action {
|
|
||||||
cargo_credential::Action::Get(_) => {
|
|
||||||
let mut error: *mut GError = null_mut();
|
|
||||||
let attr_url = CString::new("url").unwrap();
|
|
||||||
let schema = schema();
|
|
||||||
unsafe {
|
|
||||||
let token_c = secret_password_lookup_sync(
|
|
||||||
&schema,
|
|
||||||
null_mut(),
|
|
||||||
&mut error,
|
|
||||||
attr_url.as_ptr(),
|
|
||||||
index_url_c.as_ptr(),
|
|
||||||
null() as *const gchar,
|
|
||||||
);
|
|
||||||
if !error.is_null() {
|
|
||||||
return Err(format!(
|
|
||||||
"failed to get token: {}",
|
|
||||||
CStr::from_ptr((*error).message)
|
|
||||||
.to_str()
|
|
||||||
.unwrap_or_default()
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
if token_c.is_null() {
|
|
||||||
return Err(Error::NotFound);
|
|
||||||
}
|
|
||||||
let token = Secret::from(
|
|
||||||
CStr::from_ptr(token_c)
|
|
||||||
.to_str()
|
|
||||||
.map_err(|e| format!("expected utf8 token: {}", e))?
|
|
||||||
.to_string(),
|
|
||||||
);
|
|
||||||
Ok(CredentialResponse::Get {
|
|
||||||
token,
|
|
||||||
cache: CacheControl::Session,
|
|
||||||
operation_independent: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cargo_credential::Action::Login(options) => {
|
|
||||||
let label = label(registry.name.unwrap_or(registry.index_url));
|
|
||||||
let token = CString::new(read_token(options, registry)?.expose()).unwrap();
|
|
||||||
let mut error: *mut GError = null_mut();
|
|
||||||
let attr_url = CString::new("url").unwrap();
|
|
||||||
let schema = schema();
|
|
||||||
unsafe {
|
|
||||||
secret_password_store_sync(
|
|
||||||
&schema,
|
|
||||||
b"default\0".as_ptr() as *const gchar,
|
|
||||||
label.as_ptr(),
|
|
||||||
token.as_ptr(),
|
|
||||||
null_mut(),
|
|
||||||
&mut error,
|
|
||||||
attr_url.as_ptr(),
|
|
||||||
index_url_c.as_ptr(),
|
|
||||||
null() as *const gchar,
|
|
||||||
);
|
|
||||||
if !error.is_null() {
|
|
||||||
return Err(format!(
|
|
||||||
"failed to store token: {}",
|
|
||||||
CStr::from_ptr((*error).message)
|
|
||||||
.to_str()
|
|
||||||
.unwrap_or_default()
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(CredentialResponse::Login)
|
|
||||||
}
|
|
||||||
cargo_credential::Action::Logout => {
|
|
||||||
let schema = schema();
|
|
||||||
let mut error: *mut GError = null_mut();
|
|
||||||
let attr_url = CString::new("url").unwrap();
|
|
||||||
unsafe {
|
|
||||||
secret_password_clear_sync(
|
|
||||||
&schema,
|
|
||||||
null_mut(),
|
|
||||||
&mut error,
|
|
||||||
attr_url.as_ptr(),
|
|
||||||
index_url_c.as_ptr(),
|
|
||||||
null() as *const gchar,
|
|
||||||
);
|
|
||||||
if !error.is_null() {
|
|
||||||
return Err(format!(
|
|
||||||
"failed to erase token: {}",
|
|
||||||
CStr::from_ptr((*error).message)
|
|
||||||
.to_str()
|
|
||||||
.unwrap_or_default()
|
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(CredentialResponse::Logout)
|
|
||||||
}
|
|
||||||
_ => Err(Error::OperationNotSupported),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
//! Cargo registry gnome libsecret credential process.
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
cargo_credential::main(GnomeSecret);
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cargo-credential-gnome-secret"
|
name = "cargo-credential-libsecret"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
@ -10,4 +10,3 @@ description = "A Cargo credential process that stores tokens with GNOME libsecre
|
|||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
cargo-credential.workspace = true
|
cargo-credential.workspace = true
|
||||||
libloading.workspace = true
|
libloading.workspace = true
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
# cargo-credential-gnome-secret
|
# cargo-credential-libsecret
|
||||||
|
|
||||||
This is the implementation for the Cargo credential helper for [GNOME libsecret].
|
This is the implementation for the Cargo credential helper for [GNOME libsecret].
|
||||||
See the [credential-process] documentation for how to use this.
|
See the [credential-process] documentation for how to use this.
|
235
credential/cargo-credential-libsecret/src/lib.rs
Normal file
235
credential/cargo-credential-libsecret/src/lib.rs
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod linux {
|
||||||
|
//! Implementation of the libsecret credential helper.
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
|
use cargo_credential::{
|
||||||
|
read_token, Action, CacheControl, Credential, CredentialResponse, Error, RegistryInfo,
|
||||||
|
Secret,
|
||||||
|
};
|
||||||
|
use libloading::{Library, Symbol};
|
||||||
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::os::raw::{c_char, c_int};
|
||||||
|
use std::ptr::{null, null_mut};
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type gchar = c_char;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
type gboolean = c_int;
|
||||||
|
|
||||||
|
type GQuark = u32;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct GError {
|
||||||
|
domain: GQuark,
|
||||||
|
code: c_int,
|
||||||
|
message: *mut gchar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct GCancellable {
|
||||||
|
_private: [u8; 0],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct SecretSchema {
|
||||||
|
name: *const gchar,
|
||||||
|
flags: SecretSchemaFlags,
|
||||||
|
attributes: [SecretSchemaAttribute; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct SecretSchemaAttribute {
|
||||||
|
name: *const gchar,
|
||||||
|
attr_type: SecretSchemaAttributeType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
enum SecretSchemaFlags {
|
||||||
|
None = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum SecretSchemaAttributeType {
|
||||||
|
String = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecretPasswordStoreSync = extern "C" fn(
|
||||||
|
schema: *const SecretSchema,
|
||||||
|
collection: *const gchar,
|
||||||
|
label: *const gchar,
|
||||||
|
password: *const gchar,
|
||||||
|
cancellable: *mut GCancellable,
|
||||||
|
error: *mut *mut GError,
|
||||||
|
...
|
||||||
|
) -> gboolean;
|
||||||
|
type SecretPasswordClearSync = extern "C" fn(
|
||||||
|
schema: *const SecretSchema,
|
||||||
|
cancellable: *mut GCancellable,
|
||||||
|
error: *mut *mut GError,
|
||||||
|
...
|
||||||
|
) -> gboolean;
|
||||||
|
type SecretPasswordLookupSync = extern "C" fn(
|
||||||
|
schema: *const SecretSchema,
|
||||||
|
cancellable: *mut GCancellable,
|
||||||
|
error: *mut *mut GError,
|
||||||
|
...
|
||||||
|
) -> *mut gchar;
|
||||||
|
|
||||||
|
pub struct LibSecretCredential;
|
||||||
|
|
||||||
|
fn label(index_url: &str) -> CString {
|
||||||
|
CString::new(format!("cargo-registry:{}", index_url)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn schema() -> SecretSchema {
|
||||||
|
let mut attributes = [SecretSchemaAttribute {
|
||||||
|
name: null(),
|
||||||
|
attr_type: SecretSchemaAttributeType::String,
|
||||||
|
}; 32];
|
||||||
|
attributes[0] = SecretSchemaAttribute {
|
||||||
|
name: b"url\0".as_ptr() as *const gchar,
|
||||||
|
attr_type: SecretSchemaAttributeType::String,
|
||||||
|
};
|
||||||
|
SecretSchema {
|
||||||
|
name: b"org.rust-lang.cargo.registry\0".as_ptr() as *const gchar,
|
||||||
|
flags: SecretSchemaFlags::None,
|
||||||
|
attributes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Credential for LibSecretCredential {
|
||||||
|
fn perform(
|
||||||
|
&self,
|
||||||
|
registry: &RegistryInfo,
|
||||||
|
action: &Action,
|
||||||
|
_args: &[&str],
|
||||||
|
) -> Result<CredentialResponse, Error> {
|
||||||
|
// Dynamically load libsecret to avoid users needing to install
|
||||||
|
// additional -dev packages when building this provider.
|
||||||
|
let lib;
|
||||||
|
let secret_password_lookup_sync: Symbol<SecretPasswordLookupSync>;
|
||||||
|
let secret_password_store_sync: Symbol<SecretPasswordStoreSync>;
|
||||||
|
let secret_password_clear_sync: Symbol<SecretPasswordClearSync>;
|
||||||
|
unsafe {
|
||||||
|
lib = Library::new("libsecret-1.so").context(
|
||||||
|
"failed to load libsecret: try installing the `libsecret` \
|
||||||
|
or `libsecret-1-0` package with the system package manager",
|
||||||
|
)?;
|
||||||
|
secret_password_lookup_sync = lib
|
||||||
|
.get(b"secret_password_lookup_sync\0")
|
||||||
|
.map_err(Box::new)?;
|
||||||
|
secret_password_store_sync =
|
||||||
|
lib.get(b"secret_password_store_sync\0").map_err(Box::new)?;
|
||||||
|
secret_password_clear_sync =
|
||||||
|
lib.get(b"secret_password_clear_sync\0").map_err(Box::new)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let index_url_c = CString::new(registry.index_url).unwrap();
|
||||||
|
match action {
|
||||||
|
cargo_credential::Action::Get(_) => {
|
||||||
|
let mut error: *mut GError = null_mut();
|
||||||
|
let attr_url = CString::new("url").unwrap();
|
||||||
|
let schema = schema();
|
||||||
|
unsafe {
|
||||||
|
let token_c = secret_password_lookup_sync(
|
||||||
|
&schema,
|
||||||
|
null_mut(),
|
||||||
|
&mut error,
|
||||||
|
attr_url.as_ptr(),
|
||||||
|
index_url_c.as_ptr(),
|
||||||
|
null() as *const gchar,
|
||||||
|
);
|
||||||
|
if !error.is_null() {
|
||||||
|
return Err(format!(
|
||||||
|
"failed to get token: {}",
|
||||||
|
CStr::from_ptr((*error).message)
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_default()
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
if token_c.is_null() {
|
||||||
|
return Err(Error::NotFound);
|
||||||
|
}
|
||||||
|
let token = Secret::from(
|
||||||
|
CStr::from_ptr(token_c)
|
||||||
|
.to_str()
|
||||||
|
.map_err(|e| format!("expected utf8 token: {}", e))?
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
Ok(CredentialResponse::Get {
|
||||||
|
token,
|
||||||
|
cache: CacheControl::Session,
|
||||||
|
operation_independent: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cargo_credential::Action::Login(options) => {
|
||||||
|
let label = label(registry.name.unwrap_or(registry.index_url));
|
||||||
|
let token = CString::new(read_token(options, registry)?.expose()).unwrap();
|
||||||
|
let mut error: *mut GError = null_mut();
|
||||||
|
let attr_url = CString::new("url").unwrap();
|
||||||
|
let schema = schema();
|
||||||
|
unsafe {
|
||||||
|
secret_password_store_sync(
|
||||||
|
&schema,
|
||||||
|
b"default\0".as_ptr() as *const gchar,
|
||||||
|
label.as_ptr(),
|
||||||
|
token.as_ptr(),
|
||||||
|
null_mut(),
|
||||||
|
&mut error,
|
||||||
|
attr_url.as_ptr(),
|
||||||
|
index_url_c.as_ptr(),
|
||||||
|
null() as *const gchar,
|
||||||
|
);
|
||||||
|
if !error.is_null() {
|
||||||
|
return Err(format!(
|
||||||
|
"failed to store token: {}",
|
||||||
|
CStr::from_ptr((*error).message)
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_default()
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(CredentialResponse::Login)
|
||||||
|
}
|
||||||
|
cargo_credential::Action::Logout => {
|
||||||
|
let schema = schema();
|
||||||
|
let mut error: *mut GError = null_mut();
|
||||||
|
let attr_url = CString::new("url").unwrap();
|
||||||
|
unsafe {
|
||||||
|
secret_password_clear_sync(
|
||||||
|
&schema,
|
||||||
|
null_mut(),
|
||||||
|
&mut error,
|
||||||
|
attr_url.as_ptr(),
|
||||||
|
index_url_c.as_ptr(),
|
||||||
|
null() as *const gchar,
|
||||||
|
);
|
||||||
|
if !error.is_null() {
|
||||||
|
return Err(format!(
|
||||||
|
"failed to erase token: {}",
|
||||||
|
CStr::from_ptr((*error).message)
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_default()
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(CredentialResponse::Logout)
|
||||||
|
}
|
||||||
|
_ => Err(Error::OperationNotSupported),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
pub use cargo_credential::UnsupportedCredential as LibSecretCredential;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub use linux::LibSecretCredential;
|
@ -451,7 +451,7 @@ fn credential_action(
|
|||||||
"cargo:token-from-stdout" => Box::new(BasicProcessCredential {}),
|
"cargo:token-from-stdout" => Box::new(BasicProcessCredential {}),
|
||||||
"cargo:wincred" => Box::new(cargo_credential_wincred::WindowsCredential {}),
|
"cargo:wincred" => Box::new(cargo_credential_wincred::WindowsCredential {}),
|
||||||
"cargo:macos-keychain" => Box::new(cargo_credential_macos_keychain::MacKeychain {}),
|
"cargo:macos-keychain" => Box::new(cargo_credential_macos_keychain::MacKeychain {}),
|
||||||
"cargo:libsecret" => Box::new(cargo_credential_gnome_secret::GnomeSecret {}),
|
"cargo:libsecret" => Box::new(cargo_credential_libsecret::LibSecretCredential {}),
|
||||||
process => Box::new(CredentialProcessCredential::new(process)),
|
process => Box::new(CredentialProcessCredential::new(process)),
|
||||||
};
|
};
|
||||||
config.shell().verbose(|c| {
|
config.shell().verbose(|c| {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user