aboutsummaryrefslogtreecommitdiffstats
path: root/src/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/api')
-rw-r--r--src/api/login.rs3
-rw-r--r--src/api/store.rs32
-rw-r--r--src/api/users.rs3
3 files changed, 31 insertions, 7 deletions
diff --git a/src/api/login.rs b/src/api/login.rs
index 023408e..b84a412 100644
--- a/src/api/login.rs
+++ b/src/api/login.rs
@@ -14,6 +14,7 @@
//! Every request may bring a token instead of a password: `Authorization: Bearer ct1…`
//! (`bearer`).
+use crate::document::signatures::Sign;
use std::sync::Arc;
use axum::{
@@ -261,7 +262,7 @@ pub(crate) async fn revoke_tokens(state: &AppState, name: &str, by: &str) -> Res
// Issued in this very millisecond: revoked too.
let after = state.clock.now_millis().as_u64() + 1;
state
- .mutate_doc_for(Some(by.to_owned()), move |doc| {
+ .mutate_doc_for(Some(by.to_owned()), Sign::Protocol, move |doc| {
if !registry::exists(&*doc) {
return Err(ApiError(
StatusCode::CONFLICT,
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"))?;
diff --git a/src/api/users.rs b/src/api/users.rs
index 1d01af7..3b8174d 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -23,6 +23,7 @@
//! the document, logged, named by who made it, and refused (`409`) where it would lock
//! its maker out (`access::registry_kept`).
+use crate::document::signatures::Sign;
use axum::{
Extension, Json,
extract::{Path, State},
@@ -166,7 +167,7 @@ async fn change(
let writer = user.to_owned();
let since = state.clock.now_millis().as_u64();
state
- .mutate_doc_for(Some(user.to_owned()), move |doc| {
+ .mutate_doc_for(Some(user.to_owned()), Sign::Protocol, move |doc| {
let before = Before::of(&*doc, &writer);
f(doc, &by, since)?;
registry_kept(&*doc, &registry::users_dir(), before, &writer)