Validate admin targets before actions

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-10 10:26:03 -04:00
committed by Brandon McGinty
parent cf9e1c6d0a
commit 461f172035
2 changed files with 58 additions and 2 deletions
+28 -2
View File
@@ -169,7 +169,9 @@ func (b *Barnard) AdminItemKeyPress(ui *uiterm.Ui, tree *uiterm.Tree, item uiter
if !ok || admin.action == nil {
return
}
admin.action()
if !b.withValidAdminTargets(admin.action) {
b.AddOutputLine("Admin: action target is no longer available")
}
b.UiAdmin.Rebuild()
b.Ui.Refresh()
}
@@ -549,13 +551,37 @@ func (b *Barnard) handleAdminPrompt(text string) bool {
}
prompt := b.pendingAdminPrompt
b.pendingAdminPrompt = nil
prompt.action(strings.TrimSpace(text))
if !b.withValidAdminTargets(func() { prompt.action(strings.TrimSpace(text)) }) {
b.AddOutputLine("Admin: action target is no longer available")
}
if b.Client != nil && b.Client.Self != nil {
b.UpdateInputStatus(fmt.Sprintf("[%s]", b.Client.Self.Channel.Name))
}
return true
}
// withValidAdminTargets runs an action only while its selected targets are
// still members of the current connection. Menu actions can outlive server
// removal events while a prompt is open.
func (b *Barnard) withValidAdminTargets(action func()) bool {
if b.Client == nil {
return false
}
valid := true
b.Client.Do(func() {
if u := b.adminTargetUser; u != nil && b.Client.Users[u.Session] != u {
valid = false
}
if ch := b.adminTargetChan; ch != nil && b.Client.Channels[ch.ID] != ch {
valid = false
}
if valid {
action()
}
})
return valid
}
func (b *Barnard) CommandAdmin(ui *uiterm.Ui, cmd string) {
b.executeAdminCommand(cmd)
}
+30
View File
@@ -0,0 +1,30 @@
package main
import (
"testing"
"git.stormux.org/storm/barnard/gumble/gumble"
)
func TestAdminActionRejectsRemovedTarget(t *testing.T) {
user := &gumble.User{Session: 1}
client := &gumble.Client{Users: gumble.Users{1: user}, Channels: gumble.Channels{}}
b := &Barnard{Client: client, adminTargetUser: user}
called := false
if !b.withValidAdminTargets(func() { called = true }) || !called {
t.Fatal("current admin target was rejected")
}
delete(client.Users, user.Session)
called = false
if b.withValidAdminTargets(func() { called = true }) || called {
t.Fatal("removed admin target was allowed to execute")
}
}
func TestAdminActionRejectsReplacedChannelTarget(t *testing.T) {
channel := &gumble.Channel{ID: 2}
b := &Barnard{Client: &gumble.Client{Channels: gumble.Channels{2: &gumble.Channel{ID: 2}}}, adminTargetChan: channel}
if b.withValidAdminTargets(func() {}) {
t.Fatal("replaced channel target was allowed to execute")
}
}