use axum::{extract::Query, extract::State, Json}; use http::StatusCode; use serde::Deserialize; use tracing::{error, instrument}; use super::{ErrorResponse, ErrorResponseStatus, RespExt}; use crate::router::{AppState, UserAuth}; use atuin_server_database::Database; use atuin_common::record::{EncryptedData, HostId, Record, RecordId, RecordIndex}; #[instrument(skip_all, fields(user.id = user.id))] pub async fn post( UserAuth(user): UserAuth, state: State>, Json(records): Json>>, ) -> Result<(), ErrorResponseStatus<'static>> { let State(AppState { database, settings }) = state; tracing::debug!( count = records.len(), user = user.username, "request to add records" ); let too_big = records .iter() .any(|r| r.data.data.len() >= settings.max_record_size || settings.max_record_size == 0); if too_big { return Err( ErrorResponse::reply("could not add records; record too large") .with_status(StatusCode::BAD_REQUEST), ); } if let Err(e) = database.add_records(&user, &records).await { error!("failed to add record: {}", e); return Err(ErrorResponse::reply("failed to add record") .with_status(StatusCode::INTERNAL_SERVER_ERROR)); }; Ok(()) } #[instrument(skip_all, fields(user.id = user.id))] pub async fn index( UserAuth(user): UserAuth, state: State>, ) -> Result, ErrorResponseStatus<'static>> { let State(AppState { database, settings: _, }) = state; let record_index = match database.tail_records(&user).await { Ok(index) => index, Err(e) => { error!("failed to get record index: {}", e); return Err(ErrorResponse::reply("failed to calculate record index") .with_status(StatusCode::INTERNAL_SERVER_ERROR)); } }; Ok(Json(record_index)) } #[derive(Deserialize)] pub struct NextParams { host: HostId, tag: String, start: Option, count: u64, } #[instrument(skip_all, fields(user.id = user.id))] pub async fn next( params: Query, UserAuth(user): UserAuth, state: State>, ) -> Result>>, ErrorResponseStatus<'static>> { let State(AppState { database, settings: _, }) = state; let params = params.0; let records = match database .next_records(&user, params.host, params.tag, params.start, params.count) .await { Ok(records) => records, Err(e) => { error!("failed to get record index: {}", e); return Err(ErrorResponse::reply("failed to calculate record index") .with_status(StatusCode::INTERNAL_SERVER_ERROR)); } }; Ok(Json(records)) }