Add fetch doc version endpoints

This commit is contained in:
Andras Schmelczer 2025-01-14 21:41:11 +00:00
parent be591072f4
commit 60181ae53f
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
4 changed files with 237 additions and 0 deletions

View file

@ -35,6 +35,8 @@ mod app_state;
mod auth;
mod create_document;
mod delete_document;
mod fetch_document_version;
mod fetch_document_version_content;
mod fetch_latest_document_version;
mod fetch_latest_documents;
mod ping;
@ -94,6 +96,14 @@ pub async fn create_server() -> Result<()> {
"/vaults/:vault_id/documents/:document_id/json",
put(update_document::update_document_json),
)
.api_route(
"/vaults/:vault_id/documents/:document_id/versions/:version_id",
put(fetch_document_version::fetch_document_version),
)
.api_route(
"/vaults/:vault_id/documents/:document_id/versions/:version_id/content",
put(fetch_document_version_content::fetch_document_version_content),
)
.api_route(
"/vaults/:vault_id/documents/:document_id",
delete(delete_document::delete_document),

View file

@ -0,0 +1,57 @@
use anyhow::anyhow;
use axum::extract::{Path, State};
use axum_extra::{
TypedHeader,
headers::{Authorization, authorization::Bearer},
};
use axum_jsonschema::Json;
use schemars::JsonSchema;
use serde::Deserialize;
use super::{app_state::AppState, auth::auth};
use crate::{
database::models::{DocumentId, DocumentVersion, VaultId, VaultUpdateId},
errors::{SyncServerError, not_found_error, server_error},
};
// This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)]
pub struct PathParams {
vault_id: VaultId,
document_id: DocumentId,
vault_update_id: VaultUpdateId,
}
#[axum::debug_handler]
pub async fn fetch_document_version(
TypedHeader(auth_header): TypedHeader<Authorization<Bearer>>,
Path(PathParams {
vault_id,
document_id,
vault_update_id,
}): Path<PathParams>,
State(state): State<AppState>,
) -> Result<Json<DocumentVersion>, SyncServerError> {
auth(&state, auth_header.token())?;
let result = state
.database
.get_document_version(&vault_id, vault_update_id, None)
.await
.map_err(server_error)?
.map(Ok)
.unwrap_or_else(|| {
Err(not_found_error(anyhow!(
"Document with vault update id `{vault_update_id}` not found",
)))
})?;
if result.document_id != document_id {
return Err(not_found_error(anyhow!(
"Document with document id `{document_id}` does not have a version with id \
`{vault_update_id}`",
)));
}
Ok(Json(result.into()))
}

View file

@ -0,0 +1,59 @@
use anyhow::anyhow;
use axum::{
body::Bytes,
extract::{Path, State},
};
use axum_extra::{
TypedHeader,
headers::{Authorization, authorization::Bearer},
};
use schemars::JsonSchema;
use serde::Deserialize;
use super::{app_state::AppState, auth::auth};
use crate::{
database::models::{DocumentId, VaultId, VaultUpdateId},
errors::{SyncServerError, not_found_error, server_error},
};
// This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)]
pub struct PathParams {
vault_id: VaultId,
document_id: DocumentId,
vault_update_id: VaultUpdateId,
}
#[axum::debug_handler]
pub async fn fetch_document_version_content(
TypedHeader(auth_header): TypedHeader<Authorization<Bearer>>,
Path(PathParams {
vault_id,
document_id,
vault_update_id,
}): Path<PathParams>,
State(state): State<AppState>,
) -> Result<Bytes, SyncServerError> {
auth(&state, auth_header.token())?;
let result = state
.database
.get_document_version(&vault_id, vault_update_id, None)
.await
.map_err(server_error)?
.map(Ok)
.unwrap_or_else(|| {
Err(not_found_error(anyhow!(
"Document with vault update id `{vault_update_id}` not found",
)))
})?;
if result.document_id != document_id {
return Err(not_found_error(anyhow!(
"Document with document id `{document_id}` does not have a version with id \
`{vault_update_id}`",
)));
}
Ok(result.content.into())
}

View file

@ -347,6 +347,103 @@ export interface paths {
patch?: never;
trace?: never;
};
"/vaults/{vault_id}/documents/{document_id}/versions/{version_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put: {
parameters: {
query?: never;
header: {
authorization: string;
};
path: {
document_id: string;
vault_id: string;
vault_update_id: number;
};
cookie?: never;
};
requestBody?: never;
responses: {
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["DocumentVersion"];
};
};
default: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SerializedError"];
};
};
};
};
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/vaults/{vault_id}/documents/{document_id}/versions/{version_id}/content": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put: {
parameters: {
query?: never;
header: {
authorization: string;
};
path: {
document_id: string;
vault_id: string;
vault_update_id: number;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description byte stream */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/octet-stream": unknown;
};
};
default: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SerializedError"];
};
};
};
};
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
}
export type webhooks = Record<string, never>;
export interface components {
@ -458,6 +555,20 @@ export interface components {
/** Format: uuid */
document_id: string;
vault_id: string;
/** Format: int64 */
vault_update_id: number;
};
PathParams6: {
/** Format: uuid */
document_id: string;
vault_id: string;
/** Format: int64 */
vault_update_id: number;
};
PathParams7: {
/** Format: uuid */
document_id: string;
vault_id: string;
};
/** @description Response to a ping request. */
PingResponse: {