use anyhow::Result;
use super::{Config, Key, prelude::*};
const FINGERPRINT_MIN_LEN: usize = 8;
pub fn format_fingerprint<S: AsRef<str>>(fingerprint: S) -> String {
normalize_fingerprint(fingerprint)
}
pub fn normalize_fingerprint<S: AsRef<str>>(fingerprint: S) -> String {
let fp = fingerprint.as_ref().trim_start();
let fp = if fp.starts_with("0x") || fp.starts_with("0X") {
&fp[2..]
} else {
fp
};
let fp = fp.split('#').next().unwrap();
fp.trim_end().to_uppercase()
}
pub fn fingerprints_equal<S: AsRef<str>, T: AsRef<str>>(a: S, b: T) -> bool {
let a = normalize_fingerprint(a);
let b = normalize_fingerprint(b);
if a.len() < FINGERPRINT_MIN_LEN || b.len() < FINGERPRINT_MIN_LEN {
return false;
}
a.contains(&b)
}
pub fn keys_contain_fingerprint<S: AsRef<str>>(keys: &[Key], fingerprint: S) -> bool {
keys.iter()
.any(|key| fingerprints_equal(key.fingerprint(false), fingerprint.as_ref()))
}
pub fn has_private_key(config: &Config) -> Result<bool> {
Ok(!super::context(config)?.keys_private()?.is_empty())
}
#[cfg(test)]
mod tests {
#[rustfmt::skip]
const FPS_NORMALIZE: &[(&str, &str)] = &[
("E2D8DE4D35CE386F", "E2D8DE4D35CE386F"),
("364119B9", "364119B9" ),
("0xae78a4de7A738B54 ", "AE78A4DE7A738B54"),
("0xB079912385023787 # username <user@example.com>", "B079912385023787"),
(" 0X47e3b6f9970b175f # some comment # something else ", "47E3B6F9970B175F"),
];
#[rustfmt::skip]
const FPS_EQUAL: &[(&str, &str)] = &[
("AAAAAAAA", "AAAAAAAA"),
("e2d8de4d35CE386f", "E2D8DE4d35CE386f"),
("0x364119B9", "0X364119B9"),
("364119B9", "0x364119B9"),
("364119B9 # comment 1", "364119B9 # comment 2"),
("AE78A4DE7A738B54", "7A738B54"),
("AE78A4DE7A738B54", "AE78A4DE"),
(" 0xAE78A4DE7A738B54 # username <user@example.com>", "a4de7a73"),
];
#[rustfmt::skip]
const FPS_NOT_EQUAL: &[(&str, &str)] = &[
("", ""),
("AAAAAAA", "AAAAAAA"),
("AAAAAAAA", "AAAAAAA"),
("AAAAAAA", "AAAAAAAA"),
("364119B9", "0364119B9"),
("0xae78a4de7A738B54", "AE78A4DE7A738B540"),
];
#[test]
fn test_normalize_fingerprint() {
for &(a, b) in FPS_NORMALIZE {
assert_eq!(
super::normalize_fingerprint(a),
b,
"{a:?} should normalize to {b:?}"
);
}
}
#[test]
fn test_fingerprints_equal() {
for &(a, b) in FPS_NORMALIZE {
assert!(
super::fingerprints_equal(a, b),
"{a:?} and {b:?} should be equal",
);
}
for &(a, b) in FPS_EQUAL {
assert!(
super::fingerprints_equal(a, b),
"{a:?} and {b:?} should be equal",
);
}
for &(a, b) in FPS_NOT_EQUAL {
assert!(
!super::fingerprints_equal(a, b),
"{a:?} and {b:?} should not be equal",
);
}
}
}