Jiri Simsa | d7616c9 | 2015-03-24 23:44:30 -0700 | [diff] [blame] | 1 | // 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 Rosencrantz | 94502cf | 2015-03-18 09:43:44 -0700 | [diff] [blame] | 5 | package rpc |
Suharsh Sivakumar | e03aa13 | 2015-03-10 17:47:45 -0700 | [diff] [blame] | 6 | |
| 7 | import ( |
| 8 | "testing" |
| 9 | "time" |
| 10 | |
Suharsh Sivakumar | e03aa13 | 2015-03-10 17:47:45 -0700 | [diff] [blame] | 11 | "v.io/v23/security" |
| 12 | "v.io/v23/vdl" |
Asim Shankar | 4a69828 | 2015-03-21 21:59:18 -0700 | [diff] [blame] | 13 | "v.io/x/ref/test/testutil" |
Suharsh Sivakumar | e03aa13 | 2015-03-10 17:47:45 -0700 | [diff] [blame] | 14 | ) |
| 15 | |
| 16 | func 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 Shankar | 4a69828 | 2015-03-21 21:59:18 -0700 | [diff] [blame] | 23 | discharger = testutil.NewPrincipal("discharger") |
Suharsh Sivakumar | e03aa13 | 2015-03-10 17:47:45 -0700 | [diff] [blame] | 24 | 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 Sivakumar | 60b78e9 | 2015-04-23 21:36:49 -0700 | [diff] [blame] | 29 | dExpired = mkDischarge(discharger.MintDischarge(expiredCav, mkCaveat(security.NewExpiryCaveat(time.Now().Add(-1*time.Minute))))) |
Suharsh Sivakumar | e03aa13 | 2015-03-10 17:47:45 -0700 | [diff] [blame] | 30 | 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 | |
| 100 | func mkDischarge(d security.Discharge, err error) security.Discharge { |
| 101 | if err != nil { |
| 102 | panic(err) |
| 103 | } |
| 104 | return d |
| 105 | } |