Host the gRPC API and add token admin views
This commit is contained in:
+109
@@ -19,6 +19,7 @@ import (
|
||||
"gioui.org/widget"
|
||||
|
||||
"git.julianfamily.org/keepassgo/apiapproval"
|
||||
"git.julianfamily.org/keepassgo/apiaudit"
|
||||
"git.julianfamily.org/keepassgo/apitokens"
|
||||
"git.julianfamily.org/keepassgo/clipboard"
|
||||
"git.julianfamily.org/keepassgo/passwords"
|
||||
@@ -150,6 +151,114 @@ func TestUIChildGroupsComeFromVaultModel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIAPITokenLifecycleManagement(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
u := newUIWithSession("desktop", &session.Manager{})
|
||||
u.masterPassword.SetText("correct horse battery staple")
|
||||
if err := u.createVaultAction(); err != nil {
|
||||
t.Fatalf("createVaultAction() error = %v", err)
|
||||
}
|
||||
|
||||
u.showAPITokensSection()
|
||||
u.apiTokenName.SetText("Browser Extension")
|
||||
u.apiTokenClientName.SetText("firefox")
|
||||
u.apiTokenExpiresAt.SetText("2026-04-01T15:04:05Z")
|
||||
|
||||
if err := u.issueAPITokenAction(); err != nil {
|
||||
t.Fatalf("issueAPITokenAction() error = %v", err)
|
||||
}
|
||||
if strings.TrimSpace(u.apiTokenSecret) == "" {
|
||||
t.Fatal("apiTokenSecret = empty, want one-time secret")
|
||||
}
|
||||
|
||||
tokens := u.apiTokens()
|
||||
if len(tokens) != 1 {
|
||||
t.Fatalf("len(apiTokens()) = %d, want 1", len(tokens))
|
||||
}
|
||||
if tokens[0].Name != "Browser Extension" || tokens[0].ClientName != "firefox" {
|
||||
t.Fatalf("issued token = %#v, want Browser Extension/firefox", tokens[0])
|
||||
}
|
||||
|
||||
if err := u.rotateAPITokenAction(); err != nil {
|
||||
t.Fatalf("rotateAPITokenAction() error = %v", err)
|
||||
}
|
||||
if strings.TrimSpace(u.apiTokenSecret) == "" {
|
||||
t.Fatal("apiTokenSecret after rotate = empty, want one-time secret")
|
||||
}
|
||||
|
||||
if err := u.disableAPITokenAction(); err != nil {
|
||||
t.Fatalf("disableAPITokenAction() error = %v", err)
|
||||
}
|
||||
disabled, ok := u.selectedAPIToken()
|
||||
if !ok || !disabled.Disabled {
|
||||
t.Fatalf("selectedAPIToken() = %#v, want disabled token", disabled)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIAPITokenPolicyRulesCanBeAddedAndRemoved(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
u := newUIWithSession("desktop", &session.Manager{})
|
||||
u.masterPassword.SetText("correct horse battery staple")
|
||||
if err := u.createVaultAction(); err != nil {
|
||||
t.Fatalf("createVaultAction() error = %v", err)
|
||||
}
|
||||
|
||||
u.showAPITokensSection()
|
||||
u.apiTokenName.SetText("CLI")
|
||||
u.apiTokenClientName.SetText("grpc-cli")
|
||||
if err := u.issueAPITokenAction(); err != nil {
|
||||
t.Fatalf("issueAPITokenAction() error = %v", err)
|
||||
}
|
||||
|
||||
u.apiPolicyOperation.SetText(string(apitokens.OperationListEntries))
|
||||
u.apiPolicyPath.SetText("Root / Internet")
|
||||
u.apiPolicyAllow.Value = true
|
||||
u.apiPolicyGroupScopeW.Value = true
|
||||
if err := u.addAPIPolicyRuleAction(); err != nil {
|
||||
t.Fatalf("addAPIPolicyRuleAction() error = %v", err)
|
||||
}
|
||||
|
||||
token, ok := u.selectedAPIToken()
|
||||
if !ok || len(token.Policies) != 1 {
|
||||
t.Fatalf("selectedAPIToken().Policies = %#v, want 1 rule", token.Policies)
|
||||
}
|
||||
if token.Policies[0].Resource.Kind != apitokens.ResourceGroup {
|
||||
t.Fatalf("rule kind = %q, want group", token.Policies[0].Resource.Kind)
|
||||
}
|
||||
|
||||
if err := u.removeAPIPolicyRuleAction(0); err != nil {
|
||||
t.Fatalf("removeAPIPolicyRuleAction() error = %v", err)
|
||||
}
|
||||
token, ok = u.selectedAPIToken()
|
||||
if !ok || len(token.Policies) != 0 {
|
||||
t.Fatalf("selectedAPIToken().Policies after remove = %#v, want empty", token.Policies)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIAPIAuditSectionShowsRecordedEvents(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
u := newUIWithSession("desktop", &session.Manager{})
|
||||
u.auditLog = apiaudit.New(10)
|
||||
u.auditLog.Record(apiaudit.Event{
|
||||
Type: apiaudit.EventApprovalAllowed,
|
||||
TokenName: "Browser Extension",
|
||||
ClientName: "firefox",
|
||||
Message: "approved",
|
||||
})
|
||||
|
||||
u.showAPIAuditSection()
|
||||
events := u.apiAuditEvents()
|
||||
if len(events) != 1 {
|
||||
t.Fatalf("len(apiAuditEvents()) = %d, want 1", len(events))
|
||||
}
|
||||
if events[0].TokenName != "Browser Extension" {
|
||||
t.Fatalf("apiAuditEvents()[0].TokenName = %q, want %q", events[0].TokenName, "Browser Extension")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUISelectedEntryFollowsApplicationStateSelection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user