Expose API approval prompts to app state and UI

This commit is contained in:
Joe Julian
2026-03-29 23:14:39 -07:00
parent f77a185e46
commit 74dfe3f3d0
4 changed files with 298 additions and 0 deletions
+55
View File
@@ -18,6 +18,8 @@ import (
"gioui.org/unit"
"gioui.org/widget"
"git.julianfamily.org/keepassgo/apiapproval"
"git.julianfamily.org/keepassgo/apitokens"
"git.julianfamily.org/keepassgo/clipboard"
"git.julianfamily.org/keepassgo/passwords"
"git.julianfamily.org/keepassgo/session"
@@ -1937,6 +1939,43 @@ func TestUIShowsLifecycleSetupOnlyBeforeVaultIsOpened(t *testing.T) {
}
}
func TestUIPendingApprovalUsesFirstPendingRequest(t *testing.T) {
t.Parallel()
u := newUIWithModel("desktop", vault.Model{})
u.state.Approvals = &mainStubApprovalManager{
pending: []apiapproval.Request{
{ID: "approval-1", TokenName: "CLI", Operation: apitokens.OperationListEntries},
{ID: "approval-2", TokenName: "Browser", Operation: apitokens.OperationReadEntry},
},
}
request, ok := u.pendingApproval()
if !ok {
t.Fatal("pendingApproval() ok = false, want true")
}
if request.ID != "approval-1" {
t.Fatalf("pendingApproval().ID = %q, want approval-1", request.ID)
}
}
func TestUIResolvePendingApprovalDelegatesToApprovalManager(t *testing.T) {
t.Parallel()
manager := &mainStubApprovalManager{
pending: []apiapproval.Request{{ID: "approval-1"}},
}
u := newUIWithModel("desktop", vault.Model{})
u.state.Approvals = manager
if err := u.resolvePendingApproval(apiapproval.OutcomeDenyPermanent); err != nil {
t.Fatalf("resolvePendingApproval() error = %v", err)
}
if manager.lastID != "approval-1" || manager.lastOutcome != apiapproval.OutcomeDenyPermanent {
t.Fatalf("resolvePendingApproval() delegated (%q, %q), want (approval-1, deny-permanent)", manager.lastID, manager.lastOutcome)
}
}
func TestUIRequiresExplicitEditModeForEntryEditor(t *testing.T) {
t.Parallel()
@@ -2991,3 +3030,19 @@ func writeKDBXMainTestFile(t *testing.T, path string, model vault.Model, key vau
t.Fatalf("WriteFile(%s) error = %v", path, err)
}
}
type mainStubApprovalManager struct {
pending []apiapproval.Request
lastID string
lastOutcome apiapproval.Outcome
}
func (m mainStubApprovalManager) Pending() []apiapproval.Request {
return append([]apiapproval.Request(nil), m.pending...)
}
func (m *mainStubApprovalManager) Resolve(id string, outcome apiapproval.Outcome) (apiapproval.Request, *apitokens.PolicyRule, error) {
m.lastID = id
m.lastOutcome = outcome
return apiapproval.Request{ID: id}, nil, nil
}