rs_firebase_admin_sdk/
lib.rs

1pub mod api_uri;
2pub mod auth;
3pub mod client;
4pub mod credentials;
5pub mod util;
6
7use auth::FirebaseAuth;
8
9#[cfg(feature = "tokens")]
10use auth::token::{
11    cache::{HttpCache, PubKeys},
12    error::TokenVerificationError,
13    EmulatedTokenVerifier, LiveTokenVerifier, GOOGLE_COOKIE_PUB_KEY_URI, GOOGLE_PUB_KEY_URI,
14};
15use client::ReqwestApiClient;
16use credentials::emulator::EmulatorCredentials;
17pub use credentials::{error::CredentialsError, Credentials};
18use error_stack::{Report, ResultExt};
19pub use gcp_auth::provider as credentials_provider;
20use gcp_auth::TokenProvider;
21use std::sync::Arc;
22
23/// Default Firebase Auth admin manager
24pub type GcpCredentials = Arc<dyn TokenProvider>;
25pub type LiveAuthAdmin = FirebaseAuth<ReqwestApiClient<GcpCredentials>>;
26/// Default Firebase Auth Emulator admin manager
27pub type EmulatorAuthAdmin = FirebaseAuth<ReqwestApiClient<EmulatorCredentials>>;
28
29/// Base privileged manager for Firebase
30pub struct App<CredentialsT> {
31    credentials: CredentialsT,
32    project_id: String,
33}
34
35impl App<EmulatorCredentials> {
36    /// Firebase app backend by emulator
37    pub fn emulated(project_id: String) -> Self {
38        Self {
39            credentials: EmulatorCredentials::default(),
40            project_id,
41        }
42    }
43
44    /// Firebase authentication manager for emulator
45    pub fn auth(&self, emulator_url: String) -> EmulatorAuthAdmin {
46        let client = ReqwestApiClient::new(reqwest::Client::new(), self.credentials.clone());
47
48        FirebaseAuth::emulated(emulator_url, &self.project_id, client)
49    }
50
51    /// OIDC token verifier for emulator
52    #[cfg(feature = "tokens")]
53    pub fn id_token_verifier(&self) -> EmulatedTokenVerifier {
54        EmulatedTokenVerifier::new(self.project_id.clone())
55    }
56}
57
58impl App<GcpCredentials> {
59    /// Create instance of Firebase app for live project
60    pub async fn live(credentials: GcpCredentials) -> Result<Self, Report<CredentialsError>> {
61        Self::live_shared(credentials).await
62    }
63
64    pub async fn live_shared(
65        credentials: GcpCredentials,
66    ) -> Result<Self, Report<CredentialsError>> {
67        let project_id = credentials
68            .project_id()
69            .await
70            .change_context(CredentialsError::Internal)?
71            .to_string();
72
73        Ok(Self {
74            credentials,
75            project_id,
76        })
77    }
78
79    /// Create Firebase authentication manager
80    pub fn auth(&self) -> LiveAuthAdmin {
81        let client = ReqwestApiClient::new(reqwest::Client::new(), self.credentials.clone());
82
83        FirebaseAuth::live(&self.project_id, client)
84    }
85
86    /// Create OIDC token verifier
87    #[cfg(feature = "tokens")]
88    pub async fn id_token_verifier(
89        &self,
90    ) -> Result<
91        LiveTokenVerifier<HttpCache<reqwest::Client, PubKeys>>,
92        Report<TokenVerificationError>,
93    > {
94        let cache_client = HttpCache::new(
95            reqwest::Client::new(),
96            GOOGLE_PUB_KEY_URI
97                .parse()
98                .map_err(error_stack::Report::new)
99                .change_context(TokenVerificationError::FailedGettingKeys)?,
100        )
101        .await
102        .change_context(TokenVerificationError::FailedGettingKeys)?;
103
104        LiveTokenVerifier::new_id_verifier(self.project_id.clone(), cache_client)
105    }
106
107    /// Create cookie token verifier
108    #[cfg(feature = "tokens")]
109    pub async fn cookie_token_verifier(
110        &self,
111    ) -> Result<
112        LiveTokenVerifier<HttpCache<reqwest::Client, PubKeys>>,
113        Report<TokenVerificationError>,
114    > {
115        let cache_client = HttpCache::new(
116            reqwest::Client::new(),
117            GOOGLE_COOKIE_PUB_KEY_URI
118                .parse()
119                .map_err(error_stack::Report::new)
120                .change_context(TokenVerificationError::FailedGettingKeys)?,
121        )
122        .await
123        .change_context(TokenVerificationError::FailedGettingKeys)?;
124
125        LiveTokenVerifier::new_cookie_verifier(self.project_id.clone(), cache_client)
126    }
127}