aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/access/rules.rs9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/access/rules.rs b/src/access/rules.rs
index 2aed4b8..96ee9d4 100644
--- a/src/access/rules.rs
+++ b/src/access/rules.rs
@@ -15,7 +15,8 @@
//! that member only (removing an entry also by a user who may write there); epochs
//! and the swarm ID in a root only; a remake's decision by the coordinator its
//! proposal names, the rest of a record by any member; a user's tokens revoked by that
-//! user too (logging out); the rest by a user who may write there.
+//! user too (logging out); a member's forget record by that member too (cancelling it,
+//! alive); the rest by a user who may write there.
//! * User data: by a user who may write there.
//! * Under a strict policy (`access::policy`), the values their users sign
//! (`access::envelope`) only as they signed them (`signed_values`).
@@ -134,6 +135,8 @@ pub(crate) fn judge(doc: &Document, epoch: Epoch, change: &Change<'_>) -> Result
(Some(meta::EPOCHS | meta::SWARM), _) => false,
// Logging out: a user revokes its own tokens (`POST /auth/logout`).
(Some(meta::LOGOUTS), Some(owner)) => change.user == Some(owner) || user_may(path),
+ // A node forgotten while alive cancels its own record (`swarm::peer::forget`).
+ (Some(meta::FORGOTTEN), Some(owner)) => owner == node || user_may(path),
(Some(meta::REMAKES), Some(id)) => match path.get(3).map(String::as_str) {
// Its coordinator's; or a record carried into a new epoch whole, by the
// node that coordinated it (`remake::switch`): its proposal written with it.
@@ -431,6 +434,10 @@ mod tests {
let tokens = "_continuum/logouts/bob";
assert!(judged(&doc, "a", Some("bob"), &[tokens]).is_ok());
assert!(refused(judged(&doc, "a", Some("alice"), &[tokens])));
+ // A forget record: cancelled by the node it names, not by another.
+ let forgotten = "_continuum/forgotten/a";
+ assert!(judged(&doc, "a", None, &[forgotten]).is_ok());
+ assert!(refused(judged(&doc, "b", None, &[forgotten])));
}
/// A banned node's changes: refused, as the ban stood when they were made.