Invalidate UI on approval queue changes
This commit is contained in:
@@ -50,6 +50,7 @@ type Broker struct {
|
|||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
now func() time.Time
|
now func() time.Time
|
||||||
nextID func() string
|
nextID func() string
|
||||||
|
notify func()
|
||||||
}
|
}
|
||||||
|
|
||||||
type pendingRequest struct {
|
type pendingRequest struct {
|
||||||
@@ -108,6 +109,15 @@ func (b *Broker) Pending() []Request {
|
|||||||
return requests
|
return requests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Broker) SetChangeNotifier(notify func()) {
|
||||||
|
if b == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
b.notify = notify
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Broker) Request(ctx context.Context, token apitokens.Token, op apitokens.Operation, resource apitokens.Resource) (Result, error) {
|
func (b *Broker) Request(ctx context.Context, token apitokens.Token, op apitokens.Operation, resource apitokens.Resource) (Result, error) {
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return Result{}, ErrRequestTimedOut
|
return Result{}, ErrRequestTimedOut
|
||||||
@@ -128,12 +138,20 @@ func (b *Broker) Request(ctx context.Context, token apitokens.Token, op apitoken
|
|||||||
|
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
b.pending[pending.request.ID] = pending
|
b.pending[pending.request.ID] = pending
|
||||||
|
notify := b.notify
|
||||||
b.mu.Unlock()
|
b.mu.Unlock()
|
||||||
|
if notify != nil {
|
||||||
|
notify()
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
delete(b.pending, pending.request.ID)
|
delete(b.pending, pending.request.ID)
|
||||||
|
notify := b.notify
|
||||||
b.mu.Unlock()
|
b.mu.Unlock()
|
||||||
|
if notify != nil {
|
||||||
|
notify()
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
timer := time.NewTimer(b.timeout)
|
timer := time.NewTimer(b.timeout)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package apiapproval
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -120,6 +121,36 @@ func TestBrokerTimesOutPendingRequests(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBrokerNotifiesWhenPendingRequestsChange(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
broker := NewBroker(time.Minute)
|
||||||
|
changes := make(chan int, 4)
|
||||||
|
broker.SetChangeNotifier(func() {
|
||||||
|
changes <- len(broker.Pending())
|
||||||
|
})
|
||||||
|
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
_, err := broker.Request(context.Background(), apitokens.Token{ID: "token-1", Name: "CLI"}, apitokens.OperationListGroups, apitokens.Resource{Kind: apitokens.ResourceGroup, Path: []string{"Root"}})
|
||||||
|
errCh <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
waitForPending(t, broker, 1)
|
||||||
|
if _, _, err := broker.Resolve(broker.Pending()[0].ID, OutcomeAllowOnce); err != nil {
|
||||||
|
t.Fatalf("Resolve(allow once) error = %v", err)
|
||||||
|
}
|
||||||
|
if err := <-errCh; err != nil {
|
||||||
|
t.Fatalf("Request() error = %v, want nil", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := []int{<-changes, <-changes}
|
||||||
|
slices.Sort(got)
|
||||||
|
if !slices.Equal(got, []int{0, 1}) {
|
||||||
|
t.Fatalf("change notifications = %v, want [0 1]", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func waitForPending(t *testing.T, broker *Broker, want int) {
|
func waitForPending(t *testing.T, broker *Broker, want int) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ func run(w *app.Window, mode string, paths statePaths, grpcAddr string) error {
|
|||||||
ui.state.AuditLog = ui.auditLog
|
ui.state.AuditLog = ui.auditLog
|
||||||
ui.grpcAddress = host.Address()
|
ui.grpcAddress = host.Address()
|
||||||
ui.state.Approvals = &uiApprovalManager{server: host.Server()}
|
ui.state.Approvals = &uiApprovalManager{server: host.Server()}
|
||||||
|
host.Server().ApprovalBroker().SetChangeNotifier(ui.invalidate)
|
||||||
defer func() { _ = host.Stop() }()
|
defer func() { _ = host.Stop() }()
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
|
|||||||
Reference in New Issue
Block a user