Skip to content

Commit

Permalink
Keyring defaults (#250)
Browse files Browse the repository at this point in the history
When keyring interaction was initially added, federation was not part of
warg and now that it is, these changes should simplify keyring
interaction a bit.

1.) Add a default signing key to the configuration that will be used
whenever a registry specific keyring does not exist.
2.) Add a key list to local config that can be checked for a registry
specific key without password prompt to determine whether to prompt a
password for the default key or registry specific key.
3.) Remove key names and files
4.) Unrelated to keys, but there's a fix to get auth tokens based on
provided registry url flag

---------

Co-authored-by: Calvin Prewitt <calvin@jaflabs.com>
  • Loading branch information
macovedj and calvinrp authored Feb 26, 2024
1 parent 36ba63d commit 55877dc
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 147 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions crates/client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use normpath::PathExt;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::{
collections::HashSet,
env::current_dir,
fs::{self, File},
path::{Component, Path, PathBuf},
Expand Down Expand Up @@ -105,6 +106,10 @@ pub struct Config {
/// `$CACHE_DIR` is the platform-specific cache directory.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace_map_path: Option<PathBuf>,

/// List of creds availabe in keyring
#[serde(default, skip_serializing_if = "Option::is_none")]
pub keys: Option<HashSet<String>>,
}

impl Config {
Expand Down Expand Up @@ -181,6 +186,7 @@ impl Config {
assert!(p.is_absolute());
pathdiff::diff_paths(&p, &parent).unwrap()
}),
keys: self.keys.clone(),
};

serde_json::to_writer_pretty(
Expand Down
45 changes: 13 additions & 32 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Commands for the `warg` tool.
use anyhow::Context;
use anyhow::Result;
use clap::Args;
use secrecy::Secret;
Expand Down Expand Up @@ -52,15 +51,6 @@ pub struct CommonOptions {
/// The URL of the registry to use.
#[clap(long, value_name = "URL")]
pub registry: Option<String>,
/// The path to the auth token file.
#[clap(long, value_name = "TOKEN_FILE", env = "WARG_AUTH_TOKEN_FILE")]
pub token_file: Option<PathBuf>,
/// The name to use for the signing key.
#[clap(long, short, value_name = "KEY_NAME", default_value = "default")]
pub key_name: String,
/// The path to the signing key file.
#[clap(long, value_name = "KEY_FILE", env = "WARG_SIGNING_KEY_FILE")]
pub key_file: Option<PathBuf>,
/// The path to the client configuration file to use.
///
/// If not specified, the following locations are searched in order: `./warg-config.json`, `<system-config-dir>/warg/config.json`.
Expand Down Expand Up @@ -121,34 +111,25 @@ impl CommonOptions {
client: &Client<R, C, N>,
) -> Result<PrivateKey> {
let registry_url = if let Some(nm) = &client.get_warg_registry() {
RegistryUrl::new(nm.to_string())?
Some(RegistryUrl::new(nm.to_string())?)
} else {
client.url().clone()
None
};
if let Some(file) = &self.key_file {
let key_str = std::fs::read_to_string(file)
.with_context(|| format!("failed to read key from {file:?}"))?
.trim_end()
.to_string();
PrivateKey::decode(key_str)
.with_context(|| format!("failed to parse key from {file:?}"))
} else {
get_signing_key(&registry_url, &self.key_name)
}
let config = self.read_config()?;
get_signing_key(
&registry_url.map(|reg| reg.safe_label()),
config.keys.expect("Please set a default signing key by typing `warg key set <alg:base64>` or `warg key new"),
config.home_url,
)
}
/// Gets the auth token for the given registry URL.
pub fn auth_token(&self, config: &Config) -> Result<Option<Secret<String>>> {
if let Some(file) = &self.token_file {
Ok(Some(Secret::from(
std::fs::read_to_string(file)
.with_context(|| format!("failed to read auth token from {file:?}"))?
.trim_end()
.to_string(),
)))
if let Some(reg_url) = &self.registry {
Ok(get_auth_token(&RegistryUrl::new(reg_url)?)?)
} else if let Some(url) = config.home_url.as_ref() {
Ok(get_auth_token(&RegistryUrl::new(url)?)?)
} else {
Ok(get_auth_token(&RegistryUrl::new(
config.home_url.as_ref().unwrap(),
)?)?)
Ok(None)
}
}
}
Expand Down
14 changes: 9 additions & 5 deletions src/commands/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::CommonOptions;
use anyhow::{bail, Context, Result};
use clap::Args;
use std::path::PathBuf;
Expand All @@ -6,9 +7,9 @@ use warg_client::{Config, RegistryUrl};
/// Creates a new warg configuration file.
#[derive(Args)]
pub struct ConfigCommand {
/// The home registry URL to use.
#[clap(long, value_name = "URL")]
pub registry: Option<String>,
/// The common command options.
#[clap(flatten)]
pub common: CommonOptions,

/// The path to the registries directory to use.
#[clap(long, value_name = "REGISTRIES")]
Expand Down Expand Up @@ -48,8 +49,10 @@ impl ConfigCommand {
);
}

let home_url = self
let home_url = &self
.common
.registry
.clone()
.map(RegistryUrl::new)
.transpose()?
.map(|u| u.to_string());
Expand All @@ -61,10 +64,11 @@ impl ConfigCommand {
// the configuration file's directory.
let cwd = std::env::current_dir().context("failed to determine current directory")?;
let config = Config {
home_url,
home_url: home_url.clone(),
registries_dir: self.registries_dir.map(|p| cwd.join(p)),
content_dir: self.content_dir.map(|p| cwd.join(p)),
namespace_map_path: self.namespace_path.map(|p| cwd.join(p)),
keys: self.common.read_config()?.keys,
};

config.write_to_file(&path)?;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ impl InfoCommand {
.for_each(Self::print_package_info);
}
}
Self::print_namespace_map(&client).await?;

if self.namespaces {
println!("\nnamespace mappings in client storage");
Self::print_namespace_map(&client).await?;
return Ok(());
}
Expand Down
Loading

0 comments on commit 55877dc

Please sign in to comment.