Skip to content

Commit

Permalink
[PLATFORM-866]: Update examples and documentation in Veil for all the…
Browse files Browse the repository at this point in the history
… new changes (#65)

* Fix redactor tests

* Use `Redactor::builder()` instead of `RedactorBuilder::new()` in examples

* Add the `Redactable` trait and a derive macro for it

* Add examples and docs for new changes, improve existing docs and examples

* Format

* Add docs generation to CI workflow to catch broken links and stuff

* Fix broken docs link

* Oops

* Format

* Fix example for new changes

* `rustdoc::broken_intra_doc_links` is `warn` by default

* Improve comment about `#[redact(all, variant)]`

* Use `-Dwarnings` instead of `--cfg docsci` mess

* Fix broken links

* Format and sign the drone file

* Oops

* Format and sign the drone file

* Unfuck drone formatting

* Better comment

Co-authored-by: MaeIsBad <26093674+MaeIsBad@users.noreply.github.com>

Co-authored-by: William Venner <14863743+WilliamVenner@users.noreply.github.com>
Co-authored-by: mae.kasza <26093674+MaeIsBad@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 22, 2022
1 parent ff14749 commit 390a4c9
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 31 deletions.
28 changes: 18 additions & 10 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,34 @@ steps:
- name: cargo-format
image: rust:1.64
commands:
- rustup component add rustfmt &&
cargo fmt --all -- --check
- rustup component add rustfmt && cargo fmt --all -- --check
environment:
CARGO_HOME: /drone/src/.cargo
depends_on:
- cargo-deps

- name: cargo-doc-ci
image: rust:1.64
commands:
- cargo doc --document-private-items --workspace --all-features --no-deps
environment:
RUSTDOCFLAGS: -Dwarnings
depends_on:
- cargo-format

- name: cargo-clippy-ci
image: rust:1.64
commands:
- rustup component add clippy &&
cargo clippy -- -D warnings &&
cargo clippy --features toggle -- -D warnings &&
cargo clippy --release -- -D warnings &&
cargo clippy --release --features toggle -- -D warnings
- rustup component add clippy
- cargo clippy --workspace -- -D warnings
- cargo clippy --workspace --all-features -- -D warnings
- cargo clippy --workspace --release -- -D warnings
- cargo clippy --workspace --release --all-features -- -D warnings
environment:
BUILD_ENV: dev
CARGO_HOME: /drone/src/.cargo
depends_on:
- cargo-format
- cargo-doc-ci

- name: cargo-test
image: rust:1.64
Expand All @@ -55,7 +63,6 @@ steps:
environment:
BUILD_ENV: dev
CARGO_HOME: /drone/src/.cargo
CARGO_HTTP_CAINFO: ""
depends_on:
- cargo-clippy-ci

Expand Down Expand Up @@ -131,8 +138,9 @@ trigger:
depends_on:
- default
- build-production

---
kind: signature
hmac: 28171a0fb4c198384e0176ef1a6b6f120771b30b4146113488c7ff81b2e7c006
hmac: 66badf18a9b2157be8df165e445ffeb0d793c1a9031ad1aafb32f30da1a0edfd

...
9 changes: 6 additions & 3 deletions examples/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use veil::Redact;

#[derive(Redact)]
#[redact(all, variant)]
#[redact(all, variant)] // Redact all the variant names! We can still skip individual variants later on by marking them as `#[redact(variant, skip)]`
enum CreditCardIssuer {
Visa,
Mastercard,
Expand All @@ -13,8 +13,11 @@ enum CreditCardIssuer {
Jcb,
UnionPay,

#[redact(skip, variant)]
Other(#[redact] String),
#[redact(variant, skip)] // Don't redact the name of this variant
Other(
#[redact] // But do redact the contents of this field!
String,
),
}

fn main() {
Expand Down
33 changes: 33 additions & 0 deletions examples/manual_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use veil::redactor::{Redactor, RedactorBuilder};

fn main() {
// Build a new Redactor.
// We'll set up the Redactor to use flags that are equivalent to:
// `#[redact(with = 'X', partial))]`
// on a field, when using the `Redact` derive macro.
let redactor: Redactor = RedactorBuilder::new().char('X').partial().build().unwrap();

// We can now redact any string we want in a number of different ways...

// Firstly, we can simply redact directly to a `String`:
assert_eq!(redactor.redact("Hello, world!".to_string()), "HelXX, XXrld!");

// Or, we can redact a `String` in-place, which is slightly more efficient,
// and allows us to chain multiple redactions together:
let mut hello = "Hello, world!".to_string();
let mut goodbye = "Goodbye, world!".to_string();
redactor.redact_in_place(&mut hello).redact_in_place(&mut goodbye);
assert_eq!(hello, "HelXX, XXrld!");
assert_eq!(goodbye, "GooXXXX, XXrld!");

// Finally, we can use the `wrap` method to wrap a string in a `RedactWrapped` struct,
// which implements `Debug` and `Display` to redact the string when displayed or debugged.
let hello = "Hello, world!".to_string();
let hello_wrapped = redactor.wrap(&hello);

assert_ne!(hello_wrapped.to_string(), hello);
assert_ne!(format!("{:?}", hello_wrapped), format!("{:?}", hello));

assert_eq!(hello_wrapped.to_string(), "HelXX, XXrld!");
assert_eq!(format!("{:?}", hello_wrapped), "\"HelXX, XXrld!\"");
}
36 changes: 36 additions & 0 deletions examples/manual_redactable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use veil::Redactable;

// As an alternative to redacting in a type's `std::fmt::Debug` implementation (which is what the `Redact` derive macro implements),
// you can also use the `Redactable` type to more explicitly redact structured data.
//
// The `Redactable` trait requires that a type implements `std::fmt::Display`, as this is what will be used to redact the type.

#[derive(Redactable, Debug)] // `Redactable` doesn't touch `Debug` at all, so you can still derive it.
#[redact(with = 'X', partial)] // All the modifier flags you know and love from the `Redact` derive macro are also available here.
struct EmailAddress(String);

// Our `Display` implementation for `EmailAddress` will simply print out the email address as-is.
// This is what will be used to redact the type.
impl std::fmt::Display for EmailAddress {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}

fn main() {
let email = EmailAddress("john.doe@prima.it".to_string());

// The `Debug` implementation is untouched and will work as expected.
assert_eq!(format!("{:?}", email), "EmailAddress(\"john.doe@prima.it\")");

// So will the `Display` implementation.
assert_eq!(format!("{}", email), "john.doe@prima.it");

// And this is how we redact the data!
assert_eq!(email.redact(), "johX.XXX@XXXXa.it");

// We can also redact the data into an existing buffer, which is slightly more efficient if you've already got one lying around.
let mut buffer = String::new();
email.redact_into(&mut buffer).unwrap();
assert_eq!(buffer, "johX.XXX@XXXXa.it");
}
32 changes: 21 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![deny(missing_docs)]
#![warn(missing_docs)]
#![cfg_attr(docsrs, feature(doc_cfg))]

//! Implements [`std::fmt::Debug`] for a struct or enum variant, with certain fields redacted.
//! Implements [`Debug`] for a struct or enum variant, with certain fields redacted.
//!
//! The purpose of this macro is to allow for easy, configurable and efficient redaction of sensitive data in structs and enum variants.
//! This can be used to hide sensitive data in logs or anywhere where personal data should not be exposed or stored.
Expand All @@ -12,7 +12,7 @@
//!
//! Using the `#[redact]` attribute, you can control which fields are redacted and how.
//!
//! **Fields without this attribute will NOT be redacted and will be shown using their default [`std::fmt::Debug`] implementation.**
//! **Fields without this attribute will NOT be redacted and will be shown using their default [`Debug`] implementation.**
//!
//! Modifiers can be applied to control how the field is redacted:
//!
Expand All @@ -21,7 +21,7 @@
//! | `#[redact(partial)]` | | If the string is long enough, a small part of the<br>beginning and end will be exposed. If the string is too short to securely expose a portion of it, it will be redacted entirely. | | Disabled. The entire string will be redacted. |
//! | `#[redact(with = 'X')]` | | Specifies the `char` the string will be redacted with. | | `'*'` |
//! | `#[redact(fixed = <integer>)]` | | If this modifier is present, the length and contents of<br>the string are completely ignored and the string will always<br>be redacted as a fixed number of redaction characters. | | Disabled. |
//! | `#[redact(display)]` | | Overrides the redaction behavior to use the type's [`std::fmt::Display`] implementation instead of [`std::fmt::Debug`]. | | Disabled. |
//! | `#[redact(display)]` | | Overrides the redaction behavior to use the type's [`Display`](std::fmt::Display) implementation instead of [`Debug`]. | | Disabled. |
//!
//! # Redacting All Fields in a Struct or Enum Variant
//!
Expand Down Expand Up @@ -210,15 +210,25 @@
//!
//! # Limitations
//!
//! Currently, this macro only supports [`std::fmt::Debug`] formatting with no modifiers (`{:?}`) or the "alternate" modifier (`{:#?}`).
//! Modifiers like padding, alignment, etc. are not supported as the Rust standard library does not expose any of this behaviour for us.
//! Currently, this macro only supports [`Debug`] formatting with no modifiers (`{:?}`) or the "alternate" modifier (`{:#?}`).
//! Modifiers like padding, alignment, etc. are not supported as the Rust standard library does not expose any of this behavior for us.
//!
//! ## A note on [`std::fmt::Display`]
//! ## A note on [`Display`](std::fmt::Display)
//!
//! This derive macro does **NOT** implement [`std::fmt::Display`]. If you want to implement it, you can do so manually.
//! This derive macro does **NOT** implement [`Display`](std::fmt::Display). If you want to implement it, you can do so manually.
//!
//! [`std::fmt::Display`] should NOT be redacted. It is meant to be human-readable, and also has a snowball effect on [`ToString`]
//! as [`std::fmt::Display`] automatically implements it, leading to confusing and unexpected behaviour.
//! [`Display`](std::fmt::Display) should NOT be redacted. It is meant to be human-readable, and also has a snowball effect on [`ToString`]
//! as [`Display`](std::fmt::Display) automatically implements it, leading to confusing and unexpected behavior.
//!
//! If you want to use a type's [`Display`](std::fmt::Display) implementation during redaction, you can use the `#[redact(display)]` flag described in the [Controlling Redaction](#controlling-redaction) section.
//!
//! # Manually Redacting Data
//!
//! If you want to manually redact data, you have a few options:
//!
//! * Use the [`Redactable`](derive.Redactable.html) derive macro to generate a [`Redactable`] trait implementation for your type.
//! * Implement the [`Redactable`] trait manually.
//! * Use the provided [`RedactorBuilder`](redactor::RedactorBuilder) to build a [`Redactor`](redactor::Redactor) instance.
//!
//! # Environmental Awareness
//!
Expand All @@ -230,7 +240,7 @@
//!
//! - Calling the [`veil::disable`](disable) function. See this [example](https://github.com/primait/veil/blob/master/examples/disable_redaction.rs).
//!
//! These are only checked ONCE for security purposes.
//! These are only checked ONCE for security reasons.
pub use veil_macros::{Redact, Redactable};

Expand Down
6 changes: 3 additions & 3 deletions src/toggle.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#![cfg_attr(docsrs, doc(cfg(feature = "toggle")))]

//! Makes it possible to disable veil's redaction behaviour
//! Makes it possible to disable veil's redaction behavior
use once_cell::sync::OnceCell;

/// Enum describing how Veil should behave when `std::fmt::Debug` is called on a `#[derive(Redact)]` item
/// Enum describing how Veil should behave when `Debug` is called on a `#[derive(Redact)]` item
#[derive(Debug, Copy, Clone)]
#[cfg_attr(docsrs, doc(cfg(feature = "toggle")))]
pub enum RedactionBehavior {
Expand Down Expand Up @@ -33,7 +33,7 @@ static DEBUG_FORMAT: OnceCell<RedactionBehavior> = OnceCell::new();
/// See the "Environmental Awareness" section in the [crate level documentation](../index.html) for more information.
///
/// Should only be called once, preferrably at the top of main,
/// before any calls to [`std::fmt::Debug`], otherwise `Err` will be returned.
/// before any calls to [`Debug`], otherwise `Err` will be returned.
///
/// Overrides the `VEIL_DISABLE_REDACTION` environment variable, if set.
/// ```
Expand Down
2 changes: 1 addition & 1 deletion veil-macros/src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub struct FieldFlags {
/// Fields are not redacted by default unless their parent is marked as `#[redact(all)]`, and this flag turns off that redaction for this specific field.
pub skip: bool,

/// Whether to use the type's [`Display`] implementation instead of [`Debug`].
/// Whether to use the type's [`Display`](std::fmt::Display) implementation instead of [`Debug`].
pub display: bool,

/// Flags that modify the redaction behavior.
Expand Down
3 changes: 1 addition & 2 deletions veil-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Macros for `veil`
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![warn(missing_docs)]

#[macro_use]
extern crate quote;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fn main() {}
#[derive(veil::Redactable)]
struct Foo {
bar: String,
baz: String
baz: String,
}

#[derive(veil::Redactable)]
Expand Down

0 comments on commit 390a4c9

Please sign in to comment.