codetether_agent/server/auth/state/auth_state.rs
1use super::{default_public_paths, load_token};
2use std::{collections::HashSet, sync::Arc};
3
4/// Shared authentication state for the HTTP server.
5///
6/// # Examples
7///
8/// ```rust
9/// use codetether_agent::server::auth::AuthState;
10///
11/// let state = AuthState::with_token("example-token");
12///
13/// assert_eq!(state.token(), "example-token");
14/// assert!(state.is_public_path("/health"));
15/// ```
16#[derive(Debug, Clone)]
17pub struct AuthState {
18 token: Arc<String>,
19 public_paths: Arc<HashSet<String>>,
20}
21
22impl AuthState {
23 /// Build auth state from environment variables.
24 ///
25 /// # Examples
26 ///
27 /// ```rust
28 /// use codetether_agent::server::auth::AuthState;
29 ///
30 /// # unsafe {
31 /// std::env::set_var("CODETETHER_AUTH_TOKEN", "example-token");
32 /// # }
33 /// let state = AuthState::from_env();
34 ///
35 /// assert_eq!(state.token(), "example-token");
36 /// ```
37 pub fn from_env() -> Self {
38 let token = load_token();
39 Self {
40 token: Arc::new(token),
41 public_paths: Arc::new(default_public_paths()),
42 }
43 }
44
45 /// Build auth state with an explicit token.
46 ///
47 /// # Examples
48 ///
49 /// ```rust
50 /// use codetether_agent::server::auth::AuthState;
51 ///
52 /// let state = AuthState::with_token("example-token");
53 /// assert_eq!(state.token(), "example-token");
54 /// ```
55 pub fn with_token(token: impl Into<String>) -> Self {
56 Self {
57 token: Arc::new(token.into()),
58 public_paths: Arc::new(default_public_paths()),
59 }
60 }
61
62 /// Return the active bearer token.
63 ///
64 /// # Examples
65 ///
66 /// ```rust
67 /// use codetether_agent::server::auth::AuthState;
68 ///
69 /// # unsafe {
70 /// std::env::set_var("CODETETHER_AUTH_TOKEN", "example-token");
71 /// # }
72 /// let state = AuthState::from_env();
73 ///
74 /// assert_eq!(state.token(), "example-token");
75 /// ```
76 pub fn token(&self) -> &str {
77 &self.token
78 }
79
80 /// Return whether a request path is exempt from authentication.
81 ///
82 /// # Examples
83 ///
84 /// ```rust
85 /// use codetether_agent::server::auth::AuthState;
86 ///
87 /// let state = AuthState::with_token("example-token");
88 ///
89 /// assert!(state.is_public_path("/health"));
90 /// assert!(!state.is_public_path("/secure"));
91 /// ```
92 pub fn is_public_path(&self, path: &str) -> bool {
93 self.public_paths.contains(path)
94 }
95}