diff options
Diffstat (limited to 'src/access/rules.rs')
| -rw-r--r-- | src/access/rules.rs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/access/rules.rs b/src/access/rules.rs index 3eca1c9..450addb 100644 --- a/src/access/rules.rs +++ b/src/access/rules.rs @@ -193,6 +193,13 @@ pub(crate) fn judge(doc: &Document, epoch: Epoch, change: &Change<'_>) -> Result || user_may(path) || user_may(&meta::path(&[meta::USERS])) } + // A user's own keys (`/auth/keys`), whatever else it may do. + (Some(meta::USERS), Some(owner)) + if path.get(3).map(String::as_str) == Some("keys") + && change.user == Some(owner) => + { + true + } // 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) { @@ -788,6 +795,41 @@ mod tests { assert!(decide(Some("carol"), "committed", 0).is_ok()); } + /// A user's own keys: its own to change, whatever else it may do; another's, or the + /// rest of its own entry, not. + #[test] + fn users_change_their_own_keys() { + let doc = swarm(true); + assert!( + judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/bob/keys/laptop"] + ) + .is_ok() + ); + assert!(judged(&doc, "a", Some("bob"), &["_continuum/users/bob/keys"]).is_ok()); + assert!(refused(judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/alice/keys/laptop"] + ))); + assert!(refused(judged( + &doc, + "a", + Some("bob"), + &["_continuum/users/bob/caps"] + ))); + assert!(refused(judged( + &doc, + "a", + None, + &["_continuum/users/bob/keys/laptop"] + ))); + } + /// A node that isn't a member may only register itself. #[test] fn strangers_register_themselves_only() { |
