diff --git a/macaroons/constraints_test.go b/macaroons/constraints_test.go index 9db16617..4bd9f552 100644 --- a/macaroons/constraints_test.go +++ b/macaroons/constraints_test.go @@ -1,6 +1,8 @@ package macaroons import ( + "errors" + "fmt" "testing" "time" @@ -9,86 +11,99 @@ import ( macaroon "gopkg.in/macaroon.v1" ) -func TestAllowConstraint(t *testing.T) { +type macError struct { + message string +} + +func (err macError) Error() string { + return err.message +} + +func testConstraint(constraint Constraint, ok checkers.Checker, + failFn func() checkers.Checker) error { macParams := bakery.NewServiceParams{} svc, err := bakery.NewService(macParams) if err != nil { - t.Fatalf("Failed to create a new service") + return errors.New("Failed to create a new service") } mac, err := svc.NewMacaroon("", nil, nil) if err != nil { - t.Fatalf("Failed to create a new macaroon") + return errors.New("Failed to create a new macaroon") } - constraint := AllowConstraint("op1", "op2", "op4") mac, err = AddConstraints(mac, constraint) if err != nil { - t.Fatalf("Failed to add macaroon constraint") + return errors.New("Failed to add macaroon constraint") } - checker := checkers.New(AllowChecker("op1")) - if err := svc.Check(macaroon.Slice{mac}, checker); err != nil { - t.Fatalf("Allowed operation failed macaroon check") + okChecker := checkers.New(ok) + if err := svc.Check(macaroon.Slice{mac}, okChecker); err != nil { + msg := "Correct checker failed: %v" + return macError{fmt.Sprintf(msg, ok)} } - checker = checkers.New(AllowChecker("op3")) - if err := svc.Check(macaroon.Slice{mac}, checker); err == nil { - t.Fatalf("Disallowed operation passed macaroon check") + fail := failFn() + failChecker := checkers.New(fail) + if err := svc.Check(macaroon.Slice{mac}, failChecker); err == nil { + msg := "Incorrect checker succeeded: %v" + return macError{fmt.Sprintf(msg, fail)} + } + return nil +} + +func TestAllowConstraint(t *testing.T) { + if err := testConstraint( + AllowConstraint("op1", "op2", "op4"), + AllowChecker("op1"), + func() checkers.Checker { + return AllowChecker("op3") + }, + ); err != nil { + t.Fatalf(err.Error()) } } func TestTimeoutConstraint(t *testing.T) { - macParams := bakery.NewServiceParams{} - svc, err := bakery.NewService(macParams) - if err != nil { - t.Fatalf("Failed to create a new service") - } - mac, err := svc.NewMacaroon("", nil, nil) - if err != nil { - t.Fatalf("Failed to create a new macaroon") - } - - constraint := TimeoutConstraint(1) - mac, err = AddConstraints(mac, constraint) - if err != nil { - t.Fatalf("Failed to add macaroon constraint") - } - - checker := checkers.New(TimeoutChecker()) - if err := svc.Check(macaroon.Slice{mac}, checker); err != nil { - t.Fatalf("Timeout check failed within timeframe") - } - - time.Sleep(time.Second) - if err := svc.Check(macaroon.Slice{mac}, checker); err == nil { - t.Fatalf("Timeout check passed for an expired timeout") + if err := testConstraint( + TimeoutConstraint(1), + TimeoutChecker(), + func() checkers.Checker { + time.Sleep(time.Second) + return TimeoutChecker() + }, + ); err != nil { + t.Fatalf(err.Error()) } } func TestIPLockConstraint(t *testing.T) { - macParams := bakery.NewServiceParams{} - svc, err := bakery.NewService(macParams) - if err != nil { - t.Fatalf("Failed to create a new service") - } - mac, err := svc.NewMacaroon("", nil, nil) - if err != nil { - t.Fatalf("Failed to create a new macaroon") - } - - constraint := IPLockConstraint("127.0.0.1") - mac, err = AddConstraints(mac, constraint) - if err != nil { - t.Fatalf("Failed to add macaroon constraint") - } - - checker := checkers.New(IPLockChecker("127.0.0.1")) - if err := svc.Check(macaroon.Slice{mac}, checker); err != nil { - t.Fatalf("IPLock for the same IP failed the test") - } - - checker = checkers.New(IPLockChecker("0.0.0.0")) - if err := svc.Check(macaroon.Slice{mac}, checker); err == nil { - t.Fatalf("IPLock for a different IP passed the test") + if err := testConstraint( + IPLockConstraint("127.0.0.1"), + IPLockChecker("127.0.0.1"), + func() checkers.Checker { + return IPLockChecker("0.0.0.0") + }, + ); err != nil { + t.Fatalf(err.Error()) + } +} + +func TestIPLockEmptyIP(t *testing.T) { + if err := testConstraint( + IPLockConstraint(""), + IPLockChecker("127.0.0.1"), + func() checkers.Checker { + return IPLockChecker("0.0.0.0") + }, + ); err != nil { + if _, ok := err.(macError); !ok { + t.Fatalf("IPLock with an empty IP should always pass") + } + } +} + +func TestIPLockBadIP(t *testing.T) { + if err := IPLockConstraint("127.0.0/800"); err == nil { + t.Fatalf("IPLockConstraint with bad IP should fail") } }