blob: d328da46a4b548b826bc6dd6360212ac186311c2 [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 }
Asim Shankarb378e662015-01-16 10:50:48 -080054 // SetDefault(nil)
55 if err := s.SetDefault(nil); err != nil {
56 return fmt.Errorf("SetDefault(nil): %v", err)
57 }
58 if got := s.Default(); got != nil {
59 return fmt.Errorf("Default returned %v, want nil", got)
60 }
Asim Shankarae8d4c52014-10-08 13:03:31 -070061 if err := s.SetDefault(t.def); err != nil {
62 return fmt.Errorf("SetDefault(%v): %v", t.def, 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 // Changing default to an invalid blessing should not affect the existing default.
68 if err := matchesError(s.SetDefault(t.other), "public key does not match"); err != nil {
69 return err
70 }
71 if got, want := s.Default(), t.def; !reflect.DeepEqual(got, want) {
72 return fmt.Errorf("Default returned %v, want %v", got, want)
73 }
74 return nil
75}
76
77func (t *storeTester) testForPeer(s security.BlessingStore) error {
78 testdata := []struct {
79 peers []string
80 blessings security.Blessings
81 }{
82 {nil, t.forAll},
83 {[]string{"baz"}, t.forAll},
84 {[]string{"foo"}, unionOfBlessings(t.forAll, t.forFoo)},
85 {[]string{"bar"}, unionOfBlessings(t.forAll, t.forBar)},
86 {[]string{"foo/foo"}, unionOfBlessings(t.forAll, t.forFoo)},
87 {[]string{"bar/baz"}, t.forAll},
88 {[]string{"foo/foo/bar"}, unionOfBlessings(t.forAll, t.forFoo)},
89 {[]string{"bar/foo", "foo"}, unionOfBlessings(t.forAll, t.forFoo)},
90 {[]string{"bar", "foo"}, unionOfBlessings(t.forAll, t.forFoo, t.forBar)},
91 }
92 for _, d := range testdata {
93 if got, want := s.ForPeer(d.peers...), d.blessings; !reflect.DeepEqual(got, want) {
94 return fmt.Errorf("ForPeer(%v): got: %v, want: %v", d.peers, got, want)
95 }
96 }
97 return nil
98}
99
100func newStoreTester(blessed security.Principal) *storeTester {
101 var (
102 blessing = func(root, extension string) security.Blessings {
103 blesser, err := NewPrincipal()
104 if err != nil {
105 panic(err)
106 }
107 blessing, err := blesser.Bless(blessed.PublicKey(), blessSelf(blesser, root), extension, security.UnconstrainedUse())
108 if err != nil {
109 panic(err)
110 }
111 return blessing
112 }
113 )
114 pother, err := NewPrincipal()
115 if err != nil {
116 panic(err)
117 }
118
119 s := &storeTester{}
120 s.forAll = blessing("bar", "alice")
121 s.forFoo = blessing("foo", "alice")
122 s.forBar = unionOfBlessings(s.forAll, s.forFoo)
123 s.def = blessing("default", "alice")
124 s.other = blessSelf(pother, "other")
125 return s
126}
127
128func TestBlessingStore(t *testing.T) {
129 p, err := NewPrincipal()
130 if err != nil {
131 t.Fatal(err)
132 }
133 tester := newStoreTester(p)
134 s := p.BlessingStore()
135 if err := tester.testSet(s); err != nil {
136 t.Error(err)
137 }
138 if err := tester.testForPeer(s); err != nil {
139 t.Error(err)
140 }
141 if err := tester.testSetDefault(s, tester.forAll); err != nil {
142 t.Error(err)
143 }
144}
145
146func TestBlessingStorePersistence(t *testing.T) {
147 dir, err := ioutil.TempDir("", "TestPersistingBlessingStore")
148 if err != nil {
149 t.Fatal(err)
150 }
151 defer os.RemoveAll(dir)
Suharsh Sivakumaraca1c322014-10-21 11:27:32 -0700152 p, err := CreatePersistentPrincipal(dir, nil)
Asim Shankarae8d4c52014-10-08 13:03:31 -0700153 if err != nil {
154 t.Fatal(err)
155 }
Asim Shankarae8d4c52014-10-08 13:03:31 -0700156 tester := newStoreTester(p)
157 s := p.BlessingStore()
158
159 if err := tester.testSet(s); err != nil {
160 t.Error(err)
161 }
162 if err := tester.testForPeer(s); err != nil {
163 t.Error(err)
164 }
165 if err := tester.testSetDefault(s, tester.forAll); err != nil {
166 t.Error(err)
167 }
168
169 // Recreate the BlessingStore from the directory.
Suharsh Sivakumaraca1c322014-10-21 11:27:32 -0700170 p2, err := LoadPersistentPrincipal(dir, nil)
Asim Shankarae8d4c52014-10-08 13:03:31 -0700171 if err != nil {
172 t.Fatal(err)
173 }
174 s = p2.BlessingStore()
175 if err := tester.testForPeer(s); err != nil {
176 t.Error(err)
177 }
178 if got, want := s.Default(), tester.def; !reflect.DeepEqual(got, want) {
179 t.Fatalf("Default(): got: %v, want: %v", got, want)
180 }
181}
182
183func TestBlessingStoreSetOverridesOldSetting(t *testing.T) {
184 p, err := NewPrincipal()
185 if err != nil {
186 t.Fatal(err)
187 }
188 var (
189 alice = blessSelf(p, "alice")
190 bob = blessSelf(p, "bob")
191 s = p.BlessingStore()
192 )
193 // Set(alice, "alice")
194 // Set(bob, "alice/...")
195 // So, {alice, bob} is shared with "alice", whilst {bob} is shared with "alice/tv"
196 if _, err := s.Set(alice, "alice"); err != nil {
197 t.Fatal(err)
198 }
199 if _, err := s.Set(bob, "alice/..."); err != nil {
200 t.Fatal(err)
201 }
202 if got, want := s.ForPeer("alice"), unionOfBlessings(alice, bob); !reflect.DeepEqual(got, want) {
203 t.Errorf("Got %v, want %v", got, want)
204 }
205 if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
206 t.Errorf("Got %v, want %v", got, want)
207 }
208
209 // Clear out the blessing associated with "alice".
210 // Now, bob should be shared with both alice and alice/friend.
211 if _, err := s.Set(nil, "alice"); err != nil {
212 t.Fatal(err)
213 }
214 if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
215 t.Errorf("Got %v, want %v", got, want)
216 }
217 if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
218 t.Errorf("Got %v, want %v", got, want)
219 }
220
221 // Clearing out an association that doesn't exist should have no effect.
222 if _, err := s.Set(nil, "alice/enemy"); err != nil {
223 t.Fatal(err)
224 }
225 if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
226 t.Errorf("Got %v, want %v", got, want)
227 }
228 if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
229 t.Errorf("Got %v, want %v", got, want)
230 }
231
232 // Clear everything
233 if _, err := s.Set(nil, "alice/..."); err != nil {
234 t.Fatal(err)
235 }
236 if got := s.ForPeer("alice"); got != nil {
237 t.Errorf("Got %v, want nil", got)
238 }
239 if got := s.ForPeer("alice/friend"); got != nil {
240 t.Errorf("Got %v, want nil", got)
241 }
242}
243
244func TestBlessingStoreSetReturnsOldValue(t *testing.T) {
245 p, err := NewPrincipal()
246 if err != nil {
247 t.Fatal(err)
248 }
249 var (
250 alice = blessSelf(p, "alice")
251 bob = blessSelf(p, "bob")
252 s = p.BlessingStore()
253 )
254
255 if old, err := s.Set(alice, "..."); old != nil || err != nil {
256 t.Errorf("Got (%v, %v)", old, err)
257 }
258 if old, err := s.Set(alice, "..."); !reflect.DeepEqual(old, alice) || err != nil {
259 t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
260 }
261 if old, err := s.Set(bob, "..."); !reflect.DeepEqual(old, alice) || err != nil {
262 t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
263 }
264 if old, err := s.Set(nil, "..."); !reflect.DeepEqual(old, bob) || err != nil {
265 t.Errorf("Got (%v, %v) want (%v, nil)", old, err, bob)
266 }
267}