Files
psg-backchannel/backchannel-server/src/handlers/channels.rs
2026-02-19 13:51:07 +08:00

108 lines
3.2 KiB
Rust

use std::sync::Arc;
use backchannel_common::protocol::ServerMessage;
use backchannel_common::types::{has_permission, PermissionFlags};
use uuid::Uuid;
use crate::db::{channels, messages, roles};
use crate::error::{Result, ServerError};
use crate::state::{AppState, ChannelBroadcast};
use crate::ws::session::Session;
pub async fn handle_send(
session: &Session,
state: &Arc<AppState>,
channel_id: Uuid,
content: String,
) -> Result<()> {
let user_id = session.require_auth()?;
let username = session.require_username()?.to_string();
channels::find_by_id(&state.db, channel_id)
.await?
.ok_or_else(|| ServerError::NotFound("Channel not found".into()))?;
let perms = roles::get_user_permissions(&state.db, user_id).await?;
if !has_permission(perms, PermissionFlags::SEND_MESSAGES) {
return Err(ServerError::Forbidden);
}
let (message_id, timestamp) =
messages::insert_channel_message(&state.db, channel_id, user_id, &content).await?;
let _ = state.channel_broadcast.send(ChannelBroadcast {
message: ServerMessage::ChannelMessage {
message_id,
channel_id,
author_id: user_id,
author_username: username,
content,
timestamp,
},
});
Ok(())
}
pub async fn handle_history(
session: &Session,
state: &Arc<AppState>,
channel_id: Uuid,
before_message_id: Option<Uuid>,
limit: u32,
) -> Result<()> {
let user_id = session.require_auth()?;
let perms = roles::get_user_permissions(&state.db, user_id).await?;
if !has_permission(perms, PermissionFlags::READ_MESSAGES) {
return Err(ServerError::Forbidden);
}
let msgs = messages::fetch_channel_history(&state.db, channel_id, before_message_id, limit).await?;
session.send(ServerMessage::ChannelHistory { channel_id, messages: msgs })
}
pub async fn handle_create(
session: &Session,
state: &Arc<AppState>,
name: String,
topic: Option<String>,
) -> Result<()> {
let user_id = session.require_auth()?;
let perms = roles::get_user_permissions(&state.db, user_id).await?;
if !has_permission(perms, PermissionFlags::MANAGE_CHANNELS) {
return Err(ServerError::Forbidden);
}
if channels::name_exists(&state.db, &name).await? {
return Err(ServerError::BadRequest("Channel name already exists".into()));
}
let channel_id = channels::create(&state.db, &name, topic.as_deref(), user_id).await?;
let _ = state.channel_broadcast.send(ChannelBroadcast {
message: ServerMessage::ChannelCreated { channel_id, name, topic },
});
Ok(())
}
pub async fn handle_delete(
session: &Session,
state: &Arc<AppState>,
channel_id: Uuid,
) -> Result<()> {
let user_id = session.require_auth()?;
let perms = roles::get_user_permissions(&state.db, user_id).await?;
if !has_permission(perms, PermissionFlags::MANAGE_CHANNELS) {
return Err(ServerError::Forbidden);
}
if !channels::delete(&state.db, channel_id).await? {
return Err(ServerError::NotFound("Channel not found".into()));
}
let _ = state.channel_broadcast.send(ChannelBroadcast {
message: ServerMessage::ChannelDeleted { channel_id },
});
Ok(())
}