diff --git a/packages/cubejs-backend-native/src/auth.rs b/packages/cubejs-backend-native/src/auth.rs index 5a495588c6125..73b2131b2ce2d 100644 --- a/packages/cubejs-backend-native/src/auth.rs +++ b/packages/cubejs-backend-native/src/auth.rs @@ -18,6 +18,7 @@ use crate::gateway::{ GatewayAuthContext, GatewayAuthContextRef, GatewayAuthService, GatewayAuthenticateResponse, GatewayCheckAuthRequest, }; +use crate::utils::NonDebugInRelease; #[derive(Debug)] pub struct NodeBridgeAuthService { @@ -90,7 +91,7 @@ struct CheckSQLAuthTransportResponse { pub struct NativeSQLAuthContext { pub user: Option, pub superuser: bool, - pub security_context: Option, + pub security_context: NonDebugInRelease>, } impl AuthContext for NativeSQLAuthContext { @@ -141,7 +142,7 @@ impl SqlAuthService for NodeBridgeAuthService { context: Arc::new(NativeSQLAuthContext { user, superuser: response.superuser, - security_context: response.security_context, + security_context: NonDebugInRelease::from(response.security_context), }), password: response.password, skip_password_check: response.skip_password_check.unwrap_or(false), diff --git a/packages/cubejs-backend-native/src/node_export.rs b/packages/cubejs-backend-native/src/node_export.rs index efe7446537d56..ee9e49b805551 100644 --- a/packages/cubejs-backend-native/src/node_export.rs +++ b/packages/cubejs-backend-native/src/node_export.rs @@ -18,7 +18,7 @@ use crate::sql4sql::sql4sql; use crate::stream::OnDrainHandler; use crate::tokio_runtime_node; use crate::transport::NodeBridgeTransport; -use crate::utils::batch_to_rows; +use crate::utils::{batch_to_rows, NonDebugInRelease}; use cubenativeutils::wrappers::neon::context::neon_run_with_guarded_lifetime; use cubenativeutils::wrappers::neon::inner_types::NeonInnerTypes; use cubenativeutils::wrappers::neon::object::NeonObject; @@ -429,7 +429,7 @@ fn exec_sql(mut cx: FunctionContext) -> JsResult { let native_auth_ctx = Arc::new(NativeSQLAuthContext { user: Some(String::from("unknown")), superuser: false, - security_context, + security_context: NonDebugInRelease::from(security_context), }); let (deferred, promise) = cx.promise(); diff --git a/packages/cubejs-backend-native/src/sql4sql.rs b/packages/cubejs-backend-native/src/sql4sql.rs index 71c71df4bdd19..59703d948a269 100644 --- a/packages/cubejs-backend-native/src/sql4sql.rs +++ b/packages/cubejs-backend-native/src/sql4sql.rs @@ -16,6 +16,7 @@ use crate::auth::NativeSQLAuthContext; use crate::config::NodeCubeServices; use crate::cubesql_utils::with_session; use crate::tokio_runtime_node; +use crate::utils::NonDebugInRelease; enum Sql4SqlQueryType { Regular, @@ -208,7 +209,7 @@ pub fn sql4sql(mut cx: FunctionContext) -> JsResult { let native_auth_ctx = Arc::new(NativeSQLAuthContext { user: Some(String::from("unknown")), superuser: false, - security_context, + security_context: NonDebugInRelease::from(security_context), }); let (deferred, promise) = cx.promise(); diff --git a/packages/cubejs-backend-native/src/utils.rs b/packages/cubejs-backend-native/src/utils.rs index 7cf7df46fa47e..37f1ab7404cf5 100644 --- a/packages/cubejs-backend-native/src/utils.rs +++ b/packages/cubejs-backend-native/src/utils.rs @@ -1,6 +1,8 @@ use cubesql::{compile::engine::df::scan::RecordBatch, sql::dataframe, CubeError}; use neon::prelude::*; use serde_json::Value; +use std::fmt::Debug; +use std::ops::{Deref, DerefMut}; #[inline(always)] pub fn call_method<'a, AS>( @@ -38,3 +40,45 @@ pub fn batch_to_rows(batch: RecordBatch) -> Result<(Value, Vec), CubeErro Ok((columns, rows)) } + +/// Allow skipping Debug output in release builds for specific field or type. +pub struct NonDebugInRelease(T); + +impl Debug for NonDebugInRelease { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if cfg!(debug_assertions) { + self.0.fmt(f) + } else { + f.debug_struct("skipped in release build").finish() + } + } +} + +impl From for NonDebugInRelease { + fn from(value: T) -> Self { + Self(value) + } +} + +impl Deref for NonDebugInRelease { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NonDebugInRelease { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl Default for NonDebugInRelease +where + T: Default, +{ + fn default() -> Self { + Self(T::default()) + } +} diff --git a/rust/cubesql/cubesql/src/compile/router.rs b/rust/cubesql/cubesql/src/compile/router.rs index 9e013c202dbaf..2c41453c8908b 100644 --- a/rust/cubesql/cubesql/src/compile/router.rs +++ b/rust/cubesql/cubesql/src/compile/router.rs @@ -456,7 +456,6 @@ impl QueryRouter { .session_manager .server .auth - // TODO do we want to send actual password here? .authenticate(sql_auth_request, Some(to_user.clone()), None) .await .map_err(|e| { @@ -466,8 +465,13 @@ impl QueryRouter { .set_auth_context(Some(authenticate_response.context)); } else { return Err(CompilationError::user(format!( - "{:?} is not allowed to switch to '{}'", - auth_context, to_user + "user '{}' is not allowed to switch to '{}'", + auth_context + .user() + .as_ref() + .map(|v| v.as_str()) + .unwrap_or("not specified"), + to_user ))); } } diff --git a/rust/cubesql/cubesql/src/compile/snapshots/cubesql__compile__tests__set_bad_user.snap b/rust/cubesql/cubesql/src/compile/snapshots/cubesql__compile__tests__set_bad_user.snap index e1530ed6b7bff..7aef689001141 100644 --- a/rust/cubesql/cubesql/src/compile/snapshots/cubesql__compile__tests__set_bad_user.snap +++ b/rust/cubesql/cubesql/src/compile/snapshots/cubesql__compile__tests__set_bad_user.snap @@ -1,6 +1,5 @@ --- source: cubesql/src/compile/mod.rs -assertion_line: 7213 -expression: "execute_queries_with_flags(vec![\"SET user = 'bad_user'\".to_string()],\n DatabaseProtocol::PostgreSQL).await.err().unwrap().to_string()" +expression: "execute_queries_with_flags(vec![\"SET user = 'bad_user'\".to_string()],\nDatabaseProtocol::PostgreSQL).await.err().unwrap().to_string()" --- -Error during planning: SQLCompilationError: User: HttpAuthContext { access_token: "access_token", base_path: "base_path" } is not allowed to switch to 'bad_user' +Error during planning: SQLCompilationError: User: user 'not specified' is not allowed to switch to 'bad_user'