Search Apps Documentation Source Content File Folder Download Copy Actions Download

permissions_test.gno

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