feat(masking): implement prost::Message trait for Secret and StrongSecret types (#8458)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Debarshi Gupta
2025-07-02 12:12:45 +05:30
committed by GitHub
parent 01bd831665
commit ad29631c53
4 changed files with 68 additions and 0 deletions

1
Cargo.lock generated
View File

@ -4729,6 +4729,7 @@ dependencies = [
"bytes 1.10.1",
"diesel",
"erased-serde 0.4.6",
"prost",
"scylla",
"serde",
"serde_json",

View File

@ -13,6 +13,8 @@ alloc = ["zeroize/alloc"]
serde = ["dep:serde", "dep:serde_json"]
time = ["dep:time"]
cassandra = ["dep:scylla"]
proto_tonic = ["dep:bytes", "dep:prost"]
bytes = ["dep:bytes"]
[package.metadata.docs.rs]
all-features = true
@ -29,6 +31,7 @@ time = { version = "0.3.41", optional = true, features = ["serde-human-readable"
url = { version = "2.5.4", features = ["serde"] }
zeroize = { version = "1.8", default-features = false }
scylla = { git = "https://github.com/juspay/scylla-rust-driver.git",rev = "5700aa2847b25437cdd4fcf34d707aa90dca8b89", optional = true}
prost = { version = "0.13", optional = true }
[dev-dependencies]
serde_json = "1.0.140"

View File

@ -248,6 +248,38 @@ impl Strategy<serde_json::Value> for JsonMaskStrategy {
}
}
#[cfg(feature = "proto_tonic")]
impl<T> prost::Message for Secret<T, crate::WithType>
where
T: prost::Message + Default + Clone,
{
fn encode_raw(&self, buf: &mut impl bytes::BufMut) {
self.peek().encode_raw(buf);
}
fn merge_field(
&mut self,
tag: u32,
wire_type: prost::encoding::WireType,
buf: &mut impl bytes::Buf,
ctx: prost::encoding::DecodeContext,
) -> Result<(), prost::DecodeError> {
if tag == 1 {
self.peek_mut().merge_field(tag, wire_type, buf, ctx)
} else {
prost::encoding::skip_field(wire_type, tag, buf, ctx)
}
}
fn encoded_len(&self) -> usize {
self.peek().encoded_len()
}
fn clear(&mut self) {
self.peek_mut().clear();
}
}
#[cfg(test)]
#[cfg(feature = "serde")]
mod tests {

View File

@ -126,3 +126,35 @@ impl StrongEq for Vec<u8> {
bool::from(lhs.ct_eq(rhs))
}
}
#[cfg(feature = "proto_tonic")]
impl<T> prost::Message for StrongSecret<T, crate::WithType>
where
T: prost::Message + Default + Clone + ZeroizableSecret,
{
fn encode_raw(&self, buf: &mut impl bytes::BufMut) {
self.peek().encode_raw(buf);
}
fn merge_field(
&mut self,
tag: u32,
wire_type: prost::encoding::WireType,
buf: &mut impl bytes::Buf,
ctx: prost::encoding::DecodeContext,
) -> Result<(), prost::DecodeError> {
if tag == 1 {
self.peek_mut().merge_field(tag, wire_type, buf, ctx)
} else {
prost::encoding::skip_field(wire_type, tag, buf, ctx)
}
}
fn encoded_len(&self) -> usize {
self.peek().encoded_len()
}
fn clear(&mut self) {
self.peek_mut().clear();
}
}