gitdataai/lib/service/user/privacy.rs

120 lines
4.6 KiB
Rust

use db::sqlx;
use model::users::UserPrivacyModel;
use serde::{Deserialize, Serialize};
use session::Session;
use crate::{AppService, error::AppError, session_user};
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct UserPrivacyConfig {
pub profile_visibility: String,
pub email_visibility: String,
pub activity_visibility: String,
pub allow_search_indexing: bool,
pub allow_direct_messages: bool,
pub show_online_status: bool,
}
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
pub struct UpdateUserPrivacyConfig {
pub profile_visibility: Option<String>,
pub email_visibility: Option<String>,
pub activity_visibility: Option<String>,
pub allow_search_indexing: Option<bool>,
pub allow_direct_messages: Option<bool>,
pub show_online_status: Option<bool>,
}
impl AppService {
pub async fn user_update_privacy_config(
&self,
ctx: &Session,
params: UpdateUserPrivacyConfig,
) -> Result<UserPrivacyConfig, AppError> {
let user_uid = session_user(ctx)?;
let mut config = self.user_privacy_config(user_uid).await?;
if let Some(profile_visibility) = params.profile_visibility {
config.profile_visibility = profile_visibility;
}
if let Some(email_visibility) = params.email_visibility {
config.email_visibility = email_visibility;
}
if let Some(activity_visibility) = params.activity_visibility {
config.activity_visibility = activity_visibility;
}
if let Some(allow_search_indexing) = params.allow_search_indexing {
config.allow_search_indexing = allow_search_indexing;
}
if let Some(allow_direct_messages) = params.allow_direct_messages {
config.allow_direct_messages = allow_direct_messages;
}
if let Some(show_online_status) = params.show_online_status {
config.show_online_status = show_online_status;
}
let now = chrono::Utc::now();
sqlx::query(
"INSERT INTO user_privacy \
(\"user\", profile_visibility, email_visibility, activity_visibility, allow_search_indexing, allow_direct_messages, show_online_status, created_at, updated_at) \
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $8) \
ON CONFLICT (\"user\") DO UPDATE SET \
profile_visibility = EXCLUDED.profile_visibility, email_visibility = EXCLUDED.email_visibility, \
activity_visibility = EXCLUDED.activity_visibility, allow_search_indexing = EXCLUDED.allow_search_indexing, \
allow_direct_messages = EXCLUDED.allow_direct_messages, show_online_status = EXCLUDED.show_online_status, \
updated_at = EXCLUDED.updated_at",
)
.bind(user_uid)
.bind(&config.profile_visibility)
.bind(&config.email_visibility)
.bind(&config.activity_visibility)
.bind(config.allow_search_indexing)
.bind(config.allow_direct_messages)
.bind(config.show_online_status)
.bind(now)
.execute(self.db.writer())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
Ok(config)
}
pub async fn user_privacy_config(
&self,
user_uid: uuid::Uuid,
) -> Result<UserPrivacyConfig, AppError> {
let row = 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_uid)
.fetch_optional(self.db.reader())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
Ok(row.map(Into::into).unwrap_or_default())
}
}
impl Default for UserPrivacyConfig {
fn default() -> Self {
Self {
profile_visibility: "public".to_string(),
email_visibility: "private".to_string(),
activity_visibility: "public".to_string(),
allow_search_indexing: true,
allow_direct_messages: true,
show_online_status: true,
}
}
}
impl From<UserPrivacyModel> for UserPrivacyConfig {
fn from(value: UserPrivacyModel) -> Self {
Self {
profile_visibility: value.profile_visibility,
email_visibility: value.email_visibility,
activity_visibility: value.activity_visibility,
allow_search_indexing: value.allow_search_indexing,
allow_direct_messages: value.allow_direct_messages,
show_online_status: value.show_online_status,
}
}
}