Ctrl K
ComunidadGuías…

src/account.rs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
//! Exact configured account namespaces. No alias, case or punctuation inference.
use sha2::{Digest, Sha256};

/// Stable privacy-preserving key for one configured login and provider realm.
#[must_use]
pub(crate) fn namespace(username: &str, realm: &str) -> String {
    format!(
        "account-v1-{}",
        fingerprint("configured-account-v1", &[realm, username])
    )
}

#[must_use]
pub(crate) fn provider_fingerprint(realm: &str, dsid: &str) -> String {
    fingerprint("authenticated-provider-v1", &[realm, dsid])
}

fn fingerprint(kind: &str, values: &[&str]) -> String {
    let mut hash = Sha256::new();
    hash.update(kind.as_bytes());
    for value in values {
        hash.update(value.len().to_string().as_bytes());
        hash.update(b":");
        hash.update(value.as_bytes());
    }
    format!("{:x}", hash.finalize())
}

#[cfg(test)]
mod tests {
    use super::namespace;

    #[test]
    fn exact_account_namespace_preserves_distinctions() {
        let key = namespace("first.last@example.invalid", "com");
        for (username, realm) in [
            ("firstlast@example.invalid", "com"),
            ("First.last@example.invalid", "com"),
            ("first.last@example.invalid", "cn"),
            ("é@example.invalid", "com"),
            ("é@example.invalid", "com"),
        ] {
            assert_ne!(key, namespace(username, realm));
        }
        assert_ne!(
            namespace("é@example.invalid", "com"),
            namespace("é@example.invalid", "com")
        );
        assert_eq!(key, namespace("first.last@example.invalid", "com"));
        let long_a = format!("{}first.last@example.invalid", "a".repeat(200));
        let long_b = format!("{}firstlast@example.invalid", "a".repeat(200));
        assert_eq!(
            crate::auth::session::sanitize_username(&long_a),
            crate::auth::session::sanitize_username(&long_b)
        );
        assert_ne!(namespace(&long_a, "com"), namespace(&long_b, "com"));
        assert_eq!(key.len(), 75);
        assert!(!key.contains("example"));
        assert_ne!(namespace("@.+-!", "com"), namespace("", "com"));
    }
}