Migrate bos-settings from GTK4 to Tauri + Svelte 5
Ports every remaining view (Keybinds, the last one — dual Flat/MultiLayout schema detection, per-action dedicated fields with a raw-JSON fallback for anything not modeled) and removes the now-fully-dead GTK4 crate (root Cargo.toml + src/), leaving src-tauri/ as the single Rust binary crate. Also folds in the UX pass done alongside the migration: responsive multi-column layout instead of a single centered column, chip/dropdown pickers replacing free-typed fields (Wi-Fi networks, Bar style, keyboard layout, tag lists), consistent pill-switch toggles and boxed-list card styling across every page, and a sidebar scroll-chaining fix.
This commit is contained in:
parent
62365ebf10
commit
93c3b88b10
147 changed files with 15804 additions and 7516 deletions
89
src-tauri/src/commands/firewall.rs
Normal file
89
src-tauri/src/commands/firewall.rs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
//! ufw firewall rules. `ufw status` itself requires root (confirmed against
|
||||
//! the installed ufw script), so unlike every other read-only panel, this
|
||||
//! doesn't query eagerly — the frontend only calls `get_firewall_status`
|
||||
//! when the user clicks Refresh, deferring the one unavoidable polkit
|
||||
//! prompt to an explicit action instead of forcing it on app open.
|
||||
|
||||
use serde::Serialize;
|
||||
use tokio::process::Command;
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct FirewallRule {
|
||||
number: String,
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct FirewallStatus {
|
||||
active: bool,
|
||||
rules: Vec<FirewallRule>,
|
||||
}
|
||||
|
||||
/// One `pkexec ufw status numbered` call, parsed for both the active/
|
||||
/// inactive line and the numbered rules.
|
||||
#[tauri::command]
|
||||
pub async fn get_firewall_status() -> Result<FirewallStatus, String> {
|
||||
let output = Command::new("pkexec")
|
||||
.args(["ufw", "status", "numbered"])
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("couldn't run pkexec: {e}"))?;
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
|
||||
return Err(if stderr.is_empty() {
|
||||
match output.status.code() {
|
||||
Some(127) => "no polkit authentication agent is available in this session".to_string(),
|
||||
Some(code) => format!("pkexec exited with status {code}"),
|
||||
None => "pkexec was terminated by a signal".to_string(),
|
||||
}
|
||||
} else {
|
||||
stderr
|
||||
});
|
||||
}
|
||||
let text = String::from_utf8_lossy(&output.stdout);
|
||||
let active = text.lines().next().is_some_and(|l| l.trim() == "Status: active");
|
||||
let rules = text
|
||||
.lines()
|
||||
.filter_map(|l| {
|
||||
let l = l.trim_start();
|
||||
if !l.starts_with('[') {
|
||||
return None;
|
||||
}
|
||||
let (num, rest) = l.split_once(']')?;
|
||||
let number = num.trim_start_matches('[').trim().to_string();
|
||||
Some(FirewallRule { number, text: rest.trim().to_string() })
|
||||
})
|
||||
.collect();
|
||||
Ok(FirewallStatus { active, rules })
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_firewall_enabled(enabled: bool) -> Result<(), String> {
|
||||
let verb = if enabled { "enable" } else { "disable" };
|
||||
let output = Command::new("pkexec").args(["ufw", "--force", verb]).output().await.map_err(|e| e.to_string())?;
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(String::from_utf8_lossy(&output.stderr).trim().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn add_firewall_rule(rule: String) -> Result<(), String> {
|
||||
let output = Command::new("pkexec").args(["ufw", "allow", rule.trim()]).output().await.map_err(|e| e.to_string())?;
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(String::from_utf8_lossy(&output.stderr).trim().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn remove_firewall_rule(number: String) -> Result<(), String> {
|
||||
let output = Command::new("pkexec").args(["ufw", "--force", "delete", &number]).output().await.map_err(|e| e.to_string())?;
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(String::from_utf8_lossy(&output.stderr).trim().to_string())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue