From 14e35f6b14ac69eb70cbf1fc70c9e8d753c96049 Mon Sep 17 00:00:00 2001 From: Eivind Gamst Date: Wed, 8 May 2024 13:09:03 +0200 Subject: [PATCH 1/2] Added microsoft provider --- examples/microsoft.rs | 67 ++++++++++++++++++++++++++++++++++++++ src/providers/microsoft.rs | 23 +++++++++++++ src/providers/mod.rs | 1 + 3 files changed, 91 insertions(+) create mode 100644 examples/microsoft.rs create mode 100644 src/providers/microsoft.rs 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/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 b4d5b11..4826317 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -1,4 +1,5 @@ pub mod discord; pub mod github; pub mod google; +pub mod microsoft; pub mod twitter; From c4db064bee59939d7a2e17ac62773e6beda9d8cd Mon Sep 17 00:00:00 2001 From: Eivind Gamst Date: Thu, 9 May 2024 12:44:50 +0200 Subject: [PATCH 2/2] Added microsoft provider to docs --- README.md | 1 + src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 55fc862..79cc059 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 in your project, pass to the `new` function: diff --git a/src/lib.rs b/src/lib.rs index 28b4617..d711817 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ //! - DiscordProvider //! - TwitterProvider //! - GoogleProvider +//! - MicrosoftProvider //! //! in your project, pass to the ```new``` function: //!