From 3061a7126061db1b7694d4e92af1686326a7a320 Mon Sep 17 00:00:00 2001 From: dav Date: Sat, 25 May 2024 11:15:14 -0700 Subject: [PATCH] Add Fetching Slack Token --- burrow-gtk/Cargo.lock | 275 ++++++++++++++++++++--- burrow-gtk/Cargo.toml | 3 + burrow-gtk/src/auth.rs | 8 + burrow-gtk/src/components/app.rs | 7 + burrow-gtk/src/components/auth_screen.rs | 135 +++++++++++ burrow-gtk/src/components/mod.rs | 1 + burrow-gtk/src/main.rs | 1 + 7 files changed, 397 insertions(+), 33 deletions(-) create mode 100644 burrow-gtk/src/auth.rs create mode 100644 burrow-gtk/src/components/auth_screen.rs diff --git a/burrow-gtk/Cargo.lock b/burrow-gtk/Cargo.lock index 6721318..c50976e 100644 --- a/burrow-gtk/Cargo.lock +++ b/burrow-gtk/Cargo.lock @@ -125,6 +125,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.1.0" @@ -152,6 +158,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -252,7 +264,7 @@ dependencies = [ "aead", "anyhow", "async-channel", - "base64", + "base64 0.21.7", "blake2", "caps", "chacha20poly1305", @@ -293,7 +305,10 @@ dependencies = [ "gettext-rs", "glib-build-tools", "relm4", + "reqwest 0.12.4", + "serde", "tokio", + "url", ] [[package]] @@ -1206,7 +1221,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.11", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1267,6 +1301,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1274,7 +1319,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1300,20 +1368,40 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.24", + "http 0.2.11", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1321,12 +1409,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.28", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.3.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d8d52be92d09acc2e01dddb7fde3ad983fc6489c7db4837e605bc3fca4cb63e" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.3.1", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "idna" version = "0.5.0" @@ -2148,16 +2272,16 @@ version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "h2 0.3.24", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -2177,7 +2301,49 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", ] [[package]] @@ -2228,6 +2394,22 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "ryu" version = "1.0.16" @@ -2304,18 +2486,18 @@ checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", @@ -2428,16 +2610,6 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.5" @@ -2463,7 +2635,7 @@ version = "9.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da7a2b3c2bc9693bcb40870c4e9b5bf0d79f9cb46273321bf855ec513e919082" dependencies = [ - "base64", + "base64 0.21.7", "digest", "hex", "miette", @@ -2507,6 +2679,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -2641,7 +2819,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio-macros", "tracing", "windows-sys 0.48.0", @@ -2727,6 +2905,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2851,10 +3050,10 @@ dependencies = [ "libloading 0.7.4", "log", "nix 0.26.4", - "reqwest", + "reqwest 0.11.23", "schemars", "serde", - "socket2 0.4.10", + "socket2", "ssri", "tempfile", "tokio", @@ -3254,6 +3453,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "x25519-dalek" version = "2.0.0" diff --git a/burrow-gtk/Cargo.toml b/burrow-gtk/Cargo.toml index 21cb52e..25d126c 100644 --- a/burrow-gtk/Cargo.toml +++ b/burrow-gtk/Cargo.toml @@ -11,6 +11,9 @@ relm4 = { version = "0.6", features = ["libadwaita", "gnome_44"]} burrow = { version = "*", path = "../burrow/" } tokio = { version = "1.35.0", features = ["time", "sync"] } gettext-rs = { version = "0.7.0", features = ["gettext-system"] } +serde = { version = "1", features = ["derive"] } +url = "2.5.0" +reqwest = { version = "0.12.4", features = ["json"] } [build-dependencies] anyhow = "1.0" diff --git a/burrow-gtk/src/auth.rs b/burrow-gtk/src/auth.rs new file mode 100644 index 0000000..110d924 --- /dev/null +++ b/burrow-gtk/src/auth.rs @@ -0,0 +1,8 @@ +use super::*; +use serde::Serialize; + +#[derive(Serialize)] +pub struct SlackToken { + slack_token: String, +} + diff --git a/burrow-gtk/src/components/app.rs b/burrow-gtk/src/components/app.rs index 62c98c0..d9fdadc 100644 --- a/burrow-gtk/src/components/app.rs +++ b/burrow-gtk/src/components/app.rs @@ -8,6 +8,7 @@ pub struct App { daemon_client: Arc>>, settings_screen: Controller, switch_screen: AsyncController, + auth_screen: AsyncController, } #[derive(Debug)] @@ -72,11 +73,16 @@ impl AsyncComponent for App { }) .forward(sender.input_sender(), |_| AppMsg::None); + let auth_screen = auth_screen::AuthScreen::builder() + .launch(auth_screen::AuthScreenInit {}) + .forward(sender.input_sender(), |_| AppMsg::None); + let widgets = view_output!(); let view_stack = adw::ViewStack::new(); view_stack.add_titled(switch_screen.widget(), None, "Switch"); view_stack.add_titled(settings_screen.widget(), None, "Settings"); + view_stack.add_titled(auth_screen.widget(), None, "Auth Test"); let view_switcher_bar = adw::ViewSwitcherBar::builder().stack(&view_stack).build(); view_switcher_bar.set_reveal(true); @@ -110,6 +116,7 @@ impl AsyncComponent for App { daemon_client, switch_screen, settings_screen, + auth_screen, }; AsyncComponentParts { model, widgets } diff --git a/burrow-gtk/src/components/auth_screen.rs b/burrow-gtk/src/components/auth_screen.rs new file mode 100644 index 0000000..5c8f5d3 --- /dev/null +++ b/burrow-gtk/src/components/auth_screen.rs @@ -0,0 +1,135 @@ +use super::*; +use reqwest::{Client, Method}; +use serde::Deserialize; +use std::{ + io::{prelude::*, BufReader}, + net::TcpListener, + process::Command, +}; +use url::Url; + +const SLACK_CLIENT_ID: &str = "2210535565.6884042183125"; +const SLACK_CLIENT_SECRET: &str = "2793c8a5255cae38830934c664eeb62d"; +const SLACK_REDIRECT_URI: &str = "https://burrow.rs/callback/oauth2"; + +pub struct AuthScreen {} + +pub struct AuthScreenInit {} + +#[derive(Debug, PartialEq, Eq)] +pub enum AuthScreenMsg { + SlackAuth, +} + +#[relm4::component(pub, async)] +impl AsyncComponent for AuthScreen { + type Init = AuthScreenInit; + type Input = AuthScreenMsg; + type Output = (); + type CommandOutput = (); + + view! { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_valign: Align::Fill, + + gtk::Button { + set_label: "Authenticate with Slack", + connect_clicked => AuthScreenMsg::SlackAuth, + }, + } + } + + async fn init( + init: Self::Init, + root: Self::Root, + sender: AsyncComponentSender, + ) -> AsyncComponentParts { + let widgets = view_output!(); + + let model = AuthScreen {}; + + AsyncComponentParts { model, widgets } + } + + async fn update( + &mut self, + msg: Self::Input, + _: AsyncComponentSender, + _root: &Self::Root, + ) { + match msg { + AuthScreenMsg::SlackAuth => { + let url = Url::parse_with_params( + "https://slack.com/openid/connect/authorize", + &[ + ("response_type", "code"), + ("scope", "openid profile"), + ("client_id", SLACK_CLIENT_ID), + ("redirect_uri", SLACK_REDIRECT_URI), + ], + ) + .unwrap(); + Command::new("xdg-open").arg(url.as_str()).spawn().unwrap(); + let listener = TcpListener::bind("127.0.0.1:1024").unwrap(); + + let stream = listener.incoming().next().unwrap(); + let mut stream = stream.unwrap(); + + let buf_reader = BufReader::new(&mut stream); + let http_request: Vec<_> = buf_reader + .lines() + .map(|result| result.unwrap()) + .take_while(|line| !line.is_empty()) + .collect(); + + let response = "HTTP/1.1 200 OK\r\n\r\n"; + stream.write_all(response.as_bytes()).unwrap(); + + let code = http_request + .iter() + .filter_map(|field| { + if field.starts_with("GET ") { + Some( + field + .replace("GET /?code=", "") + .replace(" HTTP/1.1", "") + .to_owned(), + ) + } else { + None + } + }) + .next() + .unwrap(); + + #[derive(Debug, Clone, Deserialize)] + struct TokenRes { + ok: bool, + access_token: Option, + token_type: Option, + id_token: Option, + } + + let client = Client::builder().build().unwrap(); + let res = client + .request(Method::POST, "https://slack.com/api/openid.connect.token") + .query(&[ + ("client_id", SLACK_CLIENT_ID), + ("client_secret", SLACK_CLIENT_SECRET), + ("code", &code), + ("grant_type", "authorization_code"), + ("redirect_uri", SLACK_REDIRECT_URI), + ]) + .send() + .await + .unwrap() + .json::() + .await + .unwrap(); + + eprintln!("{:?}", res); + } + }; + } +} diff --git a/burrow-gtk/src/components/mod.rs b/burrow-gtk/src/components/mod.rs index b134809..20c213c 100644 --- a/burrow-gtk/src/components/mod.rs +++ b/burrow-gtk/src/components/mod.rs @@ -13,6 +13,7 @@ use std::sync::Arc; use tokio::sync::Mutex; mod app; +mod auth_screen; mod settings; mod settings_screen; mod switch_screen; diff --git a/burrow-gtk/src/main.rs b/burrow-gtk/src/main.rs index 6f91e2a..75dab3c 100644 --- a/burrow-gtk/src/main.rs +++ b/burrow-gtk/src/main.rs @@ -1,5 +1,6 @@ use anyhow::Result; +mod auth; pub mod components; mod diag;