fix(#3344): type the roster entry's name as Ident, per review
A bare String in a crate whose whole suite types validated names as hive_types::Ident, so a consumer had to re-derive at the boundary what every sibling field gets checked for free. Ident is strictly narrower than the store's charset — [a-z0-9-] against the [A-Za-z0-9._-] the users database allows, because that file holds humans too. Every agent name is a legal Ident by construction (creation parses one before the job is queued), so the narrowing costs real agents nothing. What it does mean is that a human hand-added to the agent group cannot be described as an agent: the reader omits that row and logs it, rather than failing the whole roster or quietly shrinking the answer. The REQUEST keeps its String. That side carries what a caller asked for, and validating it server-side is what lets a bad name be refused with a message instead of failing to deserialise.
This commit is contained in:
parent
e71c9cc431
commit
d58be6834b
6 changed files with 51 additions and 7 deletions
|
|
@ -312,7 +312,26 @@ fn list(state: &AppState) -> Result<BridgeResponse> {
|
|||
Ok(BridgeResponse::Agents {
|
||||
agents: store::agent_names(&user_store)
|
||||
.into_iter()
|
||||
.map(|name| AgentIdentity { name })
|
||||
.filter_map(|name| match hive_types::Ident::parse(&name) {
|
||||
Ok(ident) => Some(AgentIdentity { name: ident }),
|
||||
// The store's charset is wider than an agent name's, because
|
||||
// it holds humans too. Every agent this bridge creates is a
|
||||
// legal `Ident` by construction, so reaching here means a
|
||||
// subject was hand-added to the agent group that cannot be an
|
||||
// agent. Skipped rather than failing the whole roster — one
|
||||
// bad row must not make every other agent invisible — but
|
||||
// logged, because silently shrinking an answer is how a
|
||||
// roster starts lying about who is missing.
|
||||
Err(reason) => {
|
||||
tracing::warn!(
|
||||
subject = %name,
|
||||
%reason,
|
||||
"subject carries the agent group but is not a legal agent name; \
|
||||
omitting it from the roster"
|
||||
);
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue