blob: a3e59d653e5282671f1d5169e3a48575dc66f7a7 [file] [log] [blame]
Asim Shankarae8d4c52014-10-08 13:03:31 -07001package security
2
3import (
4 "fmt"
5 "io/ioutil"
6 "os"
7 "reflect"
8 "testing"
9
Jiri Simsa764efb72014-12-25 20:57:03 -080010 "v.io/core/veyron2/security"
Asim Shankarae8d4c52014-10-08 13:03:31 -070011)
12
13type storeTester struct {
14 forAll, forFoo, forBar, def security.Blessings
15 other security.Blessings // Blessings bound to a different principal.
16}
17
18func (t *storeTester) testSet(s security.BlessingStore) error {
19 testdata := []struct {
20 blessings security.Blessings
21 pattern security.BlessingPattern
22 wantErr string
23 }{
24 {t.forAll, "...", ""},
25 {t.forFoo, "foo/...", ""},
26 {t.forBar, "bar", ""},
27 {t.other, "...", "public key does not match"},
28 {t.forAll, "", "invalid BlessingPattern"},
29 {t.forAll, "foo...", "invalid BlessingPattern"},
30 {t.forAll, "...foo", "invalid BlessingPattern"},
31 {t.forAll, "foo/.../bar", "invalid BlessingPattern"},
32 }
gauthamtf8263932014-12-16 10:59:09 -080033 added := make(map[security.BlessingPattern]security.Blessings)
Asim Shankarae8d4c52014-10-08 13:03:31 -070034 for _, d := range testdata {
35 _, err := s.Set(d.blessings, d.pattern)
36 if merr := matchesError(err, d.wantErr); merr != nil {
37 return fmt.Errorf("Set(%v, %q): %v", d.blessings, d.pattern, merr)
38 }
gauthamtf8263932014-12-16 10:59:09 -080039 if err == nil {
40 added[d.pattern] = d.blessings
41 }
42 }
43 m := s.PeerBlessings()
44 if !reflect.DeepEqual(added, m) {
45 return fmt.Errorf("PeerBlessings(%v) != added(%v)", m, added)
Asim Shankarae8d4c52014-10-08 13:03:31 -070046 }
47 return nil
48}
49
50func (t *storeTester) testSetDefault(s security.BlessingStore, currentDefault security.Blessings) error {
51 if got := s.Default(); !reflect.DeepEqual(got, currentDefault) {
52 return fmt.Errorf("Default(): got: %v, want: %v", got, currentDefault)
53 }
54 if err := s.SetDefault(t.def); err != nil {
55 return fmt.Errorf("SetDefault(%v): %v", t.def, err)
56 }
57 if got, want := s.Default(), t.def; !reflect.DeepEqual(got, want) {
58 return fmt.Errorf("Default returned %v, want %v", got, want)
59 }
60 // Changing default to an invalid blessing should not affect the existing default.
61 if err := matchesError(s.SetDefault(t.other), "public key does not match"); err != nil {
62 return err
63 }
64 if got, want := s.Default(), t.def; !reflect.DeepEqual(got, want) {
65 return fmt.Errorf("Default returned %v, want %v", got, want)
66 }
67 return nil
68}
69
70func (t *storeTester) testForPeer(s security.BlessingStore) error {
71 testdata := []struct {
72 peers []string
73 blessings security.Blessings
74 }{
75 {nil, t.forAll},
76 {[]string{"baz"}, t.forAll},
77 {[]string{"foo"}, unionOfBlessings(t.forAll, t.forFoo)},
78 {[]string{"bar"}, unionOfBlessings(t.forAll, t.forBar)},
79 {[]string{"foo/foo"}, unionOfBlessings(t.forAll, t.forFoo)},
80 {[]string{"bar/baz"}, t.forAll},
81 {[]string{"foo/foo/bar"}, unionOfBlessings(t.forAll, t.forFoo)},
82 {[]string{"bar/foo", "foo"}, unionOfBlessings(t.forAll, t.forFoo)},
83 {[]string{"bar", "foo"}, unionOfBlessings(t.forAll, t.forFoo, t.forBar)},
84 }
85 for _, d := range testdata {
86 if got, want := s.ForPeer(d.peers...), d.blessings; !reflect.DeepEqual(got, want) {
87 return fmt.Errorf("ForPeer(%v): got: %v, want: %v", d.peers, got, want)
88 }
89 }
90 return nil
91}
92
93func newStoreTester(blessed security.Principal) *storeTester {
94 var (
95 blessing = func(root, extension string) security.Blessings {
96 blesser, err := NewPrincipal()
97 if err != nil {
98 panic(err)
99 }
100 blessing, err := blesser.Bless(blessed.PublicKey(), blessSelf(blesser, root), extension, security.UnconstrainedUse())
101 if err != nil {
102 panic(err)
103 }
104 return blessing
105 }
106 )
107 pother, err := NewPrincipal()
108 if err != nil {
109 panic(err)
110 }
111
112 s := &storeTester{}
113 s.forAll = blessing("bar", "alice")
114 s.forFoo = blessing("foo", "alice")
115 s.forBar = unionOfBlessings(s.forAll, s.forFoo)
116 s.def = blessing("default", "alice")
117 s.other = blessSelf(pother, "other")
118 return s
119}
120
121func TestBlessingStore(t *testing.T) {
122 p, err := NewPrincipal()
123 if err != nil {
124 t.Fatal(err)
125 }
126 tester := newStoreTester(p)
127 s := p.BlessingStore()
128 if err := tester.testSet(s); err != nil {
129 t.Error(err)
130 }
131 if err := tester.testForPeer(s); err != nil {
132 t.Error(err)
133 }
134 if err := tester.testSetDefault(s, tester.forAll); err != nil {
135 t.Error(err)
136 }
137}
138
139func TestBlessingStorePersistence(t *testing.T) {
140 dir, err := ioutil.TempDir("", "TestPersistingBlessingStore")
141 if err != nil {
142 t.Fatal(err)
143 }
144 defer os.RemoveAll(dir)
Suharsh Sivakumaraca1c322014-10-21 11:27:32 -0700145 p, err := CreatePersistentPrincipal(dir, nil)
Asim Shankarae8d4c52014-10-08 13:03:31 -0700146 if err != nil {
147 t.Fatal(err)
148 }
Asim Shankarae8d4c52014-10-08 13:03:31 -0700149 tester := newStoreTester(p)
150 s := p.BlessingStore()
151
152 if err := tester.testSet(s); err != nil {
153 t.Error(err)
154 }
155 if err := tester.testForPeer(s); err != nil {
156 t.Error(err)
157 }
158 if err := tester.testSetDefault(s, tester.forAll); err != nil {
159 t.Error(err)
160 }
161
162 // Recreate the BlessingStore from the directory.
Suharsh Sivakumaraca1c322014-10-21 11:27:32 -0700163 p2, err := LoadPersistentPrincipal(dir, nil)
Asim Shankarae8d4c52014-10-08 13:03:31 -0700164 if err != nil {
165 t.Fatal(err)
166 }
167 s = p2.BlessingStore()
168 if err := tester.testForPeer(s); err != nil {
169 t.Error(err)
170 }
171 if got, want := s.Default(), tester.def; !reflect.DeepEqual(got, want) {
172 t.Fatalf("Default(): got: %v, want: %v", got, want)
173 }
174}
175
176func TestBlessingStoreSetOverridesOldSetting(t *testing.T) {
177 p, err := NewPrincipal()
178 if err != nil {
179 t.Fatal(err)
180 }
181 var (
182 alice = blessSelf(p, "alice")
183 bob = blessSelf(p, "bob")
184 s = p.BlessingStore()
185 )
186 // Set(alice, "alice")
187 // Set(bob, "alice/...")
188 // So, {alice, bob} is shared with "alice", whilst {bob} is shared with "alice/tv"
189 if _, err := s.Set(alice, "alice"); err != nil {
190 t.Fatal(err)
191 }
192 if _, err := s.Set(bob, "alice/..."); err != nil {
193 t.Fatal(err)
194 }
195 if got, want := s.ForPeer("alice"), unionOfBlessings(alice, bob); !reflect.DeepEqual(got, want) {
196 t.Errorf("Got %v, want %v", got, want)
197 }
198 if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
199 t.Errorf("Got %v, want %v", got, want)
200 }
201
202 // Clear out the blessing associated with "alice".
203 // Now, bob should be shared with both alice and alice/friend.
204 if _, err := s.Set(nil, "alice"); err != nil {
205 t.Fatal(err)
206 }
207 if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
208 t.Errorf("Got %v, want %v", got, want)
209 }
210 if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
211 t.Errorf("Got %v, want %v", got, want)
212 }
213
214 // Clearing out an association that doesn't exist should have no effect.
215 if _, err := s.Set(nil, "alice/enemy"); err != nil {
216 t.Fatal(err)
217 }
218 if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
219 t.Errorf("Got %v, want %v", got, want)
220 }
221 if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
222 t.Errorf("Got %v, want %v", got, want)
223 }
224
225 // Clear everything
226 if _, err := s.Set(nil, "alice/..."); err != nil {
227 t.Fatal(err)
228 }
229 if got := s.ForPeer("alice"); got != nil {
230 t.Errorf("Got %v, want nil", got)
231 }
232 if got := s.ForPeer("alice/friend"); got != nil {
233 t.Errorf("Got %v, want nil", got)
234 }
235}
236
237func TestBlessingStoreSetReturnsOldValue(t *testing.T) {
238 p, err := NewPrincipal()
239 if err != nil {
240 t.Fatal(err)
241 }
242 var (
243 alice = blessSelf(p, "alice")
244 bob = blessSelf(p, "bob")
245 s = p.BlessingStore()
246 )
247
248 if old, err := s.Set(alice, "..."); old != nil || err != nil {
249 t.Errorf("Got (%v, %v)", old, err)
250 }
251 if old, err := s.Set(alice, "..."); !reflect.DeepEqual(old, alice) || err != nil {
252 t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
253 }
254 if old, err := s.Set(bob, "..."); !reflect.DeepEqual(old, alice) || err != nil {
255 t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
256 }
257 if old, err := s.Set(nil, "..."); !reflect.DeepEqual(old, bob) || err != nil {
258 t.Errorf("Got (%v, %v) want (%v, nil)", old, err, bob)
259 }
260}