From a1b49fde473c484a20099da4f233639b2fc4bcbe Mon Sep 17 00:00:00 2001 From: Kevin Yue Date: Sun, 28 May 2023 14:04:22 +0800 Subject: [PATCH] refactor: add auth window --- Cargo.lock | 12 ++ gpauth/Cargo.toml | 2 + gpauth/src/auth_service.rs | 54 +++++ gpauth/src/duplex.rs | 35 ++++ gpauth/src/lib.rs | 20 +- gpauth/src/main.rs | 90 +++++---- gpauth/src/saml.rs | 233 ++++++++++++++++++++++ gpgui/public/auth.html | 12 ++ gpgui/src-tauri/Cargo.toml | 7 +- gpgui/src-tauri/src/auth.rs | 297 ++++++++++++++++++++++++++++ gpgui/src-tauri/src/main.rs | 28 ++- gpgui/src/App.tsx | 17 +- gpgui/src/services/authService.ts | 53 +++++ gpgui/src/services/portalService.ts | 8 +- gpgui/src/services/vpnService.ts | 26 +-- gpgui/src/utils/invokeCommand.ts | 9 + 16 files changed, 821 insertions(+), 82 deletions(-) create mode 100644 gpauth/src/auth_service.rs create mode 100644 gpauth/src/duplex.rs create mode 100644 gpauth/src/saml.rs create mode 100644 gpgui/public/auth.html create mode 100644 gpgui/src-tauri/src/auth.rs create mode 100644 gpgui/src/services/authService.ts create mode 100644 gpgui/src/utils/invokeCommand.ts diff --git a/Cargo.lock b/Cargo.lock index 782b251..cb9354c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,11 +54,14 @@ dependencies = [ "env_logger", "gpcommon", "log", + "regex", "serde", "serde_json", "tauri", "tauri-build", "tauri-plugin-log", + "url", + "webkit2gtk", ] [[package]] @@ -535,6 +538,12 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" +[[package]] +name = "data-url" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" + [[package]] name = "derive_more" version = "0.99.17" @@ -1076,6 +1085,8 @@ dependencies = [ name = "gpauth" version = "0.1.0" dependencies = [ + "regex", + "tokio", "webkit2gtk", "wry", ] @@ -2819,6 +2830,7 @@ dependencies = [ "anyhow", "attohttpc", "cocoa", + "data-url", "dirs-next", "embed_plist", "encoding_rs", diff --git a/gpauth/Cargo.toml b/gpauth/Cargo.toml index 197e179..500fcf7 100644 --- a/gpauth/Cargo.toml +++ b/gpauth/Cargo.toml @@ -8,3 +8,5 @@ edition = "2021" [dependencies] wry = "0.24.3" webkit2gtk = "0.18.2" +tokio = { version = "1.14", features = ["full"] } +regex="1" \ No newline at end of file diff --git a/gpauth/src/auth_service.rs b/gpauth/src/auth_service.rs new file mode 100644 index 0000000..cac4c11 --- /dev/null +++ b/gpauth/src/auth_service.rs @@ -0,0 +1,54 @@ +use crate::{ + duplex::duplex, + saml::{SamlAuth, SamlBinding, SamlOptions}, + DuplexStreamHandle, +}; +use std::sync::Arc; +use tokio::sync::Mutex; + +#[derive(Debug)] +pub struct AuthService { + server: DuplexStreamHandle, + client: Arc>, + saml_auth: Arc, +} + +impl Default for AuthService { + fn default() -> Self { + let (client, server) = duplex(4096); + Self { + client: Arc::new(Mutex::new(client)), + server, + saml_auth: Default::default(), + } + } +} + +impl AuthService { + pub async fn run(&mut self) { + loop { + println!("Server waiting for data"); + match self.server.read().await { + Ok(data) => { + println!("Server received: {}", data); + let target = String::from("https://login.microsoftonline.com/901c038b-4638-4259-b115-c1753c7735aa/saml2?SAMLRequest=lVLBbsIwDP2VKveSNGlaiGilDg5DYlpFux12mdIQIFKbdEmKtr8fhaGxC9Lkk%2BXnZ79nzx3v2p4Vgz%2FojfwYpPPBZ9dqx86FDAxWM8OdckzzTjrmBauKpzXDE8R6a7wRpgVB4Zy0Xhm9MNoNnbSVtEcl5MtmnYGD971jEB57PemUsMZ5y73cf02E6VgcEzgyYgSrEhaLCgTL0xZK85Hvt7s1e3XtNztvdKu0HBngDEUCkWkTxgmZhjGms7CJIhqKKKVEpCmhnMNRDgbBapmBdzpL5BZFEu0oalKMpglttukpaBLHuEEnmHODXGnnufYZwAiTENEQ0xoljBJGyBsIyh%2F1D0pvld7ft6q5gBx7rOsyLJ%2BrGgSv0rqzxBMA5PNxQ3YebG9OcJ%2BWX30H%2BT9cnsObWfkl%2B%2FsD%2BTc%3D&RelayState=HEgCAOLrNmRmZTBkM2FlNDE2MDQyMDhjZTVmMTZlMTdiZTdiMTliNg%3D%3D"); + let ua = String::from("PAN GlobalProtect"); + + let saml_options = SamlOptions::new(SamlBinding::Redirect, target, ua); + let saml_auth = self.saml_auth.clone(); + tokio::spawn(async move { + saml_auth.process(saml_options).await; + }); + // self.server.write(&data).await.expect("write failed"); + } + Err(err) => { + println!("Server error: {:?}", err); + } + } + } + } + + pub fn client(&self) -> Arc> { + self.client.clone() + } +} diff --git a/gpauth/src/duplex.rs b/gpauth/src/duplex.rs new file mode 100644 index 0000000..d7525a4 --- /dev/null +++ b/gpauth/src/duplex.rs @@ -0,0 +1,35 @@ +use tokio::io::{AsyncReadExt, AsyncWriteExt, DuplexStream}; + +#[derive(Debug)] +pub struct DuplexStreamHandle { + stream: DuplexStream, + buf_size: usize, +} + +impl DuplexStreamHandle { + fn new(stream: DuplexStream, buf_size: usize) -> Self { + Self { stream, buf_size } + } + + pub async fn write(&mut self, data: &str) -> Result<(), Box> { + self.stream.write_all(data.as_bytes()).await?; + Ok(()) + } + + pub async fn read(&mut self) -> Result> { + let mut buffer = vec![0; self.buf_size]; + match self.stream.read(&mut buffer).await { + Ok(0) => Err("EOF".into()), + Ok(n) => Ok(String::from_utf8_lossy(&buffer[..n]).to_string()), + Err(err) => Err(err.to_string().into()), + } + } +} + +pub(crate) fn duplex(max_buf_size: usize) -> (DuplexStreamHandle, DuplexStreamHandle) { + let (a, b) = tokio::io::duplex(max_buf_size); + ( + DuplexStreamHandle::new(a, max_buf_size), + DuplexStreamHandle::new(b, max_buf_size), + ) +} \ No newline at end of file diff --git a/gpauth/src/lib.rs b/gpauth/src/lib.rs index 7d12d9a..63aec16 100644 --- a/gpauth/src/lib.rs +++ b/gpauth/src/lib.rs @@ -1,14 +1,8 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} +mod auth_service; +mod saml; +mod duplex; -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub use auth_service::AuthService; +pub use duplex::DuplexStreamHandle; +pub use saml::saml_login; +pub use saml::SamlBinding; \ No newline at end of file diff --git a/gpauth/src/main.rs b/gpauth/src/main.rs index 6b10091..001a847 100644 --- a/gpauth/src/main.rs +++ b/gpauth/src/main.rs @@ -1,45 +1,55 @@ -use webkit2gtk::LoadEvent; -use webkit2gtk::URIResponseExt; -use webkit2gtk::WebResourceExt; -use webkit2gtk::WebViewExt; -use wry::application::event::Event; -use wry::application::event::StartCause; -use wry::application::event::WindowEvent; -use wry::application::event_loop::ControlFlow; -use wry::application::event_loop::EventLoop; -use wry::application::window::WindowBuilder; -use wry::webview::WebViewBuilder; -use wry::webview::WebviewExtUnix; +use gpauth::{AuthService, saml_login, SamlBinding}; -fn main() -> wry::Result<()> { - let event_loop = EventLoop::new(); - let window = WindowBuilder::new() - .with_title("Hello World") - .build(&event_loop)?; - let _webview = WebViewBuilder::new(window)? - .with_url("https://tauri.studio")? - .build()?; +#[tokio::main] +async fn main() { + let url = String::from("https://globalprotect.kochind.com/global-protect/prelogin.esp?tmp=tmp&kerberos-support=yes&ipv6-support=yes&clientVer=4100&clientos=Linux"); + let _html = String::from( + r#" + +
+ + +
+