This commit is contained in:
2026-08-09 10:30:54 +02:00
parent 93800e8460
commit 20beea24d5
11 changed files with 325 additions and 61 deletions
+53 -4
View File
@@ -1,17 +1,19 @@
use crate::core::AppState;
use crate::http::context::CurrentUser;
use crate::models::user::Model as User;
use crate::permissions::ChannelPermission;
use crate::routes::gateway::GatewayClient;
use axum::{
extract::{
ws::{Message, WebSocket, WebSocketUpgrade},
State,
ws::{Message, WebSocket, WebSocketUpgrade},
},
response::IntoResponse,
};
use futures_util::{sink::SinkExt, stream::StreamExt};
use serde::Deserialize;
use tokio::sync::mpsc;
use uuid::Uuid;
#[derive(Deserialize)]
pub struct WsQuery {
@@ -41,9 +43,17 @@ async fn handle_socket(socket: WebSocket, state: AppState, user: User) {
let (mut sender, mut receiver) = socket.split();
let (tx, mut rx) = mpsc::unbounded_channel::<Message>();
let channel_ids = match accessible_channel_ids(&state, &user).await {
Ok(channel_ids) => channel_ids,
Err(error) => {
tracing::error!(user_id = %user.id, ?error, "Unable to resolve gateway channel access");
return;
}
};
let mut client = GatewayClient::new(user, tx, state.event_bus.clone());
client.on_connect().await;
state.gateway.add_client(client.clone());
state.gateway.add_client(client.clone(), channel_ids);
// Task pour envoyer les messages du canal mpsc vers le WebSocket
let mut send_task = tokio::spawn(async move {
@@ -56,7 +66,6 @@ async fn handle_socket(socket: WebSocket, state: AppState, user: User) {
// Task pour recevoir les messages du WebSocket
let client_clone = client.clone();
let state_clone = state.clone();
let mut recv_task = tokio::spawn(async move {
while let Some(Ok(message)) = receiver.next().await {
client_clone.on_message(message).await;
@@ -69,7 +78,47 @@ async fn handle_socket(socket: WebSocket, state: AppState, user: User) {
_ = (&mut recv_task) => send_task.abort(),
};
state.gateway.remove_client(client.clone());
state.gateway.remove_client(&client);
// // Déconnexion (Disconnect)
client.on_disconnect().await;
}
async fn accessible_channel_ids(state: &AppState, user: &User) -> Result<Vec<Uuid>, anyhow::Error> {
if user.is_superuser {
return Ok(state
.repositories
.channel
.get_all()
.await?
.into_iter()
.map(|channel| channel.id)
.collect());
}
let mut channel_ids = Vec::new();
for server in state.repositories.server.get_all().await? {
if state
.repositories
.server
.get_user(server.id, user.id)
.await?
.is_none()
{
continue;
}
let tree = state
.repositories
.server_tree
.get_for_user(server.id, user.id)
.await?;
channel_ids.extend(tree.channels.into_iter().filter_map(|channel| {
channel
.permissions
.filter(|permissions| permissions.contains(ChannelPermission::READ_CHANNEL))
.map(|_| channel.channel.id)
}));
}
Ok(channel_ids)
}