add token type with permission checks and composable matchers

This commit is contained in:
juancwu 2026-04-29 01:58:46 +00:00
commit 8b5fcc87c3
4 changed files with 499 additions and 0 deletions

91
matcher_test.go Normal file
View file

@ -0,0 +1,91 @@
package ficha
import "testing"
func TestPermMatcher(t *testing.T) {
tok := makeToken("read", "write")
if !tok.Check(Perm("read")) {
t.Error("Perm(read) should match")
}
if tok.Check(Perm("delete")) {
t.Error("Perm(delete) should not match")
}
}
func TestAllMatcher(t *testing.T) {
tok := makeToken("a", "b", "c")
if !tok.Check(All("a", "b")) {
t.Error("All(a,b) should match")
}
if tok.Check(All("a", "z")) {
t.Error("All(a,z) should not match")
}
if !tok.Check(All()) {
t.Error("All() empty should match (vacuous truth)")
}
}
func TestAnyMatcher(t *testing.T) {
tok := makeToken("a")
if !tok.Check(Any("a", "z")) {
t.Error("Any(a,z) should match")
}
if tok.Check(Any("x", "y")) {
t.Error("Any(x,y) should not match")
}
if tok.Check(Any()) {
t.Error("Any() empty should not match")
}
}
func TestNotMatcher(t *testing.T) {
tok := makeToken("a")
if !tok.Check(Not("z")) {
t.Error("Not(z) should match")
}
if tok.Check(Not("a")) {
t.Error("Not(a) should not match")
}
}
func TestComposedMatchers(t *testing.T) {
tok := makeToken("orders:read", "billing-manager")
// (orders:read) AND (admin OR billing-manager) AND NOT readonly
m := All(
"orders:read",
Any("admin", "billing-manager"),
Not("readonly"),
)
if !tok.Check(m) {
t.Error("composed matcher should hold")
}
// Same with readonly added — Not should fail.
tokRO := makeToken("orders:read", "billing-manager", "readonly")
if tokRO.Check(m) {
t.Error("composed matcher should fail when readonly is present")
}
}
func TestMatcherWithUnknownType(t *testing.T) {
tok := makeToken("a")
// Passing something that isn't a string or Matcher should
// produce a matcher that never holds — fail closed.
m := All(123, "a") // 123 is the bad input
if tok.Check(m) {
t.Error("matcher with unknown type should fail closed")
}
}
func TestCheckNilMatcher(t *testing.T) {
tok := makeToken("a")
if tok.Check(nil) {
t.Error("Check(nil) should return false")
}
}