use models::users::user; use models::users::user::ProfileVisibility; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; use uuid::Uuid; use super::AuthService; use crate::errors::AuthError; use crate::share::types::UserPublic; const MAX_BATCH_USERS: usize = 100; impl AuthService { fn filter_public_user(&self, caller: i64, user: user::Model) -> Result { if !user.is_active || user.system { return Err(AuthError::NotFound); } if user.visibility == ProfileVisibility::Private && caller != user.uid { return Err(AuthError::NotFound); } Ok(UserPublic { user_id: user.uid, username: user.username, display_name: user.display_name, avatar_url: space::services::spaces::resolve_user_avatar_url( user.uid, &user.avatar_url, ), }) } pub async fn public_user(&self, caller: i64, uid: i64) -> Result { let Some(user) = user::Entity::find_by_id(uid).one(self.db().read()).await? else { return Err(AuthError::NotFound); }; self.filter_public_user(caller, user) } pub async fn public_users( &self, caller: i64, ids: Vec, ) -> Result, AuthError> { if ids.len() > MAX_BATCH_USERS { return Err(AuthError::BadRequest(format!( "ids must contain at most {MAX_BATCH_USERS} entries" ))); } if ids.is_empty() { return Ok(Vec::new()); } let rows = user::Entity::find() .filter(user::Column::Uid.is_in(ids)) .all(self.db().read()) .await?; Ok(rows .into_iter() .filter_map(|u| self.filter_public_user(caller, u).ok()) .collect()) } pub async fn public_user_by_name( &self, caller: i64, username: &str, ) -> Result { let lower = username.trim().to_lowercase(); if lower.is_empty() { return Err(AuthError::NotFound); } let Some(user) = user::Entity::find() .filter(user::Column::LowerName.eq(&lower)) .one(self.db().read()) .await? else { return Err(AuthError::NotFound); }; self.filter_public_user(caller, user) } }