aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/rules.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/access/rules.rs')
-rw-r--r--src/access/rules.rs42
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() {