diff --git a/README.md b/README.md index 0359765..8d47b86 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ To use it, it's very simple. Just create a new instance of some provider: - DiscordProvider - TwitterProvider - GoogleProvider +- MicrosoftProvider - FacebookProvider - SpotifyProvider diff --git a/examples/microsoft.rs b/examples/microsoft.rs new file mode 100644 index 0000000..5d3b5f7 --- /dev/null +++ b/examples/microsoft.rs @@ -0,0 +1,67 @@ +mod utils; +use std::sync::Arc; + +use axum::extract::Query; +use axum::Router; +use axum::{routing::get, Extension}; +use oauth_axum::providers::microsoft::MicrosoftProvider; +use oauth_axum::{CustomProvider, OAuthClient}; + +use crate::utils::memory_db_util::AxumState; + +#[derive(Clone, serde::Deserialize)] +pub struct QueryAxumCallback { + pub code: String, + pub state: String, +} + +#[tokio::main] +async fn main() { + dotenv::from_filename("examples/.env").ok(); + println!("Starting server..."); + + let state = Arc::new(AxumState::new()); + let app = Router::new() + .route("/", get(create_url)) + .route("/api/v1/microsoft/callback", get(callback)) + .layer(Extension(state.clone())); + + println!("🚀 Server started successfully"); + let listener = tokio::net::TcpListener::bind("127.0.0.1:3000") + .await + .unwrap(); + axum::serve(listener, app).await.unwrap(); +} + +fn get_client() -> CustomProvider { + MicrosoftProvider::new( + std::env::var("MICROSOFT_TENANT_ID").expect("MICROSOFT_TENANT_ID must be set"), + std::env::var("MICROSOFT_CLIENT_ID").expect("MICROSOFT_CLIENT_ID must be set"), + std::env::var("MICROSOFT_SECRET").expect("MICROSOFT_SECRET must be set"), + "http://localhost:3000/api/v1/microsoft/callback".to_string(), + ) +} + +pub async fn create_url(Extension(state): Extension>) -> String { + let state_oauth = get_client() + .generate_url(Vec::from(["User.Read".to_string()]), |state_e| async move { + state.set(state_e.state, state_e.verifier); + }) + .await + .unwrap() + .state + .unwrap(); + + state_oauth.url_generated.unwrap() +} + +pub async fn callback( + Extension(state): Extension>, + Query(queries): Query, +) -> String { + println!("{:?}", state.clone().get_all_items()); + let item = state.get(queries.state.clone()); + get_client() + .generate_token(queries.code, item.unwrap()) + .await +} diff --git a/src/lib.rs b/src/lib.rs index ba79438..c736133 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ //! - DiscordProvider //! - TwitterProvider //! - GoogleProvider +//! - MicrosoftProvider //! - FacebookProvider //! - SpotifyProvider //! diff --git a/src/providers/microsoft.rs b/src/providers/microsoft.rs new file mode 100644 index 0000000..a807b37 --- /dev/null +++ b/src/providers/microsoft.rs @@ -0,0 +1,23 @@ +use crate::CustomProvider; + +pub struct MicrosoftProvider {} + +impl MicrosoftProvider { + pub fn new( + tenant_id: String, + client_id: String, + client_secret: String, + redirect_url: String, + ) -> CustomProvider { + let base_url = String::from( + "https://login.microsoftonline.com/".to_string() + tenant_id.as_str() + "/oauth2/v2.0", + ); + CustomProvider::new( + String::from(base_url.clone() + "/authorize"), + String::from(base_url + "/token"), + client_id, + client_secret, + redirect_url, + ) + } +} diff --git a/src/providers/mod.rs b/src/providers/mod.rs index e20966f..79b6fb3 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -2,5 +2,6 @@ pub mod discord; pub mod facebook; pub mod github; pub mod google; +pub mod microsoft; pub mod spotify; pub mod twitter;