322 lines
8.7 KiB
Rust
322 lines
8.7 KiB
Rust
use actix_web::{HttpRequest, HttpResponse, web};
|
|
use channel::ChannelBus;
|
|
use channel::http::{WsHandler, WsInMessage};
|
|
use serde::Deserialize;
|
|
use uuid::Uuid;
|
|
|
|
use super::rest::{channel_err, created_json, extract_user, ok_json};
|
|
use crate::error::ApiError;
|
|
|
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
|
pub struct RoomCreateRequest {
|
|
pub workspace: Uuid,
|
|
pub room_name: String,
|
|
pub public: bool,
|
|
pub category: Option<Uuid>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
|
pub struct RoomUpdateRequest {
|
|
pub room_name: Option<String>,
|
|
pub public: Option<bool>,
|
|
pub category: Option<Uuid>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
|
pub struct AccessRequest {
|
|
pub user: Uuid,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
|
pub struct CategoryCreateRequest {
|
|
pub name: String,
|
|
pub position: Option<i32>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
|
pub struct CategoryUpdateRequest {
|
|
pub name: Option<String>,
|
|
pub position: Option<i32>,
|
|
}
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/ws/rooms",
|
|
responses((status = 200, description = "List of rooms")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn list_rooms(
|
|
req: HttpRequest,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let rooms = bus.list_user_rooms(user_id)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
let categories = bus.list_user_categories(user_id)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
let workspace_id = if let Some(r) = rooms.first() {
|
|
Some(r.workspace_id)
|
|
} else {
|
|
bus.first_workspace_id(user_id).await.unwrap_or(None)
|
|
};
|
|
Ok(HttpResponse::Ok().json(serde_json::json!({
|
|
"rooms": rooms,
|
|
"categories": categories,
|
|
"workspace_id": workspace_id,
|
|
})))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/ws/rooms/{room_id}/subscribe",
|
|
responses((status = 204, description = "Subscribed, user room cache refreshed")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn subscribe(
|
|
req: HttpRequest,
|
|
room_id: web::Path<Uuid>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::Subscribe {
|
|
room: room_id.into_inner(),
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/api/v1/ws/rooms/{room_id}/subscribe",
|
|
responses((status = 204, description = "Unsubscribed")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn unsubscribe(
|
|
req: HttpRequest,
|
|
room_id: web::Path<Uuid>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::Unsubscribe {
|
|
room: room_id.into_inner(),
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/ws/rooms/{room_id}",
|
|
responses((status = 200, description = "Room info")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn room_get(
|
|
req: HttpRequest,
|
|
room_id: web::Path<Uuid>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::RoomGet {
|
|
room: room_id.into_inner(),
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/ws/rooms",
|
|
request_body = RoomCreateRequest,
|
|
responses((status = 201, description = "Room created")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn room_create(
|
|
req: HttpRequest,
|
|
body: web::Json<RoomCreateRequest>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::RoomCreate {
|
|
workspace: body.workspace,
|
|
room_name: body.room_name.clone(),
|
|
public: body.public,
|
|
category: body.category,
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(created_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
patch,
|
|
path = "/api/v1/ws/rooms/{room_id}",
|
|
request_body = RoomUpdateRequest,
|
|
responses((status = 200, description = "Room updated")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn room_update(
|
|
req: HttpRequest,
|
|
room_id: web::Path<Uuid>,
|
|
body: web::Json<RoomUpdateRequest>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::RoomUpdate {
|
|
room: room_id.into_inner(),
|
|
room_name: body.room_name.clone(),
|
|
public: body.public,
|
|
category: body.category,
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/api/v1/ws/rooms/{room_id}",
|
|
responses((status = 204, description = "Room deleted")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn room_delete(
|
|
req: HttpRequest,
|
|
room_id: web::Path<Uuid>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::RoomDelete {
|
|
room: room_id.into_inner(),
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/ws/rooms/{room_id}/members",
|
|
request_body = AccessRequest,
|
|
responses((status = 204, description = "Access granted")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn access_grant(
|
|
req: HttpRequest,
|
|
room_id: web::Path<Uuid>,
|
|
body: web::Json<AccessRequest>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::AccessGrant {
|
|
room: room_id.into_inner(),
|
|
user: body.user,
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/api/v1/ws/rooms/{room_id}/members/{user_id}",
|
|
responses((status = 204, description = "Access revoked")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn access_revoke(
|
|
req: HttpRequest,
|
|
path: web::Path<(Uuid, Uuid)>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let (room, target_user) = path.into_inner();
|
|
let msg = WsInMessage::AccessRevoke {
|
|
room,
|
|
user: target_user,
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/ws/workspaces/{workspace_id}/categories",
|
|
request_body = CategoryCreateRequest,
|
|
responses((status = 201, description = "Category created")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn category_create(
|
|
req: HttpRequest,
|
|
workspace_id: web::Path<Uuid>,
|
|
body: web::Json<CategoryCreateRequest>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::CategoryCreate {
|
|
workspace: workspace_id.into_inner(),
|
|
name: body.name.clone(),
|
|
position: body.position,
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(created_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
patch,
|
|
path = "/api/v1/ws/categories/{category_id}",
|
|
request_body = CategoryUpdateRequest,
|
|
responses((status = 200, description = "Category updated")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn category_update(
|
|
req: HttpRequest,
|
|
category_id: web::Path<Uuid>,
|
|
body: web::Json<CategoryUpdateRequest>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::CategoryUpdate {
|
|
id: category_id.into_inner(),
|
|
name: body.name.clone(),
|
|
position: body.position,
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/api/v1/ws/categories/{category_id}",
|
|
responses((status = 204, description = "Category deleted")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn category_delete(
|
|
req: HttpRequest,
|
|
category_id: web::Path<Uuid>,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let msg = WsInMessage::CategoryDelete {
|
|
id: category_id.into_inner(),
|
|
};
|
|
let result = WsHandler::handle(&bus, user_id, msg)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|