1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use toboggan_kv::{Toboggan, Tree};

use crate::{keys::private::AgentKey, AgentId, Error};

pub struct KeyManager<S: Toboggan> {
    _store: S,
    agent_keys: S::Tree,
    agent_id_config: S::Tree,
}

impl<S> KeyManager<S>
where
    S: Toboggan,
{
    pub fn new(store: S) -> Result<Self, Error> {
        Ok(Self {
            agent_keys: store.open_tree("agent_keys")?,
            agent_id_config: store.open_tree("agent_id_config")?,
            _store: store,
        })
    }
    pub fn list_agents(&self) -> Result<Vec<AgentId>, Error> {
        Ok(self
            .agent_keys
            .iter()
            .map(|kv| {
                let kv = kv.unwrap();
                let agentkey: AgentKey = bincode::deserialize(&kv.1).unwrap();
                AgentId {
                    pubkey: agentkey.pubkey(),
                }
            })
            .collect())
    }
    pub fn get_agent_key(&self, agent_id: &AgentId) -> Result<Option<AgentKey>, Error> {
        match self.agent_keys.get(&agent_id.pubkey)? {
            Some(ivec) => {
                let agentkey: AgentKey = bincode::deserialize(&ivec)?;
                Ok(Some(agentkey))
            }
            None => Ok(None),
        }
    }
    pub fn put_agent_key(&self, agentkey: AgentKey) -> Result<(), Error> {
        let key_ser: Vec<u8> = bincode::serialize(&agentkey).unwrap();

        let agent_id = agentkey.id();
        self.agent_keys.insert(&agent_id.pubkey[..], key_ser)?;
        self.agent_keys.flush()?;

        Ok(())
    }
    pub fn remove_all_agent_keys(&self) -> Result<(), Error> {
        self.agent_keys.clear()?;
        Ok(())
    }

    pub fn set_current_agent(&self, id: AgentId) -> Result<(), Error> {
        let id_ser: Vec<u8> = bincode::serialize(&id).unwrap();
        self.agent_id_config.insert("current", id_ser)?;
        Ok(())
    }
    pub fn current_agent_key(&self) -> Result<Option<AgentKey>, Error> {
        match self.agent_id_config.get("current")? {
            Some(value) => {
                let id: AgentId = bincode::deserialize(&value[..])?;

                match self.get_agent_key(&id)? {
                    Some(a) => Ok(Some(a)),
                    None => Err(Error::InvalidReferent),
                }
            }
            None => Ok(None),
        }
    }
}

impl<T> Default for KeyManager<T>
where
    T: Toboggan + Default,
{
    fn default() -> Self {
        KeyManager::new(Default::default())
            .expect("should not fail for store which implements default")
    }
}

#[cfg(test)]
mod test {
    use toboggan_kv::adapter::BTreeAdapter;

    use crate::{AgentKey, KeyManager};

    #[test]
    fn init() -> Result<(), std::io::Error> {
        let keymanager = KeyManager::new(BTreeAdapter::new())?;

        let agentkey = AgentKey::create(None);
        let id = agentkey.id();
        keymanager.put_agent_key(agentkey)?;
        keymanager.set_current_agent(id.clone())?;

        assert_eq!(
            keymanager
                .current_agent_key()
                .expect("is good")
                .expect("is some")
                .id(),
            id
        );

        Ok(())
    }
}