mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-10 08:07:03 +00:00
fix: keep connection string query parameters under token auth (#10859)
* fix: keep connection string query parameters under token auth * refactor: fold the database url parsing into one connect-options helper * docs: state the narrower invariant on base_connect_options * chore: update ee-repo-ref to 212cc7d61ec38580d4a70d9ac38d7a2cc9daf409 This commit updates the EE repository reference after PR #746 was merged in windmill-ee-private. Previous ee-repo-ref: a15d08345d7e42526c28382079ad1f575a2d1674 New ee-repo-ref: 212cc7d61ec38580d4a70d9ac38d7a2cc9daf409 Automated by sync-ee-ref workflow. --------- Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
windmill-internal-app[bot]
parent
af15a73b8b
commit
f131c3920f
@@ -1 +1 @@
|
||||
d6aef91c0f7ba556befbf4addeb7674d4a9dd819
|
||||
212cc7d61ec38580d4a70d9ac38d7a2cc9daf409
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
use anyhow::Result;
|
||||
|
||||
/// Parsed database connection parameters, shared across DB auth providers (IAM RDS, Entra ID, etc.)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DatabaseParams {
|
||||
pub hostname: String,
|
||||
pub port: u64,
|
||||
pub username: String,
|
||||
pub database: String,
|
||||
}
|
||||
|
||||
/// Extract database connection parameters from a PostgreSQL URL
|
||||
pub fn extract_database_params(database_url: &str) -> Result<DatabaseParams> {
|
||||
let url = url::Url::parse(database_url)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to parse database URL: {}", e))?;
|
||||
|
||||
let hostname = url
|
||||
.host_str()
|
||||
.ok_or_else(|| anyhow::anyhow!("Database URL missing hostname"))?
|
||||
.to_string();
|
||||
|
||||
let port = url.port().unwrap_or(5432) as u64;
|
||||
|
||||
let username = if url.username().is_empty() {
|
||||
return Err(anyhow::anyhow!("Database URL missing username"));
|
||||
} else {
|
||||
urlencoding::decode(url.username())?.to_string()
|
||||
};
|
||||
|
||||
let database = url
|
||||
.path()
|
||||
.trim_start_matches('/')
|
||||
.split('/')
|
||||
.next()
|
||||
.filter(|s| !s.is_empty())
|
||||
.ok_or_else(|| anyhow::anyhow!("Database URL missing database name"))?
|
||||
.to_string();
|
||||
|
||||
Ok(DatabaseParams {
|
||||
hostname,
|
||||
port,
|
||||
username,
|
||||
database: urlencoding::decode(&database)?.to_string(),
|
||||
})
|
||||
}
|
||||
@@ -42,7 +42,6 @@ pub mod db;
|
||||
mod db_entra_ee;
|
||||
#[cfg(all(feature = "enterprise", feature = "private"))]
|
||||
mod db_iam_ee;
|
||||
pub mod db_params;
|
||||
pub mod dbt_manifest;
|
||||
pub mod deploy_origin;
|
||||
#[cfg(feature = "private")]
|
||||
@@ -1479,6 +1478,17 @@ pub async fn create_custom_instance_database(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Connection options parsed from a database URL.
|
||||
///
|
||||
/// The only place a database URL becomes `PgConnectOptions`. Providers that mint the password
|
||||
/// themselves override it on these and keep the rest: options assembled field by field instead
|
||||
/// would drop every query parameter, `sslmode` and `sslrootcert` above all, leaving the
|
||||
/// connection on sqlx's default TLS policy rather than the operator's.
|
||||
pub fn base_connect_options(database_url: &str) -> Result<sqlx::postgres::PgConnectOptions, Error> {
|
||||
sqlx::postgres::PgConnectOptions::from_str(database_url)
|
||||
.map_err(|e| Error::InternalErr(format!("Failed to parse database URL: {}", e)))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DatabaseUrl {
|
||||
#[cfg(all(feature = "enterprise", feature = "private"))]
|
||||
@@ -1509,8 +1519,8 @@ impl DatabaseUrl {
|
||||
}
|
||||
|
||||
/// Get PgConnectOptions for this database URL.
|
||||
/// For token-based auth (IAM RDS, Entra ID), this returns options built directly from the
|
||||
/// token to avoid double-encoding issues with temporary credentials.
|
||||
/// For token-based auth (IAM RDS, Entra ID), this returns options carrying the current
|
||||
/// token, set on the builder to avoid double-encoding temporary credentials.
|
||||
/// For static URLs, this parses the URL string.
|
||||
pub async fn connect_options(&self) -> Result<sqlx::postgres::PgConnectOptions, Error> {
|
||||
match self {
|
||||
@@ -1524,8 +1534,7 @@ impl DatabaseUrl {
|
||||
let guard = entra_url.read().await;
|
||||
Ok(guard.connect_options())
|
||||
}
|
||||
DatabaseUrl::Static(url) => sqlx::postgres::PgConnectOptions::from_str(url)
|
||||
.map_err(|e| Error::InternalErr(format!("Failed to parse database URL: {}", e))),
|
||||
DatabaseUrl::Static(url) => base_connect_options(url),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user