Commit 19aef7e
Changed files (7)
cmd/ufWall/main.go
@@ -12,7 +12,7 @@ import (
func main() {
- if _, err := exec.LookPath("ufsw"); err != nil {
+ if _, err := exec.LookPath("ufw"); err != nil {
fmt.Println("Please first install ufw and try again.")
os.Exit(1)
}
internal/app/update.go
@@ -56,6 +56,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newPolicy, sectionCmd := m.policySection.Update(msg, m.policy)
m.policySection = newPolicy
return m, sectionCmd
+
+ case sections.RulesSection:
+ newRules, sectionCmd := m.rulesSection.Update(msg,m.rules)
+ m.rulesSection = newRules
+ return m, sectionCmd
}
case keys.RefreshMsg:
@@ -93,5 +98,5 @@ func (m *model) focusActiveSection() {
}
func (m *model) isMenuOpen() bool {
- return m.statsSection.GetMenu() != nil
+ return m.statsSection.GetMenu() != nil || m.rulesSection.GetMenu() != nil
}
internal/app/view.go
@@ -2,7 +2,6 @@ package app
import (
"fmt"
- "ufWall/internal/sections"
"ufWall/internal/ui"
"github.com/charmbracelet/lipgloss"
@@ -82,9 +81,18 @@ func (m model) View() string {
layout,
)
- if m.activeSection == sections.StatsSection && m.statsSection.GetMenu() != nil {
+ var menuOpen *ui.Menu
+
+ if m.statsSection.GetMenu() != nil {
+ menuOpen = m.statsSection.GetMenu()
+ } else if m.rulesSection.GetMenu() != nil {
+ menuOpen = m.rulesSection.GetMenu()
+ }
+
+ if menuOpen != nil {
+
dimmed := "\x1b[2m" + lipgloss.NewStyle().Faint(true).Render(layout) + "\x1b[0m"
- menuView := m.statsSection.GetMenu().View(m.styles)
+ menuView := menuOpen.View(m.styles)
menuW := lipgloss.Width(menuView)
menuH := lipgloss.Height(menuView)
internal/sections/rules/model.go
@@ -5,24 +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/rules/update.go
@@ -0,0 +1,64 @@
+package rules
+
+import (
+ "log"
+ "ufWall/internal/keys"
+ "ufWall/internal/ufw"
+ "ufWall/internal/ui"
+
+ "github.com/charmbracelet/bubbles/key"
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+func (m Model) Update(msg tea.Msg, rules []ufw.Rule) (Model, tea.Cmd) {
+ if m.menu != nil {
+ if quit := m.menu.Update(msg); quit {
+ m.menu = nil
+ return m, keys.Refresh()
+ }
+ } else {
+ 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 < len(rules)-1 {
+ m.cursorLine++
+ }
+ case key.Matches(msg, keys.Bindings.Execute):
+ if len(rules) > 0 {
+ return m.openMenu(rules)
+ }
+ }
+ }
+ }
+ return m, nil
+}
+
+func (m Model) openMenu(rules []ufw.Rule) (Model, tea.Cmd) {
+ if len(rules) == 0 || m.cursorLine >= len(rules) {
+ return m, nil
+ }
+
+ selectedRule := rules[m.cursorLine]
+ log.Println(selectedRule)
+
+ options := ui.MakeMenuItems(
+ []string{"Delete Rule"},
+ func(label string) tea.Cmd {
+ switch label {
+ case "Delete Rule":
+ log.Printf("Deleting rule #%d", selectedRule.Num)
+ ufw.DeleteRule(selectedRule.Num)
+ }
+ return nil
+ },
+ )
+
+ menu := ui.NewMenu(options, m.styles)
+ m.menu = &menu
+ return m, nil
+}
internal/sections/rules/view.go
@@ -18,9 +18,11 @@ func (m Model) View(rules []ufw.Rule) string {
headerContent := m.styles.Label.UnsetWidth().Render(header)
line := strings.Repeat("─", lipgloss.Width(headerContent))
- rows = append(rows, headerContent, m.styles.Label.UnsetWidth().Render(line))
+ rows = append(rows, " "+headerContent, " "+m.styles.Label.UnsetWidth().Render(line))
- for _, r := range rules {
+ sectionActiveNoMenu := m.menu == nil && m.active
+
+ for i, r := range rules {
row := fmt.Sprintf(
"%-3d │ %-6s │ %-5s │ %-16s │ %-5s │ %-16s │ %-5s",
r.Num,
@@ -31,7 +33,7 @@ func (m Model) View(rules []ufw.Rule) string {
r.ToDest,
r.ToPort,
)
- rows = append(rows, m.styles.Value.Render(row))
+ rows = append(rows, ui.InsertCursor(row, m.cursorLine == i && sectionActiveNoMenu, m.styles))
}
table := strings.Join(rows, "\n")
content := lipgloss.JoinVertical(
internal/ufw/main.go
@@ -120,7 +120,7 @@ func Disable() (stdout, stderr string, err error) {
}
func DeleteRule(num int) (stdout, stderr string, err error) {
- return RunSudo("delete", fmt.Sprintf("%d", num))
+ return RunSudo("--force", "delete", fmt.Sprintf("%d", num))
}
func DefaultIncoming(allow bool) (stdout, stderr string, err error) {