diff --git a/internal/guard/store/sqlite/store.go b/internal/guard/store/sqlite/store.go index 049c446c..e7f8f6e1 100644 --- a/internal/guard/store/sqlite/store.go +++ b/internal/guard/store/sqlite/store.go @@ -16,6 +16,7 @@ import ( _ "modernc.org/sqlite" "github.com/kontext-security/kontext-cli/internal/guard/risk" + "github.com/kontext-security/kontext-cli/internal/hook" ) type Store struct { @@ -1172,14 +1173,10 @@ func canonicalEventType(hookEventName string) string { } func canonicalDecisionResult(decision risk.Decision) string { - switch strings.ToLower(strings.TrimSpace(string(decision))) { - case "allow": - return "allow" - case "deny": - fallthrough - default: - return "deny" + if normalized, ok := hook.NormalizeDecision(string(decision)); ok { + return string(normalized) } + return "deny" } func actionStatus(canonicalEvent, decisionResult string) string { @@ -1204,11 +1201,10 @@ func actionStatus(canonicalEvent, decisionResult string) string { } func adapterDecision(decision risk.Decision) string { - normalized := strings.ToLower(strings.TrimSpace(string(decision))) - switch normalized { - case "allow", "deny": - return normalized + if normalized, ok := hook.NormalizeDecision(string(decision)); ok { + return string(normalized) } + normalized := strings.ToLower(strings.TrimSpace(string(decision))) if normalized == "" { normalized = "empty" } diff --git a/internal/guard/store/sqlite/store_test.go b/internal/guard/store/sqlite/store_test.go index c90ae4d0..6e2845dc 100644 --- a/internal/guard/store/sqlite/store_test.go +++ b/internal/guard/store/sqlite/store_test.go @@ -769,6 +769,15 @@ where id = ? } } +func TestDecisionHelpersNormalizeWhitespaceAndCase(t *testing.T) { + if got := canonicalDecisionResult(risk.Decision(" Allow \n")); got != "allow" { + t.Fatalf("canonicalDecisionResult() = %q, want allow", got) + } + if got := adapterDecision(risk.Decision("\tDeNy ")); got != "deny" { + t.Fatalf("adapterDecision() = %q, want deny", got) + } +} + func TestLedgerBatchExportsSessionsActionsAndReceipts(t *testing.T) { store, err := OpenStore(t.TempDir() + "/guard.db") if err != nil { diff --git a/internal/hook/domain.go b/internal/hook/domain.go index de12a7e3..86f5b433 100644 --- a/internal/hook/domain.go +++ b/internal/hook/domain.go @@ -1,6 +1,10 @@ package hook -import "strings" +import ( + "strings" + + "github.com/kontext-security/kontext-cli/internal/guard/decision" +) type HookName string @@ -30,11 +34,11 @@ func (h HookName) CanBlock() bool { return h == HookPreToolUse } -type Decision string +type Decision = decision.Decision const ( - DecisionAllow Decision = "allow" - DecisionDeny Decision = "deny" + DecisionAllow = decision.Allow + DecisionDeny = decision.Deny ) func NormalizeDecision(value string) (Decision, bool) {