aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/store.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/store.rs')
-rw-r--r--src/api/store.rs32
1 files changed, 27 insertions, 5 deletions
diff --git a/src/api/store.rs b/src/api/store.rs
index 48fc2c6..7307d92 100644
--- a/src/api/store.rs
+++ b/src/api/store.rs
@@ -1,5 +1,6 @@
//! /store and /stream handlers.
+use crate::document::signatures::Sign;
use std::io::Error as IoError;
use axum::{
@@ -90,12 +91,18 @@ pub(crate) struct PostQuery {
/// With `cast`, how timestamps are read from and written as strings (`rfc3339` by
/// default; `typed::TimestampFormat`).
format: Option<String>,
+ /// Whether the change is signed whatever its path (`document::signatures`).
+ #[serde(default)]
+ signed: bool,
}
#[derive(Debug, Deserialize)]
pub(crate) struct DeleteQuery {
#[serde(default)]
prune: bool,
+ /// Whether the change is signed whatever its path (`document::signatures`).
+ #[serde(default)]
+ signed: bool,
}
/// `GET /store`: the whole store (`docs/openapi.yaml`).
@@ -349,6 +356,9 @@ pub(crate) struct PutQuery {
/// default); if not, one that would is `409` (`store::Writing::retype`).
#[serde(default = "yes")]
retype: bool,
+ /// Whether the change is signed whatever its path (`document::signatures`).
+ #[serde(default)]
+ signed: bool,
}
fn yes() -> bool {
@@ -377,6 +387,10 @@ pub(crate) async fn put_store_entry(
}
let path = parse_write_path(&state, &user, &access, &key, "PUT")?;
+ let sign = Sign::Write {
+ path: path.clone(),
+ asked: query.signed,
+ };
if let Some(redirect) = to_positive(&state, &path, false, None, raw_query.as_deref()).await? {
return Ok(redirect);
}
@@ -387,7 +401,7 @@ pub(crate) async fn put_store_entry(
// A value that can't be shown as asked is refused, and the write with it.
let writer = user.0.clone();
let ((retyped, read), heads) = state
- .mutate_doc_for(Some(user.0.clone()), move |doc| {
+ .mutate_doc_for(Some(user.0.clone()), sign.clone(), move |doc| {
let before = Before::of(&*doc, &writer);
let retyped = store::write_val_path(doc, &path, &body.value, writing)
.map_err(|e| store_status(e, "Failed to write store value"))?;
@@ -706,6 +720,10 @@ pub(crate) async fn post_store_entry(
return Err(StatusCode::SERVICE_UNAVAILABLE.into());
}
let path = parse_write_path(&state, &user, &access, &key, "POST")?;
+ let sign = Sign::Write {
+ path: path.clone(),
+ asked: query.signed,
+ };
if query.increment.is_some() && query.cast.is_some() {
return Err(ApiError(
StatusCode::BAD_REQUEST,
@@ -723,7 +741,7 @@ pub(crate) async fn post_store_entry(
if let Some(by) = query.increment {
let writer = user.0.clone();
let (value, heads) = state
- .mutate_doc_for(Some(user.0.clone()), move |doc| {
+ .mutate_doc_for(Some(user.0.clone()), sign.clone(), move |doc| {
let before = Before::of(&*doc, &writer);
let value = store::increment_path(doc, &path, by)
.map_err(|e| store_status(e, "Failed to increment a counter"))?;
@@ -759,7 +777,7 @@ pub(crate) async fn post_store_entry(
// A value that can't be shown as asked is refused, and the cast with it.
let writer = user.0.clone();
let ((retyped, read), heads) = state
- .mutate_doc_for(Some(user.0.clone()), move |doc| {
+ .mutate_doc_for(Some(user.0.clone()), sign.clone(), move |doc| {
let before = Before::of(&*doc, &writer);
let retyped = store::cast_path(doc, &path, to, timestamps)
.map_err(|e| store_status(e, "Failed to cast a store value"))?;
@@ -775,7 +793,7 @@ pub(crate) async fn post_store_entry(
let value = body_value(&headers, &body)?;
let writer = user.0.clone();
let ((), heads) = state
- .mutate_doc_for(Some(user.0.clone()), move |doc| {
+ .mutate_doc_for(Some(user.0.clone()), sign.clone(), move |doc| {
let before = Before::of(&*doc, &writer);
store::insert_val_path(doc, &path, &value.value)
.map_err(|e| store_status(e, "Failed to insert into a list"))?;
@@ -803,6 +821,10 @@ pub(crate) async fn delete_store_entry(
RawQuery(raw_query): RawQuery,
) -> Result<Response, ApiError> {
let path = parse_write_path(&state, &user, &access, &key, "DELETE")?;
+ let sign = Sign::Write {
+ path: path.clone(),
+ asked: query.signed,
+ };
tracing::Span::current().record("path", path.join("/").as_str());
@@ -826,7 +848,7 @@ pub(crate) async fn delete_store_entry(
});
let writer = user.0.clone();
let ((), heads) = state
- .mutate_doc_for(Some(user.0.clone()), move |doc| {
+ .mutate_doc_for(Some(user.0.clone()), sign.clone(), move |doc| {
let before = Before::of(&*doc, &writer);
store::delete_path_pruning(doc, &path, prune)
.map_err(|e| store_status(e, "Failed to delete store value"))?;