micromegas/servers/
key_ring.rs

1use anyhow::Result;
2use micromegas_tracing::prelude::*;
3use serde::Deserialize;
4use std::{collections::HashMap, fmt::Display};
5
6/// Represents a key in the keyring.
7#[derive(Hash, Eq, PartialEq)]
8pub struct Key {
9    pub value: String,
10}
11
12impl Key {
13    /// Creates a new `Key` from a string value.
14    pub fn new(value: String) -> Self {
15        Self { value }
16    }
17}
18
19impl From<String> for Key {
20    fn from(value: String) -> Self {
21        Self { value }
22    }
23}
24
25impl Display for Key {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        write!(f, "<sensitive key>")
28    }
29}
30
31/// Deserializes a string into a `Key`.
32///
33/// This function is used by `serde` to deserialize the key from a JSON string.
34pub fn key_from_string<'de, D>(deserializer: D) -> Result<Key, D::Error>
35where
36    D: serde::Deserializer<'de>,
37{
38    let s: String = Deserialize::deserialize(deserializer)?;
39    Ok(Key::new(s))
40}
41
42/// Represents an entry in the keyring, mapping a key to a name.
43#[derive(Deserialize)]
44pub struct KeyRingEntry {
45    pub name: String,
46    #[serde(deserialize_with = "key_from_string")]
47    pub key: Key,
48}
49
50/// A map from `Key` to `String` (name).
51pub type KeyRing = HashMap<Key, String>; // key -> name
52
53/// Parses a JSON string into a `KeyRing`.
54///
55/// The JSON string is expected to be an array of objects, each with a `name` and `key` field.
56pub fn parse_key_ring(json: &str) -> Result<KeyRing> {
57    let entries: Vec<KeyRingEntry> = serde_json::from_str(json)?;
58    let mut ring = KeyRing::new();
59    for entry in entries {
60        ring.insert(entry.key, entry.name);
61    }
62    info!("loaded keys: {:?}", ring.values());
63    Ok(ring)
64}