111 lines
3.4 KiB
Rust
111 lines
3.4 KiB
Rust
use actix_web::{HttpRequest, HttpResponse, web};
|
|
use channel::http::{WsHandler, WsInMessage, WsOutEvent};
|
|
use channel::{ChannelBus, ChannelError};
|
|
use session::SessionExt;
|
|
use uuid::Uuid;
|
|
|
|
use crate::error::ApiError;
|
|
|
|
pub(crate) fn extract_user(req: &HttpRequest) -> Result<Uuid, ApiError> {
|
|
req.get_session()
|
|
.user()
|
|
.ok_or_else(|| ApiError(service::error::AppError::Unauthorized))
|
|
}
|
|
|
|
pub(crate) fn channel_err(e: ChannelError) -> ApiError {
|
|
ApiError(match e {
|
|
ChannelError::Unauthorized | ChannelError::TokenInvalidOrExpired => {
|
|
service::error::AppError::Unauthorized
|
|
}
|
|
ChannelError::AccessDenied => {
|
|
service::error::AppError::PermissionDenied
|
|
}
|
|
ChannelError::Validation(msg) => {
|
|
service::error::AppError::BadRequest(msg)
|
|
}
|
|
ChannelError::RateLimitExceeded => {
|
|
service::error::AppError::BadRequest("rate limit exceeded".into())
|
|
}
|
|
ChannelError::RenewalLimitExceeded => {
|
|
service::error::AppError::BadRequest(
|
|
"renewal limit exceeded".into(),
|
|
)
|
|
}
|
|
ChannelError::RoomNotFound => {
|
|
service::error::AppError::NotFound("room not found".into())
|
|
}
|
|
ChannelError::UserNotFound => {
|
|
service::error::AppError::NotFound("user not found".into())
|
|
}
|
|
ChannelError::Internal(msg) => {
|
|
service::error::AppError::InternalServerError(msg)
|
|
}
|
|
ChannelError::Database(e) => {
|
|
service::error::AppError::InternalServerError(e.to_string())
|
|
}
|
|
ChannelError::Cache(e) => {
|
|
service::error::AppError::InternalServerError(e.to_string())
|
|
}
|
|
ChannelError::SocketIo(e) => {
|
|
service::error::AppError::InternalServerError(e.to_string())
|
|
}
|
|
ChannelError::Serialization(e) => {
|
|
service::error::AppError::InternalServerError(e.to_string())
|
|
}
|
|
ChannelError::Redis(e) => {
|
|
service::error::AppError::InternalServerError(e.to_string())
|
|
}
|
|
ChannelError::Storage(e) => {
|
|
service::error::AppError::InternalServerError(e.to_string())
|
|
}
|
|
})
|
|
}
|
|
|
|
pub(crate) fn ok_json(event: Option<WsOutEvent>) -> HttpResponse {
|
|
match event {
|
|
Some(e) => HttpResponse::Ok().json(e),
|
|
None => HttpResponse::NoContent().finish(),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn created_json(event: Option<WsOutEvent>) -> HttpResponse {
|
|
match event {
|
|
Some(e) => HttpResponse::Created().json(e),
|
|
None => HttpResponse::NoContent().finish(),
|
|
}
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/ws/ping",
|
|
responses((status = 200, description = "Pong with protocol version")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn ping(
|
|
req: HttpRequest,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let result = WsHandler::handle(&bus, user_id, WsInMessage::Ping)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/ws/csrf",
|
|
responses((status = 200, description = "CSRF token")),
|
|
tag = "channel",
|
|
)]
|
|
pub async fn csrf_token(
|
|
req: HttpRequest,
|
|
bus: web::Data<ChannelBus>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let user_id = extract_user(&req)?;
|
|
let result = WsHandler::handle(&bus, user_id, WsInMessage::CsrfToken)
|
|
.await
|
|
.map_err(channel_err)?;
|
|
Ok(ok_json(result))
|
|
}
|