diff options
| author | tv <tv@krebsco.de> | 2026-11-08 16:15:39 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-08 17:36:11 +0100 |
| commit | 63c2272a4feb890277ed1362b48a3524d0b07165 (patch) | |
| tree | d69b836320a72f70ba15b10aec6c32b578f1f9f8 /src/api/users.rs | |
| parent | a7c70346b448f493991df1e035beaa4bde113b4f (diff) | |
users: a user can't remove its own last key
A user managing its own keys (1168) could remove the last, and then
neither sign nor log in by key. It can't now: DELETE /auth/keys/{id}
of the last answers 409, the rules take a user's change of its own keys
only with one left after it, and under a strict policy its own entry
signed only with one key at least. One who may manage users still may.
Diffstat (limited to 'src/api/users.rs')
| -rw-r--r-- | src/api/users.rs | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/api/users.rs b/src/api/users.rs index 122fc4b..1dda33b 100644 --- a/src/api/users.rs +++ b/src/api/users.rs @@ -197,6 +197,7 @@ async fn own_key( let mut path = entry.clone(); path.extend(["keys".to_owned(), id.clone()]); let adding = line.is_some(); + let id_kept = id.clone(); state .mutate_doc_for(Some(user.to_owned()), Sign::Protocol, move |doc| { if crate::access::policy::of(&*doc).strict() { @@ -215,6 +216,21 @@ async fn own_key( Some("no entry of yours".to_owned()), )); } + if line.is_none() { + let mut keys = entry.clone(); + keys.push("keys".to_owned()); + let others = store::keys_at(&*doc, &keys)? + .unwrap_or_default() + .into_iter() + .filter(|other| *other != id_kept) + .count(); + if others == 0 { + return Err(ApiError( + StatusCode::CONFLICT, + Some("your last key: add another first".to_owned()), + )); + } + } match line { Some(line) => store::write_path(doc, &path, &json!(line))?, None => match store::delete_path(doc, &path, false) { |
