passage_auth/
config.rs

1use reqwest::header::HeaderMap;
2
3/// Default v1 Passage Auth API base
4pub const PASSAGE_AUTH_API_BASE: &str = "https://auth.passage.id/v1";
5
6#[derive(Clone, Debug)]
7pub struct Config {
8    api_base: String,
9    api_key: Option<String>,
10    app_id: String,
11    app_auth_origin: String,
12    // TODO: We should probably store the key instead of a string for earlier
13    // validation and performance
14    pub_jwk: Option<String>,
15    user_bearer_token: Option<String>,
16}
17
18impl Default for Config {
19    fn default() -> Self {
20        Self {
21            api_base: PASSAGE_AUTH_API_BASE.into(),
22            // TODO: We could load this from passage using the app_id
23            app_auth_origin: std::env::var("PASSAGE_APP_AUTH_ORIGIN")
24                .unwrap_or_else(|_| "".to_string()),
25            api_key: std::env::var("PASSAGE_API_KEY").ok(),
26            // TODO: Maybe make this required
27            app_id: std::env::var("PASSAGE_APP_ID").unwrap_or_else(|_| "".to_string()),
28            // TODO: We could load this from passage using the app_id
29            pub_jwk: std::env::var("PASSAGE_PUB_JWK").ok(),
30            user_bearer_token: None,
31        }
32    }
33}
34
35impl Config {
36    pub fn new() -> Self {
37        Default::default()
38    }
39
40    pub fn with_api_base(mut self, api_base: String) -> Self {
41        self.api_base = api_base;
42        self
43    }
44
45    pub fn with_api_key(mut self, api_key: String) -> Self {
46        if api_key.is_empty() {
47            return self;
48        }
49        self.api_key = Some(api_key);
50        self
51    }
52
53    pub fn with_app_id(mut self, app_id: String) -> Self {
54        self.app_id = app_id;
55        self
56    }
57
58    pub fn with_app_auth_origin(mut self, auth_origin: String) -> Self {
59        self.app_auth_origin = auth_origin;
60        self
61    }
62
63    pub fn with_pub_jwk(mut self, pub_jwk: String) -> Self {
64        if pub_jwk.is_empty() {
65            return self;
66        }
67        self.pub_jwk = Some(pub_jwk);
68        self
69    }
70
71    pub fn with_user_bearer_token(mut self, user_bearer_token: String) -> Self {
72        self.user_bearer_token = Some(user_bearer_token);
73        self
74    }
75
76    pub fn pub_jwk(&self) -> Option<&String> {
77        self.pub_jwk.as_ref()
78    }
79
80    pub fn url(&self, path: &str) -> String {
81        format!(
82            "{}{}",
83            self.api_base,
84            path.replace("{app_id}", &self.app_id)
85        )
86    }
87
88    pub fn query(&self) -> Vec<(&str, &str)> {
89        vec![]
90    }
91
92    /// TODO: Can probably just return a token and the http client can handle
93    /// the header
94    pub fn bearer_auth(&self) -> HeaderMap {
95        let mut headers = HeaderMap::new();
96        if let Some(token) = &self.user_bearer_token {
97            headers.insert(
98                "Authorization",
99                format!("Bearer {}", token).parse().unwrap(),
100            );
101        }
102        headers
103    }
104
105    /// TODO: Remove once we have `passage-manage` crate
106    pub fn api_key_auth(&self) -> HeaderMap {
107        let mut headers = HeaderMap::new();
108        if let Some(api_key) = &self.api_key {
109            headers.insert(
110                "Authorization",
111                format!("Bearer {}", api_key).parse().unwrap(),
112            );
113        }
114        headers
115    }
116
117    pub fn app_auth_origin(&self) -> &str {
118        &self.app_auth_origin
119    }
120
121    pub fn app_id(&self) -> &str {
122        &self.app_id
123    }
124}