Skip to content

Commit 6b7d20e

Browse files
authored
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
1 parent dc06395 commit 6b7d20e

2 files changed

Lines changed: 64 additions & 22 deletions

File tree

crates/cloud_api_types/src/internal_api.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,13 @@ pub struct LookUpUsersByLegacyIdBody {
2020
pub struct LookUpUsersByLegacyIdResponse {
2121
pub users: Vec<User>,
2222
}
23+
24+
#[derive(Debug, Serialize, Deserialize)]
25+
pub struct LookUpUserByGithubLoginBody {
26+
pub github_login: String,
27+
}
28+
29+
#[derive(Debug, Serialize, Deserialize)]
30+
pub struct LookUpUserByGithubLoginResponse {
31+
pub user: Option<User>,
32+
}

crates/collab/src/services/user_service.rs

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ use std::sync::Arc;
33
use anyhow::{Context as _, anyhow};
44
use async_trait::async_trait;
55
use cloud_api_types::internal_api::{
6-
self, LookUpUsersByLegacyIdBody, LookUpUsersByLegacyIdResponse,
6+
self, LookUpUserByGithubLoginBody, LookUpUserByGithubLoginResponse, LookUpUsersByLegacyIdBody,
7+
LookUpUsersByLegacyIdResponse,
78
};
9+
use reqwest::RequestBuilder;
810
use rpc::proto;
11+
use serde::de::DeserializeOwned;
912

1013
use crate::Result;
1114
use crate::db::{Channel, Database, UserId};
@@ -65,7 +68,7 @@ impl UserService for TransitionalUserService {
6568
}
6669

6770
async fn get_user_by_github_login(&self, github_login: &str) -> Result<Option<User>> {
68-
self.database_user_service
71+
self.cloud_user_service
6972
.get_user_by_github_login(github_login)
7073
.await
7174
}
@@ -107,46 +110,75 @@ impl CloudUserService {
107110
internal_api_key,
108111
}
109112
}
110-
}
111113

112-
#[async_trait]
113-
impl UserService for CloudUserService {
114-
async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<User>> {
115-
let response = self
116-
.http_client
117-
.post(format!(
118-
"{}/internal/users/look_up_by_legacy_id",
119-
&self.zed_cloud_url
120-
))
114+
async fn send_request<T: DeserializeOwned + 'static>(
115+
&self,
116+
request: RequestBuilder,
117+
) -> Result<T> {
118+
let request = request
121119
.header("Content-Type", "application/json")
122120
.header(
123121
"Authorization",
124122
format!("Bearer {}", &self.internal_api_key),
125123
)
126-
.json(&LookUpUsersByLegacyIdBody {
127-
legacy_user_ids: ids.into_iter().map(|id| id.0).collect(),
128-
})
129-
.send()
124+
.build()
125+
.context("failed to build request")?;
126+
127+
let response = self
128+
.http_client
129+
.execute(request)
130130
.await
131-
.context("failed to get users by legacy IDs")?;
131+
.context("failed to send request to Cloud")?;
132132

133+
let status = response.status();
133134
match response.error_for_status() {
134135
Ok(response) => {
135-
let response_body: LookUpUsersByLegacyIdResponse = response
136+
let response_body: T = response
136137
.json()
137138
.await
138139
.context("failed to parse response body")?;
139140

140-
Ok(response_body.users.into_iter().map(User::from).collect())
141+
Ok(response_body)
141142
}
142-
Err(_err) => Err(anyhow!("failed to get users by legacy IDs"))?,
143+
Err(_err) => Err(anyhow!("request to Cloud failed with status {status}",))?,
143144
}
144145
}
146+
}
147+
148+
#[async_trait]
149+
impl UserService for CloudUserService {
150+
async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<User>> {
151+
let response_body: LookUpUsersByLegacyIdResponse = self
152+
.send_request(
153+
self.http_client
154+
.post(format!(
155+
"{}/internal/users/look_up_by_legacy_id",
156+
&self.zed_cloud_url
157+
))
158+
.json(&LookUpUsersByLegacyIdBody {
159+
legacy_user_ids: ids.into_iter().map(|id| id.0).collect(),
160+
}),
161+
)
162+
.await?;
163+
164+
Ok(response_body.users.into_iter().map(User::from).collect())
165+
}
145166

146167
async fn get_user_by_github_login(&self, github_login: &str) -> Result<Option<User>> {
147-
let _ = github_login;
168+
let response_body: LookUpUserByGithubLoginResponse = self
169+
.send_request(
170+
self.http_client
171+
.post(format!(
172+
"{}/internal/users/look_up_by_github_login",
173+
&self.zed_cloud_url
174+
))
175+
.json(&LookUpUserByGithubLoginBody {
176+
github_login: github_login.to_string(),
177+
}),
178+
)
179+
.await?;
148180

149-
unimplemented!("not yet implemented in Cloud")
181+
Ok(response_body.user.map(User::from))
150182
}
151183

152184
async fn fuzzy_search_users(&self, query: &str, limit: u32) -> Result<Vec<User>> {

0 commit comments

Comments
 (0)