blob: 19d4ff30b22eeadbff399d7095b0a5e4ab196da5 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package security
import (
"testing"
"time"
"v.io/v23/security"
"v.io/v23/vdl"
"v.io/v23/vom"
)
func testDischargeCache(t *testing.T, s security.BlessingStore) {
var (
discharger = mkPrincipal()
expiredCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
argsCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "peoria", security.ThirdPartyRequirements{ReportArguments: true}, security.UnconstrainedUse()))
methodCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{ReportMethod: true}, security.UnconstrainedUse()))
serverCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "peoria", security.ThirdPartyRequirements{ReportServer: true}, security.UnconstrainedUse()))
dEmpty = security.Discharge{}
dExpired = mkDischarge(discharger.MintDischarge(expiredCav, mkCaveat(security.NewExpiryCaveat(time.Now().Add(-1*time.Minute)))))
dArgs = mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
dMethod = mkDischarge(discharger.MintDischarge(methodCav, security.UnconstrainedUse()))
dServer = mkDischarge(discharger.MintDischarge(serverCav, security.UnconstrainedUse()))
emptyImp = security.DischargeImpetus{}
argsImp = security.DischargeImpetus{Arguments: []*vom.RawBytes{vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType))}}
methodImp = security.DischargeImpetus{Method: "foo"}
otherMethodImp = security.DischargeImpetus{Method: "bar"}
serverImp = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("fooserver")}}
otherServerImp = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("barserver")}}
)
// Discharges for different cavs should not be cached.
d := mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
s.CacheDischarge(d, argsCav, emptyImp)
if d, ct := s.Discharge(methodCav, emptyImp); d.ID() != "" || !ct.IsZero() {
t.Errorf("Discharge for different caveat should not have been in cache")
}
s.ClearDischarges(d)
beforeCache := time.Now()
// Add some discharges into the cache.
s.CacheDischarge(dArgs, argsCav, argsImp)
s.CacheDischarge(dMethod, methodCav, methodImp)
s.CacheDischarge(dServer, serverCav, serverImp)
s.CacheDischarge(dExpired, expiredCav, emptyImp)
afterCache := time.Now()
testCases := []struct {
caveat security.Caveat // caveat that we are fetching discharges for.
queryImpetus security.DischargeImpetus // Impetus used to query the cache.
cachedDischarge security.Discharge // Discharge that we expect to be returned from the cache, nil if the discharge should not be cached.
}{
// Expired discharges should not be returned by the cache.
{expiredCav, emptyImp, dEmpty},
// Discharges with Impetuses that have Arguments should not be cached.
{argsCav, argsImp, dEmpty},
{methodCav, methodImp, dMethod},
{methodCav, otherMethodImp, dEmpty},
{methodCav, emptyImp, dEmpty},
{serverCav, serverImp, dServer},
{serverCav, otherServerImp, dEmpty},
{serverCav, emptyImp, dEmpty},
}
for i, test := range testCases {
out, ct := s.Discharge(test.caveat, test.queryImpetus)
if got := out.ID(); got != test.cachedDischarge.ID() {
t.Errorf("#%d: got discharge %v, want %v, queried with %v", i, got, test.cachedDischarge.ID(), test.queryImpetus)
}
if test.cachedDischarge.ID() != "" && (ct.After(afterCache) || ct.Before(beforeCache)) {
t.Errorf("#%d: got cachetime %v. Expected value in (%v, %v)", i, ct, beforeCache, afterCache)
}
}
if t.Failed() {
t.Logf("dArgs.ID(): %v", dArgs.ID())
t.Logf("dMethod.ID(): %v", dMethod.ID())
t.Logf("dServer.ID(): %v", dServer.ID())
t.Logf("dExpired.ID(): %v", dExpired.ID())
}
}
func mkPrincipal() security.Principal {
p, err := NewPrincipal()
if err != nil {
panic(err)
}
return p
}
func mkDischarge(d security.Discharge, err error) security.Discharge {
if err != nil {
panic(err)
}
return d
}
func mkCaveat(c security.Caveat, err error) security.Caveat {
if err != nil {
panic(err)
}
return c
}