Skip to content

Commit

Permalink
Add guard for disabling expunge within slog
Browse files Browse the repository at this point in the history
  • Loading branch information
VanceLongwill committed Mar 13, 2024
1 parent 27b2864 commit fafed0c
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 3 deletions.
1 change: 1 addition & 0 deletions expunge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde = { version = "1.0", optional = true }
slog_derive = { version = "0.2.0", optional = true }
slog = { version = "2.7.0", optional = true, features = ["nested-values"] }
erased-serde = { version = "0.3", optional = true }
lazy_static = "1.4.0"

[dev-dependencies]
expunge_derive = { path = "../expunge_derive", features = ["all"] }
Expand Down
5 changes: 4 additions & 1 deletion expunge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
//! latitude: f64,
//! #[expunge]
//! longitude: f64,
//! #[expunge(as = "<expunged>".to_string(), zeroize)]
//! #[expunge(as = "<expunged>".to_string())]
//! password_hash: String,
//! }
//!
Expand Down Expand Up @@ -83,6 +83,9 @@ pub mod primitives;
/// A collection of utils for common ways to expunge things
pub mod utils;

#[cfg(feature = "slog")]
pub mod slog_debug;

#[cfg(feature = "zeroize")]
#[doc(hidden)]
pub use ::zeroize;
Expand Down
44 changes: 44 additions & 0 deletions expunge/src/slog_debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::cell::RefCell;

thread_local! {
static TL_SCOPES: RefCell<Vec<bool>> = RefCell::new(Vec::new())
}

/// A type guard for disabling expunging within slog. Other calls to expunge will be unaffected.
pub struct DisabledGuard;

impl DisabledGuard {
/// A thread local type guard for disabling expunging within slog:
/// true = disabled
///
/// When dropped, it will be reset to the parent value.
///
/// Expunge is enabled by default.
pub fn new(disabled: bool) -> Self {
TL_SCOPES.with(|s| {
s.borrow_mut().push(disabled);
});

DisabledGuard
}
}

impl Drop for DisabledGuard {
fn drop(&mut self) {
TL_SCOPES.with(|s| {
s.borrow_mut()
.pop()
.expect("TL_SCOPES should contain a logger");
})
}
}

pub fn is_disabled() -> bool {
TL_SCOPES.with(|s| {
let s = s.borrow();
match s.last() {
Some(disabled) => *disabled,
None => false,
}
})
}
89 changes: 88 additions & 1 deletion expunge/tests/expunge.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use expunge::Expunge;
use serde::Deserialize;

#[cfg(feature = "slog")]
#[cfg(test)]
mod buf {
use std::io::{BufRead, BufReader};
Expand Down Expand Up @@ -33,9 +33,11 @@ mod buf {
}
}

#[cfg(feature = "slog")]
#[test]
fn it_derives_logging_with_slog() {
use crate::buf::Buf;
use serde::Deserialize;
use serde::Serialize;
use slog::{info, o, Drain, Logger};
use std::sync::Mutex;
Expand Down Expand Up @@ -73,9 +75,93 @@ fn it_derives_logging_with_slog() {
);
}

#[cfg(feature = "slog")]
#[test]
fn it_debug_disables_derives_logging_with_slog() {
use crate::buf::Buf;
use expunge::slog_debug::DisabledGuard;
use serde::Deserialize;
use serde::Serialize;
use slog::{info, o, Drain, Logger};
use std::sync::Mutex;

#[derive(Debug, Clone, Expunge, Deserialize, Serialize, PartialEq, Eq)]
#[expunge(slog)]
struct Location {
#[expunge(as = "<expunged>".to_string())]
city: String,
}

let loc = Location {
city: "New York".to_string(),
};

let buf = Buf::default();
let drain = Mutex::new(slog_json::Json::default(buf.clone())).fuse();
let logger = Logger::root(drain, o!());

let guard = DisabledGuard::new(true);

info!(logger, "it should log un-expunged"; "location" => loc.clone());
drop(guard);
info!(logger, "it should log expunged"; "location" => loc.clone());
let _guard1 = DisabledGuard::new(true);
info!(logger, "it should log un-expunged"; "location" => loc.clone());
{
let _guard2 = DisabledGuard::new(false);
info!(logger, "it should log expunged"; "location" => loc.clone());
}
info!(logger, "it should log un-expunged"; "location" => loc.clone());

#[derive(Deserialize)]
struct Log {
location: Location,
}

let lines = buf.lines();
println!("{}", lines.join("\n"));

let got: Log = serde_json::from_str(&lines[0]).unwrap();
assert_eq!(
loc.clone(),
got.location,
"the slogged value should NOT be expunged"
);

let got: Log = serde_json::from_str(&lines[1]).unwrap();
assert_eq!(
loc.clone().expunge(),
got.location,
"the slogged value should be expunged"
);

let got: Log = serde_json::from_str(&lines[2]).unwrap();
assert_eq!(
loc.clone(),
got.location,
"the slogged value should NOT be expunged"
);

let got: Log = serde_json::from_str(&lines[3]).unwrap();
assert_eq!(
loc.clone().expunge(),
got.location,
"the slogged value should be expunged"
);

let got: Log = serde_json::from_str(&lines[4]).unwrap();
assert_eq!(
loc.clone(),
got.location,
"the slogged value should NOT be expunged"
);
}

#[cfg(feature = "slog")]
#[test]
fn it_derives_logging_with_slog_enum() {
use crate::buf::Buf;
use serde::Deserialize;
use serde::Serialize;
use slog::{info, o, Drain, Logger};
use std::sync::Mutex;
Expand Down Expand Up @@ -318,6 +404,7 @@ fn it_works_struct_all() {
);
}

#[cfg(feature = "zeroize")]
#[test]
fn it_works_enum() {
#[derive(PartialEq, Debug, Clone, Expunge)]
Expand Down
15 changes: 14 additions & 1 deletion expunge_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,28 @@ fn try_expunge_derive(input: DeriveInput) -> Result<TokenStream, syn::Error> {
) -> slog::Result {
use ::serde::Serialize;
use ::slog_derive::SerdeValue;
#[cfg(feature = "slog")]
use ::expunge::slog_debug::is_disabled;

#[derive(Clone, Serialize, SerdeValue)]
pub struct Wrapped {
#[slog]
#[serde(flatten)]
item: #name,
}

#[cfg(not(feature = "slog"))]
let item = self.clone().expunge();

#[cfg(feature = "slog")]
let item = if is_disabled() {
self.clone()
} else {
self.clone().expunge()
};

let wrapped = Wrapped {
item: self.clone().expunge(),
item,
};
::slog::Value::serialize(&wrapped, record, key, serializer)
}
Expand Down

0 comments on commit fafed0c

Please sign in to comment.