firebase_rs_sdk/auth/oauth/
redirect.rs1use std::sync::{Arc, Mutex};
2
3use serde::{Deserialize, Serialize};
4
5use crate::auth::error::AuthResult;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8pub struct PendingRedirectEvent {
9 pub provider_id: String,
10 pub operation: RedirectOperation,
11 pub pkce_verifier: Option<String>,
12}
13
14#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
15pub enum RedirectOperation {
16 SignIn,
17 Link,
18}
19
20pub trait RedirectPersistence: Send + Sync {
21 fn set(&self, event: Option<PendingRedirectEvent>) -> AuthResult<()>;
22 fn get(&self) -> AuthResult<Option<PendingRedirectEvent>>;
23}
24
25#[derive(Default, Debug)]
26pub struct InMemoryRedirectPersistence {
27 inner: Mutex<Option<PendingRedirectEvent>>,
28}
29
30impl RedirectPersistence for InMemoryRedirectPersistence {
31 fn set(&self, event: Option<PendingRedirectEvent>) -> AuthResult<()> {
32 *self.inner.lock().unwrap() = event;
33 Ok(())
34 }
35
36 fn get(&self) -> AuthResult<Option<PendingRedirectEvent>> {
37 Ok(self.inner.lock().unwrap().clone())
38 }
39}
40
41impl InMemoryRedirectPersistence {
42 pub fn shared() -> Arc<Self> {
44 Arc::new(Self::default())
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn in_memory_persistence_round_trip() {
54 let persistence = InMemoryRedirectPersistence::shared();
55 let event = PendingRedirectEvent {
56 provider_id: "google.com".into(),
57 operation: RedirectOperation::Link,
58 pkce_verifier: None,
59 };
60
61 persistence.set(Some(event.clone())).unwrap();
62 assert_eq!(persistence.get().unwrap(), Some(event.clone()));
63
64 persistence.set(None).unwrap();
65 assert_eq!(persistence.get().unwrap(), None);
66 }
67}