From 1d259e84f2cb6c3421be6f725c9e25c3880717de Mon Sep 17 00:00:00 2001 From: damocles Date: Tue, 16 Jun 2026 11:02:07 +0200 Subject: [PATCH] dashboard: tighten is_plain_ident to match hive-priv validate_name_chars (argus review) --- hive-c0re/src/dashboard/matrix_accounts.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/hive-c0re/src/dashboard/matrix_accounts.rs b/hive-c0re/src/dashboard/matrix_accounts.rs index 1afa571c..af3ba0e7 100644 --- a/hive-c0re/src/dashboard/matrix_accounts.rs +++ b/hive-c0re/src/dashboard/matrix_accounts.rs @@ -116,12 +116,15 @@ struct MatrixLoginResult { user_id: String, } -/// Plain-identifier check (ascii alnum + `-`/`_`), matching what hive-priv -/// re-applies root-side to the agent + account before building the path. +/// Plain-identifier check matching hive-priv's `validate_name_chars` +/// exactly (lowercase ascii + digits + hyphens) — the root-side guard +/// re-applies the same rule before building the token path. Keeping the +/// dashboard check identical means a name that passes here can't then be +/// rejected at the priv boundary with a confusing "write token failed". fn is_plain_ident(s: &str) -> bool { !s.is_empty() && s.chars() - .all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') + .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-') } /// Provision (or refresh) the token for an agent's extra matrix account. @@ -301,10 +304,16 @@ mod tests { } #[test] - fn is_plain_ident_rejects_path_chars() { + fn is_plain_ident_matches_validate_name_chars() { + // Accepts exactly what hive-priv's validate_name_chars does: + // lowercase ascii + digits + hyphens. assert!(is_plain_ident("catgirl")); - assert!(is_plain_ident("acct-1_x")); + assert!(is_plain_ident("acct-1")); assert!(!is_plain_ident("")); + // Rejected: uppercase + underscore (would pass a looser check + // then fail at the priv boundary), and path chars. + assert!(!is_plain_ident("MyAccount")); + assert!(!is_plain_ident("my_account")); assert!(!is_plain_ident("../escape")); assert!(!is_plain_ident("a/b")); assert!(!is_plain_ident("a.b"));