diff --git a/Cargo.lock b/Cargo.lock index d232fcbf024c..2d1f3cf4b06a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3698,6 +3698,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "histogram" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cb882ccb290b8646e554b157ab0b71e64e8d5bef775cd66b6531e52d302669" + [[package]] name = "hkdf" version = "0.12.4" @@ -4309,6 +4315,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -4566,6 +4581,15 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "lz4_flex" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" +dependencies = [ + "twox-hash", +] + [[package]] name = "masking" version = "0.1.0" @@ -4573,6 +4597,7 @@ dependencies = [ "bytes 1.7.1", "diesel", "erased-serde 0.4.5", + "scylla", "serde", "serde_json", "subtle", @@ -5970,6 +5995,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core", +] + [[package]] name = "rand_xorshift" version = "0.3.0" @@ -6891,6 +6925,66 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "scylla" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8139623d3fb0c8205b15e84fa587f3aa0ba61f876c19a9157b688f7c1763a7c5" +dependencies = [ + "arc-swap", + "async-trait", + "byteorder", + "bytes 1.7.1", + "chrono", + "dashmap", + "futures 0.3.30", + "hashbrown 0.14.5", + "histogram", + "itertools 0.13.0", + "lazy_static", + "lz4_flex", + "rand", + "rand_pcg", + "scylla-cql", + "scylla-macros", + "smallvec 1.13.2", + "snap", + "socket2", + "thiserror", + "tokio 1.40.0", + "tracing", + "uuid", +] + +[[package]] +name = "scylla-cql" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de7020bcd1f6fdbeaed356cd426bf294b2071bd7120d48d2e8e319295e2acdcd" +dependencies = [ + "async-trait", + "byteorder", + "bytes 1.7.1", + "lz4_flex", + "scylla-macros", + "snap", + "thiserror", + "tokio 1.40.0", + "uuid", +] + +[[package]] +name = "scylla-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3859b6938663fc5062e3b26f3611649c9bd26fb252e85f6fdfa581e0d2ce74b6" +dependencies = [ + "darling 0.20.10", + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "sdd" version = "3.0.2" @@ -7314,6 +7408,12 @@ dependencies = [ "serde", ] +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + [[package]] name = "socket2" version = "0.5.7" @@ -7568,6 +7668,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "storage_impl" version = "0.1.0" @@ -8669,6 +8775,16 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if 1.0.0", + "static_assertions", +] + [[package]] name = "typeid" version = "1.0.2" diff --git a/crates/masking/Cargo.toml b/crates/masking/Cargo.toml index ed20a08de343..425c1ca36ec4 100644 --- a/crates/masking/Cargo.toml +++ b/crates/masking/Cargo.toml @@ -12,6 +12,7 @@ default = ["alloc", "serde", "diesel", "time"] alloc = ["zeroize/alloc"] serde = ["dep:serde", "dep:serde_json"] time = ["dep:time"] +cassandra = ["dep:scylla"] [package.metadata.docs.rs] all-features = true @@ -27,6 +28,7 @@ subtle = "2.5.0" time = { version = "0.3.35", optional = true, features = ["serde-human-readable"] } url = { version = "2.5.0", features = ["serde"] } zeroize = { version = "1.7", default-features = false } +scylla = { version = "0.14.0", optional = true} [dev-dependencies] serde_json = "1.0.115" diff --git a/crates/masking/src/cassandra.rs b/crates/masking/src/cassandra.rs new file mode 100644 index 000000000000..dc81512e79d5 --- /dev/null +++ b/crates/masking/src/cassandra.rs @@ -0,0 +1,50 @@ +use scylla::{ + cql_to_rust::FromCqlVal, + deserialize::DeserializeValue, + frame::response::result::{ColumnType, CqlValue}, + serialize::{ + value::SerializeValue, + writers::{CellWriter, WrittenCellProof}, + SerializationError, + }, +}; + +use crate::{abs::PeekInterface, StrongSecret}; + +impl SerializeValue for StrongSecret +where + T: SerializeValue + zeroize::Zeroize + Clone, +{ + fn serialize<'b>( + &self, + typ: &ColumnType, + writer: CellWriter<'b>, + ) -> Result, SerializationError> { + self.peek().serialize(typ, writer) + } +} + +impl<'frame, T> DeserializeValue<'frame> for StrongSecret +where + T: DeserializeValue<'frame> + zeroize::Zeroize + Clone, +{ + fn type_check(typ: &ColumnType) -> Result<(), scylla::deserialize::TypeCheckError> { + T::type_check(typ) + } + + fn deserialize( + typ: &'frame ColumnType, + v: Option>, + ) -> Result { + Ok(Self::new(T::deserialize(typ, v)?)) + } +} + +impl FromCqlVal for StrongSecret +where + T: FromCqlVal + zeroize::Zeroize + Clone, +{ + fn from_cql(cql_val: CqlValue) -> Result { + Ok(Self::new(T::from_cql(cql_val)?)) + } +} diff --git a/crates/masking/src/lib.rs b/crates/masking/src/lib.rs index ca0da6b67672..d376e935bd6e 100644 --- a/crates/masking/src/lib.rs +++ b/crates/masking/src/lib.rs @@ -57,6 +57,9 @@ pub mod prelude { #[cfg(feature = "diesel")] mod diesel; +#[cfg(feature = "cassandra")] +mod cassandra; + pub mod maskable; pub use maskable::*;