This commit is contained in:
2026-08-30 16:08:57 +02:00
parent f2197a6b28
commit 78cb70d8e8
28 changed files with 740 additions and 42 deletions
+25 -2
View File
@@ -21,6 +21,23 @@ pub async fn join(
State(state): State<AppState>,
ValidatedJson(payload): ValidatedJson<JoinRequest>,
) -> Result<impl IntoResponse, HTTPError> {
let target_server_id = if let Some(server_id) = payload.server_id {
let server = state
.repositories
.server
.get_by_id(server_id)
.await?
.ok_or(HTTPError::NotFound)?;
if server.password.is_some() {
return Err(HTTPError::BadRequest(
"This server requires a password; join it after creating your account".into(),
));
}
server_id
} else {
state.default_server.id
};
let user_exists = state
.repositories
.user
@@ -56,12 +73,18 @@ pub async fn join(
state
.repositories
.server
.add_user(state.default_server.id, user.id),
.add_user(target_server_id, user.id),
state
.repositories
.role
.add_to_default(user.id, state.default_server.id)
.add_to_default(user.id, target_server_id)
)?;
state
.repositories
.read_state
.mark_server_read(target_server_id, user.id)
.await?;
Ok(StatusCode::CREATED)
}
+8
View File
@@ -214,6 +214,14 @@ pub async fn create(
)
.await
.map_err(|error| HTTPError::BadRequest(error.to_string()))?;
// L'auteur a forcément lu le message qu'il vient d'envoyer.
state
.repositories
.read_state
.set(message.channel_id, user.id, Some(message.id))
.await?;
let attachments = state
.repositories
.message
+2
View File
@@ -16,12 +16,14 @@ pub mod message;
pub mod openapi;
pub mod role;
pub mod server;
pub mod server_item_order;
pub mod user;
pub fn router() -> OxRouter {
// Routes nécessitant une authentification
let secure_routes = Router::new()
.merge(server::routes::router())
.merge(server_item_order::routes::router())
.merge(category::routes::router())
.merge(channel::routes::router())
.merge(conversation::routes::router())
+6
View File
@@ -18,9 +18,11 @@ use utoipa::{Modify, OpenApi};
server::handlers::get_all,
server::handlers::get_by_id,
server::handlers::create,
server::handlers::join,
server::handlers::update,
server::handlers::delete,
server::handlers::get_tree,
server_item_order::handlers::reorder,
category::handlers::get_all,
category::handlers::get_by_id,
category::handlers::create,
@@ -64,7 +66,11 @@ use utoipa::{Modify, OpenApi};
crate::domain::dto::user::UpdateUserRequest,
crate::domain::dto::server::ServerResponse,
crate::domain::dto::server::CreateServerRequest,
crate::domain::dto::server::JoinServerRequest,
crate::domain::dto::server::UpdateServerRequest,
crate::domain::dto::server_item_order::ReorderServerItemRequest,
crate::domain::dto::server_item_order::ServerItemOrderReference,
crate::domain::dto::server_item_order::ServerItemOrderPosition,
crate::domain::dto::category::CategoryResponse,
crate::domain::dto::category::CreateCategoryRequest,
crate::domain::dto::category::UpdateCategoryRequest,
+42 -5
View File
@@ -1,6 +1,7 @@
use crate::core::state::AppState;
use crate::domain::dto::server::{
CreateServerRequest, ServerResponse, ServerRolePermissionResponse, ServerTreeResponse,
CreateServerRequest, JoinServerRequest, ServerResponse, ServerRolePermissionResponse,
ServerTreeResponse,
ServerUserPermissionResponse, SetServerPermissionRequest, UpdateServerRequest,
};
use crate::http::context::{CurrentUser, Superuser};
@@ -54,7 +55,7 @@ pub async fn get_all(
user: CurrentUser,
State(state): State<AppState>,
) -> Result<Json<Vec<ServerResponse>>, HTTPError> {
let servers = state.repositories.server.get_all().await?;
let servers = state.repositories.server.get_all_for_user(user.id).await?;
let unread_counts = state
.repositories
.read_state
@@ -117,14 +118,14 @@ pub async fn get_by_id(
)
)]
pub async fn create(
_admin: Superuser,
user: CurrentUser,
State(state): State<AppState>,
Json(payload): Json<CreateServerRequest>,
) -> Result<(StatusCode, Json<ServerResponse>), HTTPError> {
let server = state
.services
.server
.create_server(payload.name, payload.is_default)
.create_server(payload.name, payload.password, payload.is_default, user.id)
.await?;
Ok((
StatusCode::CREATED,
@@ -132,6 +133,41 @@ pub async fn create(
))
}
#[utoipa::path(
post,
path = "/servers/{id}/join",
request_body = JoinServerRequest,
responses(
(status = 200, description = "Serveur rejoint", body = ServerResponse),
(status = 404, description = "Serveur introuvable"),
(status = 400, description = "Mot de passe incorrect")
),
params(("id" = Uuid, Path, description = "ID du serveur")),
tag = "Servers",
security(("bearerAuth" = []))
)]
pub async fn join(
user: CurrentUser,
State(state): State<AppState>,
Path(id): Path<Uuid>,
Json(payload): Json<JoinServerRequest>,
) -> Result<Json<ServerResponse>, HTTPError> {
let result = state
.services
.server
.join_server(id, user.id, payload.password)
.await;
match result {
Ok(server) => Ok(Json(mapper::server_model_to_server_response(server))),
Err(error) if error.to_string() == "Server not found" => Err(HTTPError::NotFound),
Err(error) if error.to_string() == "Invalid server password" => {
Err(HTTPError::BadRequest("Invalid server password".into()))
}
Err(error) => Err(HTTPError::Internal(error)),
}
}
/// Met à jour un serveur existant
#[utoipa::path(
put,
@@ -251,6 +287,7 @@ pub async fn list_user_permissions(
.get_by_id(server_id)
.await?
.ok_or(HTTPError::NotFound)?;
let permissions = state
.repositories
.server
@@ -491,7 +528,7 @@ pub async fn get_tree(
state
.repositories
.server
.get_by_id(server_id)
.get_by_id_for_user(server_id, user.id)
.await?
.ok_or(HTTPError::NotFound)?;
+2 -1
View File
@@ -1,10 +1,11 @@
use super::handlers;
use crate::core::state::AppState;
use axum::{Router, routing::get};
use axum::{Router, routing::{get, post}};
pub fn router() -> Router<AppState> {
Router::new()
.route("/servers", get(handlers::get_all).post(handlers::create))
.route("/servers/{id}/join", post(handlers::join))
.route(
"/servers/{id}",
get(handlers::get_by_id)
+40
View File
@@ -0,0 +1,40 @@
use crate::core::state::AppState;
use crate::domain::dto::server_item_order::ReorderServerItemRequest;
use crate::domain::events::server_tree::ServerTreeInvalidatedEvent;
use crate::http::context::CurrentUser;
use crate::http::error::HTTPError;
use axum::http::StatusCode;
use axum::{Json, extract::State};
#[utoipa::path(
put,
path = "/server-item-orders/reorder",
request_body = ReorderServerItemRequest,
responses((status = 204, description = "Ordre mis à jour")),
tag = "Server item orders",
security(("bearerAuth" = []))
)]
pub async fn reorder(
_user: CurrentUser,
State(state): State<AppState>,
Json(payload): Json<ReorderServerItemRequest>,
) -> Result<StatusCode, HTTPError> {
let server_id = payload.server_id;
state
.repositories
.server
.get_by_id(server_id)
.await?
.ok_or(HTTPError::NotFound)?;
state.services.server_order.reorder(payload).await?;
state.event_bus.emit(
"server_tree_invalidated",
ServerTreeInvalidatedEvent {
server_id,
user_ids: None,
},
);
Ok(StatusCode::NO_CONTENT)
}
+2
View File
@@ -0,0 +1,2 @@
pub mod handlers;
pub mod routes;
+7
View File
@@ -0,0 +1,7 @@
use super::handlers;
use crate::core::state::AppState;
use axum::{Router, routing::put};
pub fn router() -> Router<AppState> {
Router::new().route("/server-item-orders/reorder", put(handlers::reorder))
}