im-core 0.1.0

Rust IM SDK for Awiki clients built on Agent Network Protocol (ANP)
Documentation
use super::policy::SecretAccessPolicy;
use serde::{Deserialize, Serialize};
use std::fmt;

pub(crate) const VAULT_RECORD_SCHEMA_VERSION: u32 = 1;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SecretKind {
    IdentityRootPrivate,
    IdentityE2eeSigningPrivate,
    IdentityE2eeAgreementPrivate,
    IdentityDaemonPrivate,
    AuthJwt,
    DirectE2eeSignedPrekeyPrivate,
    DirectE2eeOneTimePrekeyPrivate,
    DirectE2eeSessionState,
    GroupMlsState,
    RuntimeSecret,
}

impl SecretKind {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::IdentityRootPrivate => "identity.root.private",
            Self::IdentityE2eeSigningPrivate => "identity.e2ee.signing.private",
            Self::IdentityE2eeAgreementPrivate => "identity.e2ee.agreement.private",
            Self::IdentityDaemonPrivate => "identity.daemon.private",
            Self::AuthJwt => "auth.jwt",
            Self::DirectE2eeSignedPrekeyPrivate => "direct_e2ee.signed_prekey.private",
            Self::DirectE2eeOneTimePrekeyPrivate => "direct_e2ee.one_time_prekey.private",
            Self::DirectE2eeSessionState => "direct_e2ee.session_state",
            Self::GroupMlsState => "group_mls.state",
            Self::RuntimeSecret => "runtime.secret",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum VaultCipher {
    ChaCha20Poly1305,
}

impl VaultCipher {
    pub(crate) fn as_str(&self) -> &'static str {
        match self {
            Self::ChaCha20Poly1305 => "chacha20-poly1305",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum VaultKdf {
    HkdfSha256,
}

impl VaultKdf {
    pub(crate) fn as_str(&self) -> &'static str {
        match self {
            Self::HkdfSha256 => "hkdf-sha256",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SecretMetadata {
    pub workspace_id: String,
    pub device_id: String,
    pub identity_id: Option<String>,
    pub did: Option<String>,
    pub kind: SecretKind,
    pub key_id: String,
    pub key_version: u32,
    pub policy: SecretAccessPolicy,
}

impl SecretMetadata {
    pub fn secret_ref(&self) -> SecretRef {
        SecretRef {
            workspace_id: self.workspace_id.clone(),
            device_id: self.device_id.clone(),
            identity_id: self.identity_id.clone(),
            did: self.did.clone(),
            kind: self.kind.clone(),
            key_id: self.key_id.clone(),
            key_version: self.key_version,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SecretRef {
    pub workspace_id: String,
    pub device_id: String,
    pub identity_id: Option<String>,
    pub did: Option<String>,
    pub kind: SecretKind,
    pub key_id: String,
    pub key_version: u32,
}

#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub(crate) struct VaultSecretRecord {
    pub(crate) schema_version: u32,
    pub(crate) workspace_id: String,
    pub(crate) device_id: String,
    pub(crate) identity_id: Option<String>,
    pub(crate) did: Option<String>,
    pub(crate) kind: SecretKind,
    pub(crate) key_id: String,
    pub(crate) key_version: u32,
    pub(crate) cipher: VaultCipher,
    pub(crate) kdf: VaultKdf,
    pub(crate) nonce_b64u: String,
    pub(crate) aad_b64u: String,
    pub(crate) ciphertext_b64u: String,
    pub(crate) created_at: String,
    pub(crate) updated_at: String,
    pub(crate) policy: SecretAccessPolicy,
}

impl VaultSecretRecord {
    pub(crate) fn metadata(&self) -> SecretMetadata {
        SecretMetadata {
            workspace_id: self.workspace_id.clone(),
            device_id: self.device_id.clone(),
            identity_id: self.identity_id.clone(),
            did: self.did.clone(),
            kind: self.kind.clone(),
            key_id: self.key_id.clone(),
            key_version: self.key_version,
            policy: self.policy.clone(),
        }
    }

    pub(crate) fn secret_ref(&self) -> SecretRef {
        self.metadata().secret_ref()
    }
}

impl fmt::Debug for VaultSecretRecord {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("VaultSecretRecord")
            .field("schema_version", &self.schema_version)
            .field("workspace_id", &self.workspace_id)
            .field("device_id", &self.device_id)
            .field("identity_id", &self.identity_id)
            .field("did", &self.did)
            .field("kind", &self.kind)
            .field("key_id", &self.key_id)
            .field("key_version", &self.key_version)
            .field("cipher", &self.cipher)
            .field("kdf", &self.kdf)
            .field("nonce", &"[REDACTED]")
            .field("aad", &"[REDACTED]")
            .field("ciphertext", &"[REDACTED]")
            .field("created_at", &self.created_at)
            .field("updated_at", &self.updated_at)
            .field("policy", &self.policy)
            .finish()
    }
}