blob: b7059e26b566619d770b24813c10c0f815c75d2f [file] [log] [blame]
Matt Rosencrantzb0cd02d2015-08-17 17:37:06 -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
5package security_test
6
7import (
8 "fmt"
9 "testing"
10 "time"
11
12 "v.io/v23"
13 "v.io/v23/context"
14 "v.io/v23/rpc"
15 "v.io/v23/security"
16 securitylib "v.io/x/ref/lib/security"
Matt Rosencrantzb0cd02d2015-08-17 17:37:06 -070017 _ "v.io/x/ref/runtime/factories/generic"
18 "v.io/x/ref/test"
19 "v.io/x/ref/test/testutil"
20)
21
22func init() {
23 test.Init()
24}
25
26type expiryDischarger struct {
27 called bool
28}
29
30func (ed *expiryDischarger) Discharge(ctx *context.T, call rpc.StreamServerCall, cav security.Caveat, _ security.DischargeImpetus) (security.Discharge, error) {
31 tp := cav.ThirdPartyDetails()
32 if tp == nil {
33 return security.Discharge{}, fmt.Errorf("discharger: %v does not represent a third-party caveat", cav)
34 }
35 if err := tp.Dischargeable(ctx, call.Security()); err != nil {
36 return security.Discharge{}, fmt.Errorf("third-party caveat %v cannot be discharged for this context: %v", cav, err)
37 }
38 expDur := 10 * time.Millisecond
39 if ed.called {
40 expDur = time.Second
41 }
42 expiry, err := security.NewExpiryCaveat(time.Now().Add(expDur))
43 if err != nil {
44 return security.Discharge{}, fmt.Errorf("failed to create an expiration on the discharge: %v", err)
45 }
46 d, err := call.Security().LocalPrincipal().MintDischarge(cav, expiry)
47 if err != nil {
48 return security.Discharge{}, err
49 }
50 ctx.Infof("got discharge on sever %#v", d)
51 ed.called = true
52 return d, nil
53}
54
55func TestPrepareDischarges(t *testing.T) {
56 ctx, shutdown := test.V23Init()
57 defer shutdown()
58
59 pclient := testutil.NewPrincipal("client")
60 cctx, err := v23.WithPrincipal(ctx, pclient)
61 if err != nil {
62 t.Fatal(err)
63 }
64 pdischarger := testutil.NewPrincipal("discharger")
65 dctx, err := v23.WithPrincipal(ctx, pdischarger)
66 if err != nil {
67 t.Fatal(err)
68 }
69 pclient.AddToRoots(pdischarger.BlessingStore().Default())
70 pclient.AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
71 pdischarger.AddToRoots(pclient.BlessingStore().Default())
72 pdischarger.AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
73
74 expcav, err := security.NewExpiryCaveat(time.Now().Add(time.Hour))
75 if err != nil {
76 t.Fatal(err)
77 }
78 tpcav, err := security.NewPublicKeyCaveat(
79 pdischarger.PublicKey(),
80 "discharger",
81 security.ThirdPartyRequirements{},
82 expcav)
83 if err != nil {
84 t.Fatal(err)
85 }
86 cbless, err := pclient.BlessSelf("clientcaveats", tpcav)
87 if err != nil {
88 t.Fatal(err)
89 }
90 tpid := tpcav.ThirdPartyDetails().ID()
91
92 v23.GetPrincipal(dctx)
Matt Rosencrantz53ac5852015-09-04 15:14:54 -070093 dctx, _, err = v23.WithNewServer(dctx,
Matt Rosencrantzb0cd02d2015-08-17 17:37:06 -070094 "discharger",
95 &expiryDischarger{},
96 security.AllowEveryone())
97 if err != nil {
98 t.Fatal(err)
99 }
100
101 // Fetch discharges for tpcav.
102 buffer := 100 * time.Millisecond
103 discharges := securitylib.PrepareDischarges(cctx, cbless,
104 security.DischargeImpetus{}, buffer)
105 if len(discharges) != 1 {
106 t.Errorf("Got %d discharges, expected 1.", len(discharges))
107 }
108 dis, has := discharges[tpid]
109 if !has {
110 t.Errorf("Got %#v, Expected discharge for %s", discharges, tpid)
111 }
112 // Check that the discharges is not yet expired, but is expired after 100 milliseconds.
113 expiry := dis.Expiry()
114 // The discharge should expire.
115 select {
116 case <-time.After(time.Now().Sub(expiry)):
117 break
118 case <-time.After(time.Second):
119 t.Fatalf("discharge didn't expire within a second")
120 }
121
122 // Preparing Discharges again to get fresh discharges.
123 discharges = securitylib.PrepareDischarges(cctx, cbless,
124 security.DischargeImpetus{}, buffer)
125 if len(discharges) != 1 {
126 t.Errorf("Got %d discharges, expected 1.", len(discharges))
127 }
128 dis, has = discharges[tpid]
129 if !has {
130 t.Errorf("Got %#v, Expected discharge for %s", discharges, tpid)
131 }
132 now := time.Now()
133 if expiry = dis.Expiry(); expiry.Before(now) {
134 t.Fatalf("discharge has expired %v, but should be fresh", dis)
135 }
136}