diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/peers.rs | 15 | ||||
| -rw-r--r-- | src/remake/mod.rs | 13 | ||||
| -rw-r--r-- | src/remake/quarantine.rs | 11 | ||||
| -rw-r--r-- | src/state/host.rs | 19 |
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 } |
