Skip to main content

bitwarden_core/global/
global_client.rs

1use std::sync::Arc;
2
3use crate::{
4    client::{build_default_headers, new_http_client_builder},
5    global::GlobalInternalClient,
6};
7
8/// The entry point for unauthenticated SDK operations.
9///
10/// `GlobalClient` internally contains an [`Arc`] so is cheap to clone.
11///
12/// Headers are sourced from the process-wide
13/// [`crate::HostPlatformInfo`] singleton, which must be initialized via
14/// [`crate::init_host_platform_info`] before constructing a `GlobalClient`.
15#[derive(Clone)]
16pub struct GlobalClient {
17    internal: Arc<GlobalInternalClient>,
18}
19
20impl GlobalClient {
21    /// Build a `GlobalClient` using the process-wide
22    /// [`crate::HostPlatformInfo`].
23    ///
24    /// # Panics
25    /// Panics if [`crate::init_host_platform_info`] has not been called.
26    pub fn new() -> Self {
27        let info = crate::client::get_host_platform_info();
28        let http_client = new_http_client_builder()
29            .default_headers(build_default_headers(info))
30            .build()
31            .expect("Global HTTP Client build should not fail")
32            .into();
33        Self {
34            internal: Arc::new(GlobalInternalClient { http_client }),
35        }
36    }
37
38    /// Build an API client targeting `base_url`.
39    pub fn make_api_client(&self, base_url: String) -> bitwarden_api_api::apis::ApiClient {
40        self.internal.make_api_client(base_url)
41    }
42
43    /// Build an identity client targeting `base_url`.
44    pub fn make_identity_client(
45        &self,
46        base_url: String,
47    ) -> bitwarden_api_identity::apis::ApiClient {
48        self.internal.make_identity_client(base_url)
49    }
50}
51
52impl Default for GlobalClient {
53    fn default() -> Self {
54        Self::new()
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use reqwest_middleware::ClientBuilder;
61
62    use super::*;
63
64    fn dummy_client() -> GlobalClient {
65        GlobalClient {
66            internal: Arc::new(GlobalInternalClient {
67                http_client: ClientBuilder::new(reqwest::Client::new()).build(),
68            }),
69        }
70    }
71
72    #[test]
73    fn clone_shares_internal_state() {
74        let original = dummy_client();
75        let cloned = original.clone();
76        assert!(Arc::ptr_eq(&original.internal, &cloned.internal));
77    }
78}