1use std::sync::Arc;
2
3use bitwarden_auth::token_management::PasswordManagerTokenHandler;
4use bitwarden_core::ClientBuilder;
5
6use crate::PasswordManagerClient;
7
8pub struct PasswordManagerClientBuilder {
10 settings: Option<bitwarden_core::ClientSettings>,
11 cookie_provider:
12 Option<std::sync::Arc<dyn bitwarden_server_communication_config::CookieProvider>>,
13}
14
15impl PasswordManagerClientBuilder {
16 pub fn new() -> Self {
18 Self {
19 settings: None,
20 cookie_provider: None,
21 }
22 }
23
24 pub fn with_settings(mut self, settings: bitwarden_core::ClientSettings) -> Self {
26 self.settings = Some(settings);
27 self
28 }
29
30 pub fn with_server_communication_config(
33 mut self,
34 cookie_provider: std::sync::Arc<dyn bitwarden_server_communication_config::CookieProvider>,
35 ) -> Self {
36 self.cookie_provider = Some(cookie_provider);
37 self
38 }
39
40 pub fn build(self) -> PasswordManagerClient {
42 let token_handler = Arc::new(PasswordManagerTokenHandler::default());
43 let mut builder = ClientBuilder::new().with_token_handler(token_handler);
44 if let Some(s) = self.settings {
45 builder = builder.with_settings(s);
46 }
47 if let Some(cookie_provider) = self.cookie_provider {
48 let cookie_middleware: Arc<dyn reqwest_middleware::Middleware> = Arc::new(
49 bitwarden_server_communication_config::ServerCommunicationConfigMiddleware::new(
50 cookie_provider,
51 ),
52 );
53 builder = builder.with_middleware(vec![cookie_middleware]);
54 }
55 PasswordManagerClient(builder.build())
56 }
57}
58
59impl Default for PasswordManagerClientBuilder {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn test_pm_builder_default_builds() {
71 let _client = PasswordManagerClientBuilder::new().build();
72 }
73
74 #[test]
75 fn test_pm_builder_with_settings_builds() {
76 let settings = bitwarden_core::ClientSettings::default();
77 let _client = PasswordManagerClientBuilder::new()
78 .with_settings(settings)
79 .build();
80 }
81
82 #[test]
83 fn test_pm_builder_with_server_communication_config_builds() {
84 struct MockCookieProvider;
85
86 #[async_trait::async_trait]
87 impl bitwarden_server_communication_config::CookieProvider for MockCookieProvider {
88 async fn cookies(&self, _hostname: &str) -> Vec<(String, String)> {
89 vec![]
90 }
91
92 async fn acquire_cookie(
93 &self,
94 _hostname: &str,
95 ) -> Result<(), bitwarden_server_communication_config::AcquireCookieError> {
96 Ok(())
97 }
98
99 async fn needs_bootstrap(&self, _hostname: &str) -> bool {
100 false
101 }
102 }
103
104 let _client = PasswordManagerClientBuilder::new()
105 .with_server_communication_config(Arc::new(MockCookieProvider))
106 .build();
107 }
108}