73 lines
2.5 KiB
Rust
73 lines
2.5 KiB
Rust
use db::sqlx;
|
|
use model::users::{UserPrivacyModel, UserProfileModel};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::{AppService, error::AppError};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
|
pub struct PublicUserResponse {
|
|
pub username: String,
|
|
pub display_name: String,
|
|
pub avatar_url: String,
|
|
pub website_url: String,
|
|
pub language: String,
|
|
pub timezone: String,
|
|
pub allow_direct_messages: bool,
|
|
pub show_online_status: bool,
|
|
}
|
|
|
|
impl AppService {
|
|
pub async fn users_public_by_username(
|
|
&self,
|
|
username: &str,
|
|
) -> Result<PublicUserResponse, AppError> {
|
|
let user = self.users_find_active_user_by_username(username).await?;
|
|
|
|
let privacy = sqlx::query_as::<_, UserPrivacyModel>(
|
|
"SELECT \"user\", profile_visibility, email_visibility, activity_visibility, allow_search_indexing, allow_direct_messages, show_online_status, created_at, updated_at \
|
|
FROM user_privacy WHERE \"user\" = $1",
|
|
)
|
|
.bind(user.id)
|
|
.fetch_optional(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
if privacy
|
|
.as_ref()
|
|
.is_some_and(|privacy| privacy.profile_visibility == "private")
|
|
{
|
|
return Err(AppError::Forbidden("profile is private".to_string()));
|
|
}
|
|
|
|
let profile = sqlx::query_as::<_, UserProfileModel>(
|
|
"SELECT \"user\", language, theme, timezone, created_at, updated_at \
|
|
FROM user_profile WHERE \"user\" = $1",
|
|
)
|
|
.bind(user.id)
|
|
.fetch_optional(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
Ok(PublicUserResponse {
|
|
username: user.username,
|
|
display_name: user.display_name,
|
|
avatar_url: user.avatar_url,
|
|
website_url: user.website_url,
|
|
language: profile
|
|
.as_ref()
|
|
.map(|profile| profile.language.clone())
|
|
.unwrap_or_else(|| "en".to_string()),
|
|
timezone: profile
|
|
.map(|profile| profile.timezone)
|
|
.unwrap_or_else(|| "UTC".to_string()),
|
|
allow_direct_messages: privacy
|
|
.as_ref()
|
|
.map(|privacy| privacy.allow_direct_messages)
|
|
.unwrap_or(true),
|
|
show_online_status: privacy
|
|
.map(|privacy| privacy.show_online_status)
|
|
.unwrap_or(true),
|
|
})
|
|
}
|
|
}
|