otter/src/server/gpodder/advanced/devices.rs

65 lines
1.6 KiB
Rust

use axum::{
extract::{Path, State},
middleware,
routing::{get, post},
Extension, Json, Router,
};
use crate::{
gpodder,
server::{
error::{AppError, AppResult},
gpodder::{
auth_middleware,
format::{Format, StringWithFormat},
models,
},
Context,
},
};
pub fn router(ctx: Context) -> Router<Context> {
Router::new()
.route("/{username}", get(get_devices))
.route("/{username}/{id}", post(post_device))
.layer(middleware::from_fn_with_state(ctx.clone(), auth_middleware))
}
async fn get_devices(
State(ctx): State<Context>,
Path(username): Path<StringWithFormat>,
Extension(user): Extension<gpodder::User>,
) -> AppResult<Json<Vec<models::Device>>> {
if username.format != Format::Json {
return Err(AppError::NotFound);
}
if *username != user.username {
return Err(AppError::BadRequest);
}
Ok(
tokio::task::spawn_blocking(move || ctx.store.devices_for_user(&user))
.await
.unwrap()
.map(|devices| Json(devices.into_iter().map(models::Device::from).collect()))?,
)
}
async fn post_device(
State(ctx): State<Context>,
Path((_username, id)): Path<(String, StringWithFormat)>,
Extension(user): Extension<gpodder::User>,
Json(patch): Json<models::DevicePatch>,
) -> AppResult<()> {
if id.format != Format::Json {
return Err(AppError::NotFound);
}
tokio::task::spawn_blocking(move || ctx.store.update_device_info(&user, &id, patch.into()))
.await
.unwrap()?;
Ok(())
}