Skip to content

Commit

Permalink
Add a cargo credential implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bilelmoussaoui committed Sep 16, 2024
1 parent 3ba3e8d commit 6f1c7a4
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 0 deletions.
69 changes: 69 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"

members = [
"cargo-credential",
"client",
"cli",
"portal",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ James Bond went on a new mission and this time as a [Secret Service provider](ht

The repository consists of the following projects:

- [cargo-credential](./cargo-credential/): a [cargo credential](https://doc.rust-lang.org/stable/cargo/reference/registry-authentication.html#registry-authentication) provider
- [cli](./cli/): a secret-tool replacement
- [client](./client/): the client side library
- [portal](./portal/): [org.freedesktop.impl.portal.Secret](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.impl.portal.Secret.html) implementation
Expand Down
17 changes: 17 additions & 0 deletions cargo-credential/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "cargo-credential-oo7"
version.workspace = true
edition.workspace = true
authors.workspace = true
keywords.workspace = true
categories.workspace = true
repository.workspace = true
homepage.workspace = true
license.workspace = true
rust-version.workspace = true
exclude.workspace = true

[dependencies]
cargo-credential = "0.4"
oo7.workspace = true
tokio = {workspace = true, features = ["rt-multi-thread"]}
22 changes: 22 additions & 0 deletions cargo-credential/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

# cargo-credential-oo7

[![crates.io](https://img.shields.io/crates/v/cargo-credential-oo7)](https://crates.io/crates/cargo-credential-oo7)

A [cargo credential provider](https://doc.rust-lang.org/stable/cargo/reference/registry-authentication.html#registry-authentication) built using oo7 instead of [libsecret](https://github.com/rust-lang/cargo/tree/master/credential/cargo-credential-libsecret).


## Installation

1 - `cargo install cargo-credential-oo7`

2 - Set as the default [credential provider](https://doc.rust-lang.org/stable/cargo/reference/registry-authentication.html)

```toml
[registry]
global-credential-providers = ["cargo-credential-oo7"]
```

## License

The project is released under the MIT license.
102 changes: 102 additions & 0 deletions cargo-credential/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use std::collections::HashMap;

use cargo_credential::{Action, CredentialResponse, Error, RegistryInfo, Secret};

pub struct SecretServiceCredential;

impl SecretServiceCredential {
async fn preform_future(
&self,
registry: &RegistryInfo<'_>,
action: &Action<'_>,
) -> Result<CredentialResponse, Error> {
let service = oo7::dbus::Service::new()
.await
.map_err(|err| Error::Other(Box::new(err)))?;
let collection = service
.default_collection()
.await
.map_err(|err| Error::Other(Box::new(err)))?;
let attributes = HashMap::from([("url", registry.index_url)]);
let items = collection
.search_items(&attributes)
.await
.map_err(|err| Error::Other(Box::new(err)))?;

match action {
cargo_credential::Action::Get(_) => {
if items.len() == 0 {
return Err(Error::NotFound);
}

let token = Secret::from(
std::str::from_utf8(
&items[0]
.secret()
.await
.map_err(|err| Error::Other(Box::new(err)))?,
)
.unwrap()
.to_owned(),
);

Ok(CredentialResponse::Get {
token,
cache: cargo_credential::CacheControl::Session,
operation_independent: true,
})
}
cargo_credential::Action::Login(options) => {
let token = cargo_credential::read_token(options, registry)?.expose();

if let Some(item) = items.get(0) {
item.set_secret(token, "text/utf8")
.await
.map_err(|err| Error::Other(Box::new(err)))?;
} else {

collection
.create_item(
&format!("cargo-registry:{}", registry.index_url),
&attributes,
token,
true,
"text/utf8",
)
.await
.map_err(|err| Error::Other(Box::new(err)))?;
}

Ok(CredentialResponse::Login)
}
cargo_credential::Action::Logout => {
if items.len() == 0 {
return Err(Error::NotFound);
}

items[0]
.delete()
.await
.map_err(|err| Error::Other(Box::new(err)))?;
Ok(CredentialResponse::Logout)
}
_ => Err(Error::OperationNotSupported),
}
}
}

impl cargo_credential::Credential for SecretServiceCredential {
fn perform(
&self,
registry: &RegistryInfo<'_>,
action: &Action<'_>,
_args: &[&str],
) -> Result<CredentialResponse, Error> {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async move { self.preform_future(registry, action).await })
}
}

fn main() {
cargo_credential::main(SecretServiceCredential {});
}

0 comments on commit 6f1c7a4

Please sign in to comment.