blob: 946d976dff1ebc1bb7678e6a5016b5a3f6d83bfa [file] [log] [blame]
package auditor
import (
"reflect"
"testing"
"time"
vsecurity "veyron.io/veyron/veyron/security"
"veyron.io/veyron/veyron/security/audit"
"veyron.io/veyron/veyron2/security"
)
func TestBlessingAuditor(t *testing.T) {
db := &mockDatabase{}
auditor, reader := &blessingAuditor{db}, &blessingLogReader{db}
p, err := vsecurity.NewPrincipal()
if err != nil {
t.Fatalf("failed to create principal: %v", err)
}
expiryCaveat := newCaveat(security.ExpiryCaveat(time.Now().Add(time.Hour)))
revocationCaveat := newThirdPartyCaveat(t, p)
tests := []struct {
Extension string
Email string
Caveats []security.Caveat
RevocationCaveatID string
Blessings security.Blessings
}{
{
Extension: "email/nocaveats",
Email: "email",
RevocationCaveatID: "",
Blessings: newBlessing(t, p, "test/email/nocaveats"),
},
{
Extension: "email/caveat",
Email: "email",
Caveats: []security.Caveat{expiryCaveat},
RevocationCaveatID: "",
Blessings: newBlessing(t, p, "test/email/caveat"),
},
{
Extension: "email/caveatAndRevocation",
Email: "email",
Caveats: []security.Caveat{expiryCaveat, newCaveat(security.NewCaveat(revocationCaveat))},
RevocationCaveatID: revocationCaveat.ID(),
Blessings: newBlessing(t, p, "test/email/caveatAndRevocation"),
},
}
for _, test := range tests {
args := []interface{}{nil, nil, test.Extension}
for _, cav := range test.Caveats {
args = append(args, cav)
}
if err := auditor.Audit(audit.Entry{
Method: "Bless",
Arguments: args,
Results: []interface{}{test.Blessings},
}); err != nil {
t.Errorf("Failed to audit Blessing %v: %v", test.Blessings, err)
}
ch := reader.Read("query")
got := <-ch
if got.Email != test.Email {
t.Errorf("got %v, want %v", got.Email, test.Email)
}
if !reflect.DeepEqual(got.Caveats, test.Caveats) {
t.Errorf("got %#v, want %#v", got.Caveats, test.Caveats)
}
if got.RevocationCaveatID != test.RevocationCaveatID {
t.Errorf("got %v, want %v", got.RevocationCaveatID, test.RevocationCaveatID)
}
if !reflect.DeepEqual(got.Blessings, test.Blessings) {
t.Errorf("got %v, want %v", got.Blessings, test.Blessings)
}
var extraRoutines bool
for _ = range ch {
// Drain the channel to prevent the producer goroutines from being leaked.
extraRoutines = true
}
if extraRoutines {
t.Errorf("Got more entries that expected for test %+v", test)
}
}
}
type mockDatabase struct {
NextEntry databaseEntry
}
func (db *mockDatabase) Insert(entry databaseEntry) error {
db.NextEntry = entry
return nil
}
func (db *mockDatabase) Query(email string) <-chan databaseEntry {
c := make(chan databaseEntry)
go func() {
c <- db.NextEntry
close(c)
}()
return c
}
func newThirdPartyCaveat(t *testing.T, p security.Principal) security.ThirdPartyCaveat {
tp, err := security.NewPublicKeyCaveat(p.PublicKey(), "location", security.ThirdPartyRequirements{}, newCaveat(security.MethodCaveat("method")))
if err != nil {
t.Fatal(err)
}
return tp
}
func newBlessing(t *testing.T, p security.Principal, name string) security.Blessings {
b, err := p.BlessSelf(name)
if err != nil {
t.Fatal(err)
}
return b
}
func newCaveat(caveat security.Caveat, err error) security.Caveat {
if err != nil {
panic(err)
}
return caveat
}