From 6b7d20efdb4f99152e384d7956ca147b4472a1fd Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 8 May 2026 12:21:09 -0400 Subject: [PATCH] collab: Route `UserService::get_user_by_github_login` through Cloud (#56190) This PR makes it so we route the `UserService::get_user_by_github_login` call through Cloud instead of hitting the database. Closes CLO-743. Release Notes: - N/A --- crates/cloud_api_types/src/internal_api.rs | 10 +++ crates/collab/src/services/user_service.rs | 76 +++++++++++++++------- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/crates/cloud_api_types/src/internal_api.rs b/crates/cloud_api_types/src/internal_api.rs index 954dcdad42036f7af0e1e7c833580a5ac0ef7163..ad3b4557fc080fa2c4b9b77c4c58753f55cad48c 100644 --- a/crates/cloud_api_types/src/internal_api.rs +++ b/crates/cloud_api_types/src/internal_api.rs @@ -20,3 +20,13 @@ pub struct LookUpUsersByLegacyIdBody { pub struct LookUpUsersByLegacyIdResponse { pub users: Vec, } + +#[derive(Debug, Serialize, Deserialize)] +pub struct LookUpUserByGithubLoginBody { + pub github_login: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct LookUpUserByGithubLoginResponse { + pub user: Option, +} diff --git a/crates/collab/src/services/user_service.rs b/crates/collab/src/services/user_service.rs index f2fb968b231de22e0742ce7c038724e56b432239..1f589213d51fbb551b0d8a9820a11fa668227aa8 100644 --- a/crates/collab/src/services/user_service.rs +++ b/crates/collab/src/services/user_service.rs @@ -3,9 +3,12 @@ use std::sync::Arc; use anyhow::{Context as _, anyhow}; use async_trait::async_trait; use cloud_api_types::internal_api::{ - self, LookUpUsersByLegacyIdBody, LookUpUsersByLegacyIdResponse, + self, LookUpUserByGithubLoginBody, LookUpUserByGithubLoginResponse, LookUpUsersByLegacyIdBody, + LookUpUsersByLegacyIdResponse, }; +use reqwest::RequestBuilder; use rpc::proto; +use serde::de::DeserializeOwned; use crate::Result; use crate::db::{Channel, Database, UserId}; @@ -65,7 +68,7 @@ impl UserService for TransitionalUserService { } async fn get_user_by_github_login(&self, github_login: &str) -> Result> { - self.database_user_service + self.cloud_user_service .get_user_by_github_login(github_login) .await } @@ -107,46 +110,75 @@ impl CloudUserService { internal_api_key, } } -} -#[async_trait] -impl UserService for CloudUserService { - async fn get_users_by_ids(&self, ids: Vec) -> Result> { - let response = self - .http_client - .post(format!( - "{}/internal/users/look_up_by_legacy_id", - &self.zed_cloud_url - )) + async fn send_request( + &self, + request: RequestBuilder, + ) -> Result { + let request = request .header("Content-Type", "application/json") .header( "Authorization", format!("Bearer {}", &self.internal_api_key), ) - .json(&LookUpUsersByLegacyIdBody { - legacy_user_ids: ids.into_iter().map(|id| id.0).collect(), - }) - .send() + .build() + .context("failed to build request")?; + + let response = self + .http_client + .execute(request) .await - .context("failed to get users by legacy IDs")?; + .context("failed to send request to Cloud")?; + let status = response.status(); match response.error_for_status() { Ok(response) => { - let response_body: LookUpUsersByLegacyIdResponse = response + let response_body: T = response .json() .await .context("failed to parse response body")?; - Ok(response_body.users.into_iter().map(User::from).collect()) + Ok(response_body) } - Err(_err) => Err(anyhow!("failed to get users by legacy IDs"))?, + Err(_err) => Err(anyhow!("request to Cloud failed with status {status}",))?, } } +} + +#[async_trait] +impl UserService for CloudUserService { + async fn get_users_by_ids(&self, ids: Vec) -> Result> { + let response_body: LookUpUsersByLegacyIdResponse = self + .send_request( + self.http_client + .post(format!( + "{}/internal/users/look_up_by_legacy_id", + &self.zed_cloud_url + )) + .json(&LookUpUsersByLegacyIdBody { + legacy_user_ids: ids.into_iter().map(|id| id.0).collect(), + }), + ) + .await?; + + Ok(response_body.users.into_iter().map(User::from).collect()) + } async fn get_user_by_github_login(&self, github_login: &str) -> Result> { - let _ = github_login; + let response_body: LookUpUserByGithubLoginResponse = self + .send_request( + self.http_client + .post(format!( + "{}/internal/users/look_up_by_github_login", + &self.zed_cloud_url + )) + .json(&LookUpUserByGithubLoginBody { + github_login: github_login.to_string(), + }), + ) + .await?; - unimplemented!("not yet implemented in Cloud") + Ok(response_body.user.map(User::from)) } async fn fuzzy_search_users(&self, query: &str, limit: u32) -> Result> {