blob: 7b67b1bcd9e008c5b9b67911237658445287770b [file] [log] [blame]
Jiri Simsad7616c92015-03-24 23:44:30 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Matt Rosencrantz94502cf2015-03-18 09:43:44 -07005package rpc
Suharsh Sivakumare03aa132015-03-10 17:47:45 -07006
7import (
8 "testing"
9 "time"
10
Suharsh Sivakumare03aa132015-03-10 17:47:45 -070011 "v.io/v23/security"
12 "v.io/v23/vdl"
Asim Shankar4a698282015-03-21 21:59:18 -070013 "v.io/x/ref/test/testutil"
Suharsh Sivakumare03aa132015-03-10 17:47:45 -070014)
15
16func TestDischargeClientCache(t *testing.T) {
17 dcc := &dischargeCache{
18 cache: make(map[dischargeCacheKey]security.Discharge),
19 idToKeys: make(map[string][]dischargeCacheKey),
20 }
21
22 var (
Asim Shankar4a698282015-03-21 21:59:18 -070023 discharger = testutil.NewPrincipal("discharger")
Suharsh Sivakumare03aa132015-03-10 17:47:45 -070024 expiredCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
25 argsCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
26 methodCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
27 serverCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
28
Suharsh Sivakumar60b78e92015-04-23 21:36:49 -070029 dExpired = mkDischarge(discharger.MintDischarge(expiredCav, mkCaveat(security.NewExpiryCaveat(time.Now().Add(-1*time.Minute)))))
Suharsh Sivakumare03aa132015-03-10 17:47:45 -070030 dArgs = mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
31 dMethod = mkDischarge(discharger.MintDischarge(methodCav, security.UnconstrainedUse()))
32 dServer = mkDischarge(discharger.MintDischarge(serverCav, security.UnconstrainedUse()))
33
34 emptyImp = security.DischargeImpetus{}
35 argsImp = security.DischargeImpetus{Arguments: []*vdl.Value{&vdl.Value{}}}
36 methodImp = security.DischargeImpetus{Method: "foo"}
37 otherMethodImp = security.DischargeImpetus{Method: "bar"}
38 serverImp = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("fooserver")}}
39 otherServerImp = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("barserver")}}
40 )
41
42 // Discharges for different cavs should not be cached.
43 d := mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
44 dcc.Add(d, emptyImp)
45 outdis := make([]*security.Discharge, 1)
46 if remaining := dcc.Discharges([]security.Caveat{methodCav}, []security.DischargeImpetus{emptyImp}, outdis); remaining == 0 {
47 t.Errorf("Discharge for different caveat should not have been in cache")
48 }
49 dcc.invalidate(d)
50
51 // Add some discharges into the cache.
52 dcc.Add(dArgs, argsImp)
53 dcc.Add(dMethod, methodImp)
54 dcc.Add(dServer, serverImp)
55 dcc.Add(dExpired, emptyImp)
56
57 testCases := []struct {
58 caveat security.Caveat // caveat that we are fetching discharges for.
59 queryImpetus security.DischargeImpetus // Impetus used to query the cache.
60 cachedDischarge *security.Discharge // Discharge that we expect to be returned from the cache, nil if the discharge should not be cached.
61 }{
62 // Expired discharges should not be returned by the cache.
63 {expiredCav, emptyImp, nil},
64
65 // Discharges with Impetuses that have Arguments should not be cached.
66 {argsCav, argsImp, nil},
67
68 {methodCav, methodImp, &dMethod},
69 {methodCav, otherMethodImp, nil},
70 {methodCav, emptyImp, nil},
71
72 {serverCav, serverImp, &dServer},
73 {serverCav, otherServerImp, nil},
74 {serverCav, emptyImp, nil},
75 }
76
77 for i, test := range testCases {
78 out := make([]*security.Discharge, 1)
79 remaining := dcc.Discharges([]security.Caveat{test.caveat}, []security.DischargeImpetus{test.queryImpetus}, out)
80 if test.cachedDischarge != nil {
81 got := "nil"
82 if remaining == 0 {
83 got = out[0].ID()
84 }
85 if got != test.cachedDischarge.ID() {
86 t.Errorf("#%d: got discharge %v, want %v, queried with %v", i, got, test.cachedDischarge.ID(), test.queryImpetus)
87 }
88 } else if remaining == 0 {
89 t.Errorf("#%d: discharge %v should not have been in cache, queried with %v", i, out[0].ID(), test.queryImpetus)
90 }
91 }
92 if t.Failed() {
93 t.Logf("dArgs.ID(): %v", dArgs.ID())
94 t.Logf("dMethod.ID(): %v", dMethod.ID())
95 t.Logf("dServer.ID(): %v", dServer.ID())
96 t.Logf("dExpired.ID(): %v", dExpired.ID())
97 }
98}
99
100func mkDischarge(d security.Discharge, err error) security.Discharge {
101 if err != nil {
102 panic(err)
103 }
104 return d
105}