From 36ba63d7720ca7a34a785677f4b90667fdbc12b2 Mon Sep 17 00:00:00 2001 From: Daniel Macovei Date: Thu, 22 Feb 2024 11:01:10 -0600 Subject: [PATCH] Auth token (#248) This PR adds login and logout commands to add or delete auth tokens to your keyring and then adds them as bearer tokens to requests made to your warg server --------- Co-authored-by: Calvin Prewitt --- Cargo.lock | 24 ++--------------- Cargo.toml | 2 +- crates/client/Cargo.toml | 1 + crates/client/src/api.rs | 44 +++++++++++++++++++++++------- crates/client/src/lib.rs | 23 +++++++++++++--- src/bin/warg.rs | 9 ++++++- src/commands.rs | 37 ++++++++++++++++++++++--- src/commands/info.rs | 1 + src/commands/key.rs | 9 ++++--- src/commands/login.rs | 53 ++++++++++++++++++++++++++++++++++++ src/commands/logout.rs | 47 ++++++++++++++++++++++++++++++++ src/keyring.rs | 58 +++++++++++++++++++++++++++++++++++++++- tests/client.rs | 2 +- tests/memory/mod.rs | 6 ++--- tests/postgres/mod.rs | 4 +-- tests/server.rs | 6 ++--- tests/support/mod.rs | 2 +- 17 files changed, 273 insertions(+), 55 deletions(-) create mode 100644 src/commands/login.rs create mode 100644 src/commands/logout.rs diff --git a/Cargo.lock b/Cargo.lock index ed1d872d..96bcc1c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3498,27 +3498,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "rpassword" -version = "7.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" -dependencies = [ - "libc", - "rtoolbox", - "windows-sys 0.48.0", -] - -[[package]] -name = "rtoolbox" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "rust-ini" version = "0.13.0" @@ -4663,7 +4642,7 @@ dependencies = [ "ptree", "rand_core", "reqwest", - "rpassword", + "secrecy", "semver", "serde_json", "testresult", @@ -4708,6 +4687,7 @@ dependencies = [ "pathdiff", "ptree", "reqwest", + "secrecy", "semver", "serde 1.0.196", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 76444e47..68e8d655 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,8 +42,8 @@ wat = "1.0.85" wasmprinter = "0.2.78" keyring = "2.3.0" dialoguer = "0.11.0" -rpassword = "7.3.1" itertools = "0.12.1" +secrecy= { workspace = true } [dev-dependencies] reqwest = { workspace = true } diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 76ebb499..1f2ba7a8 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -48,6 +48,7 @@ wasm-encoder.workspace = true wasmprinter = "0.2.75" sha256 = "1.4.0" ptree = { workspace = true } +secrecy= { workspace = true } [target.'cfg(windows)'.dependencies.windows-sys] version = "0.52" diff --git a/crates/client/src/api.rs b/crates/client/src/api.rs index e45913bb..a1c86d27 100644 --- a/crates/client/src/api.rs +++ b/crates/client/src/api.rs @@ -7,6 +7,7 @@ use reqwest::{ header::{HeaderMap, HeaderName, HeaderValue}, Body, IntoUrl, Method, RequestBuilder, Response, StatusCode, }; +use secrecy::{ExposeSecret, Secret}; use serde::de::DeserializeOwned; use std::{borrow::Cow, collections::HashMap}; use thiserror::Error; @@ -157,12 +158,10 @@ async fn into_result) -> Result; } impl WithWargHeader for RequestBuilder { - type Client = Client; fn warg_header(self, registry_header: &Option) -> Result { if let Some(reg) = registry_header { Ok(self.header(REGISTRY_HEADER_NAME, HeaderValue::try_from(reg.clone())?)) @@ -172,25 +171,46 @@ impl WithWargHeader for RequestBuilder { } } +trait WithAuth { + fn auth(self, auth_token: &Option>) -> RequestBuilder; +} + +impl WithAuth for RequestBuilder { + fn auth(self, auth_token: &Option>) -> reqwest::RequestBuilder { + if let Some(tok) = auth_token { + self.bearer_auth(tok.expose_secret()) + } else { + self + } + } +} + /// Represents a Warg API client for communicating with /// a Warg registry server. pub struct Client { url: RegistryUrl, client: reqwest::Client, warg_registry_header: Option, + auth_token: Option>, } impl Client { /// Creates a new API client with the given URL. - pub fn new(url: impl IntoUrl) -> Result { + pub fn new(url: impl IntoUrl, auth_token: Option>) -> Result { let url = RegistryUrl::new(url)?; Ok(Self { url, client: reqwest::Client::new(), warg_registry_header: None, + auth_token, }) } + /// Gets auth token + pub fn auth_token(&self) -> &Option> { + &self.auth_token + } + /// Gets the URL of the API client. pub fn url(&self) -> &RegistryUrl { &self.url @@ -206,6 +226,7 @@ impl Client { self.client .get(url) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?, ) @@ -226,6 +247,7 @@ impl Client { self.client .get(url) .header(registry_header, header_val) + .auth(self.auth_token()) .send() .await?, ) @@ -248,6 +270,7 @@ impl Client { .post(url) .json(&request) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?; into_result::<_, MonitorError>(response).await @@ -265,6 +288,7 @@ impl Client { .post(&url) .json(&request) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?; @@ -291,6 +315,7 @@ impl Client { .client .post(url) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .json(&request) .send() .await?; @@ -306,6 +331,7 @@ impl Client { self.client .get(url) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?, ) @@ -329,6 +355,7 @@ impl Client { .post(url) .json(&request) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?; into_result::<_, PackageError>(response).await @@ -347,6 +374,7 @@ impl Client { self.client .get(url) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?, ) @@ -365,6 +393,7 @@ impl Client { self.client .get(url) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?, ) @@ -389,12 +418,7 @@ impl Client { tracing::debug!("downloading content `{digest}` from `{url}`"); - let response = self - .client - .get(url) - .warg_header(self.get_warg_registry())? - .send() - .await?; + let response = self.client.get(url).send().await?; if !response.status().is_success() { tracing::debug!( "failed to download content `{digest}` from `{url}`: {status}", @@ -434,6 +458,7 @@ impl Client { .post(url) .json(&request) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?, ) @@ -455,6 +480,7 @@ impl Client { .post(url) .json(&request) .warg_header(self.get_warg_registry())? + .auth(self.auth_token()) .send() .await?, ) diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index 4af6f864..46930a4d 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -5,6 +5,7 @@ use crate::storage::PackageInfo; use anyhow::{anyhow, Context, Result}; use reqwest::header::HeaderValue; use reqwest::{Body, IntoUrl}; +use secrecy::Secret; use semver::{Version, VersionReq}; use std::cmp::Ordering; use std::fs; @@ -63,12 +64,19 @@ where impl Client { /// Creates a new client for the given URL, registry storage, and /// content storage. - pub fn new(url: impl IntoUrl, registry: R, content: C, namespace_map: N) -> ClientResult { + pub fn new( + url: impl IntoUrl, + registry: R, + content: C, + namespace_map: N, + auth_token: Option>, + ) -> ClientResult { + let api = api::Client::new(url, auth_token)?; Ok(Self { registry, content, namespace_map, - api: api::Client::new(url)?, + api, }) } @@ -138,7 +146,7 @@ impl Client, config: &Config, + auth_token: Option>, ) -> Result, ClientError> { let StoragePaths { registry_url: url, @@ -940,6 +949,7 @@ impl FileSystemClient { packages, content, namespace_map, + auth_token, )?)) } @@ -949,7 +959,11 @@ impl FileSystemClient { /// URL, an error is returned. /// /// This method blocks if storage locks cannot be acquired. - pub fn new_with_config(url: Option<&str>, config: &Config) -> Result { + pub fn new_with_config( + url: Option<&str>, + config: &Config, + auth_token: Option>, + ) -> Result { let StoragePaths { registry_url, registries_dir, @@ -961,6 +975,7 @@ impl FileSystemClient { FileSystemRegistryStorage::lock(registries_dir)?, FileSystemContentStorage::lock(content_dir)?, FileSystemNamespaceMapStorage::new(namespace_map_path), + auth_token, ) } } diff --git a/src/bin/warg.rs b/src/bin/warg.rs index b23e9d24..e088e25a 100644 --- a/src/bin/warg.rs +++ b/src/bin/warg.rs @@ -5,7 +5,8 @@ use std::process::exit; use tracing_subscriber::EnvFilter; use warg_cli::commands::{ BundleCommand, ClearCommand, ConfigCommand, DependenciesCommand, DownloadCommand, InfoCommand, - KeyCommand, LockCommand, PublishCommand, ResetCommand, Retry, UpdateCommand, + KeyCommand, LockCommand, LoginCommand, LogoutCommand, PublishCommand, ResetCommand, Retry, + UpdateCommand, }; use warg_client::ClientError; @@ -35,6 +36,8 @@ enum WargCli { Publish(PublishCommand), Reset(ResetCommand), Clear(ClearCommand), + Login(LoginCommand), + Logout(LogoutCommand), } #[tokio::main] @@ -55,6 +58,8 @@ async fn main() -> Result<()> { WargCli::Publish(cmd) => cmd.exec(None).await, WargCli::Reset(cmd) => cmd.exec().await, WargCli::Clear(cmd) => cmd.exec().await, + WargCli::Login(cmd) => cmd.exec().await, + WargCli::Logout(cmd) => cmd.exec().await, } { if let Some(e) = e.downcast_ref::() { describe_client_error_or_retry(e).await?; @@ -142,6 +147,8 @@ async fn describe_client_error_or_retry(e: &ClientError) -> Result<()> { } WargCli::Reset(cmd) => cmd.exec().await, WargCli::Clear(cmd) => cmd.exec().await, + WargCli::Login(cmd) => cmd.exec().await, + WargCli::Logout(cmd) => cmd.exec().await, } { if let Some(e) = e.downcast_ref::() { describe_client_error(e).await?; diff --git a/src/commands.rs b/src/commands.rs index 353f9931..b5d63b66 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -3,6 +3,7 @@ use anyhow::Context; use anyhow::Result; use clap::Args; +use secrecy::Secret; use std::path::PathBuf; use std::str::FromStr; use warg_client::storage::ContentStorage; @@ -22,10 +23,13 @@ mod download; mod info; mod key; mod lock; +mod login; +mod logout; mod publish; mod reset; mod update; +use crate::keyring::get_auth_token; use crate::keyring::get_signing_key; pub use self::bundle::*; @@ -36,6 +40,8 @@ pub use self::download::*; pub use self::info::*; pub use self::key::*; pub use self::lock::*; +pub use self::login::*; +pub use self::logout::*; pub use self::publish::*; pub use self::reset::*; pub use self::update::*; @@ -46,6 +52,9 @@ pub struct CommonOptions { /// The URL of the registry to use. #[clap(long, value_name = "URL")] pub registry: Option, + /// The path to the auth token file. + #[clap(long, value_name = "TOKEN_FILE", env = "WARG_AUTH_TOKEN_FILE")] + pub token_file: Option, /// The name to use for the signing key. #[clap(long, short, value_name = "KEY_NAME", default_value = "default")] pub key_name: String, @@ -81,8 +90,11 @@ impl CommonOptions { config: &Config, retry: Option, ) -> Result { - let client = match FileSystemClient::try_new_with_config(self.registry.as_deref(), config)? - { + let client = match FileSystemClient::try_new_with_config( + self.registry.as_deref(), + config, + self.auth_token(config)?, + )? { StorageLockResult::Acquired(client) => Ok(client), StorageLockResult::NotAcquired(path) => { println!( @@ -90,7 +102,11 @@ impl CommonOptions { path = path.display() ); - FileSystemClient::new_with_config(self.registry.as_deref(), config) + FileSystemClient::new_with_config( + self.registry.as_deref(), + config, + self.auth_token(config)?.map(Secret::from), + ) } }?; if let Some(retry) = retry { @@ -120,6 +136,21 @@ impl CommonOptions { get_signing_key(®istry_url, &self.key_name) } } + /// Gets the auth token for the given registry URL. + pub fn auth_token(&self, config: &Config) -> Result>> { + 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(), + ))) + } else { + Ok(get_auth_token(&RegistryUrl::new( + config.home_url.as_ref().unwrap(), + )?)?) + } + } } /// Namespace mapping to store when retrying a command after receiving a hint header diff --git a/src/commands/info.rs b/src/commands/info.rs index b6450e99..1b3f1e7d 100644 --- a/src/commands/info.rs +++ b/src/commands/info.rs @@ -52,6 +52,7 @@ impl InfoCommand { .for_each(Self::print_package_info); } } + Self::print_namespace_map(&client).await?; if self.namespaces { Self::print_namespace_map(&client).await?; diff --git a/src/commands/key.rs b/src/commands/key.rs index de76665f..be10f0e0 100644 --- a/src/commands/key.rs +++ b/src/commands/key.rs @@ -1,7 +1,7 @@ use crate::keyring::{delete_signing_key, get_signing_key, get_signing_key_entry, set_signing_key}; use anyhow::{bail, Context, Result}; use clap::{Args, Subcommand}; -use dialoguer::{theme::ColorfulTheme, Confirm}; +use dialoguer::{theme::ColorfulTheme, Confirm, Password}; use keyring::{Entry, Error as KeyringError}; use p256::ecdsa::SigningKey; use rand_core::OsRng; @@ -146,9 +146,10 @@ pub struct KeySetCommand { impl KeySetCommand { /// Executes the command. pub async fn exec(self) -> Result<()> { - let key_str = - rpassword::prompt_password("input signing key (expected format is `:`): ") - .context("failed to read signing key")?; + let key_str = Password::with_theme(&ColorfulTheme::default()) + .with_prompt("input signing key (expected format is `:`): ") + .interact() + .context("failed to read signing key")?; let key = PrivateKey::decode(key_str).context("signing key is not in the correct format")?; diff --git a/src/commands/login.rs b/src/commands/login.rs new file mode 100644 index 00000000..c54857de --- /dev/null +++ b/src/commands/login.rs @@ -0,0 +1,53 @@ +use anyhow::{bail, Context, Result}; +use clap::Args; +use dialoguer::{theme::ColorfulTheme, Password}; +use warg_client::RegistryUrl; + +use crate::keyring::set_auth_token; + +use super::CommonOptions; + +/// Manage auth tokens for interacting with a registry. +#[derive(Args)] +pub struct LoginCommand { + /// The common command options. + #[clap(flatten)] + pub common: CommonOptions, + + /// The subcommand to execute. + #[clap(flatten)] + keyring_entry: KeyringEntryArgs, +} + +#[derive(Args)] +struct KeyringEntryArgs { + /// The URL of the registry to store an auth token for. + #[clap(value_name = "URL")] + pub url: Option, +} + +impl KeyringEntryArgs { + fn set_entry(&self, home_url: Option, token: &str) -> Result<()> { + if let Some(url) = &self.url { + set_auth_token(url, token) + } else if let Some(url) = &home_url { + set_auth_token(&RegistryUrl::new(url)?, token) + } else { + bail!("Please configure your home registry: warg config --registry ") + } + } +} + +impl LoginCommand { + /// Executes the command. + pub async fn exec(self) -> Result<()> { + let token = Password::with_theme(&ColorfulTheme::default()) + .with_prompt("Enter auth token") + .interact() + .context("failed to read token")?; + self.keyring_entry + .set_entry(self.common.read_config()?.home_url, &token)?; + println!("auth token was set successfully",); + Ok(()) + } +} diff --git a/src/commands/logout.rs b/src/commands/logout.rs new file mode 100644 index 00000000..00e34560 --- /dev/null +++ b/src/commands/logout.rs @@ -0,0 +1,47 @@ +use anyhow::{bail, Result}; +use clap::Args; +use warg_client::RegistryUrl; + +use crate::keyring::delete_auth_token; + +use super::CommonOptions; + +/// Manage auth tokens for interacting with a registry. +#[derive(Args)] +pub struct LogoutCommand { + /// The common command options. + #[clap(flatten)] + pub common: CommonOptions, + /// The subcommand to execute. + #[clap(flatten)] + keyring_entry: KeyringEntryArgs, +} + +#[derive(Args)] +struct KeyringEntryArgs { + /// The URL of the registry to delete an auth token for. + #[clap(value_name = "URL")] + pub url: Option, +} + +impl KeyringEntryArgs { + fn delete_entry(&self, home_url: Option) -> Result<()> { + if let Some(url) = &self.url { + delete_auth_token(url) + } else if let Some(url) = &home_url { + delete_auth_token(&RegistryUrl::new(url)?) + } else { + bail!("Please configure your home registry: warg config --registry ") + } + } +} + +impl LogoutCommand { + /// Executes the command. + pub async fn exec(self) -> Result<()> { + self.keyring_entry + .delete_entry(self.common.read_config()?.home_url)?; + println!("auth token was deleted successfully",); + Ok(()) + } +} diff --git a/src/keyring.rs b/src/keyring.rs index 2e2e2f09..6654b332 100644 --- a/src/keyring.rs +++ b/src/keyring.rs @@ -2,9 +2,65 @@ use anyhow::{bail, Context, Result}; use keyring::Entry; +use secrecy::{self, Secret}; use warg_client::RegistryUrl; use warg_crypto::signing::PrivateKey; +/// Gets the auth token entry for the given registry and key name. +pub fn get_auth_token_entry(registry_url: &RegistryUrl) -> Result { + let label = format!("warg-auth-token:{}", registry_url.safe_label()); + Entry::new(&label, ®istry_url.safe_label()).context("failed to get keyring entry") +} + +/// Gets the auth token +pub fn get_auth_token(registry_url: &RegistryUrl) -> Result>> { + let entry = get_auth_token_entry(registry_url)?; + match entry.get_password() { + Ok(secret) => Ok(Some(Secret::from(secret))), + Err(keyring::Error::NoEntry) => Ok(None), + Err(keyring::Error::Ambiguous(_)) => { + bail!("more than one auth token for registry `{registry_url}`"); + } + Err(e) => { + bail!("failed to get auth token for registry `{registry_url}`: {e}"); + } + } +} + +/// Deletes the auth token +pub fn delete_auth_token(registry_url: &RegistryUrl) -> Result<()> { + let entry = get_auth_token_entry(registry_url)?; + match entry.delete_password() { + Ok(()) => Ok(()), + Err(keyring::Error::NoEntry) => { + bail!("no auth token found for registry `{registry_url}`"); + } + Err(keyring::Error::Ambiguous(_)) => { + bail!("more than one auth token found for registry `{registry_url}`"); + } + Err(e) => { + bail!("failed to delete auth torkn for registry `{registry_url}`: {e}"); + } + } +} + +/// Sets the auth token +pub fn set_auth_token(registry_url: &RegistryUrl, token: &str) -> Result<()> { + let entry = get_auth_token_entry(registry_url)?; + match entry.set_password(token) { + Ok(()) => Ok(()), + Err(keyring::Error::NoEntry) => { + bail!("no auth token found for registry `{registry_url}`"); + } + Err(keyring::Error::Ambiguous(_)) => { + bail!("more than one auth token for registry `{registry_url}`"); + } + Err(e) => { + bail!("failed to set auth token for registry `{registry_url}`: {e}"); + } + } +} + /// Gets the signing key entry for the given registry and key name. pub fn get_signing_key_entry(registry_url: &RegistryUrl, key_name: &str) -> Result { let label = format!("warg-signing-key:{}", registry_url.safe_label()); @@ -58,7 +114,7 @@ pub fn delete_signing_key(registry_url: &RegistryUrl, key_name: &str) -> Result< bail!("more than one signing key found with name `{key_name}` of registry `{registry_url}`"); } Err(e) => { - bail!("failed to set signing key with name `{key_name}` of registry `{registry_url}`: {e}"); + bail!("failed to delete signing key with name `{key_name}` of registry `{registry_url}`: {e}"); } } } diff --git a/tests/client.rs b/tests/client.rs index b8339cd5..20a26db9 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -10,7 +10,7 @@ use warg_protocol::registry::PackageName; pub mod support; fn create_client(config: &Config) -> Result { - match FileSystemClient::try_new_with_config(None, config)? { + match FileSystemClient::try_new_with_config(None, config, None)? { StorageLockResult::Acquired(client) => Ok(client), _ => bail!("failed to acquire storage lock"), } diff --git a/tests/memory/mod.rs b/tests/memory/mod.rs index 5a7368c3..daa15ab0 100644 --- a/tests/memory/mod.rs +++ b/tests/memory/mod.rs @@ -16,7 +16,7 @@ async fn it_publishes_a_component() -> Result<()> { test_component_publishing(&config).await?; // There should be two log entries in the registry - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; assert_eq!( ts_checkpoint.as_ref().checkpoint.log_length, @@ -35,7 +35,7 @@ async fn it_yanks_a_package() -> Result<()> { test_package_yanking(&config).await?; // There should be three entries in the registry - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; assert_eq!( ts_checkpoint.as_ref().checkpoint.log_length, @@ -52,7 +52,7 @@ async fn it_publishes_a_wit_package() -> Result<()> { test_wit_publishing(&config).await?; // There should be two log entries in the registry - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; assert_eq!( ts_checkpoint.as_ref().checkpoint.log_length, diff --git a/tests/postgres/mod.rs b/tests/postgres/mod.rs index f7c08ad2..bd348440 100644 --- a/tests/postgres/mod.rs +++ b/tests/postgres/mod.rs @@ -66,7 +66,7 @@ async fn it_works_with_postgres() -> TestResult { ]; // There should be two log entries in the registry - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; assert_eq!( ts_checkpoint.as_ref().checkpoint.log_length, @@ -84,7 +84,7 @@ async fn it_works_with_postgres() -> TestResult { packages.push(PackageName::new("test:unknown-key")?); - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; assert_eq!( ts_checkpoint.as_ref().checkpoint.log_length, diff --git a/tests/server.rs b/tests/server.rs index 60290e86..672f3faf 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -39,7 +39,7 @@ mod memory; mod postgres; async fn test_initial_checkpoint(config: &Config) -> Result<()> { - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; let checkpoint = &ts_checkpoint.as_ref().checkpoint; @@ -450,7 +450,7 @@ async fn test_custom_content_url(config: &Config) -> Result<()> { .expect("expected the package version to exist"); // Look up the content URL for the record - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ContentSourcesResponse { content_sources } = client.content_sources(&digest).await?; assert_eq!(content_sources.len(), 1); let sources = content_sources @@ -511,7 +511,7 @@ async fn test_fetch_package_names(config: &Config) -> Result<()> { } async fn test_get_ledger(config: &Config) -> Result<()> { - let client = api::Client::new(config.home_url.as_ref().unwrap())?; + let client = api::Client::new(config.home_url.as_ref().unwrap(), None)?; let ts_checkpoint = client.latest_checkpoint().await?; let checkpoint = &ts_checkpoint.as_ref().checkpoint; diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 1d54f2be..9307b4ac 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -43,7 +43,7 @@ pub fn test_signing_key() -> PrivateKey { } pub fn create_client(config: &warg_client::Config) -> Result { - match FileSystemClient::try_new_with_config(None, config)? { + match FileSystemClient::try_new_with_config(None, config, None)? { StorageLockResult::Acquired(client) => Ok(client), _ => bail!("failed to acquire storage lock"), }