diff --git a/zeroidc/src/lib.rs b/zeroidc/src/lib.rs index dc94d95ee..99db6517d 100644 --- a/zeroidc/src/lib.rs +++ b/zeroidc/src/lib.rs @@ -6,9 +6,10 @@ use std::sync::{Arc, Mutex}; use std::thread::{sleep, spawn, JoinHandle}; use std::time::Duration; -use openidconnect::core::{CoreClient, CoreProviderMetadata}; +use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType}; use openidconnect::reqwest::http_client; -use openidconnect::{ClientId, IssuerUrl, RedirectUrl}; +use openidconnect::AuthenticationFlow; +use openidconnect::{ClientId, CsrfToken, IssuerUrl, Nonce, PkceCodeChallenge, RedirectUrl, Scope}; use url::Url; @@ -21,15 +22,36 @@ pub struct ZeroIDC { struct Inner { running: bool, + auth_endpoint: String, oidc_thread: Option>, oidc_client: Option, } +fn csrf_func(csrf_token: String) -> Box CsrfToken> { + return Box::new(move || CsrfToken::new(csrf_token.to_string())); +} + +fn nonce_func(nonce: String) -> Box Nonce> { + return Box::new(move || Nonce::new(nonce.to_string())); +} + +struct authres { + url: Url, + csrf_token: CsrfToken, + nonce: Nonce, +} + impl ZeroIDC { - fn new(issuer: &str, client_id: &str, port: u16) -> Result { + fn new( + issuer: &str, + client_id: &str, + auth_ep: &str, + local_web_port: u16, + ) -> Result { let idc = ZeroIDC { inner: Arc::new(Mutex::new(Inner { running: false, + auth_endpoint: auth_ep.to_string(), oidc_thread: None, oidc_client: None, })), @@ -45,7 +67,7 @@ impl ZeroIDC { Err(e) => return Err(e.to_string()), }; - let r = format!("http://localhost:{}", port); + let r = format!("http://localhost:{}/sso", local_web_port); let redir_url = match Url::parse(&r) { Ok(s) => s, Err(e) => return Err(e.to_string()), @@ -94,13 +116,40 @@ impl ZeroIDC { } } } + + fn get_auth_url(&mut self) -> Option { + let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256(); + + let r = (*self.inner.lock().unwrap()).oidc_client.as_ref().map(|c| { + let (auth_url, csrf_token, nonce) = c + .authorize_url( + AuthenticationFlow::::AuthorizationCode, + csrf_func("my-csrf".to_string()), + nonce_func("my-nonce".to_string()), + ) + .add_scope(Scope::new("read".to_string())) + .add_scope(Scope::new("read".to_string())) + .add_scope(Scope::new("openid".to_string())) + .set_pkce_challenge(pkce_challenge) + .url(); + + return authres { + url: auth_url, + csrf_token, + nonce, + }; + }); + + r + } } #[no_mangle] pub extern "C" fn zeroidc_new( issuer: *const c_char, client_id: *const c_char, - web_port: u16, + auth_endpoint: *const c_char, + web_listen_port: u16, ) -> *mut ZeroIDC { if issuer.is_null() { println!("issuer is null"); @@ -112,10 +161,20 @@ pub extern "C" fn zeroidc_new( return std::ptr::null_mut(); } + if auth_endpoint.is_null() { + println!("auth_endpoint is null"); + return std::ptr::null_mut(); + } + let iss = unsafe { CStr::from_ptr(issuer) }; let c_id = unsafe { CStr::from_ptr(client_id) }; - - match ZeroIDC::new(iss.to_str().unwrap(), c_id.to_str().unwrap(), web_port) { + let auth_endpoint = unsafe { CStr::from_ptr(auth_endpoint) }; + match ZeroIDC::new( + iss.to_str().unwrap(), + c_id.to_str().unwrap(), + auth_endpoint.to_str().unwrap(), + web_listen_port, + ) { Ok(idc) => { return Box::into_raw(Box::new(idc)); }