Skip to content

Commit 8f91e79

Browse files
committed
feat(context): support unquoted identifiers for CIPHERSTASH.KEYSET_NAME
Add support for unquoted PostgreSQL identifiers when setting keyset name via SET CIPHERSTASH.KEYSET_NAME. Previously only quoted strings and numbers were accepted; now valid PG identifiers work without quotes. Update tests to validate the new behavior and adjust invalid test cases.
1 parent 47592d1 commit 8f91e79

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

packages/cipherstash-proxy-integration/src/multitenant/set_keyset_name.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ mod tests {
115115
let result = client.simple_query(&sql).await;
116116
assert!(result.is_ok());
117117

118+
// SET TENANT_1 WITHOUT QUOTES
119+
// VALID AS LONG AS NAME IS A VALID PG IDENTIFIER
120+
let sql = format!("SET CIPHERSTASH.KEYSET_NAME = {tenant_keyset_name_1}");
121+
let result = client.simple_query(&sql).await;
122+
assert!(result.is_ok());
123+
118124
// INSERT
119125
let tenant_1_id = random_id();
120126
let encrypted_text = "hello";
@@ -372,8 +378,8 @@ mod tests {
372378

373379
// Test cases that should potentially fail or be handled gracefully
374380
let invalid_cases = vec![
375-
format!("SET CIPHERSTASH.KEYSET_NAME = {tenant_keyset_name_1}"), // unquoted string
376-
format!("SET CIPHERSTASH.KEYSET_NAME = NULL"), // null value
381+
format!("SET CIPHERSTASH.KEYSET_NAME = test-1"), // unquoted string that is NOT a valid pg Identifier
382+
format!("SET CIPHERSTASH.KEYSET_NAME = NULL"), // null value
377383
];
378384

379385
for invalid_sql in invalid_cases {

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -446,17 +446,20 @@ where
446446
}) = statement
447447
{
448448
if variable == &*SQL_SETTING_NAME_KEYSET_NAME {
449-
if let Some(Expr::Value(ValueWithSpan { value, .. })) = values.first() {
450-
let keyset_name = match value {
451-
Value::SingleQuotedString(s) | Value::DoubleQuotedString(s) => s.clone(),
452-
Value::Number(n, _) => n.to_string(),
453-
_ => {
454-
let err = EncryptError::KeysetNameCouldNotBeSet;
455-
warn!(target: CONTEXT, client_id = self.client_id, msg = err.to_string());
456-
return Ok(None);
449+
// Try to extract keyset name from Value (quoted string/number) or Identifier (unquoted)
450+
let keyset_name = match values.first() {
451+
Some(Expr::Value(ValueWithSpan { value, .. })) => match value {
452+
Value::SingleQuotedString(s) | Value::DoubleQuotedString(s) => {
453+
Some(s.clone())
457454
}
458-
};
459-
455+
Value::Number(n, _) => Some(n.to_string()),
456+
_ => None,
457+
},
458+
Some(Expr::Identifier(ident)) => Some(ident.value.clone()),
459+
_ => None,
460+
};
461+
462+
if let Some(keyset_name) = keyset_name {
460463
debug!(target: CONTEXT, client_id = self.client_id, msg = "Set KeysetName", ?keyset_name);
461464

462465
let identifier = KeysetIdentifier(IdentifiedBy::Name(keyset_name.into()));
@@ -469,7 +472,7 @@ where
469472
} else {
470473
let err = EncryptError::KeysetNameCouldNotBeSet;
471474
warn!(target: CONTEXT, client_id = self.client_id, msg = err.to_string());
472-
// We let the database handle any syntax errors to avoid complexifying the fronted flow (more)
475+
// We let the database handle any syntax errors to avoid complexifying the frontend flow
473476
}
474477
}
475478
}

0 commit comments

Comments
 (0)