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

88 lines
2.4 KiB
Rust

use std::sync::Arc;
use backchannel_common::protocol::ServerMessage;
use backchannel_common::types::{has_permission, PermissionFlags};
use uuid::Uuid;
use crate::db::{keys, roles};
use crate::error::{Result, ServerError};
use crate::state::{AppState, ChannelBroadcast};
use crate::ws::session::Session;
pub async fn handle_create(
session: &Session,
state: &Arc<AppState>,
name: String,
permissions: u64,
) -> Result<()> {
let user_id = session.require_auth()?;
let perms = roles::get_user_permissions(&state.db, user_id).await?;
if !has_permission(perms, PermissionFlags::MANAGE_ROLES) {
return Err(ServerError::Forbidden);
}
let role_id = roles::create(&state.db, &name, permissions).await?;
let _ = state.channel_broadcast.send(ChannelBroadcast {
message: ServerMessage::RoleCreated { role_id, name, permissions },
});
Ok(())
}
pub async fn handle_assign(
session: &Session,
state: &Arc<AppState>,
user_id: Uuid,
role_id: Uuid,
) -> Result<()> {
let caller_id = session.require_auth()?;
let perms = roles::get_user_permissions(&state.db, caller_id).await?;
if !has_permission(perms, PermissionFlags::MANAGE_ROLES) {
return Err(ServerError::Forbidden);
}
roles::find_by_id(&state.db, role_id)
.await?
.ok_or_else(|| ServerError::NotFound("Role not found".into()))?;
roles::assign(&state.db, user_id, role_id).await?;
let _ = state.channel_broadcast.send(ChannelBroadcast {
message: ServerMessage::RoleAssigned { user_id, role_id },
});
Ok(())
}
pub async fn handle_revoke(
session: &Session,
state: &Arc<AppState>,
user_id: Uuid,
role_id: Uuid,
) -> Result<()> {
let caller_id = session.require_auth()?;
let perms = roles::get_user_permissions(&state.db, caller_id).await?;
if !has_permission(perms, PermissionFlags::MANAGE_ROLES) {
return Err(ServerError::Forbidden);
}
roles::revoke(&state.db, user_id, role_id).await?;
let _ = state.channel_broadcast.send(ChannelBroadcast {
message: ServerMessage::RoleRevoked { user_id, role_id },
});
Ok(())
}
pub async fn handle_query_key(
session: &Session,
state: &Arc<AppState>,
user_id: Uuid,
) -> Result<()> {
session.require_auth()?;
let pubkey = keys::get_identity_key(&state.db, user_id).await?;
session.send(ServerMessage::IdentityKeyResponse { user_id, identity_pubkey: pubkey })
}