arcp_runtime/auth/
bearer.rs1use std::collections::HashMap;
4
5use async_trait::async_trait;
6
7use arcp_core::auth::{AuthOutcome, Authenticator};
8use arcp_core::error::ARCPError;
9use arcp_core::messages::{AuthScheme, Capabilities, ClientIdentity, Credentials};
10
11#[derive(Debug, Default)]
17pub struct BearerAuthenticator {
18 tokens: HashMap<String, String>,
19}
20
21impl BearerAuthenticator {
22 #[must_use]
24 pub fn new() -> Self {
25 Self::default()
26 }
27
28 #[must_use]
30 pub fn with_token(mut self, token: impl Into<String>, principal: impl Into<String>) -> Self {
31 self.tokens.insert(token.into(), principal.into());
32 self
33 }
34}
35
36#[async_trait]
37impl Authenticator for BearerAuthenticator {
38 fn scheme(&self) -> AuthScheme {
39 AuthScheme::Bearer
40 }
41
42 async fn authenticate(
43 &self,
44 creds: &Credentials,
45 _client: &ClientIdentity,
46 _negotiated: &Capabilities,
47 ) -> Result<AuthOutcome, ARCPError> {
48 let Some(token) = &creds.token else {
49 return Ok(AuthOutcome::Reject {
50 reason: "bearer scheme requires a token".into(),
51 });
52 };
53 Ok(self.tokens.get(token).map_or_else(
54 || AuthOutcome::Reject {
55 reason: "unknown bearer token".into(),
56 },
57 |principal| AuthOutcome::Accept {
58 principal: principal.clone(),
59 },
60 ))
61 }
62}