Skip to main content

rullst_connect/
lib.rs

1pub mod client;
2pub mod error;
3#[cfg(any(
4    feature = "axum",
5    feature = "actix",
6    feature = "leptos",
7    feature = "rullst"
8))]
9pub mod extractors;
10#[macro_use]
11pub mod macros;
12pub mod mock_idp;
13pub mod pkce;
14pub mod prelude;
15pub mod provider;
16pub mod providers;
17pub mod user;
18
19pub use error::ConnectError;
20
21pub use provider::Provider;
22pub use user::ConnectUser;
23
24/// The main entry point for the rullst-connect library.
25pub struct Connect;
26
27impl Connect {
28    /// Factory method to dynamically instantiate an OAuth provider by name.
29    ///
30    /// Available providers (case-insensitive):
31    /// "github", "google", "facebook", "gitlab", "discord", "linkedin", "x", "microsoft"
32    ///
33    /// Note: Providers requiring specialized configuration (like Apple, Auth0, Cognito, and Okta)
34    /// must be instantiated manually.
35    pub fn driver(
36        name: &str,
37        client_id: String,
38        client_secret: secrecy::SecretString,
39        redirect_url: String,
40    ) -> Result<Box<dyn Provider>, crate::error::ConnectError> {
41        let name = name.to_lowercase();
42        let provider: Box<dyn Provider> = match name.as_str() {
43            "github" => Box::new(crate::providers::GithubProvider::new(
44                client_id,
45                client_secret,
46                redirect_url,
47            )),
48            "google" => Box::new(crate::providers::GoogleProvider::new(
49                client_id,
50                client_secret,
51                redirect_url,
52            )),
53            "facebook" => Box::new(crate::providers::FacebookProvider::new(
54                client_id,
55                client_secret,
56                redirect_url,
57            )),
58            "discord" => Box::new(crate::providers::DiscordProvider::new(
59                client_id,
60                client_secret,
61                redirect_url,
62            )),
63            "linkedin" => Box::new(crate::providers::LinkedinProvider::new(
64                client_id,
65                client_secret,
66                redirect_url,
67            )),
68            "x" => Box::new(crate::providers::XProvider::new(
69                client_id,
70                client_secret,
71                redirect_url,
72            )),
73            "microsoft" => Box::new(crate::providers::MicrosoftProvider::new(
74                client_id,
75                client_secret,
76                redirect_url,
77            )),
78            "apple" | "auth0" | "cognito" | "oidc" => {
79                return Err(crate::error::ConnectError::Provider(format!(
80                    "Provider '{}' requires custom configuration (domain or key_id) and cannot be instantiated via the generic driver factory. Please instantiate it directly.",
81                    name
82                )));
83            }
84            _ => {
85                return Err(crate::error::ConnectError::Provider(format!(
86                    "Unknown provider: {}",
87                    name
88                )));
89            }
90        };
91        Ok(provider)
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[test]
100    fn test_driver_factory() {
101        let github = Connect::driver(
102            "github",
103            "id".to_string(),
104            secrecy::SecretString::from("secret".to_string()),
105            "http://url".to_string(),
106        );
107        assert!(github.is_ok());
108
109        let apple = Connect::driver(
110            "apple",
111            "id".to_string(),
112            secrecy::SecretString::from("secret".to_string()),
113            "http://url".to_string(),
114        );
115        assert!(apple.is_err());
116
117        let unknown = Connect::driver(
118            "unknown",
119            "id".to_string(),
120            secrecy::SecretString::from("secret".to_string()),
121            "http://url".to_string(),
122        );
123        assert!(unknown.is_err());
124    }
125}