ndn_cert/challenge/
token.rs1use std::{future::Future, pin::Pin, sync::Arc};
9
10use dashmap::DashMap;
11
12use crate::{
13 challenge::{ChallengeHandler, ChallengeOutcome, ChallengeState},
14 error::CertError,
15 protocol::CertRequest,
16};
17
18#[derive(Default, Clone)]
20pub struct TokenStore {
21 tokens: Arc<DashMap<String, ()>>,
22}
23
24impl TokenStore {
25 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn add(&self, token: impl Into<String>) {
31 self.tokens.insert(token.into(), ());
32 }
33
34 pub fn add_many(&self, tokens: impl IntoIterator<Item = impl Into<String>>) {
36 for t in tokens {
37 self.add(t);
38 }
39 }
40
41 pub fn consume(&self, token: &str) -> bool {
43 self.tokens.remove(token).is_some()
44 }
45
46 pub fn len(&self) -> usize {
48 self.tokens.len()
49 }
50
51 pub fn is_empty(&self) -> bool {
52 self.tokens.is_empty()
53 }
54}
55
56pub struct TokenChallenge {
58 store: TokenStore,
59}
60
61impl TokenChallenge {
62 pub fn new(store: TokenStore) -> Self {
63 Self { store }
64 }
65}
66
67impl ChallengeHandler for TokenChallenge {
68 fn challenge_type(&self) -> &'static str {
69 "token"
70 }
71
72 fn begin<'a>(
73 &'a self,
74 _req: &'a CertRequest,
75 ) -> Pin<Box<dyn Future<Output = Result<ChallengeState, CertError>> + Send + 'a>> {
76 Box::pin(async move {
77 Ok(ChallengeState {
78 challenge_type: "token".to_string(),
79 data: serde_json::Value::Null,
80 })
81 })
82 }
83
84 fn verify<'a>(
85 &'a self,
86 _state: &'a ChallengeState,
87 parameters: &'a serde_json::Map<String, serde_json::Value>,
88 ) -> Pin<Box<dyn Future<Output = Result<ChallengeOutcome, CertError>> + Send + 'a>> {
89 let token = parameters
90 .get("token")
91 .and_then(|v| v.as_str())
92 .map(str::to_string);
93 Box::pin(async move {
94 match token {
95 None => Ok(ChallengeOutcome::Denied(
96 "missing 'token' parameter".to_string(),
97 )),
98 Some(t) => {
99 if self.store.consume(&t) {
100 Ok(ChallengeOutcome::Approved)
101 } else {
102 Ok(ChallengeOutcome::Denied(
103 "invalid or expired token".to_string(),
104 ))
105 }
106 }
107 }
108 })
109 }
110}