reworked api errors, now returning proper error codes
This commit is contained in:
+62
-295
@@ -7,7 +7,7 @@ use axum::{
|
||||
use sqlx::{PgPool, Pool, Postgres};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{auth::verify_jwt, db::room_id_from_uuid};
|
||||
use crate::{MAX_ROOM_NAME_LENGTH, auth::verify_jwt, db::room_id_from_uuid, errors::APIError};
|
||||
use crate::{
|
||||
db::{id_from_username, room_name_from_uuid, user_id_from_uuid, username_from_id},
|
||||
routes::users::UserProfile,
|
||||
@@ -93,10 +93,10 @@ pub async fn is_member(user_id: i32, room_id: i32, db: &Pool<Postgres>) -> bool
|
||||
async fn list_rooms(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
) -> Result<Json<Vec<Room>>, (StatusCode, String)> {
|
||||
) -> Result<Json<Vec<Room>>, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
if claims.sub != claims.sub {
|
||||
return Err((StatusCode::FORBIDDEN, "Forbidden".to_string()));
|
||||
return Err(APIError::InvalidToken);
|
||||
}
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
@@ -137,9 +137,16 @@ async fn create_room(
|
||||
Extension(db): Extension<PgPool>,
|
||||
headers: HeaderMap,
|
||||
Json(payload): Json<NewRoomPayload>,
|
||||
) -> Result<(StatusCode, Json<Room>), (StatusCode, String)> {
|
||||
) -> Result<(StatusCode, Json<Room>), APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
{
|
||||
let room_name_length = payload.name.len();
|
||||
if room_name_length > MAX_ROOM_NAME_LENGTH || room_name_length < 1 {
|
||||
return Err(APIError::RoomNameLength);
|
||||
}
|
||||
}
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
|
||||
let room_uuid = uuid::Uuid::now_v7();
|
||||
@@ -154,8 +161,7 @@ async fn create_room(
|
||||
// .bind(&payload.global)
|
||||
.bind(false) // We do not allow global rooms
|
||||
.execute(&db)
|
||||
.await
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, format!("Could not create room")))?;
|
||||
.await?;
|
||||
|
||||
let room_id = room_id_from_uuid(&db, room_uuid).await?;
|
||||
|
||||
@@ -164,14 +170,9 @@ async fn create_room(
|
||||
.bind(user_id)
|
||||
.bind(room_id)
|
||||
.execute(&db)
|
||||
.await
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, format!("Could not create room")))?;
|
||||
.await?;
|
||||
|
||||
let owner_name = sqlx::query_scalar("SELECT username FROM user_ WHERE id = $1")
|
||||
.bind(user_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, format!("Could not create room")))?;
|
||||
let owner_name = username_from_id(&db, user_id).await?;
|
||||
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
@@ -190,7 +191,7 @@ async fn get_room(
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
) -> Result<Json<Room>, (StatusCode, String)> {
|
||||
) -> Result<Json<Room>, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
@@ -232,16 +233,10 @@ async fn get_room(
|
||||
.bind(user_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed getting room: {e}");
|
||||
(StatusCode::NOT_FOUND, "Room not found".to_string())
|
||||
})?;
|
||||
.map_err(|_| APIError::RoomNotFound)?;
|
||||
|
||||
if !row.is_member.unwrap_or(false) {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room".to_string(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
Ok(Json(Room {
|
||||
@@ -257,7 +252,7 @@ async fn get_room(
|
||||
async fn list_invites(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
) -> Result<Json<Vec<RoomInvite>>, (StatusCode, String)> {
|
||||
) -> Result<Json<Vec<RoomInvite>>, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
|
||||
@@ -276,14 +271,7 @@ async fn list_invites(
|
||||
)
|
||||
.bind(user_id)
|
||||
.fetch_all(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Could not list room invites".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
Ok(Json(requests))
|
||||
}
|
||||
@@ -292,7 +280,7 @@ async fn send_invite(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
Json(payload): Json<SendRoomInvitePayload>,
|
||||
) -> Result<(StatusCode, Json<RoomInvite>), (StatusCode, String)> {
|
||||
) -> Result<(StatusCode, Json<RoomInvite>), APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let sender_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
@@ -300,10 +288,7 @@ async fn send_invite(
|
||||
let room_id = room_id_from_uuid(&db, payload.room_uuid).await?;
|
||||
|
||||
if sender_id == receiver_id {
|
||||
return Err((
|
||||
StatusCode::BAD_REQUEST,
|
||||
"Cannot send a room invite to yourself".into(),
|
||||
));
|
||||
return Err(APIError::InviteSelf);
|
||||
}
|
||||
|
||||
let is_already_member = sqlx::query_scalar::<_, bool>(
|
||||
@@ -318,14 +303,10 @@ async fn send_invite(
|
||||
.bind(receiver_id)
|
||||
.bind(room_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Database error".into()))?;
|
||||
.await?;
|
||||
|
||||
if is_already_member {
|
||||
return Err((
|
||||
StatusCode::CONFLICT,
|
||||
"This user is already a member of this room".into(),
|
||||
));
|
||||
return Err(APIError::AlreadyMember);
|
||||
}
|
||||
|
||||
sqlx::query("INSERT INTO room_invite_ (sender, receiver, room) VALUES ($1, $2, $3)")
|
||||
@@ -334,12 +315,7 @@ async fn send_invite(
|
||||
.bind(room_id)
|
||||
.execute(&db)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::CONFLICT,
|
||||
"You have already invited this user".into(),
|
||||
)
|
||||
})?;
|
||||
.map_err(|_| APIError::AlreadyInvited)?;
|
||||
|
||||
let room_name = room_name_from_uuid(&db, payload.room_uuid).await?;
|
||||
|
||||
@@ -358,16 +334,13 @@ async fn accept_request(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
Json(payload): Json<AcceptRoomInvitePayload>,
|
||||
) -> Result<(StatusCode, Json<Room>), (StatusCode, String)> {
|
||||
) -> Result<(StatusCode, Json<Room>), APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let receiver_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
let sender_id = user_id_from_uuid(&db, payload.sender_uuid).await?;
|
||||
|
||||
let mut tx = db
|
||||
.begin()
|
||||
.await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB error".into()))?;
|
||||
let mut tx = db.begin().await?;
|
||||
|
||||
let rows = sqlx::query(
|
||||
r#"
|
||||
@@ -378,12 +351,11 @@ async fn accept_request(
|
||||
.bind(sender_id)
|
||||
.bind(receiver_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB error".into()))?
|
||||
.await?
|
||||
.rows_affected();
|
||||
|
||||
if rows == 0 {
|
||||
return Err((StatusCode::NOT_FOUND, "No such invite".into()));
|
||||
return Err(APIError::InviteNotFound);
|
||||
}
|
||||
|
||||
let room_id = room_id_from_uuid(&db, payload.room_uuid).await?;
|
||||
@@ -393,12 +365,7 @@ async fn accept_request(
|
||||
.bind(room_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::CONFLICT,
|
||||
"Error creating room membership".into(),
|
||||
)
|
||||
})?;
|
||||
.map_err(|_| APIError::AlreadyMember)?;
|
||||
|
||||
let room: Room = sqlx::query_as(
|
||||
r#"
|
||||
@@ -418,19 +385,9 @@ async fn accept_request(
|
||||
.bind(sender_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::NOT_FOUND,
|
||||
"Room not found or wrong owner".into(),
|
||||
)
|
||||
})?;
|
||||
.map_err(|_| APIError::RoomNotFound)?;
|
||||
|
||||
tx.commit().await.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Could not accept room invite".into(),
|
||||
)
|
||||
})?;
|
||||
tx.commit().await?;
|
||||
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
@@ -449,7 +406,7 @@ async fn decline_request(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
Json(payload): Json<AcceptRoomInvitePayload>,
|
||||
) -> Result<StatusCode, (StatusCode, String)> {
|
||||
) -> Result<StatusCode, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let receiver_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
@@ -464,17 +421,11 @@ async fn decline_request(
|
||||
.bind(sender_id)
|
||||
.bind(receiver_id)
|
||||
.execute(&db)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Could not decline the room invite".into(),
|
||||
)
|
||||
})?
|
||||
.await?
|
||||
.rows_affected();
|
||||
|
||||
if rows == 0 {
|
||||
return Err((StatusCode::NOT_FOUND, "No such invite".into()));
|
||||
return Err(APIError::InviteNotFound);
|
||||
}
|
||||
|
||||
Ok(StatusCode::CREATED)
|
||||
@@ -484,110 +435,25 @@ async fn leave_room(
|
||||
headers: HeaderMap,
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
Extension(db): Extension<PgPool>,
|
||||
) -> Result<StatusCode, (StatusCode, String)> {
|
||||
) -> Result<StatusCode, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
let room_id = room_id_from_uuid(&db, room_uuid).await?;
|
||||
|
||||
if !is_member(user_id, room_id, &db).await {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room.".into(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
let mut tx = db
|
||||
.begin()
|
||||
.await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB error".into()))?;
|
||||
let mut tx = db.begin().await?;
|
||||
|
||||
let owner: i32 = sqlx::query_scalar(r#"SELECT owner FROM room_ WHERE id = $1"#)
|
||||
.bind(room_id)
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to get room owner: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to get room owner".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
if owner == user_id {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You cannot leave a room that you own".into(),
|
||||
));
|
||||
// let member_count: i64 =
|
||||
// sqlx::query_scalar(r#"SELECT count(*) FROM membership_ WHERE room = $1"#)
|
||||
// .bind(room_id)
|
||||
// .fetch_one(&mut *tx)
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// tracing::error!("Failed to get member count: {e}");
|
||||
// (
|
||||
// StatusCode::INTERNAL_SERVER_ERROR,
|
||||
// "Failed to get member count".into(),
|
||||
// )
|
||||
// })?;
|
||||
//
|
||||
// if member_count > 0 {
|
||||
// if let Some(new_owner) = payload.new_owner_uuid {
|
||||
// let exists: bool =
|
||||
// sqlx::query_scalar(r#"SELECT EXISTS (SELECT 1 FROM user_ WHERE uuid = $1)"#)
|
||||
// .bind(new_owner)
|
||||
// .fetch_one(&mut *tx)
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// tracing::error!("Failed to check user existence: {e}");
|
||||
// (
|
||||
// StatusCode::INTERNAL_SERVER_ERROR,
|
||||
// "Failed to check user existence".into(),
|
||||
// )
|
||||
// })?;
|
||||
//
|
||||
// if !exists {
|
||||
// tracing::debug!(
|
||||
// "User {user_id} tried to leave a room without transfering ownership"
|
||||
// );
|
||||
// return Err((
|
||||
// StatusCode::FORBIDDEN,
|
||||
// "Tried to transfer ownership to nonexistant user".into(),
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// sqlx::query("UPDATE room_ SET owner = $1 WHERE id = $2")
|
||||
// .bind(new_owner)
|
||||
// .bind(room_id)
|
||||
// .execute(&mut *tx)
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// tracing::error!("Failed to set new owner: {e}");
|
||||
// (
|
||||
// StatusCode::INTERNAL_SERVER_ERROR,
|
||||
// "Failed to set new owner".into(),
|
||||
// )
|
||||
// })?;
|
||||
// } else {
|
||||
// return Err((
|
||||
// StatusCode::BAD_REQUEST,
|
||||
// "Please provide a new owner for a non-empty room".into(),
|
||||
// ));
|
||||
// }
|
||||
// } else {
|
||||
// sqlx::query("DELETE FROM room_ WHERE id = $1")
|
||||
// .bind(room_id)
|
||||
// .execute(&mut *tx)
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// tracing::error!("Failed to delete room: {e}");
|
||||
// (
|
||||
// StatusCode::INTERNAL_SERVER_ERROR,
|
||||
// "Failed to delete room".into(),
|
||||
// )
|
||||
// })?;
|
||||
// }
|
||||
return Err(APIError::RoomOwnerCannotLeave);
|
||||
}
|
||||
|
||||
sqlx::query(
|
||||
@@ -599,15 +465,9 @@ async fn leave_room(
|
||||
.bind(user_id)
|
||||
.bind(room_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB error".into()))?;
|
||||
.await?;
|
||||
|
||||
tx.commit().await.map_err(|_| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Could not accept room invite".into(),
|
||||
)
|
||||
})?;
|
||||
tx.commit().await?;
|
||||
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
@@ -616,58 +476,35 @@ async fn transfer_ownership(
|
||||
headers: HeaderMap,
|
||||
Extension(db): Extension<PgPool>,
|
||||
Json(payload): Json<TransferOwnershipPayload>,
|
||||
) -> Result<StatusCode, (StatusCode, String)> {
|
||||
) -> Result<StatusCode, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
let room_id = room_id_from_uuid(&db, payload.room_uuid).await?;
|
||||
|
||||
if !is_member(user_id, room_id, &db).await {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room.".into(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
let owner: i32 = sqlx::query_scalar(r#"SELECT owner FROM room_ WHERE id = $1"#)
|
||||
.bind(room_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to get owner for room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to get room owner".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
if owner != user_id {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room.".into(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
let exists: bool = sqlx::query_scalar(r#"SELECT EXISTS (SELECT 1 FROM user_ WHERE uuid = $1)"#)
|
||||
.bind(payload.new_owner_uuid)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to check user existence: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to check user existence".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
if !exists {
|
||||
tracing::debug!(
|
||||
"User {user_id} tried to leave room {room_id} without transfering ownership"
|
||||
);
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"Tried to transfer ownership to nonexistant user".into(),
|
||||
));
|
||||
return Err(APIError::UserNotFound);
|
||||
}
|
||||
|
||||
let new_owner_id = user_id_from_uuid(&db, payload.new_owner_uuid).await?;
|
||||
@@ -676,14 +513,7 @@ async fn transfer_ownership(
|
||||
.bind(new_owner_id)
|
||||
.bind(room_id)
|
||||
.execute(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to set new owner for room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to set new owner".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
@@ -692,36 +522,23 @@ async fn list_members(
|
||||
headers: HeaderMap,
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
Extension(db): Extension<PgPool>,
|
||||
) -> Result<(StatusCode, Json<Vec<UserProfile>>), (StatusCode, String)> {
|
||||
) -> Result<(StatusCode, Json<Vec<UserProfile>>), APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
let room_id = room_id_from_uuid(&db, room_uuid).await?;
|
||||
|
||||
if !is_member(user_id, room_id, &db).await {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room.".into(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
let is_global: bool = sqlx::query_scalar("SELECT global FROM room_ WHERE id = $1")
|
||||
.bind(room_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to get global boolean {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to fetch room".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
if is_global {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"Cannot get member list for global rooms".into(),
|
||||
));
|
||||
return Err(APIError::GlobalRoomMemberError);
|
||||
}
|
||||
|
||||
let members = sqlx::query_as::<_, UserProfile>(
|
||||
@@ -735,14 +552,7 @@ async fn list_members(
|
||||
)
|
||||
.bind(room_id)
|
||||
.fetch_all(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to get member list for room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to get member list".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
Ok((StatusCode::OK, Json(members)))
|
||||
}
|
||||
@@ -751,86 +561,43 @@ async fn delete_room(
|
||||
headers: HeaderMap,
|
||||
Path(room_uuid): Path<Uuid>,
|
||||
Extension(db): Extension<PgPool>,
|
||||
) -> Result<StatusCode, (StatusCode, String)> {
|
||||
) -> Result<StatusCode, APIError> {
|
||||
let claims = verify_jwt(headers)?;
|
||||
|
||||
let user_id = user_id_from_uuid(&db, claims.sub).await?;
|
||||
let room_id = room_id_from_uuid(&db, room_uuid).await?;
|
||||
|
||||
if !is_member(user_id, room_id, &db).await {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room.".into(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
let owner: i32 = sqlx::query_scalar(r#"SELECT owner FROM room_ WHERE id = $1"#)
|
||||
.bind(room_id)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to get owner for room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to get room owner".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
if owner != user_id {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"You are not a member of this room.".into(),
|
||||
));
|
||||
return Err(APIError::NotAMember);
|
||||
}
|
||||
|
||||
let mut tx = db
|
||||
.begin()
|
||||
.await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB error".into()))?;
|
||||
let mut tx = db.begin().await?;
|
||||
|
||||
sqlx::query(r#"DELETE FROM message_ WHERE room = $1"#)
|
||||
.bind(room_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to delete messages on room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to delete messages".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
sqlx::query(r#"DELETE FROM membership_ WHERE room = $1"#)
|
||||
.bind(room_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to delete room memberships {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to delete room memberships".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
sqlx::query(r#"DELETE FROM room_ WHERE id = $1"#)
|
||||
.bind(room_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Failed to delete room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to delete room".into(),
|
||||
)
|
||||
})?;
|
||||
.await?;
|
||||
|
||||
tx.commit().await.map_err(|e| {
|
||||
tracing::error!("Failed to delete room {room_id}: {e}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Failed to delete room".into(),
|
||||
)
|
||||
})?;
|
||||
tx.commit().await?;
|
||||
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user