Validate admin targets before actions
This commit is contained in:
committed by
Brandon McGinty
parent
cf9e1c6d0a
commit
461f172035
@@ -169,7 +169,9 @@ func (b *Barnard) AdminItemKeyPress(ui *uiterm.Ui, tree *uiterm.Tree, item uiter
|
|||||||
if !ok || admin.action == nil {
|
if !ok || admin.action == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
admin.action()
|
if !b.withValidAdminTargets(admin.action) {
|
||||||
|
b.AddOutputLine("Admin: action target is no longer available")
|
||||||
|
}
|
||||||
b.UiAdmin.Rebuild()
|
b.UiAdmin.Rebuild()
|
||||||
b.Ui.Refresh()
|
b.Ui.Refresh()
|
||||||
}
|
}
|
||||||
@@ -549,13 +551,37 @@ func (b *Barnard) handleAdminPrompt(text string) bool {
|
|||||||
}
|
}
|
||||||
prompt := b.pendingAdminPrompt
|
prompt := b.pendingAdminPrompt
|
||||||
b.pendingAdminPrompt = nil
|
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 {
|
if b.Client != nil && b.Client.Self != nil {
|
||||||
b.UpdateInputStatus(fmt.Sprintf("[%s]", b.Client.Self.Channel.Name))
|
b.UpdateInputStatus(fmt.Sprintf("[%s]", b.Client.Self.Channel.Name))
|
||||||
}
|
}
|
||||||
return true
|
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) {
|
func (b *Barnard) CommandAdmin(ui *uiterm.Ui, cmd string) {
|
||||||
b.executeAdminCommand(cmd)
|
b.executeAdminCommand(cmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user