init
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::domain::dto::message::{
|
||||
use crate::domain::dto::reaction::{CreateReactionRequest, DeleteReactionQuery, ReactionResponse};
|
||||
use crate::http::context::CurrentUser;
|
||||
use crate::http::error::HTTPError;
|
||||
use crate::models::{channel, channel_user};
|
||||
use crate::routes::message::mapper;
|
||||
use axum::{
|
||||
Json,
|
||||
@@ -13,6 +14,20 @@ use axum::{
|
||||
http::StatusCode,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||
|
||||
pub(crate) async fn can_access(state: &AppState, channel_id: Uuid, user_id: Uuid) -> Result<bool, HTTPError> {
|
||||
let Some(channel) = channel::Entity::find_by_id(channel_id).one(&state.db).await? else {
|
||||
return Ok(false);
|
||||
};
|
||||
if channel.channel_type != channel::ChannelType::DM {
|
||||
return Ok(true);
|
||||
}
|
||||
Ok(channel_user::Entity::find()
|
||||
.filter(channel_user::Column::ChannelId.eq(channel_id))
|
||||
.filter(channel_user::Column::UserId.eq(user_id))
|
||||
.one(&state.db).await?.is_some())
|
||||
}
|
||||
|
||||
/// Liste une fenêtre paginée de messages
|
||||
#[utoipa::path(
|
||||
@@ -29,6 +44,7 @@ use uuid::Uuid;
|
||||
tag = "Messages"
|
||||
)]
|
||||
pub async fn get_all(
|
||||
user: CurrentUser,
|
||||
State(state): State<AppState>,
|
||||
Query(filters): Query<MessageQueryParams>,
|
||||
) -> Result<Json<MessagePageResponse>, HTTPError> {
|
||||
@@ -39,6 +55,11 @@ pub async fn get_all(
|
||||
}
|
||||
|
||||
let params = mapper::query_params_to_message_filter(filters);
|
||||
if let Some(channel_id) = params.channel_id {
|
||||
if !can_access(&state, channel_id, user.id).await? {
|
||||
return Err(HTTPError::Forbidden);
|
||||
}
|
||||
}
|
||||
let page = state.repositories.message.filter(params).await?;
|
||||
let message_ids: Vec<_> = page.messages.iter().map(|message| message.id).collect();
|
||||
let mut reactions = state
|
||||
@@ -80,6 +101,7 @@ pub async fn get_all(
|
||||
tag = "Messages"
|
||||
)]
|
||||
pub async fn get_by_id(
|
||||
user: CurrentUser,
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<Json<MessageResponse>, HTTPError> {
|
||||
@@ -89,6 +111,9 @@ pub async fn get_by_id(
|
||||
.get_by_id(id)
|
||||
.await?
|
||||
.ok_or(HTTPError::NotFound)?;
|
||||
if !can_access(&state, message.channel_id, user.id).await? {
|
||||
return Err(HTTPError::Forbidden);
|
||||
}
|
||||
|
||||
let reactions = state
|
||||
.services
|
||||
@@ -130,6 +155,9 @@ pub async fn create(
|
||||
.get_by_id(payload.channel_id)
|
||||
.await?
|
||||
.ok_or(HTTPError::BadRequest("Channel not found".to_string()))?;
|
||||
if !can_access(&state, channel.id, user.id).await? {
|
||||
return Err(HTTPError::Forbidden);
|
||||
}
|
||||
|
||||
// Optionnel: vérifier reply_to_id
|
||||
if let Some(reply_id) = payload.reply_to_id {
|
||||
@@ -233,6 +261,8 @@ pub async fn add_reaction(
|
||||
Path(message_id): Path<Uuid>,
|
||||
Json(payload): Json<CreateReactionRequest>,
|
||||
) -> Result<(StatusCode, Json<ReactionResponse>), HTTPError> {
|
||||
let message = state.repositories.message.get_by_id(message_id).await?.ok_or(HTTPError::NotFound)?;
|
||||
if !can_access(&state, message.channel_id, user.id).await? { return Err(HTTPError::Forbidden); }
|
||||
let (reaction, created) = state
|
||||
.services
|
||||
.message_reaction
|
||||
@@ -270,6 +300,8 @@ pub async fn remove_reaction(
|
||||
Path((message_id, emoji_id)): Path<(Uuid, Uuid)>,
|
||||
Query(query): Query<DeleteReactionQuery>,
|
||||
) -> Result<StatusCode, HTTPError> {
|
||||
let message = state.repositories.message.get_by_id(message_id).await?.ok_or(HTTPError::NotFound)?;
|
||||
if !can_access(&state, message.channel_id, user.id).await? { return Err(HTTPError::Forbidden); }
|
||||
state
|
||||
.services
|
||||
.message_reaction
|
||||
|
||||
Reference in New Issue
Block a user