Fix API token detail panel panic
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"image"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
|
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
|
"gioui.org/op"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
"gioui.org/widget"
|
"gioui.org/widget"
|
||||||
|
|
||||||
@@ -237,6 +239,44 @@ func TestUIAPITokenPolicyRulesCanBeAddedAndRemoved(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUIAPITokenDetailPanelHandlesMissingRemoveClickables(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("Joe / codex")
|
||||||
|
u.apiPolicyAllow.Value = true
|
||||||
|
u.apiPolicyGroupScopeW.Value = true
|
||||||
|
if err := u.addAPIPolicyRuleAction(); err != nil {
|
||||||
|
t.Fatalf("addAPIPolicyRuleAction() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.apiPolicyRemoves = nil
|
||||||
|
ops := new(op.Ops)
|
||||||
|
gtx := layout.Context{
|
||||||
|
Ops: ops,
|
||||||
|
Constraints: layout.Exact(image.Pt(800, 600)),
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
t.Fatalf("apiTokenDetailPanel() panicked: %v", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_ = u.apiTokenDetailPanel(gtx)
|
||||||
|
}
|
||||||
|
|
||||||
func TestUIAPIAuditSectionShowsRecordedEvents(t *testing.T) {
|
func TestUIAPIAuditSectionShowsRecordedEvents(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ func (u *ui) loadSelectedAPITokenIntoEditor() {
|
|||||||
u.apiPolicyOperation.SetText(string(apitokens.OperationListEntries))
|
u.apiPolicyOperation.SetText(string(apitokens.OperationListEntries))
|
||||||
u.apiPolicyPath.SetText(strings.Join(u.displayPath(), " / "))
|
u.apiPolicyPath.SetText(strings.Join(u.displayPath(), " / "))
|
||||||
u.apiPolicyEntryID.SetText("")
|
u.apiPolicyEntryID.SetText("")
|
||||||
u.apiPolicyAllow.Value = true
|
u.apiPolicyAllow.Value = true
|
||||||
u.apiPolicyGroupScope = true
|
u.apiPolicyGroupScope = true
|
||||||
u.apiPolicyGroupScopeW.Value = true
|
u.apiPolicyGroupScopeW.Value = true
|
||||||
u.apiPolicyRemoves = nil
|
u.apiPolicyRemoves = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -444,6 +444,9 @@ func (u *ui) apiAuditListPanel(gtx layout.Context) layout.Dimensions {
|
|||||||
|
|
||||||
func (u *ui) apiTokenDetailPanel(gtx layout.Context) layout.Dimensions {
|
func (u *ui) apiTokenDetailPanel(gtx layout.Context) layout.Dimensions {
|
||||||
token, ok := u.selectedAPIToken()
|
token, ok := u.selectedAPIToken()
|
||||||
|
if ok && len(u.apiPolicyRemoves) < len(token.Policies) {
|
||||||
|
u.apiPolicyRemoves = make([]widget.Clickable, len(token.Policies))
|
||||||
|
}
|
||||||
rows := []layout.Widget{
|
rows := []layout.Widget{
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
lbl := material.Label(u.theme, unit.Sp(20), "API Token")
|
lbl := material.Label(u.theme, unit.Sp(20), "API Token")
|
||||||
@@ -505,15 +508,25 @@ func (u *ui) apiTokenDetailPanel(gtx layout.Context) layout.Dimensions {
|
|||||||
layout.Spacer{Height: unit.Dp(10)}.Layout,
|
layout.Spacer{Height: unit.Dp(10)}.Layout,
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.saveAPIToken, "Save Token") }),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.saveAPIToken, "Save Token")
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.rotateAPIToken, "Rotate") }),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.rotateAPIToken, "Rotate")
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.disableAPIToken, "Disable") }),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.disableAPIToken, "Disable")
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.revokeAPIToken, "Revoke") }),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.revokeAPIToken, "Revoke")
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.deleteAPIToken, "Delete") }),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.deleteAPIToken, "Delete")
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
layout.Spacer{Height: unit.Dp(14)}.Layout,
|
layout.Spacer{Height: unit.Dp(14)}.Layout,
|
||||||
|
|||||||
Reference in New Issue
Block a user