Fix bugs from a full audit: Tailscale recovery, SSID verification, captive portals, config races
The watch loop could spin forever on a stopped Tailscale daemon (the
auto-start path was unreachable) while re-notifying every retry, report
"connected" when NM autoconnect won a race onto a different SSID, and
classify captive portals as healthy (200/302 accepted as internet). The
bread-bus subscription thread also read/wrote config and state files
concurrently with the watch loop. Fix all of those plus: EDITOR values
with arguments, scan --to silently ignoring unknown profiles, deleted
core profiles being resurrected, inline-network migration data loss,
login never retried, XDG-unaware install-service, detect persisting a
stale default profile, password length leaking through the mask, a
stdin/stdout pipe deadlock, and several minor UI/robustness issues.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
parent
02e96126e0
commit
c02360a873
12 changed files with 538 additions and 189 deletions
|
|
@ -50,6 +50,7 @@ impl RecordedCall {
|
|||
}
|
||||
|
||||
type Matcher = Box<dyn Fn(&str, &[&str]) -> bool>;
|
||||
type DynamicRule = (Matcher, Box<dyn Fn(&str, &[&str]) -> Output>);
|
||||
|
||||
/// A canned, rule-based [`Runner`]. Rules are tried in registration order;
|
||||
/// the first whose matcher returns `true` supplies the response. No rule
|
||||
|
|
@ -58,6 +59,7 @@ type Matcher = Box<dyn Fn(&str, &[&str]) -> bool>;
|
|||
/// (a wrong exit code) rather than silently returning success.
|
||||
pub struct FakeRunner {
|
||||
rules: Vec<(Matcher, Output)>,
|
||||
dynamic_rules: Vec<DynamicRule>,
|
||||
commands: HashSet<String>,
|
||||
calls: Rc<RefCell<Vec<RecordedCall>>>,
|
||||
}
|
||||
|
|
@ -66,6 +68,7 @@ impl FakeRunner {
|
|||
pub fn new() -> Self {
|
||||
FakeRunner {
|
||||
rules: Vec::new(),
|
||||
dynamic_rules: Vec::new(),
|
||||
commands: HashSet::new(),
|
||||
calls: Rc::new(RefCell::new(Vec::new())),
|
||||
}
|
||||
|
|
@ -99,6 +102,20 @@ impl FakeRunner {
|
|||
output,
|
||||
)
|
||||
}
|
||||
|
||||
/// Register a rule whose *response* is computed at call time (rather
|
||||
/// than canned), enabling stateful fakes — e.g. answering "which SSID is
|
||||
/// active?" with the SSID of the most recently dialed connection.
|
||||
/// Dynamic rules are tried after the static ones.
|
||||
pub fn on_dynamic(
|
||||
mut self,
|
||||
matcher: impl Fn(&str, &[&str]) -> bool + 'static,
|
||||
out: impl Fn(&str, &[&str]) -> Output + 'static,
|
||||
) -> Self {
|
||||
self.dynamic_rules
|
||||
.push((Box::new(matcher), Box::new(out)));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FakeRunner {
|
||||
|
|
@ -119,6 +136,11 @@ impl Runner for FakeRunner {
|
|||
return out.clone();
|
||||
}
|
||||
}
|
||||
for (matcher, out) in &self.dynamic_rules {
|
||||
if matcher(prog, args) {
|
||||
return out(prog, args);
|
||||
}
|
||||
}
|
||||
Output::failed()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue