Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}