MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / validate_source_privileges

Function validate_source_privileges

src/sql-server-util/src/inspect.rs:937–1018  ·  view source on GitHub ↗

Return a Result that is empty if all tables, columns, and capture instances have the necessary permissions to and an error if any table, column, or capture instance does not have the necessary permissions for tracking changes.

(
    client: &mut Client,
    capture_instances: impl IntoIterator<Item = &str>,
)

Source from the content-addressed store, hash-verified

935/// or capture instance does not have the necessary permissions
936/// for tracking changes.
937pub async fn validate_source_privileges(
938 client: &mut Client,
939 capture_instances: impl IntoIterator<Item = &str>,
940) -> Result<(), SqlServerError> {
941 let params: SmallVec<[_; 1]> = capture_instances.into_iter().collect();
942
943 if params.is_empty() {
944 return Ok(());
945 }
946
947 let params_dyn: SmallVec<[_; 1]> = params
948 .iter()
949 .map(|instance| {
950 let instance: &dyn tiberius::ToSql = instance;
951 instance
952 })
953 .collect();
954
955 let param_indexes = (1..params.len() + 1)
956 .map(|idx| format!("@P{}", idx))
957 .join(", ");
958
959 // NB(ptravers): we rely on HAS_PERMS_BY_NAME to check both table and column permissions.
960 let capture_instance_query = format!(
961 "
962 SELECT
963 SCHEMA_NAME(o.schema_id) + '.' + o.name AS qualified_table_name,
964 ct.capture_instance AS capture_instance,
965 COALESCE(HAS_PERMS_BY_NAME(SCHEMA_NAME(o.schema_id) + '.' + o.name, 'OBJECT', 'SELECT'), 0) AS table_select,
966 COALESCE(HAS_PERMS_BY_NAME('cdc.' + QUOTENAME(ct.capture_instance + '_CT') , 'OBJECT', 'SELECT'), 0) AS capture_table_select
967 FROM cdc.change_tables ct
968 JOIN sys.objects o ON o.object_id = ct.source_object_id
969 WHERE ct.capture_instance IN ({param_indexes});
970 "
971 );
972
973 let rows = client
974 .query(capture_instance_query, &params_dyn[..])
975 .await?;
976
977 let mut capture_instances_without_perms = vec![];
978 let mut tables_without_perms = vec![];
979
980 for row in rows {
981 let table: &str = row
982 .try_get("qualified_table_name")
983 .context("getting table column")?
984 .ok_or_else(|| anyhow::anyhow!("no table column?"))?;
985
986 let capture_instance: &str = row
987 .try_get("capture_instance")
988 .context("getting capture_instance column")?
989 .ok_or_else(|| anyhow::anyhow!("no capture_instance column?"))?;
990
991 let permitted_table: i32 = row
992 .try_get("table_select")
993 .context("getting table_select column")?
994 .ok_or_else(|| anyhow::anyhow!("no table_select column?"))?;

Callers 2

purify_source_exportsFunction · 0.50

Calls 11

collectMethod · 0.45
into_iterMethod · 0.45
is_emptyMethod · 0.45
mapMethod · 0.45
iterMethod · 0.45
joinMethod · 0.45
lenMethod · 0.45
queryMethod · 0.45
contextMethod · 0.45
pushMethod · 0.45
to_stringMethod · 0.45

Tested by

no test coverage detected