aboutsummaryrefslogtreecommitdiffstats
path: root/crates/api-auth/src/lib.rs
blob: 24b966ca304a2f4f4f0494b232e469956a831749 (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
#[cfg(feature = "discord")]
pub mod discord;

pub mod client;
pub(crate) mod util;

mod error;
use api_core::auth::AuthClientConfig;
use api_core::models::user::User;
pub use error::AuthClientError;

use oauth2::{EndpointNotSet, EndpointSet};

type C = oauth2::basic::BasicClient<
    EndpointSet,
    EndpointNotSet,
    EndpointNotSet,
    EndpointNotSet,
    EndpointSet,
>;

#[derive(Clone, Debug)]
pub struct BasicClient(C);

#[async_trait::async_trait]
pub trait OauthDriver: Send + Sync {
    async fn get_user(
        &self,
        client: &client::AuthHttpClient,
        code: &str,
    ) -> Result<User, AuthError>;
    async fn validate_session(&self, cookie: &str, state: &str) -> Result<(), AuthError>;
    async fn create_oauth_session(&self) -> Result<SessionResponse, AuthError>;
    async fn save_session(&self, user: &User) -> Result<(), AuthError>;
}

use oauth2::{AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl};
use std::{convert::TryFrom, ops::Deref};
use url::Url;

use crate::error::AuthError;

#[allow(dead_code)]
static CSRF_TOKEN: &str = "csrf_token";

pub struct SessionResponse {
    pub cookie_value: String,
    pub auth_url: Url,
}

impl Deref for BasicClient {
    type Target = C;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl TryFrom<AuthClientConfig> for BasicClient {
    type Error = AuthClientError;

    fn try_from(value: AuthClientConfig) -> Result<Self, Self::Error> {
        let auth_url = AuthUrl::new(value.auth_url).map_err(AuthClientError::InvalidAuthUrl)?;

        let token_url = TokenUrl::new(value.token_uri).map_err(AuthClientError::InvalidTokenUrl)?;

        let redirect_url =
            RedirectUrl::new(value.redirect_uri).map_err(AuthClientError::InvalidRedirectUrl)?;

        Ok(Self(
            oauth2::basic::BasicClient::new(ClientId::new(value.client_id))
                .set_client_secret(ClientSecret::new(value.client_secret))
                .set_auth_uri(auth_url)
                .set_token_uri(token_url)
                .set_redirect_uri(redirect_url),
        ))
    }
}