diff --git a/Cargo.lock b/Cargo.lock index 1d38a25e..27232671 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,7 +916,7 @@ dependencies = [ "paste", "percent-encoding", "rustls 0.22.4", - "rustls-pemfile 2.1.3", + "rustls-pemfile", "schemars", "scopeguard", "serde", @@ -1297,25 +1297,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.6" @@ -1512,7 +1493,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1535,7 +1515,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", + "h2", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -1549,29 +1529,36 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 0.2.12", - "hyper 0.14.30", - "rustls 0.21.12", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "rustls 0.23.12", + "rustls-pki-types", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.0", + "tower-service", + "webpki-roots", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", - "hyper 0.14.30", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", ] [[package]] @@ -2085,16 +2072,16 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "oauth2" -version = "4.4.2" +version = "5.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" +checksum = "23d385da3c602d29036d2f70beed71c36604df7570be17fed4c5b839616785bf" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "chrono", "getrandom", - "http 0.2.12", + "http 1.1.0", "rand", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "serde_path_to_error", @@ -2203,10 +2190,10 @@ dependencies = [ "clap", "dirs", "futures", - "progenitor-client 0.7.0", + "progenitor-client 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand", "regress", - "reqwest 0.11.27", + "reqwest", "schemars", "serde", "serde_json", @@ -2253,7 +2240,7 @@ dependencies = [ "rand", "ratatui", "rcgen", - "reqwest 0.11.27", + "reqwest", "schemars", "serde", "serde_json", @@ -2533,21 +2520,21 @@ name = "progenitor" version = "0.8.0" source = "git+https://github.com/oxidecomputer/progenitor#e507f30e1701a8ec925734e683dc0dda5f426143" dependencies = [ - "progenitor-client 0.8.0", + "progenitor-client 0.8.0 (git+https://github.com/oxidecomputer/progenitor)", "progenitor-impl", "progenitor-macro", ] [[package]] name = "progenitor-client" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd37f0c1cbefc31ca9e1a046edbffb9bd549742f58c1316c88119eb7a29493a" +checksum = "d4a5db54eac3cae7007a0785854bc3e89fd418cca7dfc2207b99b43979154c1b" dependencies = [ "bytes", "futures-core", "percent-encoding", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "serde_urlencoded", @@ -2561,7 +2548,7 @@ dependencies = [ "bytes", "futures-core", "percent-encoding", - "reqwest 0.12.8", + "reqwest", "serde", "serde_json", "serde_urlencoded", @@ -2605,6 +2592,54 @@ dependencies = [ "syn", ] +[[package]] +name = "quinn" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.12", + "socket2 0.5.7", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +dependencies = [ + "bytes", + "rand", + "ring 0.17.8", + "rustc-hash", + "rustls 0.23.12", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +dependencies = [ + "libc", + "once_cell", + "socket2 0.5.7", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.37" @@ -2735,52 +2770,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", - "hyper-rustls", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", - "tokio", - "tokio-native-tls", - "tokio-rustls 0.24.1", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", - "winreg", -] - [[package]] name = "reqwest" version = "0.12.8" @@ -2789,25 +2778,37 @@ checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64 0.22.1", "bytes", + "encoding_rs", "futures-core", "futures-util", + "h2", "http 1.1.0", "http-body 1.0.1", "http-body-util", "hyper 1.4.1", + "hyper-rustls", + "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "quinn", + "rustls 0.23.12", + "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper", + "system-configuration", "tokio", + "tokio-native-tls", + "tokio-rustls 0.26.0", "tokio-util", "tower-service", "url", @@ -2815,6 +2816,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", + "webpki-roots", "windows-registry", ] @@ -2854,6 +2856,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustfmt-wrapper" version = "0.2.1" @@ -2894,18 +2902,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.4" @@ -2915,18 +2911,23 @@ dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.7", + "rustls-webpki", "subtle", "zeroize", ] [[package]] -name = "rustls-pemfile" -version = "1.0.4" +name = "rustls" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ - "base64 0.21.7", + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", ] [[package]] @@ -2945,16 +2946,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - [[package]] name = "rustls-webpki" version = "0.102.7" @@ -3028,16 +3019,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - [[package]] name = "security-framework" version = "2.11.1" @@ -3442,12 +3423,6 @@ 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 = "sync_wrapper" version = "1.0.1" @@ -3459,20 +3434,20 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", @@ -3707,21 +3682,22 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.21.12", + "rustls 0.22.4", + "rustls-pki-types", "tokio", ] [[package]] name = "tokio-rustls" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.22.4", + "rustls 0.23.12", "rustls-pki-types", "tokio", ] @@ -4182,9 +4158,12 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "winapi" @@ -4423,16 +4402,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "xtask" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index f3ab8a79..3606d5b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ libc = "0.2.159" log = "0.4.22" md5 = "0.7.0" newline-converter = "0.3.0" -oauth2 = "4.4.2" +oauth2 = "5.0.0-rc.1" open = "4.2.0" oxide = { path = "sdk", version = "0.8.0" } oxide-httpmock = { path = "sdk-httpmock", version = "0.8.0" } @@ -40,13 +40,13 @@ oxnet = { git = "https://github.com/oxidecomputer/oxnet" } predicates = "3.1.2" pretty_assertions = "1.4.1" progenitor = { git = "https://github.com/oxidecomputer/progenitor" } -progenitor-client = "0.7.0" +progenitor-client = "0.8.0" rand = "0.8.5" ratatui = "0.26.3" rcgen = "0.10.0" regex = "1.11.0" regress = "0.10.1" -reqwest = "0.11.27" +reqwest = "0.12.8" rustfmt-wrapper = "0.2.1" schemars = { version = "0.8.20", features = ["chrono", "uuid1"] } serde = { version = "1.0.210", features = ["derive"] } diff --git a/cli/src/cmd_auth.rs b/cli/src/cmd_auth.rs index 6db1bef3..8f383e29 100644 --- a/cli/src/cmd_auth.rs +++ b/cli/src/cmd_auth.rs @@ -13,10 +13,8 @@ use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; use clap::Parser; use indicatif::{ProgressBar, ProgressStyle}; -use oauth2::{ - basic::BasicClient, devicecode::StandardDeviceAuthorizationResponse, AuthType, AuthUrl, - ClientId, DeviceAuthorizationUrl, TokenResponse, TokenUrl, -}; +use oauth2::{basic::BasicClient, AuthType, AuthUrl, ClientId, DeviceAuthorizationUrl, TokenUrl}; +use oauth2::{StandardDeviceAuthorizationResponse, TokenResponse}; use oxide::types::CurrentUser; use oxide::{Client, ClientConfig, ClientSessionExt}; use std::time::Duration; @@ -187,28 +185,6 @@ impl CmdAuthLogin { .make_unauthenticated_client_builder() .redirect(reqwest::redirect::Policy::none()) .build()?; - // Copied from oauth2::async_http_client to customize the - // reqwest::Client with the top-level command-line options. - let async_http_client_custom = |request: oauth2::HttpRequest| async move { - let mut request_builder = client - .request(request.method, request.url.as_str()) - .body(request.body); - for (name, value) in &request.headers { - request_builder = request_builder.header(name.as_str(), value.as_bytes()); - } - let request = request_builder.build()?; - - let response = client.execute(request).await?; - - let status_code = response.status(); - let headers = response.headers().to_owned(); - let chunks = response.bytes().await?; - std::result::Result::<_, reqwest::Error>::Ok(oauth2::HttpResponse { - status_code, - headers, - body: chunks.to_vec(), - }) - }; // Do an OAuth 2.0 Device Authorization Grant dance to get a token. let device_auth_url = DeviceAuthorizationUrl::new(format!("{}device/auth", &self.host))?; @@ -216,18 +192,15 @@ impl CmdAuthLogin { // since we're not doing that and this ID would be public if it were // static, we just generate a random one each time we authenticate. let client_id = Uuid::new_v4(); - let auth_client = BasicClient::new( - ClientId::new(client_id.to_string()), - None, - AuthUrl::new(format!("{}authorize", &self.host))?, - Some(TokenUrl::new(format!("{}device/token", &self.host))?), - ) - .set_auth_type(AuthType::RequestBody) - .set_device_authorization_url(device_auth_url); + let auth_client = BasicClient::new(ClientId::new(client_id.to_string())) + .set_auth_uri(AuthUrl::new(format!("{}authorize", &self.host))?) + .set_token_uri(TokenUrl::new(format!("{}device/token", &self.host))?) + .set_auth_type(AuthType::RequestBody) + .set_device_authorization_url(device_auth_url); let details: StandardDeviceAuthorizationResponse = auth_client - .exchange_device_code()? - .request_async(async_http_client_custom) + .exchange_device_code() + .request_async(client) .await?; let uri = details.verification_uri().to_string(); @@ -253,7 +226,7 @@ impl CmdAuthLogin { let token = auth_client .exchange_device_access_token(&details) - .request_async(async_http_client_custom, tokio::time::sleep, None) + .request_async(client, tokio::time::sleep, None) .await? .access_token() .secret() @@ -543,10 +516,15 @@ impl CmdAuthStatus { if error.is_timeout() { "Request timed out".to_string() } else if error.is_connect() { - // Reqwest will just tell us there was an error; we want to - // look at its internal error to understand the cause. + // Unfortunately this relies on internal knowledge of + // reqwest::Error. In particular, in this case its source + // will be a hyper_util::client::legacy::Error. Both the + // reqwest error and the hyper_util error effectively add + // no useful information. We therefore descend twice into + // the source list to find a useful error to report. let details = error .source() + .and_then(Error::source) .map_or("(no details)".to_string(), ToString::to_string); format!("Failed to connect to server: {}", details) } else { @@ -639,8 +617,8 @@ mod tests { .arg(bad_url) .assert() .failure() - .stderr(str::starts_with(format!( - "Request failed: error sending request for url (https://{bad_url}/device/auth):" + .stderr(str::starts_with(&format!( + "Request failed: request failed: error sending request for url (https://{bad_url}/device/auth):" ))); } diff --git a/cli/tests/data/test_auth_status.stdout b/cli/tests/data/test_auth_status.stdout index 3c935cd7..8b382f00 100644 --- a/cli/tests/data/test_auth_status.stdout +++ b/cli/tests/data/test_auth_status.stdout @@ -1,4 +1,4 @@ Profile "jennifer" () status: Authenticated Profile "lightman" () status: Authenticated Profile "malvin" () status: Server responded with an error message: ** IMPROPER REQUEST ** -Profile "sting" (https://unresolvabledomainnameihope) status: Failed to connect to server: error trying to connect: \ No newline at end of file +Profile "sting" (https://unresolvabledomainnameihope) status: Failed to connect to server: \ No newline at end of file