From c6c5844d123facc66b943f4df623908ac465ad84 Mon Sep 17 00:00:00 2001 From: Tamas Juhasz Date: Mon, 6 May 2024 23:05:21 -0400 Subject: [PATCH] readyset-data: Integrate 'url' crate and refine authentication code This commit addresses the following issues: - Included the 'url' crate in Cargo.toml - Adjusted the approach for processing user credentials from the upstream DB URL by using the 'url' crate to parse the URL and extract the username and password components. Change-Id: Ic59d96884571accd19aaf13b8b8f51e20f97299b --- Cargo.lock | 1 + readyset/Cargo.toml | 1 + readyset/src/lib.rs | 56 ++++++++++++++++++++++++++------------------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index faecefeb90..d6c1b55074 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4370,6 +4370,7 @@ dependencies = [ "tracing", "tracing-futures", "tracing-subscriber", + "url", ] [[package]] diff --git a/readyset/Cargo.toml b/readyset/Cargo.toml index 2dc5371c07..1dea1d0a47 100644 --- a/readyset/Cargo.toml +++ b/readyset/Cargo.toml @@ -53,6 +53,7 @@ readyset-tracing = { path = "../readyset-tracing" } readyset-version = { path = "../readyset-version" } replicators = { path = "../replicators" } serde_json = "1.0.89" +url = "2.2.2" [dev-dependencies] diff --git a/readyset/src/lib.rs b/readyset/src/lib.rs index 8265092b8c..4be85677bd 100644 --- a/readyset/src/lib.rs +++ b/readyset/src/lib.rs @@ -4,6 +4,7 @@ pub mod mysql; pub mod psql; mod query_logger; + use std::collections::HashMap; use std::fs::remove_dir_all; use std::io; @@ -64,6 +65,8 @@ use tokio::time::{sleep, timeout}; use tokio_stream::wrappers::TcpListenerStream; use tracing::{debug, debug_span, error, info, info_span, span, warn, Level}; use tracing_futures::Instrument; +use url::form_urlencoded::{parse}; + // readyset_alloc initializes the global allocator extern crate readyset_alloc; @@ -555,6 +558,7 @@ where out } + impl NoriaAdapter where H: ConnectionHandler + Clone + Send + Sync + 'static, @@ -602,37 +606,43 @@ where .as_ref() .and_then(|s| s.parse::().ok()); + let decoded_username = upstream_url.as_ref().and_then(|url| + parse(url.user()?.as_bytes()) + .map(|(key, _)| key.to_string()) + .next() + ); + + let decoded_password = upstream_url.as_ref().and_then(|url| url.password()).and_then(|password| + parse(password.as_bytes()) + .map(|(key, _)| key.to_string()) + .next() + ); + match ( (options.username, options.password), - ( - upstream_url.as_ref().and_then(|url| url.user()), - upstream_url.as_ref().and_then(|url| url.password()), - ), - ) { - // --username and --password + (decoded_username, decoded_password) + ) { ((Some(user), Some(pass)), _) => (user, pass.0), - // --password, username from url - ((None, Some(pass)), (Some(user), _)) => (user.to_owned(), pass.0), - // username and password from url - (_, (Some(user), Some(pass))) => (user.to_owned(), pass.to_owned()), + ((None, Some(pass)), (Some(user), _)) => (user, pass.0), + (_, (Some(user), Some(pass))) => (user, pass), _ => { if upstream_url.is_some() { bail!( - "Failed to infer ReadySet username and password from \ - upstream DB URL. Please ensure they are present and \ - correctly formatted as follows: \ - ://:@
[:][/] \ - You can also configure ReadySet to accept credentials \ - different from those of your upstream database via \ - --username/-u and --password/-p, or use \ - --allow-unauthenticated-connections." - ) + "Failed to infer ReadySet username and password from \ + upstream DB URL. Please ensure they are present and \ + correctly formatted as follows: \ + ://:@
[:][/] \ + You can also configure ReadySet to accept credentials \ + different from those of your upstream database via \ + --username/-u and --password/-p, or use \ + --allow-unauthenticated-connections." + ) } else { bail!( - "Must specify --username/-u and --password/-p if one of \ - --allow-unauthenticated-connections or --upstream-db-url is not \ - passed" - ) + "Must specify --username/-u and --password/-p if one of \ + --allow-unauthenticated-connections or --upstream-db-url is not \ + passed" + ) } } }