permissions_test.gno
14.84 Kb · 584 lines
1package permissions
2
3import (
4 "testing"
5
6 "gno.land/p/gnoland/boards"
7 "gno.land/p/nt/uassert/v0"
8 "gno.land/p/nt/urequire/v0"
9)
10
11// cur is a zero-value realm used as a placeholder when forwarding to
12// uassert/urequire dispatch helpers that gained an `rlm realm` param.
13// These tests pass `func()` callbacks (no crossing inside the callback),
14// so rlm is ignored — a nil realm here is safe.
15var cur realm
16
17// Test permission constants
18const (
19 testPermA boards.Permission = iota
20 testPermB
21 testPermC
22)
23
24var _ boards.Permissions = (*Permissions)(nil)
25
26func TestBasicPermissionsWithPermission(cur realm, t *testing.T) {
27 cases := []struct {
28 name string
29 user address
30 permission boards.Permission
31 args boards.Args
32 setup func() *Permissions
33 err string
34 called bool
35 }{
36 {
37 name: "ok",
38 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
39 permission: testPermA,
40 setup: func() *Permissions {
41 perms := New()
42 perms.AddRole("foo", testPermA)
43 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo")
44 return perms
45 },
46 called: true,
47 },
48 {
49 name: "ok with arguments",
50 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
51 permission: testPermA,
52 args: boards.Args{"a", "b"},
53 setup: func() *Permissions {
54 perms := New()
55 perms.AddRole("foo", testPermA)
56 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo")
57 return perms
58 },
59 called: true,
60 },
61 {
62 name: "no permission",
63 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
64 permission: testPermA,
65 setup: func() *Permissions {
66 perms := New()
67 perms.AddRole("foo", testPermA)
68 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
69 return perms
70 },
71 err: "unauthorized, user g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 doesn't have the required permission",
72 },
73 {
74 name: "is not a DAO member",
75 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
76 permission: testPermA,
77 setup: func() *Permissions {
78 return New()
79 },
80 err: "unauthorized, user g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 doesn't have the required permission",
81 },
82 }
83
84 for _, tc := range cases {
85 t.Run(tc.name, func(t *testing.T) {
86 var called bool
87
88 perms := tc.setup()
89 testCaseFn := func() {
90 perms.WithPermission(tc.user, tc.permission, tc.args, func() {
91 called = true
92 })
93 }
94
95 if tc.err != "" {
96 urequire.PanicsWithMessage(t, cur, tc.err, testCaseFn, "expect panic with message")
97 return
98 } else {
99 urequire.NotPanics(t, cur, testCaseFn, "expect no panic")
100 }
101
102 urequire.Equal(t, tc.called, called, "expect callback to be called")
103 })
104 }
105}
106
107func TestBasicPermissionsSetPublicPermissions(t *testing.T) {
108 user := address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
109 perms := New()
110
111 // Add a new role with permissions
112 perms.AddRole("adminRole", testPermA, testPermB, testPermC)
113 urequire.False(t, perms.HasPermission(user, testPermA))
114 urequire.False(t, perms.HasPermission(user, testPermB))
115 urequire.False(t, perms.HasPermission(user, testPermC))
116
117 // Assign a couple of public permissions
118 perms.SetPublicPermissions(testPermA, testPermC)
119 urequire.True(t, perms.HasPermission(user, testPermA))
120 urequire.False(t, perms.HasPermission(user, testPermB))
121 urequire.True(t, perms.HasPermission(user, testPermC))
122
123 // Clear all public permissions
124 perms.SetPublicPermissions()
125 urequire.False(t, perms.HasPermission(user, testPermA))
126 urequire.False(t, perms.HasPermission(user, testPermB))
127 urequire.False(t, perms.HasPermission(user, testPermC))
128}
129
130func TestBasicPermissionsGetUserRoles(t *testing.T) {
131 cases := []struct {
132 name string
133 user address
134 roles []string
135 setup func() *Permissions
136 }{
137 {
138 name: "single role",
139 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
140 roles: []string{"admin"},
141 setup: func() *Permissions {
142 perms := New()
143 perms.AddRole("admin", testPermA)
144 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "admin")
145 return perms
146 },
147 },
148 {
149 name: "multiple roles",
150 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
151 roles: []string{"admin", "bar", "foo"},
152 setup: func() *Permissions {
153 perms := New()
154 perms.AddRole("admin", testPermA)
155 perms.AddRole("foo", testPermA)
156 perms.AddRole("bar", testPermA)
157 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "admin", "foo", "bar")
158 return perms
159 },
160 },
161 {
162 name: "without roles",
163 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
164 setup: func() *Permissions {
165 perms := New()
166 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
167 return perms
168 },
169 },
170 {
171 name: "not a user",
172 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
173 setup: func() *Permissions {
174 return New()
175 },
176 },
177 {
178 name: "multiple users",
179 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
180 roles: []string{"admin"},
181 setup: func() *Permissions {
182 perms := New()
183 perms.AddRole("admin", testPermA)
184 perms.AddRole("bar", testPermA)
185 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "admin")
186 perms.SetUserRoles("g1w4ek2u33ta047h6lta047h6lta047h6ldvdwpn", "admin")
187 perms.SetUserRoles("g1w4ek2u3jta047h6lta047h6lta047h6l9huexc", "admin", "bar")
188 return perms
189 },
190 },
191 }
192
193 for _, tc := range cases {
194 t.Run(tc.name, func(t *testing.T) {
195 perms := tc.setup()
196 roles := perms.GetUserRoles(tc.user)
197
198 urequire.Equal(t, len(tc.roles), len(roles), "user role count")
199 for i, r := range roles {
200 uassert.Equal(t, tc.roles[i], string(r))
201 }
202 })
203 }
204}
205
206func TestBasicPermissionsHasRole(t *testing.T) {
207 cases := []struct {
208 name string
209 user address
210 role boards.Role
211 setup func() *Permissions
212 want bool
213 }{
214 {
215 name: "ok",
216 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
217 role: "admin",
218 setup: func() *Permissions {
219 perms := New()
220 perms.AddRole("admin", testPermA)
221 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "admin")
222 return perms
223 },
224 want: true,
225 },
226 {
227 name: "ok with multiple roles",
228 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
229 role: "foo",
230 setup: func() *Permissions {
231 perms := New()
232 perms.AddRole("admin", testPermA)
233 perms.AddRole("foo", testPermA)
234 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "admin", "foo")
235 return perms
236 },
237 want: true,
238 },
239 {
240 name: "user without roles",
241 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
242 setup: func() *Permissions {
243 perms := New()
244 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
245 return perms
246 },
247 },
248 {
249 name: "has no role",
250 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
251 role: "bar",
252 setup: func() *Permissions {
253 perms := New()
254 perms.AddRole("foo", testPermA)
255 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo")
256 return perms
257 },
258 },
259 }
260
261 for _, tc := range cases {
262 t.Run(tc.name, func(t *testing.T) {
263 perms := tc.setup()
264 got := perms.HasRole(tc.user, tc.role)
265 uassert.Equal(t, got, tc.want)
266 })
267 }
268}
269
270func TestBasicPermissionsHasPermission(t *testing.T) {
271 cases := []struct {
272 name string
273 user address
274 permission boards.Permission
275 setup func() *Permissions
276 want bool
277 }{
278 {
279 name: "ok",
280 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
281 permission: testPermA,
282 setup: func() *Permissions {
283 perms := New()
284 perms.AddRole("foo", testPermA)
285 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo")
286 return perms
287 },
288 want: true,
289 },
290 {
291 name: "ok with multiple users",
292 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
293 permission: testPermA,
294 setup: func() *Permissions {
295 perms := New()
296 perms.AddRole("foo", testPermA)
297 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo")
298 perms.SetUserRoles("g1w4ek2u33ta047h6lta047h6lta047h6ldvdwpn", "foo")
299 return perms
300 },
301 want: true,
302 },
303 {
304 name: "ok with multiple roles",
305 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
306 permission: testPermB,
307 setup: func() *Permissions {
308 perms := New()
309 perms.AddRole("foo", testPermA)
310 perms.AddRole("baz", testPermB)
311 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo", "baz")
312 return perms
313 },
314 want: true,
315 },
316 {
317 name: "no permission",
318 user: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
319 permission: testPermB,
320 setup: func() *Permissions {
321 perms := New()
322 perms.AddRole("foo", testPermA)
323 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "foo")
324 return perms
325 },
326 },
327 }
328
329 for _, tc := range cases {
330 t.Run(tc.name, func(t *testing.T) {
331 perms := tc.setup()
332 got := perms.HasPermission(tc.user, tc.permission)
333 uassert.Equal(t, tc.want, got)
334 })
335 }
336}
337
338func TestBasicPermissionsSetUserRoles(cur realm, t *testing.T) {
339 cases := []struct {
340 name string
341 user address
342 expectedRoles []boards.Role
343 setup func() *Permissions
344 err string
345 }{
346 {
347 name: "add user",
348 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
349 expectedRoles: []boards.Role{"a"},
350 setup: func() *Permissions {
351 perms := New()
352 perms.AddRole("a", testPermA)
353 return perms
354 },
355 },
356 {
357 name: "add user with multiple roles",
358 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
359 expectedRoles: []boards.Role{"a", "b"},
360 setup: func() *Permissions {
361 perms := New()
362 perms.AddRole("a", testPermA)
363 perms.AddRole("b", testPermB)
364 return perms
365 },
366 },
367 {
368 name: "add when other users exists",
369 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
370 expectedRoles: []boards.Role{"a"},
371 setup: func() *Permissions {
372 perms := New()
373 perms.AddRole("a", testPermA)
374 perms.SetUserRoles("g1w4ek2u33ta047h6lta047h6lta047h6ldvdwpn", "a")
375 perms.SetUserRoles("g1w4ek2u3jta047h6lta047h6lta047h6l9huexc")
376 return perms
377 },
378 },
379 {
380 name: "add user using single role",
381 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
382 expectedRoles: []boards.Role{"a"},
383 setup: func() *Permissions {
384 perms := New(UseSingleUserRole())
385 perms.AddRole("a", testPermA)
386 return perms
387 },
388 },
389 {
390 name: "update user roles",
391 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
392 expectedRoles: []boards.Role{"a", "b"},
393 setup: func() *Permissions {
394 perms := New()
395 perms.AddRole("a", testPermA)
396 perms.AddRole("b", testPermB)
397 perms.AddRole("c", testPermB)
398 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "c")
399 return perms
400 },
401 },
402 {
403 name: "update user roles using single role",
404 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
405 expectedRoles: []boards.Role{"b"},
406 setup: func() *Permissions {
407 perms := New(UseSingleUserRole())
408 perms.AddRole("a", testPermA)
409 perms.AddRole("b", testPermB)
410 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "a")
411 return perms
412 },
413 },
414 {
415 name: "clear user roles",
416 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
417 expectedRoles: []boards.Role{},
418 setup: func() *Permissions {
419 perms := New()
420 perms.AddRole("a", testPermA)
421 perms.AddRole("b", testPermB)
422 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", "a", "b")
423 return perms
424 },
425 },
426 {
427 name: "set invalid role",
428 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
429 expectedRoles: []boards.Role{"a", "foo"},
430 setup: func() *Permissions {
431 perms := New()
432 perms.AddRole("a", testPermA)
433 return perms
434 },
435 err: "invalid role: foo",
436 },
437 {
438 name: "use single role error",
439 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
440 expectedRoles: []boards.Role{"a", "b"},
441 setup: func() *Permissions {
442 perms := New(UseSingleUserRole())
443 perms.AddRole("a", testPermA)
444 perms.AddRole("b", testPermB)
445 return perms
446 },
447 err: "user can only have one role",
448 },
449 }
450
451 for _, tc := range cases {
452 t.Run(tc.name, func(t *testing.T) {
453 perms := tc.setup()
454
455 setUserRoles := func() {
456 perms.SetUserRoles(tc.user, tc.expectedRoles...)
457 }
458
459 if tc.err != "" {
460 urequire.PanicsWithMessage(t, cur, tc.err, setUserRoles, "expected an error")
461 return
462 } else {
463 urequire.NotPanics(t, cur, setUserRoles, "expected no error")
464 }
465
466 roles := perms.GetUserRoles(tc.user)
467 uassert.Equal(t, len(tc.expectedRoles), len(roles))
468 for i, r := range roles {
469 urequire.Equal(t, string(tc.expectedRoles[i]), string(r))
470 }
471 })
472 }
473}
474
475func TestBasicPermissionsRemoveUser(t *testing.T) {
476 cases := []struct {
477 name string
478 user address
479 setup func() *Permissions
480 want bool
481 }{
482 {
483 name: "ok",
484 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
485 setup: func() *Permissions {
486 perms := New()
487 perms.SetUserRoles("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
488 return perms
489 },
490 want: true,
491 },
492 {
493 name: "user not found",
494 user: address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
495 setup: func() *Permissions {
496 return New()
497 },
498 },
499 }
500
501 for _, tc := range cases {
502 t.Run(tc.name, func(t *testing.T) {
503 perms := tc.setup()
504 got := perms.RemoveUser(tc.user)
505 uassert.Equal(t, tc.want, got)
506 })
507 }
508}
509
510func TestBasicPermissionsIterateUsers(t *testing.T) {
511 users := []boards.User{
512 {
513 Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
514 Roles: []boards.Role{"foo"},
515 },
516 {
517 Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj",
518 Roles: []boards.Role{"bar", "foo"},
519 },
520 {
521 Address: "g1vh7krmmzfua5xjmkatvmx09z37w34lsvd2mxa5",
522 Roles: []boards.Role{"bar"},
523 },
524 }
525
526 perms := New()
527 perms.AddRole("foo", testPermA)
528 perms.AddRole("bar", testPermB)
529 for _, u := range users {
530 perms.SetUserRoles(u.Address, u.Roles...)
531 }
532
533 cases := []struct {
534 name string
535 start, count, want int
536 }{
537 {
538 name: "exceed users count",
539 count: 50,
540 want: 3,
541 },
542 {
543 name: "exact users count",
544 count: 3,
545 want: 3,
546 },
547 {
548 name: "two users",
549 start: 1,
550 count: 2,
551 want: 2,
552 },
553 {
554 name: "one user",
555 start: 1,
556 count: 1,
557 want: 1,
558 },
559 {
560 name: "no iteration",
561 start: 50,
562 },
563 }
564
565 for _, tc := range cases {
566 t.Run(tc.name, func(t *testing.T) {
567 var i int
568 perms.IterateUsers(0, len(users), func(u boards.User) bool {
569 urequire.True(t, i < len(users), "expect iterator to respect number of users")
570 uassert.Equal(t, users[i].Address, u.Address)
571
572 urequire.Equal(t, len(users[i].Roles), len(u.Roles), "expect number of roles to match")
573 for j := range u.Roles {
574 uassert.Equal(t, string(users[i].Roles[j]), string(u.Roles[j]))
575 }
576
577 i++
578 return false
579 })
580
581 uassert.Equal(t, i, len(users), "expect iterator to iterate all users")
582 })
583 }
584}