diff --git a/Cargo.lock b/Cargo.lock index b9fbaa3d0f..7810dcc3b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,28 +206,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -2322,12 +2300,11 @@ dependencies = [ [[package]] name = "objectstore-client" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033eedf125e31b30962c0172842e964fc9983bbccd99d9ff033e7e413946861c" +checksum = "f99caa869461b61decd1985c029d7e1462d1bde8e2448040db27d567165fcc1e" dependencies = [ "async-compression", - "async-stream", "bytes", "futures-util", "infer", @@ -2346,9 +2323,9 @@ dependencies = [ [[package]] name = "objectstore-types" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956cbdef3971ea108a15e5248625d6229870da3a3c637b6e7aada213526f8014" +checksum = "c375bccef8773d1739eabb7e2b1bbd7e9a9071c8f9557e3b50dce7220e8c8736" dependencies = [ "http", "humantime", @@ -3345,6 +3322,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" dependencies = [ + "serde", "zeroize", ] @@ -4142,6 +4120,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", + "futures-util", "pin-project-lite", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 12b7dffead..eb0d4bf774 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ java-properties = "2.0.0" lazy_static = "1.4.0" libc = "0.2.139" log = { version = "0.4.17", features = ["std"] } -objectstore-client = { version = "0.1.2" , default-features = false, features = ["native-tls"] } +objectstore-client = { version = "0.1.6" , default-features = false, features = ["native-tls"] } open = "3.2.0" parking_lot = "0.12.1" percent-encoding = "2.2.0" @@ -79,7 +79,7 @@ zip = "2.4.2" data-encoding = "2.3.3" magic_string = "0.3.4" chrono-tz = "0.8.4" -secrecy = "0.8.0" +secrecy = { version = "0.8.0", features = ["serde"] } lru = "0.16.3" backon = { version = "1.5.2", features = ["std", "std-blocking-sleep"] } diff --git a/src/api/mod.rs b/src/api/mod.rs index 03f3ec5460..ea3d5eb279 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -33,7 +33,7 @@ use lazy_static::lazy_static; use log::{debug, info, warn}; use parking_lot::Mutex; use regex::{Captures, Regex}; -use secrecy::ExposeSecret as _; +use secrecy::{ExposeSecret as _, SecretString}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use sha1_smol::Digest; @@ -2065,5 +2065,6 @@ pub struct SnapshotsUploadOptions { pub struct ObjectstoreUploadOptions { pub url: String, pub scopes: Vec<(String, String)>, + pub auth_token: Option, pub expiration_policy: String, } diff --git a/src/commands/build/snapshots.rs b/src/commands/build/snapshots.rs index 04bea69fa4..ec247e540d 100644 --- a/src/commands/build/snapshots.rs +++ b/src/commands/build/snapshots.rs @@ -295,15 +295,25 @@ fn upload_images( let expiration = ExpirationPolicy::from_str(&options.objectstore.expiration_policy) .context("Failed to parse expiration policy from upload options")?; - let client = ClientBuilder::new(options.objectstore.url) - .token({ - // TODO: replace with auth from `ObjectstoreUploadOptions` when appropriate - let auth = match authenticated_api.auth() { - Auth::Token(token) => token.raw().expose_secret().to_owned(), - }; - auth + let mut builder = ClientBuilder::new(options.objectstore.url); + if let Some(token) = options.objectstore.auth_token { + builder = builder.token(token.expose_secret().to_owned()); + } + + let sentry_token = match authenticated_api.auth() { + Auth::Token(token) => token.raw().expose_secret().to_owned(), + }; + let sentry_token = format!("Bearer {sentry_token}") + .parse() + // Ignore original error to avoid leaking the token (even though it's invalid) + .map_err(|_| anyhow::anyhow!("Invalid auth token"))?; + let client = builder + .configure_reqwest(|r| { + let mut headers = http::HeaderMap::new(); + headers.insert(http::header::AUTHORIZATION, sentry_token); + r.connect_timeout(Duration::from_secs(10)) + .default_headers(headers) }) - .configure_reqwest(|r| r.connect_timeout(Duration::from_secs(10))) .build()?; let mut scope = Usecase::new("preprod").scope(); @@ -400,7 +410,7 @@ fn upload_images( warn!("Some images share identical file names. Only the first occurrence of each is included:{details}"); } - let result = runtime.block_on(async { many_builder.send().error_for_failures().await }); + let result = runtime.block_on(async { many_builder.send().await.error_for_failures().await }); let uploaded_count = manifest_entries.len();