swarm-controller: refuse new agents named hive-<anything>
`hive-<hive>` is each hive's read-only forge account, and an agent's forge account takes the agent's name, so an agent called `hive-<x>` would claim hive `<x>`'s account. `hive_types::reserved_agent_prefix_violation` names the rule, and `broken_name_rules` applies it, so both creation paths that go through it (`POST /api/agents` and placing an undeclared agent on a hive) refuse such a name for a new agent. An agent already in the roster keeps its name with a warning, as for every other naming rule. The email check between hive and agent accounts stays as the second guard, for agents created before this rule. Refs #4851
This commit is contained in:
parent
21e3f626f4
commit
4e7142ae53
5 changed files with 78 additions and 13 deletions
|
|
@ -93,6 +93,24 @@ pub fn forge_username_violation(name: &str) -> Option<&'static str> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The prefix no new agent's name may start with. `hive-<hive>` is each hive's
|
||||
/// own forge account (`swarm_secret_client::forge::hive_login`), and every
|
||||
/// agent's forge account takes the agent's name, so an agent called
|
||||
/// `hive-<x>` would claim hive `<x>`'s account.
|
||||
pub const RESERVED_AGENT_PREFIX: &str = "hive-";
|
||||
|
||||
/// The reserved-prefix rule `name` breaks as a new agent's name, or `None`.
|
||||
///
|
||||
/// Creation sites only, for the reason given at [`is_reserved_name`]. Agent
|
||||
/// names only: hive names are kept off `hive` by
|
||||
/// `nix/reserved-hive-fragments.nix`, and the other [`Ident`]s never become a
|
||||
/// forge user.
|
||||
#[must_use]
|
||||
pub fn reserved_agent_prefix_violation(name: &str) -> Option<&'static str> {
|
||||
name.starts_with(RESERVED_AGENT_PREFIX)
|
||||
.then_some("must not start with 'hive-': that prefix is reserved for hive forge accounts")
|
||||
}
|
||||
|
||||
/// A validated hive identifier: 1-63 chars of `[a-z0-9-]`.
|
||||
///
|
||||
/// The single ident type for agent names, forge labels, and matrix / github
|
||||
|
|
@ -187,7 +205,7 @@ impl<'de> serde::Deserialize<'de> for Ident {
|
|||
mod ident_tests {
|
||||
use super::{
|
||||
FORGE_USERNAME_MAX_LEN, Ident, forge_username_violation, is_reserved_name,
|
||||
parse_reserved_names,
|
||||
parse_reserved_names, reserved_agent_prefix_violation,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
|
@ -302,6 +320,20 @@ mod ident_tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_hive_prefix_is_refused_for_an_agent() {
|
||||
for bad in ["hive-x", "hive-alpha", "hive-"] {
|
||||
assert!(
|
||||
reserved_agent_prefix_violation(bad).is_some_and(|r| r.contains("hive forge")),
|
||||
"{bad:?}"
|
||||
);
|
||||
}
|
||||
// The accept arm: `hive` elsewhere in the name, or without the dash.
|
||||
for ok in ["hivemind", "xhive-y", "hive", "my-hive", "hives-x"] {
|
||||
assert_eq!(reserved_agent_prefix_violation(ok), None, "{ok:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trips_and_serde_validates() {
|
||||
let id = Ident::parse("damocles").unwrap();
|
||||
|
|
|
|||
Loading…
Reference in a new issue