Skip to content

Commit 6b9eda3

Browse files
authored
chore(deps): bump workspace; migrate sqlx 0.9 + keyring 4 (#3324)
1 parent b29bcd5 commit 6b9eda3

19 files changed

Lines changed: 570 additions & 403 deletions

File tree

Cargo.lock

Lines changed: 341 additions & 347 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ ahash = { version = "0.8.12", features = ["serde"] }
7474
aligned-vec = "0.6.4"
7575
anyhow = "1.0.102"
7676
apache-avro = "0.21.0"
77+
apple-native-keyring-store = { version = "1.0.0", features = ["keychain"] }
7778
argon2 = "0.5.3"
79+
# Pinned to 57 because iceberg 0.9.1 still requires arrow/parquet 57.
7880
arrow = "57.3.1"
7981
arrow-array = "57.3.1"
8082
arrow-json = "57.3.1"
@@ -128,7 +130,7 @@ configs_derive = { path = "core/configs_derive", version = "0.1.0" }
128130
consensus = { path = "core/consensus" }
129131
console-subscriber = "0.5.0"
130132
crossbeam = "0.8.4"
131-
crossfire = "3.1.13"
133+
crossfire = "3.1.16"
132134
csv = "1.4.0"
133135
ctor = "1.0.6"
134136
ctrlc = { version = "3.5", features = ["termination"] }
@@ -137,6 +139,7 @@ cyper = { version = "0.8.3", features = ["rustls"], default-features = false }
137139
cyper-axum = { version = "0.8.0" }
138140
darling = "0.23"
139141
dashmap = "6.2.1"
142+
dbus-secret-service-keyring-store = { version = "1.0.0", features = ["crypto-rust", "vendored"] }
140143
deltalake = { version = "0.32.3", features = ["azure", "gcs", "s3"] }
141144
derive-new = "0.7.0"
142145
derive_builder = "0.20.2"
@@ -153,7 +156,7 @@ err_trail = { version = "0.11.0", features = ["tracing"] }
153156
error_set = "0.9.1"
154157
figlet-rs = "1.0.0"
155158
figment = { version = "0.10.19", features = ["toml", "env"] }
156-
file-operation = "0.8.20"
159+
file-operation = "0.8.21"
157160
flatbuffers = "25.12.19"
158161
flume = "0.12.0"
159162
fs2 = "0.4.3"
@@ -184,12 +187,12 @@ integration = { path = "core/integration" }
184187
journal = { path = "core/journal" }
185188
js-sys = "0.3"
186189
jsonwebtoken = { version = "10.4.0", features = ["rust_crypto"] }
187-
keyring = { version = "3.6.3", features = ["sync-secret-service", "vendored"] }
190+
keyring-core = "1.0.0"
188191
lazy_static = "1.5.0"
189192
left-right = "0.11"
190193
lending-iterator = "0.1.7"
191194
libc = "0.2.186"
192-
log = "0.4.29"
195+
log = "0.4.30"
193196
lz4_flex = "0.13.1"
194197
message_bus = { path = "core/message_bus" }
195198
metadata = { path = "core/metadata" }
@@ -214,7 +217,7 @@ opentelemetry-otlp = { version = "0.32.0", features = [
214217
"reqwest-client",
215218
] }
216219
opentelemetry-semantic-conventions = "0.32.0"
217-
opentelemetry_sdk = { version = "0.32.0", features = [
220+
opentelemetry_sdk = { version = "0.32.1", features = [
218221
"logs",
219222
"trace",
220223
"experimental_async_runtime",
@@ -241,7 +244,7 @@ rand_xoshiro = "0.8.1"
241244
rayon = "1.12.0"
242245
rcgen = "0.14.8"
243246
regex = "1.12.3"
244-
reqwest = { version = "0.13.3", default-features = false, features = ["json", "rustls"] }
247+
reqwest = { version = "0.13.4", default-features = false, features = ["json", "rustls"] }
245248
reqwest-middleware = { version = "0.5.2", features = ["json", "query"] }
246249
reqwest-retry = "0.9.1"
247250
reqwest-tracing = "0.7.1"
@@ -259,7 +262,7 @@ sd-notify = "0.5"
259262
secrecy = { version = "0.10", features = ["serde"] }
260263
send_wrapper = "0.6.0"
261264
serde = { version = "1.0.228", features = ["derive", "rc"] }
262-
serde_json = "1.0.149"
265+
serde_json = "1.0.150"
263266
serde_with = { version = "3.20.0", features = ["base64", "macros"] }
264267
serde_yaml_ng = "0.10.0"
265268
serial_test = "3.4.0"
@@ -271,8 +274,9 @@ simd-json = { version = "0.17.0", features = ["serde_impl"] }
271274
slab = "0.4.12"
272275
smallvec = "1.15"
273276
socket2 = "0.6.3"
274-
sqlx = { version = "0.8.6", features = [
275-
"runtime-tokio-rustls",
277+
sqlx = { version = "0.9.0", features = [
278+
"runtime-tokio",
279+
"tls-rustls",
276280
"postgres",
277281
"chrono",
278282
"uuid",
@@ -322,6 +326,7 @@ web-sys = { version = "0.3", features = [
322326
"ResizeObserverEntry",
323327
] }
324328
webpki-roots = "1.0.7"
329+
windows-native-keyring-store = "1.1.0"
325330
yew = { version = "0.23", features = ["csr"] }
326331
yew-router = "0.20"
327332
zip = { version = "8.6.0", default-features = false, features = ["deflate"] }

core/cli/Cargo.toml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ path = "src/main.rs"
4141

4242
[features]
4343
default = ["login-session"]
44-
login-session = ["dep:keyring"]
44+
login-session = [
45+
"dep:keyring-core",
46+
"dep:dbus-secret-service-keyring-store",
47+
"dep:apple-native-keyring-store",
48+
"dep:windows-native-keyring-store",
49+
]
4550

4651
[dependencies]
4752
anyhow = { workspace = true }
@@ -56,7 +61,7 @@ figlet-rs = { workspace = true }
5661
iggy = { workspace = true }
5762
iggy_binary_protocol = { workspace = true }
5863
iggy_common = { workspace = true }
59-
keyring = { workspace = true, optional = true }
64+
keyring-core = { workspace = true, optional = true }
6065
passterm = { workspace = true }
6166
secrecy = { workspace = true }
6267
serde = { workspace = true }
@@ -68,6 +73,15 @@ tracing = { workspace = true }
6873
tracing-appender = { workspace = true }
6974
tracing-subscriber = { workspace = true, default-features = false }
7075

76+
[target.'cfg(target_os = "linux")'.dependencies]
77+
dbus-secret-service-keyring-store = { workspace = true, optional = true }
78+
79+
[target.'cfg(target_os = "macos")'.dependencies]
80+
apple-native-keyring-store = { workspace = true, optional = true }
81+
82+
[target.'cfg(target_os = "windows")'.dependencies]
83+
windows-native-keyring-store = { workspace = true, optional = true }
84+
7185
[dev-dependencies]
7286
tempfile = { workspace = true }
7387
tokio = { workspace = true, features = ["macros", "rt"] }

core/cli/src/commands/binary_personal_access_tokens/create_personal_access_token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use async_trait::async_trait;
2222
use iggy_common::Client;
2323
use iggy_common::PersonalAccessTokenExpiry;
2424
use iggy_common::create_personal_access_token::CreatePersonalAccessToken;
25-
use keyring::Entry;
25+
use keyring_core::Entry;
2626
use tracing::{Level, event};
2727

2828
pub struct CreatePersonalAccessTokenCmd {

core/cli/src/commands/binary_personal_access_tokens/delete_personal_access_tokens.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use anyhow::Context;
2121
use async_trait::async_trait;
2222
use iggy_common::Client;
2323
use iggy_common::delete_personal_access_token::DeletePersonalAccessToken;
24-
use keyring::Entry;
24+
use keyring_core::Entry;
2525
use tracing::{Level, event};
2626

2727
pub struct DeletePersonalAccessTokenCmd {

core/cli/src/commands/binary_system/session.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,47 @@
1616
* under the License.
1717
*/
1818

19-
use keyring::{Entry, Result};
19+
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
20+
use std::sync::Mutex;
21+
22+
#[cfg(target_os = "macos")]
23+
use apple_native_keyring_store::keychain::Store;
24+
#[cfg(target_os = "linux")]
25+
use dbus_secret_service_keyring_store::store::Store;
26+
use keyring_core::{Entry, error::Result};
27+
use tracing::warn;
28+
#[cfg(target_os = "windows")]
29+
use windows_native_keyring_store::store::Store;
30+
31+
use crate::commands::cli_command::PRINT_TARGET;
2032

2133
const SESSION_TOKEN_NAME: &str = "iggy-cli-session";
2234
const SESSION_KEYRING_SERVICE_NAME: &str = "iggy-cli-session";
2335

36+
/// `keyring-core` 1.x has no implicit default backend. Register one on the
37+
/// first `Entry::new` so unrelated CLI subcommands never touch the OS keyring.
38+
///
39+
/// The mutex serializes concurrent callers so two threads cannot both observe
40+
/// an empty default store and race to install one. `get_default_store()` acts
41+
/// as the idempotency check, so a transient `Store::new()` failure stays
42+
/// retryable on the next call.
43+
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
44+
pub fn ensure_default_store() -> Result<()> {
45+
static INIT_LOCK: Mutex<()> = Mutex::new(());
46+
let _guard = INIT_LOCK.lock().unwrap_or_else(|p| p.into_inner());
47+
if keyring_core::get_default_store().is_some() {
48+
return Ok(());
49+
}
50+
let store = Store::new()?;
51+
keyring_core::set_default_store(store);
52+
Ok(())
53+
}
54+
55+
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
56+
pub fn ensure_default_store() -> Result<()> {
57+
Ok(())
58+
}
59+
2460
pub struct ServerSession {
2561
server_address: String,
2662
}
@@ -43,6 +79,10 @@ impl ServerSession {
4379
}
4480

4581
pub fn is_active(&self) -> bool {
82+
if let Err(e) = ensure_default_store() {
83+
warn!(target: PRINT_TARGET, "keyring backend unavailable, treating session as inactive: {e}");
84+
return false;
85+
}
4686
if let Ok(entry) = Entry::new(&self.get_service_name(), &self.get_token_name()) {
4787
return entry.get_password().is_ok();
4888
}
@@ -51,12 +91,17 @@ impl ServerSession {
5191
}
5292

5393
pub fn store(&self, token: &str) -> Result<()> {
94+
ensure_default_store()?;
5495
let entry = Entry::new(&self.get_service_name(), &self.get_token_name())?;
5596
entry.set_password(token)?;
5697
Ok(())
5798
}
5899

59100
pub fn get_token(&self) -> Option<String> {
101+
if let Err(e) = ensure_default_store() {
102+
warn!(target: PRINT_TARGET, "keyring backend unavailable, cannot read session token: {e}");
103+
return None;
104+
}
60105
if let Ok(entry) = Entry::new(&self.get_service_name(), &self.get_token_name())
61106
&& let Ok(token) = entry.get_password()
62107
{
@@ -67,6 +112,7 @@ impl ServerSession {
67112
}
68113

69114
pub fn delete(&self) -> Result<()> {
115+
ensure_default_store()?;
70116
let entry = Entry::new(&self.get_service_name(), &self.get_token_name())?;
71117
entry.delete_credential()
72118
}

core/cli/src/credentials.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ use crate::error::{CmdToolError, IggyCmdError};
2121
use anyhow::{Context, bail};
2222
use iggy::clients::client::IggyClient;
2323
use iggy::prelude::{Args, IggyError, PersonalAccessTokenClient, UserClient};
24-
use iggy_cli::commands::binary_system::session::ServerSession;
24+
use iggy_cli::commands::binary_system::session::{ServerSession, ensure_default_store};
2525
use passterm::{Stream, isatty, prompt_password_tty};
2626
use secrecy::{ExposeSecret, SecretString};
2727
use std::env::var;
2828

2929
#[cfg(feature = "login-session")]
3030
mod credentials_login_session {
3131
pub(crate) use iggy_cli::commands::cli_command::PRINT_TARGET;
32-
pub(crate) use keyring::Entry;
32+
pub(crate) use keyring_core::Entry;
3333
pub(crate) use tracing::{Level, event};
3434
}
3535

@@ -91,6 +91,7 @@ impl<'a> IggyCredentials<'a> {
9191
let server_address = format!("iggy:{server_address}");
9292
event!(target: PRINT_TARGET, Level::DEBUG,"Checking token presence under service: {} and name: {}",
9393
server_address, token_name);
94+
ensure_default_store()?;
9495
let entry = Entry::new(&server_address, token_name)?;
9596
let token = entry.get_password()?;
9697

core/cli/src/main.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ use tracing::{Level, event};
9797
#[cfg(feature = "login-session")]
9898
mod main_login_session {
9999
pub(crate) use crate::args::session::SessionAction;
100+
pub(crate) use iggy_cli::commands::binary_system::session::ensure_default_store;
100101
pub(crate) use iggy_cli::commands::binary_system::session_status::SessionStatusCmd;
101102
pub(crate) use iggy_cli::commands::binary_system::{login::LoginCmd, logout::LogoutCmd};
102103
pub(crate) use iggy_cli::commands::utils::login_session_expiry::LoginSessionExpiry;
@@ -377,6 +378,14 @@ async fn main() -> Result<(), IggyCmdError> {
377378
let mut logging = Logging::new();
378379
logging.init(args.cli.quiet, &args.cli.debug);
379380

381+
// keyring-core 1.x has no implicit default backend. Register one up front
382+
// so any subcommand that touches `Entry::new` (login, PAT store/delete,
383+
// token-name lookup) sees the backend regardless of code-path ordering.
384+
#[cfg(feature = "login-session")]
385+
if let Err(e) = ensure_default_store() {
386+
tracing::warn!(target: PRINT_TARGET, "keyring backend unavailable: {e}");
387+
}
388+
380389
let command = args.command.clone().unwrap();
381390

382391
let mut context_manager = ContextManager::default();

core/connectors/sinks/postgres_sink/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl PostgresSink {
216216
sql.push_str(&format!(", payload {payload_type}"));
217217
sql.push_str(", created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW())");
218218

219-
sqlx::query(&sql)
219+
sqlx::query(sqlx::AssertSqlSafe(sql))
220220
.execute(pool)
221221
.await
222222
.map_err(|e| Error::InitError(format!("Failed to create table '{table_name}': {e}")))?;
@@ -368,7 +368,7 @@ impl PostgresSink {
368368
include_origin_timestamp: bool,
369369
payload_format: PayloadFormat,
370370
) -> Result<(), (sqlx::Error, bool)> {
371-
let mut query_builder = sqlx::query(query);
371+
let mut query_builder = sqlx::query(sqlx::AssertSqlSafe(query));
372372

373373
for message in messages {
374374
let payload_bytes = message.payload.clone().try_into_vec().map_err(|e| {

0 commit comments

Comments
 (0)