108 lines
3.2 KiB
Rust
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(())
|
|
}
|