1use std::sync::Arc;
2
3use bitwarden_auth::token_management::PasswordManagerTokenHandler;
4use bitwarden_core::{ClientBuilder, client::tracing_middleware::ReqwestTracingMiddleware};
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 mut builder = ClientBuilder::new()
43 .with_token_handler(Arc::new(PasswordManagerTokenHandler::default()));
44 if let Some(s) = self.settings {
45 builder = builder.with_settings(s);
46 }
47 let mut middleware: Vec<Arc<dyn reqwest_middleware::Middleware>> =
48 vec![Arc::new(ReqwestTracingMiddleware)];
49
50 if let Some(cookie_provider) = self.cookie_provider {
51 middleware.push(Arc::new(
52 bitwarden_server_communication_config::ServerCommunicationConfigMiddleware::new(
53 cookie_provider,
54 ),
55 ));
56 }
57
58 builder = builder.with_middleware(middleware);
59 PasswordManagerClient(builder.build())
60 }
61}
62
63impl Default for PasswordManagerClientBuilder {
64 fn default() -> Self {
65 Self::new()
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_pm_builder_default_builds() {
75 let _client = PasswordManagerClientBuilder::new().build();
76 }
77
78 #[test]
79 fn test_pm_builder_with_settings_builds() {
80 let settings = bitwarden_core::ClientSettings::default();
81 let _client = PasswordManagerClientBuilder::new()
82 .with_settings(settings)
83 .build();
84 }
85
86 #[test]
87 fn test_pm_builder_with_server_communication_config_builds() {
88 struct MockCookieProvider;
89
90 #[async_trait::async_trait]
91 impl bitwarden_server_communication_config::CookieProvider for MockCookieProvider {
92 async fn cookies(&self, _hostname: &str) -> Vec<(String, String)> {
93 vec![]
94 }
95
96 async fn acquire_cookie(
97 &self,
98 _hostname: &str,
99 ) -> Result<(), bitwarden_server_communication_config::AcquireCookieError> {
100 Ok(())
101 }
102
103 async fn needs_bootstrap(&self, _hostname: &str) -> bool {
104 false
105 }
106 }
107
108 let _client = PasswordManagerClientBuilder::new()
109 .with_server_communication_config(Arc::new(MockCookieProvider))
110 .build();
111 }
112}