diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index ccd7bda344..7588f15f51 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -5,7 +5,7 @@ mod socks; pub mod telemetry; pub mod user; -use anyhow::{anyhow, Context as _, Result}; +use anyhow::{anyhow, bail, Context as _, Result}; use async_recursion::async_recursion; use async_tungstenite::tungstenite::{ client::IntoClientRequest, @@ -1395,11 +1395,64 @@ impl Client { id: u64, } + let github_user = { + #[derive(Deserialize)] + struct GithubUser { + id: i32, + login: String, + } + + let request = { + let mut request_builder = + Request::get(&format!("https://api.github.com/users/{login}")); + if let Ok(github_token) = std::env::var("GITHUB_TOKEN") { + request_builder = + request_builder.header("Authorization", format!("Bearer {}", github_token)); + } + + request_builder.body(AsyncBody::empty())? + }; + + let mut response = http + .send(request) + .await + .context("error fetching GitHub user")?; + + let mut body = Vec::new(); + response + .body_mut() + .read_to_end(&mut body) + .await + .context("error reading GitHub user")?; + + if !response.status().is_success() { + let text = String::from_utf8_lossy(body.as_slice()); + bail!( + "status error {}, response: {text:?}", + response.status().as_u16() + ); + } + + let user = serde_json::from_slice::(body.as_slice()).map_err(|err| { + log::error!("Error deserializing: {:?}", err); + log::error!( + "GitHub API response text: {:?}", + String::from_utf8_lossy(body.as_slice()) + ); + anyhow!("error deserializing GitHub user") + })?; + + user + }; + // Use the collab server's admin API to retrieve the id // of the impersonated user. let mut url = self.rpc_url(http.clone(), None).await?; url.set_path("/user"); - url.set_query(Some(&format!("github_login={login}"))); + url.set_query(Some(&format!( + "github_login={}&github_user_id={}", + github_user.login, github_user.id + ))); let request: http_client::Request = Request::get(url.as_str()) .header("Authorization", format!("token {api_token}")) .body("".into())?;