tako_rs_extractors/cookie_signed/
key.rs1use cookie::Key;
2
3#[derive(Clone)]
10pub struct KeyRing {
11 pub(crate) active_kid: String,
12 pub(crate) active: Key,
13 pub(crate) previous: Vec<(String, Key)>,
14}
15
16impl KeyRing {
17 pub fn new(active_kid: impl Into<String>, active: Key) -> Self {
19 Self {
20 active_kid: active_kid.into(),
21 active,
22 previous: Vec::new(),
23 }
24 }
25
26 pub fn with_previous(mut self, kid: impl Into<String>, key: Key) -> Self {
29 self.previous.push((kid.into(), key));
30 self
31 }
32
33 pub fn revoke(&mut self, kid: &str) -> bool {
37 let before = self.previous.len();
38 self.previous.retain(|(k, _)| k != kid);
39 before != self.previous.len()
40 }
41
42 pub fn previous_kids(&self) -> impl Iterator<Item = &str> {
46 self.previous.iter().map(|(k, _)| k.as_str())
47 }
48
49 pub fn active(&self) -> &Key {
51 &self.active
52 }
53
54 pub fn active_kid(&self) -> &str {
56 &self.active_kid
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn keyring_revoke_removes_previous_key() {
66 let active = Key::generate();
67 let old = Key::generate();
68 let older = Key::generate();
69 let mut ring = KeyRing::new("v3", active)
70 .with_previous("v2", old)
71 .with_previous("v1", older);
72
73 assert_eq!(ring.previous_kids().collect::<Vec<_>>(), vec!["v2", "v1"]);
74
75 assert!(ring.revoke("v2"));
76 assert_eq!(ring.previous_kids().collect::<Vec<_>>(), vec!["v1"]);
77
78 assert!(!ring.revoke("v99"));
80
81 assert!(ring.revoke("v1"));
82 assert_eq!(ring.previous_kids().count(), 0);
83 }
84}