170 lines
4.5 KiB
Rust
170 lines
4.5 KiB
Rust
use actix_web::{HttpRequest, HttpResponse, web};
|
|
use serde::Serialize;
|
|
use service::{
|
|
AppService,
|
|
workspace::{
|
|
types::WorkspaceResponse,
|
|
workspace::{AvatarUploadResponse, CreateWorkspace, UpdateWorkspace},
|
|
},
|
|
};
|
|
use session::Session;
|
|
|
|
use crate::error::ApiError;
|
|
|
|
fn ok_json<T: Serialize>(data: T) -> Result<HttpResponse, ApiError> {
|
|
Ok(HttpResponse::Ok().json(data))
|
|
}
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/workspace",
|
|
request_body = CreateWorkspace,
|
|
responses(
|
|
(status = 200, body = WorkspaceResponse),
|
|
(status = 401, description = "Unauthorized"),
|
|
(status = 409, description = "Workspace name already exists"),
|
|
),
|
|
security(
|
|
("session" = [])
|
|
)
|
|
)]
|
|
pub async fn create_workspace(
|
|
session: Session,
|
|
service: web::Data<AppService>,
|
|
params: web::Json<CreateWorkspace>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let data = service
|
|
.workspace_create(&session, params.into_inner())
|
|
.await?;
|
|
ok_json(data)
|
|
}
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/workspace/my",
|
|
responses(
|
|
(status = 200, body = Vec<WorkspaceResponse>),
|
|
(status = 401, description = "Unauthorized"),
|
|
),
|
|
security(
|
|
("session" = [])
|
|
)
|
|
)]
|
|
pub async fn my_workspaces(
|
|
session: Session,
|
|
service: web::Data<AppService>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let data = service.workspace_my(&session).await?;
|
|
ok_json(data)
|
|
}
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/workspace/{wk}",
|
|
params(
|
|
("wk" = String, Path, description = "Workspace name"),
|
|
),
|
|
responses(
|
|
(status = 200, body = WorkspaceResponse),
|
|
(status = 401, description = "Unauthorized"),
|
|
(status = 404, description = "Workspace not found"),
|
|
),
|
|
security(
|
|
("session" = [])
|
|
)
|
|
)]
|
|
pub async fn get_workspace(
|
|
session: Session,
|
|
service: web::Data<AppService>,
|
|
path: web::Path<String>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let wk = path.into_inner();
|
|
let data = service.workspace_get(&session, &wk).await?;
|
|
ok_json(data)
|
|
}
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/api/v1/workspace/{wk}",
|
|
params(
|
|
("wk" = String, Path, description = "Workspace name"),
|
|
),
|
|
request_body = UpdateWorkspace,
|
|
responses(
|
|
(status = 200, body = WorkspaceResponse),
|
|
(status = 401, description = "Unauthorized"),
|
|
(status = 403, description = "Permission denied"),
|
|
(status = 404, description = "Workspace not found"),
|
|
),
|
|
security(
|
|
("session" = [])
|
|
)
|
|
)]
|
|
pub async fn update_workspace(
|
|
session: Session,
|
|
service: web::Data<AppService>,
|
|
path: web::Path<String>,
|
|
params: web::Json<UpdateWorkspace>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let wk = path.into_inner();
|
|
let data = service
|
|
.workspace_update(&session, &wk, params.into_inner())
|
|
.await?;
|
|
ok_json(data)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/v1/workspace/{wk}/avatar",
|
|
params(
|
|
("wk" = String, Path, description = "Workspace name"),
|
|
),
|
|
responses(
|
|
(status = 302, description = "Redirect to avatar image URL"),
|
|
(status = 404, description = "Workspace or avatar not found"),
|
|
),
|
|
tag = "workspace"
|
|
)]
|
|
pub async fn get_avatar(
|
|
service: web::Data<AppService>,
|
|
path: web::Path<String>,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let wk = path.into_inner();
|
|
let url = service.workspace_get_avatar_url(&wk).await?;
|
|
Ok(HttpResponse::Found()
|
|
.insert_header(("Location", url))
|
|
.finish())
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/workspace/{wk}/avatar",
|
|
params(
|
|
("wk" = String, Path, description = "Workspace name"),
|
|
),
|
|
request_body(content = Vec<u8>, content_type = "image/*"),
|
|
responses(
|
|
(status = 200, body = AvatarUploadResponse),
|
|
(status = 400, description = "Invalid file type or size"),
|
|
(status = 403, description = "Permission denied"),
|
|
),
|
|
security(
|
|
("session" = [])
|
|
)
|
|
)]
|
|
pub async fn upload_avatar(
|
|
session: Session,
|
|
service: web::Data<AppService>,
|
|
path: web::Path<String>,
|
|
body: web::Bytes,
|
|
req: HttpRequest,
|
|
) -> Result<HttpResponse, ApiError> {
|
|
let wk = path.into_inner();
|
|
let content_type = req
|
|
.headers()
|
|
.get("content-type")
|
|
.and_then(|v| v.to_str().ok())
|
|
.unwrap_or("application/octet-stream");
|
|
|
|
let response = service
|
|
.workspace_upload_avatar(&session, &wk, body.to_vec(), content_type)
|
|
.await?;
|
|
ok_json(response)
|
|
}
|