zerokms-protocol 0.12.5

Library to manage the CipherStash ZeroKMS communication protocol
Documentation
//! Implementations of `Dummy` for various types in the `zerokms-protocol` crate.
use fake::{
    faker::lorem::en::{Word, Words},
    Dummy, Fake, Faker,
};
use rand::{Fill, Rng};
use std::borrow::Cow;
use uuid::Uuid;

use crate::{
    CreateClientRequest, CreateKeysetRequest, CreateKeysetResponse, GenerateKeyRequest,
    GenerateKeySpec, GrantKeysetRequest, IdentifiedBy, Keyset, RetrieveKeyRequest,
    RetrieveKeyRequestFallible, RetrieveKeySpec,
};

/// Generate a random `CreateDatasetRequest` with a random description and the given name.
impl Dummy<&'static str> for CreateKeysetRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(name: &&'static str, _: &mut R) -> Self {
        Self {
            name: Cow::Borrowed(*name),
            description: Cow::Owned("description".to_string()),
            client: None,
        }
    }
}

impl Dummy<Faker> for Keyset {
    fn dummy_with_rng<R: Rng + ?Sized>(_: &Faker, _: &mut R) -> Self {
        Self {
            id: Uuid::new_v4(),
            name: Word().fake(),
            description: Words(3..10).fake::<Vec<String>>().join(" "),
            is_disabled: false,
            is_default: false,
        }
    }
}

/// Generate a random `CreateDatasetRequest` with a random name and description.
impl Dummy<Faker> for CreateKeysetRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(_: &Faker, _: &mut R) -> Self {
        let words: Vec<String> = Words(3..10).fake();
        let word: String = Word().fake();

        Self {
            name: Cow::Owned(format!("{word}-{}", Uuid::new_v4())),
            description: Cow::Owned(words.join(" ")),
            client: None,
        }
    }
}

/// Generate a random `CreateClientRequest` for the given `Keyset`.
/// The name and description are random.
impl Dummy<Keyset> for CreateClientRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(Keyset { id, .. }: &Keyset, _: &mut R) -> Self {
        Self {
            keyset_id: Some(IdentifiedBy::Uuid(*id)),
            name: Cow::Owned(Word().fake()),
            description: Cow::Owned(Word().fake()),
        }
    }
}

/// Generate a random `CreateClientRequest` from a `CreateKeysetResponse`.
impl Dummy<CreateKeysetResponse> for CreateClientRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(resp: &CreateKeysetResponse, rng: &mut R) -> Self {
        Self::dummy_with_rng(&resp.keyset, rng)
    }
}

/// Generate a `GrantDatasetRequest` for the given `Keyset` and client ID (`Uuid`).
impl Dummy<(&Keyset, Uuid)> for GrantKeysetRequest {
    fn dummy_with_rng<R: Rng + ?Sized>((keyset, client_id): &(&Keyset, Uuid), _: &mut R) -> Self {
        Self {
            keyset_id: IdentifiedBy::Uuid(keyset.id),
            client_id: *client_id,
        }
    }
}

impl Dummy<(&CreateKeysetResponse, Uuid)> for GrantKeysetRequest {
    fn dummy_with_rng<R: Rng + ?Sized>(
        (resp, client_id): &(&CreateKeysetResponse, Uuid),
        rng: &mut R,
    ) -> Self {
        Self::dummy_with_rng(&(&resp.keyset, *client_id), rng)
    }
}

impl Dummy<(&Keyset, Uuid)> for GenerateKeyRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>((keyset, client_id): &(&Keyset, Uuid), _: &mut R) -> Self {
        Self {
            keyset_id: Some(IdentifiedBy::Uuid(keyset.id)),
            client_id: *client_id,
            keys: Cow::Owned(fake::vec![GenerateKeySpec; 4]),
            unverified_context: Default::default(),
        }
    }
}

impl Dummy<(&CreateKeysetResponse, Uuid)> for GenerateKeyRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(
        (resp, client_id): &(&CreateKeysetResponse, Uuid),
        rng: &mut R,
    ) -> Self {
        Self::dummy_with_rng(&(&resp.keyset, *client_id), rng)
    }
}

impl Dummy<Faker> for GenerateKeySpec<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(_: &Faker, rng: &mut R) -> Self {
        let mut buf: [u8; 16] = Default::default();
        buf.try_fill(rng).unwrap();

        Self {
            iv: buf.into(),
            descriptor: Cow::Owned(Word().fake()),
            context: Default::default(),
        }
    }
}

impl Dummy<(&Keyset, Uuid)> for RetrieveKeyRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>((keyset, client_id): &(&Keyset, Uuid), _: &mut R) -> Self {
        Self {
            keyset_id: Some(IdentifiedBy::Uuid(keyset.id)),
            client_id: *client_id,
            keys: Cow::Owned(fake::vec![RetrieveKeySpec; 4]),
            unverified_context: Default::default(),
        }
    }
}

impl Dummy<(&CreateKeysetResponse, Uuid)> for RetrieveKeyRequest<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(
        (resp, client_id): &(&CreateKeysetResponse, Uuid),
        rng: &mut R,
    ) -> Self {
        Self::dummy_with_rng(&(&resp.keyset, *client_id), rng)
    }
}

impl Dummy<(&Keyset, Uuid)> for RetrieveKeyRequestFallible<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>((keyset, client_id): &(&Keyset, Uuid), _: &mut R) -> Self {
        Self {
            keyset_id: Some(IdentifiedBy::Uuid(keyset.id)),
            client_id: *client_id,
            keys: Cow::Owned(fake::vec![RetrieveKeySpec; 4]),
            unverified_context: Default::default(),
        }
    }
}

impl Dummy<Faker> for RetrieveKeySpec<'_> {
    fn dummy_with_rng<R: Rng + ?Sized>(_: &Faker, rng: &mut R) -> Self {
        let mut buf: [u8; 16] = Default::default();
        buf.try_fill(rng).unwrap();

        Self {
            iv: buf.into(),
            descriptor: Cow::Owned(Word().fake()),
            tag: Cow::Owned([0u8; 16].map(|_| rng.gen()).to_vec()),
            context: Cow::Owned(vec![]),
            tag_version: 1,
        }
    }
}