116 lines
3.1 KiB
Rust
116 lines
3.1 KiB
Rust
use axum::{
|
|
extract::Path,
|
|
response::IntoResponse,
|
|
routing::{get, post},
|
|
Json, Router,
|
|
};
|
|
use serde_json::json;
|
|
use std::sync::Arc;
|
|
|
|
use crate::{
|
|
content::{
|
|
collection::CollectionRepository,
|
|
site::{CreateSiteData, SiteRepository, UpdateSiteData},
|
|
},
|
|
database::Database,
|
|
http::{error::ApiError, json::JsonBody, session::RequireUser},
|
|
state::AppState,
|
|
};
|
|
|
|
/// Retrieve site info/metadata
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/sites/{site}",
|
|
params(
|
|
("site" = String, Path, description = "Site slug")
|
|
),
|
|
responses(
|
|
(status = 200, description = "Site info found", body = SiteData),
|
|
(status = 404, description = "Site not found")
|
|
)
|
|
)]
|
|
pub(super) async fn get_site<Repo: SiteRepository>(
|
|
repository: Repo,
|
|
Path(name): Path<String>,
|
|
) -> Result<impl IntoResponse, ApiError<'static>> {
|
|
Ok(Json(repository.get_site_by_name(&name).await?))
|
|
}
|
|
|
|
/// Create a new site
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/sites",
|
|
request_body = CreateSiteData,
|
|
responses(
|
|
(status = 200, description = "Site created"),
|
|
(status = 409, description = "The chosen site identifier/slug is not available")
|
|
)
|
|
)]
|
|
pub(super) async fn create_site<Repo: SiteRepository + CollectionRepository>(
|
|
repository: Repo,
|
|
RequireUser(user): RequireUser,
|
|
JsonBody(options): JsonBody<CreateSiteData>,
|
|
) -> Result<impl IntoResponse, ApiError<'static>> {
|
|
let id = repository.create_site(&user.id, options).await?;
|
|
|
|
// Create default content for the new site
|
|
repository.create_default_collections(&id).await?;
|
|
|
|
Ok(Json(json!({"ok": true})))
|
|
}
|
|
|
|
/// Update an existing site's info
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/sites/{site}",
|
|
params(
|
|
("site" = String, Path, description = "Site slug")
|
|
),
|
|
request_body = UpdateSiteData,
|
|
responses(
|
|
(status = 200, description = "Site updated"),
|
|
(status = 404, description = "Site not found")
|
|
)
|
|
)]
|
|
pub(super) async fn update_site<Repo: SiteRepository>(
|
|
repository: Repo,
|
|
Path(name): Path<String>,
|
|
RequireUser(user): RequireUser,
|
|
JsonBody(options): JsonBody<UpdateSiteData>,
|
|
) -> Result<impl IntoResponse, ApiError<'static>> {
|
|
repository.update_site(&user.id, &name, options).await?;
|
|
Ok(Json(json!({"ok": true})))
|
|
}
|
|
|
|
/// Delete an existing site
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/sites/{site}",
|
|
params(
|
|
("site" = String, Path, description = "Site slug")
|
|
),
|
|
responses(
|
|
(status = 200, description = "Site deleted"),
|
|
(status = 404, description = "Site not found")
|
|
)
|
|
)]
|
|
pub(super) async fn delete_site<Repo: SiteRepository>(
|
|
repository: Repo,
|
|
Path(name): Path<String>,
|
|
RequireUser(user): RequireUser,
|
|
) -> Result<impl IntoResponse, ApiError<'static>> {
|
|
repository.delete_site(&user.id, &name, true).await?;
|
|
Ok(Json(json!({"ok": true})))
|
|
}
|
|
|
|
pub(super) fn router() -> Router<Arc<AppState>> {
|
|
Router::new()
|
|
.route("/", post(create_site::<Database>))
|
|
.route(
|
|
"/:name",
|
|
get(get_site::<Database>)
|
|
.put(update_site::<Database>)
|
|
.delete(delete_site::<Database>),
|
|
)
|
|
}
|