Skip to content

Commit dbeee44

Browse files
committed
refactor(proxy): replace local ColumnEncryptionConfig with canonical CanonicalEncryptionConfig
Migrate from the proxy-local encryption config types to the canonical types provided by the cipherstash-config crate. This removes ~200 lines of duplicated type definitions (CastAs, Column, Indexes, etc.) and consolidates config parsing into the shared crate. - Bump cipherstash-client/cts-common to 0.34.0-alpha.5 - Add cipherstash-config workspace dependency - Add InvalidEncryptionConfig error variant for config crate errors - Update manager to use CanonicalEncryptionConfig with Identifier conversion - Rename Utf8Str -> Text and JsonB -> Json to match canonical types - Add [patch.crates-io] for local development against cipherstash-suite NOTE: The [patch.crates-io] section and version bumps to 0.34.0-alpha.5 must be updated when the canonical types are published to crates.io.
1 parent cb4e0e6 commit dbeee44

9 files changed

Lines changed: 68 additions & 267 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ debug = true
4343

4444
[workspace.dependencies]
4545
sqltk = { version = "0.10.0" }
46-
cipherstash-client = { version = "0.34.0-alpha.4" }
47-
cts-common = { version = "0.34.0-alpha.4" }
46+
cipherstash-client = { version = "0.34.0-alpha.5" }
47+
cipherstash-config = { version = "0.34.0-alpha.5" }
48+
cts-common = { version = "0.34.0-alpha.5" }
4849

4950
thiserror = "2.0.9"
5051
tokio = { version = "1.44.2", features = ["full"] }
@@ -55,3 +56,9 @@ tracing-subscriber = { version = "^0.3.20", features = [
5556
"env-filter",
5657
"std",
5758
] }
59+
60+
[patch.crates-io]
61+
cipherstash-client = { path = "../cipherstash-suite/packages/cipherstash-client" }
62+
cipherstash-config = { path = "../cipherstash-suite/packages/cipherstash-config" }
63+
cts-common = { path = "../cipherstash-suite/packages/cts-common" }
64+
zerokms-protocol = { path = "../cipherstash-suite/packages/zerokms-protocol" }

packages/cipherstash-proxy/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ arc-swap = "1.7.1"
1212
bytes = { version = "1.9", default-features = false }
1313
chrono = { version = "0.4.39", features = ["clock"] }
1414
cipherstash-client = { workspace = true, features = ["tokio"] }
15+
cipherstash-config = { workspace = true }
1516
clap = { version = "4.5.31", features = ["derive", "env"] }
1617
config = { version = "0.15", features = [
1718
"async",

packages/cipherstash-proxy/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ pub enum ConfigError {
185185
#[error(transparent)]
186186
Parse(#[from] serde_json::Error),
187187

188+
#[error("Invalid encryption configuration: {0}")]
189+
InvalidEncryptionConfig(#[from] cipherstash_config::errors::ConfigError),
190+
188191
#[error("Database schema could not be loaded")]
189192
SchemaCouldNotBeLoaded,
190193

packages/cipherstash-proxy/src/postgresql/context/column.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ fn column_type_to_postgres_type(
7777
(ColumnType::Int, _) => postgres_types::Type::INT4,
7878
(ColumnType::SmallInt, _) => postgres_types::Type::INT2,
7979
(ColumnType::Timestamp, _) => postgres_types::Type::TIMESTAMPTZ,
80-
(ColumnType::Utf8Str, _) => postgres_types::Type::TEXT,
81-
(ColumnType::JsonB, EqlTermVariant::JsonAccessor) => postgres_types::Type::TEXT,
82-
(ColumnType::JsonB, _) => postgres_types::Type::JSONB,
80+
(ColumnType::Text, _) => postgres_types::Type::TEXT,
81+
(ColumnType::Json, EqlTermVariant::JsonAccessor) => postgres_types::Type::TEXT,
82+
(ColumnType::Json, _) => postgres_types::Type::JSONB,
8383
}
8484
}

packages/cipherstash-proxy/src/postgresql/data/from_sql.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub fn literal_from_sql(
115115
///
116116
/// | Input Type | Target Column Type | Result |
117117
/// |------------|--------------------|--------|
118-
/// | `Type::INT4` | `ColumnType::Utf8Str` | `Plaintext::Utf8Str` |
118+
/// | `Type::INT4` | `ColumnType::Text` | `Plaintext::Text` |
119119
/// | `Type::INT2` | `ColumnType::Int` | `Plaintext::Int` |
120120
/// | `Type::INT8` | `ColumnType::Int` | `Error`` |
121121
fn text_from_sql(
@@ -126,7 +126,7 @@ fn text_from_sql(
126126
debug!(target: ENCODING, ?val, ?eql_term, ?col_type);
127127

128128
match (eql_term, col_type) {
129-
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Utf8Str) => {
129+
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Text) => {
130130
Ok(Plaintext::new(val))
131131
}
132132
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Float) => {
@@ -168,20 +168,20 @@ fn text_from_sql(
168168
}
169169

170170
// If JSONB, JSONPATH values are treated as strings
171-
(EqlTermVariant::JsonPath | EqlTermVariant::JsonAccessor, ColumnType::JsonB) => {
171+
(EqlTermVariant::JsonPath | EqlTermVariant::JsonAccessor, ColumnType::Json) => {
172172
let val = if val.starts_with("$.") {
173173
val.to_string()
174174
} else {
175175
format!("$.{val}")
176176
};
177177
Ok(Plaintext::new(val))
178178
}
179-
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::JsonB) => {
179+
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Json) => {
180180
serde_json::from_str::<serde_json::Value>(val)
181181
.map_err(|_| MappingError::CouldNotParseParameter)
182182
.map(Plaintext::new)
183183
}
184-
(EqlTermVariant::Tokenized, ColumnType::Utf8Str) => Ok(Plaintext::new(val)),
184+
(EqlTermVariant::Tokenized, ColumnType::Text) => Ok(Plaintext::new(val)),
185185

186186
(eql_term, col_type) => Err(MappingError::UnsupportedParameterType {
187187
eql_term,
@@ -202,7 +202,7 @@ fn binary_from_sql(
202202
debug!(target: ENCODING, ?pg_type, ?eql_term, ?col_type);
203203

204204
match (eql_term, col_type, pg_type) {
205-
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Utf8Str, _) => {
205+
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Text, _) => {
206206
parse_bytes_from_sql::<String>(bytes, pg_type).map(Plaintext::new)
207207
}
208208
(EqlTermVariant::Full | EqlTermVariant::Partial, ColumnType::Boolean, _) => {
@@ -253,7 +253,7 @@ fn binary_from_sql(
253253
}
254254

255255
// If JSONB, JSONPATH values are treated as strings
256-
(EqlTermVariant::JsonPath, ColumnType::JsonB, &Type::JSONPATH) => {
256+
(EqlTermVariant::JsonPath, ColumnType::Json, &Type::JSONPATH) => {
257257
parse_bytes_from_sql::<String>(bytes, pg_type).map(|val| {
258258
let val = if val.starts_with("$.") {
259259
val
@@ -263,7 +263,7 @@ fn binary_from_sql(
263263
Plaintext::new(val)
264264
})
265265
}
266-
(EqlTermVariant::JsonAccessor, ColumnType::JsonB, &Type::TEXT | &Type::VARCHAR) => {
266+
(EqlTermVariant::JsonAccessor, ColumnType::Json, &Type::TEXT | &Type::VARCHAR) => {
267267
parse_bytes_from_sql::<String>(bytes, pg_type).map(|val| {
268268
let val = if val.starts_with("$.") {
269269
val
@@ -276,7 +276,7 @@ fn binary_from_sql(
276276
// Python psycopg sends JSON/B as BYTEA
277277
(
278278
EqlTermVariant::Full | EqlTermVariant::Partial,
279-
ColumnType::JsonB,
279+
ColumnType::Json,
280280
&Type::JSON | &Type::JSONB | &Type::BYTEA,
281281
) => parse_bytes_from_sql::<serde_json::Value>(bytes, pg_type).map(Plaintext::new),
282282

@@ -356,9 +356,9 @@ fn decimal_from_sql(
356356
.ok_or(MappingError::CouldNotParseParameter)
357357
.map(Plaintext::new),
358358

359-
ColumnType::Utf8Str => Ok(Plaintext::new(decimal.to_string())),
359+
ColumnType::Text => Ok(Plaintext::new(decimal.to_string())),
360360

361-
ColumnType::JsonB => {
361+
ColumnType::Json => {
362362
let val: serde_json::Value = serde_json::from_str(&decimal.to_string())
363363
.map_err(|_| MappingError::CouldNotParseParameter)?;
364364
Ok(Plaintext::new(val))
@@ -408,7 +408,7 @@ mod tests {
408408
config: ColumnConfig {
409409
name: "column".to_owned(),
410410
in_place: false,
411-
cast_type: ColumnType::Utf8Str,
411+
cast_type: ColumnType::Text,
412412
indexes: vec![],
413413
mode: ColumnMode::PlaintextDuplicate,
414414
},

packages/cipherstash-proxy/src/postgresql/data/to_sql.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn to_sql(plaintext: &Plaintext, format_code: &FormatCode) -> Result<Option<
1616

1717
fn text_to_sql(plaintext: &Plaintext) -> Result<BytesMut, Error> {
1818
let s = match &plaintext {
19-
Plaintext::Utf8Str(Some(x)) => x.to_string(),
19+
Plaintext::Text(Some(x)) => x.to_string(),
2020
Plaintext::Int(Some(x)) => x.to_string(),
2121
Plaintext::BigInt(Some(x)) => x.to_string(),
2222
Plaintext::BigUInt(Some(x)) => x.to_string(),
@@ -26,7 +26,7 @@ fn text_to_sql(plaintext: &Plaintext) -> Result<BytesMut, Error> {
2626
Plaintext::NaiveDate(Some(x)) => x.to_string(),
2727
Plaintext::SmallInt(Some(x)) => x.to_string(),
2828
Plaintext::Timestamp(Some(x)) => x.to_string(),
29-
Plaintext::JsonB(Some(x)) => x.to_string(),
29+
Plaintext::Json(Some(x)) => x.to_string(),
3030
_ => "".to_string(),
3131
};
3232

@@ -44,8 +44,8 @@ fn binary_to_sql(plaintext: &Plaintext) -> Result<BytesMut, Error> {
4444
Plaintext::NaiveDate(x) => x.to_sql_checked(&Type::DATE, &mut bytes),
4545
Plaintext::SmallInt(x) => x.to_sql_checked(&Type::INT2, &mut bytes),
4646
Plaintext::Timestamp(x) => x.to_sql_checked(&Type::TIMESTAMPTZ, &mut bytes),
47-
Plaintext::Utf8Str(x) => x.to_sql_checked(&Type::TEXT, &mut bytes),
48-
Plaintext::JsonB(x) => x.to_sql_checked(&Type::JSONB, &mut bytes),
47+
Plaintext::Text(x) => x.to_sql_checked(&Type::TEXT, &mut bytes),
48+
Plaintext::Json(x) => x.to_sql_checked(&Type::JSONB, &mut bytes),
4949
Plaintext::Decimal(x) => x.to_sql_checked(&Type::NUMERIC, &mut bytes),
5050
// TODO: Implement these
5151
Plaintext::BigUInt(_x) => unimplemented!(),

0 commit comments

Comments
 (0)