use chrono::Utc; use uuid::Uuid; use crate::event::{UserInfo, WorkspaceInfo, ban}; use crate::{ChannelBus, ChannelResult}; use super::WsOutEvent; use super::WsHandler; impl WsHandler { pub(super) async fn ban_create( bus: &ChannelBus, _user_id: Uuid, workspace: Uuid, user: Uuid, reason: Option, _expires_at: Option>, ) -> ChannelResult> { Self::ensure_workspace_member(bus, _user_id, workspace).await?; db::sqlx::query( "INSERT INTO user_blacklist (\"user\", black, created_at) \ VALUES ($1, $2, now()) \ ON CONFLICT DO NOTHING", ) .bind(user) .bind(_user_id) .execute(bus.inner.db.writer()) .await?; let ban_key = format!("ban:{}:{}:{}", workspace, _user_id, user); let ban_data = serde_json::json!({ "workspace": workspace, "banned_by": _user_id, "reason": reason, "expires_at": _expires_at, "banned_at": Utc::now(), }); bus.inner.cache.set(&ban_key, &ban_data).await?; let data = ban::BannedService { workspace: bus.lookup_workspace(workspace).await.unwrap_or_else(|_| WorkspaceInfo::unknown(workspace)), user: bus.lookup_user(user).await.unwrap_or_else(|_| UserInfo::unknown(user)), banned_by: bus.lookup_user(_user_id).await.unwrap_or_else(|_| UserInfo::unknown(_user_id)), reason, expires_at: _expires_at, banned_at: Utc::now(), }; bus.workspace_changed(workspace).await?; Ok(Some(WsOutEvent::UserBanned { data })) } pub(super) async fn ban_remove( bus: &ChannelBus, _user_id: Uuid, workspace: Uuid, user: Uuid, ) -> ChannelResult> { db::sqlx::query( "DELETE FROM user_blacklist WHERE \"user\" = $1 AND black = $2", ) .bind(user) .bind(_user_id) .execute(bus.inner.db.writer()) .await?; let ban_key = format!("ban:{}:{}:{}", workspace, _user_id, user); bus.inner.cache.remove(&ban_key).await?; let data = ban::UnbannedService { workspace: bus.lookup_workspace(workspace).await.unwrap_or_else(|_| WorkspaceInfo::unknown(workspace)), user: bus.lookup_user(user).await.unwrap_or_else(|_| UserInfo::unknown(user)), unbanned_by: bus.lookup_user(_user_id).await.unwrap_or_else(|_| UserInfo::unknown(_user_id)), unbanned_at: Utc::now(), }; bus.workspace_changed(workspace).await?; Ok(Some(WsOutEvent::UserUnbanned { data })) } }