From d78203ebba9aa2412334550a316202cf175229f5 Mon Sep 17 00:00:00 2001 From: Luc Date: Mon, 22 Jul 2024 17:39:10 +0000 Subject: [PATCH] Introduce openid callback --- engine/Cargo.lock | 8 +++++ engine/Cargo.toml | 2 ++ engine/src/main.rs | 3 ++ engine/src/openid.rs | 3 ++ engine/src/routes/auth.rs | 61 ++++++++++++++++++++++++++++----------- engine/src/routes/mod.rs | 1 + engine/src/state.rs | 4 +-- 7 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 engine/src/openid.rs diff --git a/engine/Cargo.lock b/engine/Cargo.lock index 3bb148c..a6662e5 100644 --- a/engine/Cargo.lock +++ b/engine/Cargo.lock @@ -401,6 +401,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "dotenvy" version = "0.15.7" @@ -2470,6 +2476,8 @@ name = "v3x-property-engine" version = "0.1.0" dependencies = [ "axum", + "dotenv", + "dotenvy", "openid", "reqwest", "serde", diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 086f8e2..00b8975 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" [dependencies] axum = "0.7.3" +dotenv = "0.15.0" +dotenvy = "0.15.7" openid = "0.14.0" reqwest = "0.12.5" serde = "1.0.204" diff --git a/engine/src/main.rs b/engine/src/main.rs index ec70f45..27b6ab5 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -5,6 +5,7 @@ mod database; mod permissions; mod routes; mod state; +mod openid; #[tokio::main] async fn main() { @@ -15,6 +16,8 @@ async fn main() { .render(); println!("{}", banner); + dotenvy::dotenv().ok(); + tracing_subscriber::fmt::init(); info!("Starting v3x-property"); diff --git a/engine/src/openid.rs b/engine/src/openid.rs new file mode 100644 index 0000000..d5fc1bd --- /dev/null +++ b/engine/src/openid.rs @@ -0,0 +1,3 @@ +use openid::{Client, Discovered, StandardClaims}; + +pub type OpenIDClient = Client; diff --git a/engine/src/routes/auth.rs b/engine/src/routes/auth.rs index d4547f8..6674588 100644 --- a/engine/src/routes/auth.rs +++ b/engine/src/routes/auth.rs @@ -1,7 +1,16 @@ -use axum::response::{IntoResponse, Redirect}; -use openid::{DiscoveredClient, Options}; +use std::{borrow::BorrowMut, ops::Deref, sync::Arc}; -pub async fn login() -> impl IntoResponse { +use axum::{ + extract::{Query, State}, + response::{IntoResponse, Redirect}, +}; +use openid::{Options, Token}; +use serde::Deserialize; +use tracing::info; + +use crate::state::AppState; + +pub async fn login(state: State>) -> impl IntoResponse { // let discovery_url = "http://localhost:8080/realms/master/.well-known/openid-configuration"; // let http_client = reqwest::Client::new(); @@ -12,25 +21,43 @@ pub async fn login() -> impl IntoResponse { // .json() // .await.unwrap(); - // Create the OpenID client - let client_id = "devclient"; - let client_secret = Some("wavt7wfi7VXkv5ex9PMFKOGBBnVhfZzy"); - let redirect_url = "http://localhost:3000/callback"; - - let client = DiscoveredClient::discover( - client_id.to_string(), - client_secret.map(|s| s.to_string()), - Some(redirect_url.to_string()), - "http://localhost:8080/realms/master".parse().unwrap() - // discovery_response.issuer.parse().unwrap() - ) - .await.unwrap(); + let options = Options { + scope: Some("openid email profile".to_string()), + ..Default::default() + }; // Generate the authorization URL - let authorize_url = client.auth_url(&Options::default()); + let authorize_url = state.openid.auth_url(&options); println!("OpenID Connect Authorization URL: {}", authorize_url); // redirect to the authorization URL Redirect::temporary(authorize_url.as_str()) } + +#[derive(Deserialize)] +pub struct MyQuery { + pub session_state: Option, + pub iss: Option, + pub code: String, + pub prompt: Option, +} + +pub async fn callback(query: Query, state: State>) -> impl IntoResponse { + let mut token = state.openid.request_token(&query.code).await.unwrap(); + + // let mut id_token = (&token.id_token).clone().unwrap().clone(); + + let mut token = Token::from(token); + + let mut id_token = token.id_token.take().unwrap(); + + state.openid.decode_token(&mut id_token).unwrap(); + state.openid.validate_token(&id_token, None, None).unwrap(); + + // info!("Token: {:?}", id_token); + + let x = state.openid.request_userinfo(&token).await.unwrap(); + + format!("Hello {:?}", x) +} diff --git a/engine/src/routes/mod.rs b/engine/src/routes/mod.rs index 499628e..ab9b59e 100644 --- a/engine/src/routes/mod.rs +++ b/engine/src/routes/mod.rs @@ -11,6 +11,7 @@ pub async fn serve(state: AppState) -> Result<(), axum::Error> { let app = Router::new() .route("/", get(root)) .route("/login", get(auth::login)) + .route("/callback", get(auth::callback)) // .route("/devices", get(routes::devices::get)) .with_state(Arc::new(state)); diff --git a/engine/src/state.rs b/engine/src/state.rs index d1349e8..53a5b6c 100644 --- a/engine/src/state.rs +++ b/engine/src/state.rs @@ -1,11 +1,11 @@ use std::env; -use crate::database::Database; +use crate::{database::Database, openid::OpenIDClient}; use openid::DiscoveredClient; pub struct AppState { pub database: Database, - pub openid: DiscoveredClient, + pub openid: OpenIDClient, } impl AppState {