Commit 6182b6f
Changed files (8)
internal/app/update.go
@@ -37,6 +37,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case key.Matches(msg, keys.Bindings.Quit):
return m, tea.Quit
+
+ case key.Matches(msg, keys.Bindings.Execute):
+ if !m.stats.Active {
+ ufw.Enable()
+ return m, keys.Refresh()
+ }
}
}
@@ -45,6 +51,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newStats, sectionCmd := m.statsSection.Update(msg)
m.statsSection = newStats
return m, sectionCmd
+
+ case sections.PolicySection:
+ newPolicy, sectionCmd := m.policySection.Update(msg, m.policy)
+ m.policySection = newPolicy
+ return m, sectionCmd
}
case keys.RefreshMsg:
internal/app/view.go
@@ -32,6 +32,23 @@ func (m model) View() string {
)
}
+ if !m.stats.Active {
+ prompt := lipgloss.JoinVertical(
+ lipgloss.Center,
+ m.styles.Error.Render("Firewall is disabled"),
+ "",
+ lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render("Press Space to activate"),
+ lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render("Press Esc or Q to quit"),
+ )
+ return lipgloss.Place(
+ m.width,
+ m.height,
+ lipgloss.Center,
+ lipgloss.Center,
+ prompt,
+ )
+ }
+
title := m.styles.Title.
Width(containerWidth).
Render("Firewall Manager")
internal/keys/keys.go
@@ -35,16 +35,14 @@ var Bindings = KeyMap{
Refresh: key.NewBinding(
key.WithKeys("r"),
- key.WithHelp("r", "refresh"),
),
Quit: key.NewBinding(
key.WithKeys("q", "esc", "ctrl+c"),
- key.WithHelp("q/esc", "quit"),
),
Execute: key.NewBinding(
- key.WithKeys("enter"),
+ key.WithKeys(" ", "enter"),
),
}
internal/sections/policy/model.go
@@ -5,26 +5,40 @@ import (
)
type Model struct {
- styles ui.Styles
- active bool
+ styles ui.Styles
+ totalOpts int
+ cursorLine int
+ showMenu bool
+ menu *ui.Menu
+ active bool
}
func New(styles ui.Styles) Model {
return Model{
- styles: styles,
- active: false,
+ styles: styles,
+ cursorLine: 0,
+ showMenu: false,
+ menu: nil,
+ active: false,
+ totalOpts: 2,
}
}
func (m *Model) Focus() {
- // m.cursorLine = 0
+ m.cursorLine = 0
m.active = true
}
func (m *Model) Blur() {
m.active = false
- // m.showMenu = false
- // m.cursorLine = 0
+ m.showMenu = false
+ m.cursorLine = 0
}
+func (m Model) HasOpenMenu() bool {
+ return m.menu != nil
+}
+func (m Model) GetMenu() *ui.Menu {
+ return m.menu
+}
internal/sections/policy/update.go
@@ -0,0 +1,35 @@
+package policy
+
+import (
+ "ufWall/internal/keys"
+ "ufWall/internal/ufw"
+
+ "github.com/charmbracelet/bubbles/key"
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+func (m Model) Update(msg tea.Msg, policy ufw.Policy) (Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ switch {
+ case key.Matches(msg, keys.Bindings.CursorUp):
+ if m.cursorLine > 0 {
+ m.cursorLine--
+ }
+ case key.Matches(msg, keys.Bindings.CursorDown):
+ if m.cursorLine < m.totalOpts {
+ m.cursorLine++
+ }
+ case key.Matches(msg, keys.Bindings.Execute):
+ switch m.cursorLine {
+ case 0:
+ ufw.DefaultIncoming(!(policy.DefaultIncoming == "ALLOW"))
+ case 1:
+ ufw.DefaultOutgoing(!(policy.DefaultOutgoing == "ALLOW"))
+ case 2:
+ ufw.DefaultRouted(!(policy.DefaultRouted == "ALLOW"))
+ }
+ }
+ }
+ return m, keys.Refresh()
+}
internal/sections/policy/view.go
@@ -45,11 +45,14 @@ func (m Model) View(policy ufw.Policy) string {
routedStyle.Render(policy.DefaultRouted),
)
+ sectionActiveNoMenu := m.menu == nil && m.active
+
content := lipgloss.JoinVertical(
- lipgloss.Left,
- incomingLine,
- outgoingLine,
- routedLine,
+ lipgloss.Top,
+ ui.InsertCursor(incomingLine, m.cursorLine == 0 && sectionActiveNoMenu, m.styles),
+ ui.InsertCursor(outgoingLine, m.cursorLine == 1 && sectionActiveNoMenu, m.styles),
+ ui.InsertCursor(routedLine, m.cursorLine == 2 && sectionActiveNoMenu, m.styles),
)
+
return ui.TitledBox("Default Policies", content, m.styles, -1, m.active)
}
internal/ufw/main.go
@@ -9,8 +9,8 @@ import (
)
type Stats struct {
- Active bool
- Logging string
+ Active bool
+ Logging string
TotalRules int
}
@@ -70,12 +70,12 @@ func extractPolicy(s string) string {
return "unknown"
}
-func GetUFWData() (ufwData) {
+func GetUFWData() ufwData {
var data ufwData
numOut, _, errNum := RunSudo("status", "numbered")
verbOut, _, errVerb := RunSudo("status", "verbose")
-
+
if errNum != nil && errVerb != nil {
data.Error = fmt.Errorf("ufw status: %w", errNum)
return data
@@ -139,6 +139,14 @@ func DefaultOutgoing(allow bool) (stdout, stderr string, err error) {
return RunSudo("default", pol, "outgoing")
}
+func DefaultRouted(allow bool) (stdout, stderr string, err error) {
+ pol := "deny"
+ if allow {
+ pol = "allow"
+ }
+ return RunSudo("default", pol, "routed")
+}
+
func SetLogging(level string) (stdout, stderr string, err error) {
return RunSudo("logging", level)
}