hive-c0re: drop unrecognised tool-group names on read, matching capabilities' prune_unknown
This commit is contained in:
parent
597fdebaf3
commit
06951ddc30
1 changed files with 39 additions and 7 deletions
|
|
@ -35,9 +35,45 @@ pub fn tool_groups_path() -> PathBuf {
|
||||||
|
|
||||||
/// Read the per-agent tool-group map. An absent file is the empty map —
|
/// Read the per-agent tool-group map. An absent file is the empty map —
|
||||||
/// callers treat a missing entry as "use role default". A file that
|
/// callers treat a missing entry as "use role default". A file that
|
||||||
/// exists but can't be read or parsed is an error.
|
/// exists but can't be read or parsed is an error. Any entry that isn't a
|
||||||
|
/// recognised [`hive_sh4re::permissions::ToolGroup`] is dropped (with a
|
||||||
|
/// `warn!`) from what's returned — a stale or renamed name is never
|
||||||
|
/// honoured — but `read` itself never writes; unknown names stay on disk
|
||||||
|
/// until the next `set_groups` rewrites the file.
|
||||||
pub fn read() -> std::io::Result<BTreeMap<String, Vec<String>>> {
|
pub fn read() -> std::io::Result<BTreeMap<String, Vec<String>>> {
|
||||||
super::read_map(&tool_groups_path())
|
let mut map = super::read_map(&tool_groups_path())?;
|
||||||
|
prune_unknown(&mut map);
|
||||||
|
Ok(map)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// True if `name` matches a recognised [`hive_sh4re::permissions::ToolGroup`]
|
||||||
|
/// exactly (same comparison [`validate_groups`] uses).
|
||||||
|
fn is_known(name: &str) -> bool {
|
||||||
|
hive_sh4re::permissions::ToolGroup::ALL
|
||||||
|
.iter()
|
||||||
|
.any(|g| <&str>::from(*g) == name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Drop any tool-group string in `map` that isn't a recognised
|
||||||
|
/// [`hive_sh4re::permissions::ToolGroup`], warning per dropped string so a
|
||||||
|
/// stale or renamed grant doesn't look like it's still in effect. An agent
|
||||||
|
/// left with no groups is removed entirely, matching [`set_groups`]'s
|
||||||
|
/// empty-vec behaviour (reverts to the harness role default). Returns
|
||||||
|
/// whether anything was dropped.
|
||||||
|
fn prune_unknown(map: &mut BTreeMap<String, Vec<String>>) -> bool {
|
||||||
|
let mut dropped_any = false;
|
||||||
|
map.retain(|agent, groups| {
|
||||||
|
groups.retain(|g| {
|
||||||
|
let known = is_known(g);
|
||||||
|
if !known {
|
||||||
|
dropped_any = true;
|
||||||
|
tracing::warn!(agent, tool_group = %g, "dropping unrecognised tool group");
|
||||||
|
}
|
||||||
|
known
|
||||||
|
});
|
||||||
|
!groups.is_empty()
|
||||||
|
});
|
||||||
|
dropped_any
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the configured tool groups for one agent. Returns an empty
|
/// Look up the configured tool groups for one agent. Returns an empty
|
||||||
|
|
@ -51,14 +87,10 @@ pub fn groups_for(name: &str) -> std::io::Result<Vec<String>> {
|
||||||
/// Returns `Ok(())` when all names are known, or `Err` listing the
|
/// Returns `Ok(())` when all names are known, or `Err` listing the
|
||||||
/// unrecognised names so callers can surface a useful error message.
|
/// unrecognised names so callers can surface a useful error message.
|
||||||
pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> {
|
pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> {
|
||||||
let valid: std::collections::BTreeSet<&str> = hive_sh4re::permissions::ToolGroup::ALL
|
|
||||||
.iter()
|
|
||||||
.map(|g| <&str>::from(*g))
|
|
||||||
.collect();
|
|
||||||
let unknown: Vec<&str> = groups
|
let unknown: Vec<&str> = groups
|
||||||
.iter()
|
.iter()
|
||||||
.map(String::as_str)
|
.map(String::as_str)
|
||||||
.filter(|s| !valid.contains(s))
|
.filter(|s| !is_known(s))
|
||||||
.collect();
|
.collect();
|
||||||
if unknown.is_empty() {
|
if unknown.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue