agp_config/auth/
bearer.rs1use serde::Deserialize;
5use tower_http::auth::{AddAuthorizationLayer, require_authorization::Bearer};
6use tower_http::validate_request::ValidateRequestHeaderLayer;
7
8use super::{AuthError, ClientAuthenticator, ServerAuthenticator};
9use crate::opaque::OpaqueString;
10
11#[derive(Debug, Deserialize, Clone, PartialEq)]
12pub struct Config {
13 token: OpaqueString,
14}
15
16impl Default for Config {
17 fn default() -> Self {
18 Config {
19 token: OpaqueString::new("token"),
20 }
21 }
22}
23
24impl Config {
25 pub fn new(token: &str) -> Self {
27 Config {
28 token: OpaqueString::new(token),
29 }
30 }
31
32 pub fn token(&self) -> &OpaqueString {
34 &self.token
35 }
36}
37
38impl ClientAuthenticator for Config {
39 type ClientLayer = AddAuthorizationLayer;
41
42 fn get_client_layer(&self) -> Result<Self::ClientLayer, AuthError> {
43 match self.token().as_ref() {
44 "" => Err(AuthError::ConfigError("token is empty".to_string())),
45 _ => Ok(AddAuthorizationLayer::bearer(self.token())),
46 }
47 }
48}
49
50impl<Response> ServerAuthenticator<Response> for Config
51where
52 Response: Default,
53{
54 type ServerLayer = ValidateRequestHeaderLayer<Bearer<Response>>;
56
57 fn get_server_layer(&self) -> Result<Self::ServerLayer, AuthError> {
58 Ok(ValidateRequestHeaderLayer::bearer(self.token()))
59 }
60}
61
62#[cfg(test)]
64mod tests {
65 use tower::ServiceBuilder;
66 use tower_reqwest::HttpClientLayer;
67
68 use super::*;
69
70 #[test]
71 fn test_config() {
72 let token = OpaqueString::new("token");
73 let config = Config::new(&token);
74
75 assert_eq!(config.token(), &token);
76 }
77
78 #[tokio::test]
79 async fn test_authenticator() {
80 let token = OpaqueString::new("token");
81 let config = Config::new(&token);
82
83 let client_layer = config.get_client_layer().unwrap();
84 let server_layer: ValidateRequestHeaderLayer<Bearer<String>> =
85 config.get_server_layer().unwrap();
86
87 let _ = ServiceBuilder::new().layer(server_layer);
89
90 let _ = ServiceBuilder::new()
91 .layer(HttpClientLayer)
92 .layer(client_layer);
93 }
94}