aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/peers.rs15
-rw-r--r--src/remake/mod.rs13
-rw-r--r--src/remake/quarantine.rs11
-rw-r--r--src/state/host.rs19
4 files changed, 52 insertions, 6 deletions
diff --git a/src/api/peers.rs b/src/api/peers.rs
index b00593f..cd9381f 100644
--- a/src/api/peers.rs
+++ b/src/api/peers.rs
@@ -252,6 +252,7 @@ pub(crate) async fn peer_list(state: &AppState) -> PeerListResponse {
/// `DELETE /peers/{pk}`: forgets a peer swarm-wide.
pub(crate) async fn delete_peer(
State(state): State<AppState>,
+ user: Option<axum::Extension<crate::api::auth::AuthenticatedUser>>,
Path(peer): Path<String>,
Query(query): Query<DeletePeerQuery>,
) -> Result<StatusCode, StatusCode> {
@@ -279,11 +280,17 @@ pub(crate) async fn delete_peer(
serde_json::json!({ "at": state.clock.now_millis().as_u64(), "by": state.local_id() });
let peer_clone = peer.clone();
+ // Named as who asked: rules by path judge the change by them (`access::rules`).
+ let user = user.map(|axum::Extension(user)| user.0);
state
- .mutate_doc(move |doc| {
- store::write_path(doc, &forgotten_path(&peer_clone), &record)?;
- crate::swarm::members::unregister(doc, &peer_clone)
- })
+ .mutate_doc_for(
+ user,
+ crate::document::signatures::Sign::Protocol,
+ move |doc| {
+ store::write_path(doc, &forgotten_path(&peer_clone), &record)?;
+ crate::swarm::members::unregister(doc, &peer_clone)
+ },
+ )
.await
.map_err(|e| store_status(e, "Failed to write forget record").status())?;
diff --git a/src/remake/mod.rs b/src/remake/mod.rs
index 67fa77b..342eab3 100644
--- a/src/remake/mod.rs
+++ b/src/remake/mod.rs
@@ -297,6 +297,19 @@ pub(crate) trait Host: Clone + Send + Sync + 'static {
T: Send + 'static,
E: From<StoreError> + Send + 'static;
+ /// [`commit_doc`](Self::commit_doc) for `user`, who asked through the API: the
+ /// change names them (`replica::Writer`), as rules by path judge it
+ /// (`access::rules`).
+ fn commit_doc_for<T, E, F>(
+ &self,
+ user: Option<String>,
+ f: F,
+ ) -> impl Future<Output = Result<T, E>> + Send
+ where
+ F: FnOnce(&mut Transaction<'_>) -> Result<T, E> + Send + 'static,
+ T: Send + 'static,
+ E: From<StoreError> + Send + 'static;
+
/// What a replay does with writes a newer one superseded (`--superseded-writes`).
fn superseded(&self) -> Superseded;
diff --git a/src/remake/quarantine.rs b/src/remake/quarantine.rs
index bb34d73..e7214d6 100644
--- a/src/remake/quarantine.rs
+++ b/src/remake/quarantine.rs
@@ -159,7 +159,13 @@ pub(crate) async fn document<H: Host>(State(host): State<H>, Path(id): Path<Stri
}
}
-pub(crate) async fn replay<H: Host>(State(host): State<H>, Path(id): Path<String>) -> Response {
+/// `POST /admin/quarantine/{id}/replay`: the entry's paths written as they were,
+/// by the user who asked (`access::rules` judges the change by them).
+pub(crate) async fn replay<H: Host>(
+ State(host): State<H>,
+ user: Option<axum::Extension<crate::api::auth::AuthenticatedUser>>,
+ Path(id): Path<String>,
+) -> Response {
if !host.is_node_ready().await {
return error_response(StatusCode::SERVICE_UNAVAILABLE, "node is not ready", None);
}
@@ -170,7 +176,8 @@ pub(crate) async fn replay<H: Host>(State(host): State<H>, Path(id): Path<String
let entry = Arc::new(entry);
let replayed = {
let entry = Arc::clone(&entry);
- host.commit_doc(move |doc| {
+ let user = user.map(|axum::Extension(user)| user.0);
+ host.commit_doc_for(user, move |doc| {
// As they are: the operator decided they belong at their old paths.
Ok::<_, StoreError>(delta::replay_paths(
&entry.document,
diff --git a/src/state/host.rs b/src/state/host.rs
index 47fd946..a48a6fb 100644
--- a/src/state/host.rs
+++ b/src/state/host.rs
@@ -246,6 +246,25 @@ impl Host for AppState {
async move { state.mutate_doc(f).await }
}
+ fn commit_doc_for<T, E, F>(
+ &self,
+ user: Option<String>,
+ f: F,
+ ) -> impl Future<Output = Result<T, E>> + Send
+ where
+ F: FnOnce(&mut Transaction<'_>) -> Result<T, E> + Send + 'static,
+ T: Send + 'static,
+ E: From<StoreError> + Send + 'static,
+ {
+ let state = self.clone();
+ async move {
+ state
+ .mutate_doc_for(user, crate::document::signatures::Sign::Protocol, f)
+ .await
+ .map(|(out, _)| out)
+ }
+ }
+
fn superseded(&self) -> crate::remake::Superseded {
self.superseded_writes
}