collab: Remove database access in Authorization header verification (#56558)

This PR removes the database access in the `Authorization` header
verification in Collab.

We already have the user returned from the call to Cloud, but were just
fetching the user from the database to get some additional fields.

We're now returning the additional fields we need from Cloud, so we can
just convert the user from the internal API response into a `User`
entity.

Closes CLO-762.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2026-05-13 11:17:42 -04:00 committed by GitHub
parent 074585934c
commit bb18442e2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 17 additions and 35 deletions

View file

@ -247,6 +247,7 @@ pub fn make_get_authenticated_user_response(
name: None,
is_staff: false,
accepted_tos_at: None,
has_connected_to_collab_once: false,
},
feature_flags: vec![],
organizations: vec![],

View file

@ -41,6 +41,7 @@ pub struct AuthenticatedUser {
pub name: Option<String>,
pub is_staff: bool,
pub accepted_tos_at: Option<Timestamp>,
pub has_connected_to_collab_once: bool,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]

View file

@ -5,7 +5,7 @@ pub struct User {
pub id: String,
pub legacy_user_id: i32,
pub github_login: String,
pub github_user_id: i32,
pub avatar_url: String,
pub name: Option<String>,
pub admin: bool,
pub connected_once: bool,

View file

@ -1,3 +1,4 @@
use crate::entities::User;
use crate::{AppState, Error, db::UserId, rpc::Principal};
use anyhow::Context as _;
use axum::{
@ -65,15 +66,16 @@ pub async fn validate_header<B>(mut req: Request<B>, next: Next<B>) -> impl Into
.await
.context("failed to parse response body")?;
let user_id = UserId(response_body.user.id);
let user = User {
id: UserId(response_body.user.id),
github_login: response_body.user.github_login,
avatar_url: response_body.user.avatar_url,
name: response_body.user.name,
admin: response_body.user.is_staff,
connected_once: response_body.user.has_connected_to_collab_once,
};
let user = state
.db
.get_user_by_id(user_id)
.await?
.with_context(|| format!("user {user_id} not found"))?;
req.extensions_mut().insert(Principal::User(user.into()));
req.extensions_mut().insert(Principal::User(user));
return Ok::<_, Error>(next.run(req).await);
}

View file

@ -38,12 +38,6 @@ impl Database {
.await
}
/// Returns a user by ID. There are no access checks here, so this should only be used internally.
pub async fn get_user_by_id(&self, id: UserId) -> Result<Option<user::Model>> {
self.transaction(|tx| async move { Ok(user::Entity::find_by_id(id).one(&*tx).await?) })
.await
}
pub async fn update_or_create_user_by_github_account(
&self,
github_login: &str,

View file

@ -19,19 +19,6 @@ pub struct Model {
pub created_at: NaiveDateTime,
}
impl From<Model> for crate::entities::User {
fn from(user: Model) -> Self {
crate::entities::User {
id: user.id,
github_login: user.github_login,
github_user_id: user.github_user_id,
name: user.name,
admin: user.admin,
connected_once: user.connected_once,
}
}
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_one = "super::room_participant::Entity")]

View file

@ -4,7 +4,7 @@ use crate::db::UserId;
pub struct User {
pub id: UserId,
pub github_login: String,
pub github_user_id: i32,
pub avatar_url: String,
pub name: Option<String>,
pub admin: bool,
pub connected_once: bool,

View file

@ -4226,10 +4226,7 @@ impl From<User> for proto::User {
fn from(user: User) -> Self {
Self {
id: user.id.to_proto(),
avatar_url: format!(
"https://avatars.githubusercontent.com/u/{}?s=128&v=4",
user.github_user_id
),
avatar_url: user.avatar_url,
github_login: user.github_login,
name: user.name,
}

View file

@ -211,8 +211,8 @@ impl From<internal_api::User> for User {
fn from(user: internal_api::User) -> Self {
Self {
id: UserId(user.legacy_user_id),
avatar_url: user.avatar_url,
github_login: user.github_login,
github_user_id: user.github_user_id,
name: user.name,
admin: user.admin,
connected_once: user.connected_once,
@ -281,8 +281,8 @@ mod fake_user_service {
user_id,
User {
id: user_id,
avatar_url: format!("https://github.com/{}.png?size=128", params.github_login),
github_login: params.github_login,
github_user_id: params.github_user_id,
name: name.map(|name| name.to_string()),
admin,
connected_once: false,