feat: integrate security features into TUI
- SFTPBrowserTab: added storagePassword, passphraseCallback fields - Model: added storagePassword, knownHosts fields - cmd/hostkeeper/tui.go: initialize known_hosts on startup - SFTP connect: wire passphrase callback to SSH client - SetStoragePassword/SetKnownHosts/SetPassphraseCallback methods
This commit is contained in:
@@ -74,6 +74,10 @@ type SFTPBrowserTab struct {
|
||||
|
||||
program *tea.Program
|
||||
|
||||
// Security
|
||||
storagePassword string // master password for encrypted storage
|
||||
passphraseCallback func() string // callback for SSH key passphrases
|
||||
|
||||
mu sync.Mutex
|
||||
closeOnce sync.Once
|
||||
}
|
||||
@@ -107,6 +111,14 @@ func (t *SFTPBrowserTab) SetProgram(p *tea.Program) {
|
||||
t.program = p
|
||||
}
|
||||
|
||||
func (t *SFTPBrowserTab) SetStoragePassword(password string) {
|
||||
t.storagePassword = password
|
||||
}
|
||||
|
||||
func (t *SFTPBrowserTab) SetPassphraseCallback(cb func() string) {
|
||||
t.passphraseCallback = cb
|
||||
}
|
||||
|
||||
func (t *SFTPBrowserTab) Init() tea.Cmd {
|
||||
go t.connect()
|
||||
go t.refreshLocal()
|
||||
@@ -132,6 +144,11 @@ func (t *SFTPBrowserTab) connect() {
|
||||
timeout := 30 * time.Second
|
||||
cl := sshclient.NewClient(t.host, timeout)
|
||||
|
||||
// Wire up passphrase callback for encrypted keys
|
||||
if t.passphraseCallback != nil {
|
||||
cl.SetPassphraseCallback(t.passphraseCallback)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := cl.Connect(ctx); err != nil {
|
||||
t.mu.Lock()
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
||||
"git.tukangketik.id/swanadiva/hostkeeper/internal/models"
|
||||
"git.tukangketik.id/swanadiva/hostkeeper/pkg/knownhosts"
|
||||
"git.tukangketik.id/swanadiva/hostkeeper/pkg/storage"
|
||||
)
|
||||
|
||||
@@ -28,6 +29,10 @@ type Model struct {
|
||||
Quit bool
|
||||
dataDir string
|
||||
program *tea.Program
|
||||
|
||||
// Security
|
||||
storagePassword string
|
||||
knownHosts *knownhosts.KnownHosts
|
||||
}
|
||||
|
||||
// New creates a new TUI model
|
||||
@@ -53,6 +58,16 @@ func (m *Model) SetProgram(p *tea.Program) {
|
||||
m.program = p
|
||||
}
|
||||
|
||||
// SetStoragePassword sets the master password for encrypted storage
|
||||
func (m *Model) SetStoragePassword(password string) {
|
||||
m.storagePassword = password
|
||||
}
|
||||
|
||||
// SetKnownHosts sets the known_hosts manager for host key verification
|
||||
func (m *Model) SetKnownHosts(kh *knownhosts.KnownHosts) {
|
||||
m.knownHosts = kh
|
||||
}
|
||||
|
||||
// Update handles messages and updates the model
|
||||
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
@@ -91,6 +106,15 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
if m.program != nil {
|
||||
tab.SetProgram(m.program)
|
||||
}
|
||||
if m.storagePassword != "" {
|
||||
tab.SetStoragePassword(m.storagePassword)
|
||||
}
|
||||
if m.knownHosts != nil {
|
||||
tab.SetPassphraseCallback(func() string {
|
||||
// TODO: prompt for passphrase in TUI
|
||||
return ""
|
||||
})
|
||||
}
|
||||
cmd := m.tabs.Add(tab)
|
||||
return m, cmd
|
||||
|
||||
|
||||
Reference in New Issue
Block a user