summaryrefslogtreecommitdiff
path: root/server/src/fake_auth.rs
blob: caea745f0ad6db8e9b72a917cb48624978b2e539 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::{
    collections::HashMap,
    env,
    sync::{Arc, Mutex},
};

use async_trait::async_trait;
use chrono::Utc;
use openidconnect::{AccessToken, RefreshToken};
use reqwest::Url;

use crate::{
    auth::{
        store_authenticated_session, AuthenticatedSession, Authenticator,
        SessionId,
    },
    error::{self, BridgeError},
};

pub struct FakeAuthenticator {
    login_cache: Arc<Mutex<HashMap<SessionId, Option<String>>>>,
}

impl FakeAuthenticator {
    pub fn new() -> Self {
        Self {
            login_cache: Arc::new(Mutex::new(HashMap::new())),
        }
    }
}

impl Default for FakeAuthenticator {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait]
impl Authenticator for FakeAuthenticator {
    async fn user_info(
        &self,
        session: &mut AuthenticatedSession,
    ) -> Result<String, error::BridgeError> {
        let user: String = self
            .login_cache
            .lock()
            .unwrap()
            .get(&session.session_id)
            .and_then(|u| u.as_ref())
            .ok_or(BridgeError::NotLoggedIn)?
            .clone();
        Ok(user)
    }

    async fn authenticate(
        &self,
        pool: &sqlx::PgPool,
        session_id: SessionId,
        auth_params: HashMap<String, String>,
    ) -> Result<AuthenticatedSession, error::BridgeError> {
        let user = auth_params
            .get("user")
            .ok_or(BridgeError::Internal("missing 'user' param".to_string()))?;
        self.login_cache
            .lock()
            .unwrap()
            .insert(session_id.clone(), Some(user.clone()));

        let mut session = AuthenticatedSession::new(
            user.clone(),
            session_id,
            Utc::now() + chrono::Duration::days(10000),
            AccessToken::new("fake".to_string()),
            RefreshToken::new("fake".to_string()),
        );

        store_authenticated_session(pool, &mut session).await?;
        Ok(session)
    }

    async fn get_login_url(&self) -> (SessionId, reqwest::Url) {
        let auth_url = Url::parse(&format!(
            "{}/api/fake_login",
            env::var("APP_URL").unwrap()
        ))
        .unwrap();
        let user_id = SessionId::new();
        self.login_cache
            .lock()
            .unwrap()
            .insert(user_id.clone(), None);
        (user_id, auth_url)
    }
}