firebase_rs_sdk/auth/
token_provider.rs1use std::sync::atomic::{AtomicBool, Ordering};
2use std::sync::Arc;
3
4use crate::auth::error::AuthError;
5use crate::auth::Auth;
6use crate::firestore::error::{
7 internal_error, unauthenticated, unavailable, FirestoreError, FirestoreResult,
8};
9use crate::firestore::remote::datastore::{TokenProvider, TokenProviderArc};
10
11pub struct AuthTokenProvider {
12 auth: Arc<Auth>,
13 force_refresh: AtomicBool,
14}
15
16impl AuthTokenProvider {
17 pub fn new(auth: Arc<Auth>) -> Self {
19 Self {
20 auth,
21 force_refresh: AtomicBool::new(false),
22 }
23 }
24
25 pub fn into_arc(self) -> TokenProviderArc {
27 Arc::new(self)
28 }
29}
30
31impl Clone for AuthTokenProvider {
32 fn clone(&self) -> Self {
33 Self {
34 auth: self.auth.clone(),
35 force_refresh: AtomicBool::new(self.force_refresh.load(Ordering::SeqCst)),
36 }
37 }
38}
39
40impl TokenProvider for AuthTokenProvider {
41 fn get_token(&self) -> FirestoreResult<Option<String>> {
42 let force_refresh = self.force_refresh.swap(false, Ordering::SeqCst);
43 self.auth.get_token(force_refresh).map_err(map_auth_error)
44 }
45
46 fn invalidate_token(&self) {
47 self.force_refresh.store(true, Ordering::SeqCst);
48 }
49}
50
51fn map_auth_error(error: AuthError) -> FirestoreError {
52 match error {
53 AuthError::InvalidCredential(message) => unauthenticated(message),
54 AuthError::Network(message) => unavailable(message),
55 AuthError::Firebase(firebase_error) => unauthenticated(firebase_error.message),
56 AuthError::App(app_error) => internal_error(app_error.to_string()),
57 AuthError::NotImplemented(feature) => {
58 internal_error(format!("{feature} is not implemented"))
59 }
60 }
61}
62
63pub fn auth_token_provider_arc(auth: Arc<Auth>) -> TokenProviderArc {
65 AuthTokenProvider::new(auth).into_arc()
66}