From b01d212f053b69e62d15fb4a1431f425fafee178 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 18 Oct 2024 20:25:07 +0200 Subject: [PATCH 01/13] feat: new functions inside acl --- examples/gno.land/p/demo/acl/acl.gno | 138 +++++++++++++++++++++++++- examples/gno.land/p/demo/acl/perm.gno | 23 +++++ 2 files changed, 157 insertions(+), 4 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index fe017490f78..7c158d5eb85 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -65,6 +65,17 @@ func (d *Directory) AddUserPerm(addr std.Address, verb, resource string) { d.addPermToBucket(bucket, p) } +func (d *Directory) AddUserPerms(addr std.Address, verbs []string, resource string) { + bucket := "u:" + addr.String() + for i, verb := range verbs { + p := perm{ + verbs: []string{verb}, + resources: []string{resource}, + } + d.addPermToBucket(bucket, p) + } +} + func (d *Directory) AddGroupPerm(name string, verb, resource string) { bucket := "g:" + name p := perm{ @@ -74,6 +85,17 @@ func (d *Directory) AddGroupPerm(name string, verb, resource string) { d.addPermToBucket(bucket, p) } +func (d *Directory) AddGroupPerms(name string, verbs []string, resource string) { + bucket := "g:" + name + for i, verb := range verbs { + p := perm{ + verbs: []string{verb}, + resources: []string{resource}, + } + d.addPermToBucket(bucket, p) + } +} + func (d *Directory) addPermToBucket(bucket string, p perm) { var ps perms @@ -96,7 +118,115 @@ func (d *Directory) AddUserToGroup(user std.Address, group string) { d.userGroups.Set(user.String(), groups) } -// TODO: helpers to remove permissions. -// TODO: helpers to adds multiple permissions at once -> {verbs: []string{"read","write"}}. -// TODO: helpers to delete users from gorups. -// TODO: helpers to quickly reset states. +func (d *Directory) AddUserToGroups(user std.Address, groups []string) { + existing, ok := d.userGroups.Get(user.String()) + var existingGroups []string + if ok { + existingGroups = existing.([]string) + } + existingGroups = append(existingGroups, groups...) + d.userGroups.Set(user.String(), existingGroups) +} + +func (d *Directory) RemoveUserFromGroup(user std.Address, group string) { + existing, ok := d.userGroups.Get(user.String()) + var groups []string + if ok { + groups = existing.([]string) + } + for i, g := range groups { + if g == group { + groups = append(groups[:i], groups[i+1:]...) + break + } + } + d.userGroups.Set(user.String(), groups) +} + +func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) { + existing, ok := d.userGroups.Get(user.String()) + var existingGroups []string + if ok { + existingGroups = existing.([]string) + } + for _, group := range groups { + for i, g := range existingGroups { + if g == group { + existingGroups = append(existingGroups[:i], existingGroups[i+1:]...) + break + } + } + } + d.userGroups.Set(user.String(), existingGroups) +} + +func (d *Directory) removePermFromBucket(bucket string, p perm) { + existing, ok := d.permBuckets.Get(bucket) + if !ok { + return + } + ps := existing.(perms) + for i, perm := range ps { + if &perm == &p { + ps = append(ps[:i], ps[i+1:]...) + break + } + } + d.permBuckets.Set(bucket, ps) +} + +func (d *Directory) RemoveUserPerm(addr std.Address, verb, resource string) { + bucket := "u:" + addr.String() + p := perm{ + verbs: []string{verb}, + resources: []string{resource}, + } + d.removePermFromBucket(bucket, p) +} + +func (d *Directory) RemoveUserPerms(addr std.Address, verbs []string, resource string) { + bucket := "u:" + addr.String() + for i, verb := range verbs { + p := perm{ + verbs: []string{verb}, + resources: []string{resource}, + } + d.removePermFromBucket(bucket, p) + } +} + +func (d *Directory) RemoveGroupPerm(name string, verb, resource string) { + bucket := "g:" + name + p := perm{ + verbs: []string{verb}, + resources: []string{resource}, + } + d.removePermFromBucket(bucket, p) +} + +func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource string) { + bucket := "g:" + name + for i, verb := range verbs { + p := perm{ + verbs: []string{verb}, + resources: []string{resource}, + } + d.removePermFromBucket(bucket, p) + } +} + +func (d *Directory) ResetGroup(group string) { + d.permBuckets.Remove("g:" + group) +} + +func (d *Directory) ResetGroupUsers(group string) { + d.userGroups.Remove(group) +} + +func (d *Directory) ResetGroupPerms(group string) { + d.permBuckets.Remove("g:" + group) +} + +func (d *Directory) ResetUser(addr std.Address) { + d.permBuckets.Remove("u:" + addr.String()) +} diff --git a/examples/gno.land/p/demo/acl/perm.gno b/examples/gno.land/p/demo/acl/perm.gno index 8705c685539..ec4ddd69907 100644 --- a/examples/gno.land/p/demo/acl/perm.gno +++ b/examples/gno.land/p/demo/acl/perm.gno @@ -42,3 +42,26 @@ func match(pattern, target string) bool { match, _ := regexp.MatchString(pattern, target) return match } + +func (p perm) Equal(p2 perm) bool { + if len(p.verbs) != len(p2.verbs) { + return false + } + if len(p.resources) != len(p2.resources) { + return false + } + + for i, verb := range p.verbs { + if verb != p2.verbs[i] { + return false + } + } + + for i, resource := range p.resources { + if resource != p2.resources[i] { + return false + } + } + + return true +} \ No newline at end of file From 7aefac4f2498b937ce51d0b392d7da33364e19c3 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 18 Oct 2024 20:25:24 +0200 Subject: [PATCH 02/13] tests: add start of acl new tests --- examples/gno.land/p/demo/acl/acl_test.gno | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/gno.land/p/demo/acl/acl_test.gno b/examples/gno.land/p/demo/acl/acl_test.gno index 53804eab4e1..9f042064488 100644 --- a/examples/gno.land/p/demo/acl/acl_test.gno +++ b/examples/gno.land/p/demo/acl/acl_test.gno @@ -132,3 +132,13 @@ func shouldNotHasPerm(t *testing.T, dir *Directory, addr std.Address, verb strin check := dir.HasPerm(addr, verb, resource) uassert.Equal(t, false, check, ufmt.Sprintf("%s should not has perm for %s - %s", addr.String(), verb, resource)) } + +func TestAddUserPerms(t *testing.T) { + usr := testutils.TestAddress("user") + + dir := New() + + dir.AddUserPerms(usr, "write", "r/demo/boards:gnolang/1") + + shouldHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") +} From 3a803ee5fbb6c2a894a45666afd9b03ee7c3474a Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Sun, 20 Oct 2024 11:35:35 +0200 Subject: [PATCH 03/13] feat: optimize acl functions --- examples/gno.land/p/demo/acl/acl.gno | 54 +++++++++++++++------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 7c158d5eb85..67b32e835b1 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -62,17 +62,17 @@ func (d *Directory) AddUserPerm(addr std.Address, verb, resource string) { verbs: []string{verb}, resources: []string{resource}, } - d.addPermToBucket(bucket, p) + d.addPermsToBucket(bucket, []perm{p}) } func (d *Directory) AddUserPerms(addr std.Address, verbs []string, resource string) { bucket := "u:" + addr.String() - for i, verb := range verbs { + for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.addPermToBucket(bucket, p) + d.addPermsToBucket(bucket, []perm{p}) } } @@ -82,28 +82,28 @@ func (d *Directory) AddGroupPerm(name string, verb, resource string) { verbs: []string{verb}, resources: []string{resource}, } - d.addPermToBucket(bucket, p) + d.addPermsToBucket(bucket, []perm{p}) } func (d *Directory) AddGroupPerms(name string, verbs []string, resource string) { bucket := "g:" + name - for i, verb := range verbs { + for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.addPermToBucket(bucket, p) + d.addPermsToBucket(bucket, []perm{p}) } } -func (d *Directory) addPermToBucket(bucket string, p perm) { +func (d *Directory) addPermsToBucket(bucket string, p []perm) { var ps perms existing, ok := d.permBuckets.Get(bucket) if ok { ps = existing.(perms) } - ps = append(ps, p) + ps = append(ps, p...) d.permBuckets.Set(bucket, ps) } @@ -130,10 +130,10 @@ func (d *Directory) AddUserToGroups(user std.Address, groups []string) { func (d *Directory) RemoveUserFromGroup(user std.Address, group string) { existing, ok := d.userGroups.Get(user.String()) - var groups []string - if ok { - groups = existing.([]string) + if !ok { + return } + groups := existing.([]string) for i, g := range groups { if g == group { groups = append(groups[:i], groups[i+1:]...) @@ -145,10 +145,10 @@ func (d *Directory) RemoveUserFromGroup(user std.Address, group string) { func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) { existing, ok := d.userGroups.Get(user.String()) - var existingGroups []string - if ok { - existingGroups = existing.([]string) + if !ok { + return } + existingGroups := existing.([]string) for _, group := range groups { for i, g := range existingGroups { if g == group { @@ -160,18 +160,22 @@ func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) { d.userGroups.Set(user.String(), existingGroups) } -func (d *Directory) removePermFromBucket(bucket string, p perm) { +func (d *Directory) removePermsFromBucket(bucket string, p []perm) { existing, ok := d.permBuckets.Get(bucket) if !ok { return } ps := existing.(perms) - for i, perm := range ps { - if &perm == &p { - ps = append(ps[:i], ps[i+1:]...) - break + + for _, perm := range p { + for i, existingPerm := range ps { + if perm.Equal(existingPerm) { + ps = append(ps[:i], ps[i+1:]...) + break + } } } + d.permBuckets.Set(bucket, ps) } @@ -181,17 +185,17 @@ func (d *Directory) RemoveUserPerm(addr std.Address, verb, resource string) { verbs: []string{verb}, resources: []string{resource}, } - d.removePermFromBucket(bucket, p) + d.removePermsFromBucket(bucket, []perm{p}) } func (d *Directory) RemoveUserPerms(addr std.Address, verbs []string, resource string) { bucket := "u:" + addr.String() - for i, verb := range verbs { + for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.removePermFromBucket(bucket, p) + d.removePermsFromBucket(bucket, []perm{p}) } } @@ -201,17 +205,17 @@ func (d *Directory) RemoveGroupPerm(name string, verb, resource string) { verbs: []string{verb}, resources: []string{resource}, } - d.removePermFromBucket(bucket, p) + d.removePermsFromBucket(bucket, []perm{p}) } func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource string) { bucket := "g:" + name - for i, verb := range verbs { + for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.removePermFromBucket(bucket, p) + d.removePermsFromBucket(bucket, []perm{p}) } } From ba165729725d17b626c6b96550060c428cde8cbb Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Sun, 20 Oct 2024 11:36:14 +0200 Subject: [PATCH 04/13] feat: reset functions for acl --- examples/gno.land/p/demo/acl/acl.gno | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 67b32e835b1..2ba449530fa 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -219,18 +219,16 @@ func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource strin } } -func (d *Directory) ResetGroup(group string) { - d.permBuckets.Remove("g:" + group) -} - -func (d *Directory) ResetGroupUsers(group string) { - d.userGroups.Remove(group) +func (d *Directory) ResetGroupPerms(name string) { + bucket := "g:" + name + d.permBuckets.Set(bucket, perms{}) } -func (d *Directory) ResetGroupPerms(group string) { - d.permBuckets.Remove("g:" + group) +func (d *Directory) ResetUserPerms(addr std.Address) { + bucket := "u:" + addr.String() + d.permBuckets.Set(bucket, perms{}) } -func (d *Directory) ResetUser(addr std.Address) { - d.permBuckets.Remove("u:" + addr.String()) +func (d *Directory) ResetUserGroups(addr std.Address) { + d.userGroups.Set(addr.String(), []string{}) } From 5765f49d8d8a8aca9d3061f403a5ee50b9eb3447 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Sun, 20 Oct 2024 11:37:26 +0200 Subject: [PATCH 05/13] tests: extra acl tests for new functions --- examples/gno.land/p/demo/acl/acl_test.gno | 257 +++++++++++++++++++++- 1 file changed, 247 insertions(+), 10 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl_test.gno b/examples/gno.land/p/demo/acl/acl_test.gno index 9f042064488..685f890c3ff 100644 --- a/examples/gno.land/p/demo/acl/acl_test.gno +++ b/examples/gno.land/p/demo/acl/acl_test.gno @@ -109,6 +109,253 @@ func Test(t *testing.T) { shouldHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/1") // new } +func TestUserPerms(t *testing.T) { + adm := testutils.TestAddress("admin") + mod := testutils.TestAddress("mod") + usr := testutils.TestAddress("user") + cst := testutils.TestAddress("custom") + + dir := New() + + dir.AddUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/2") + shouldHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/2") + shouldHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") + + dir.RemoveUserPerm(usr, "write", "r/demo/boards:gnolang/2") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/2") + shouldHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") + + dir.AddUserPerm(usr, "write", "r/demo/boards:gnolang/2") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/2") + shouldHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/2") + shouldHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") + + dir.RemoveUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") + + dir.AddUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + dir.ResetUserPerms(usr) + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") +} + +func TestUserGroups(t *testing.T) { + adm := testutils.TestAddress("admin") + mod := testutils.TestAddress("mod") + usr := testutils.TestAddress("user") + cst := testutils.TestAddress("custom") + + dir := New() + + dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + dir.AddUserToGroup(usr, "mods") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.RemoveUserFromGroup(usr, "mods") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.AddGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + dir.AddUserToGroups(adm, []string{"mods", "admins"}) + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.AddGroupPerms("mods", []string{"read", "write"}, "r/demo/boards:gnolang/3") + dir.RemoveUserFromGroups(adm, []string{"mods"}) + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.RemoveGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.AddGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.RemoveGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.ResetGroupPerms("admins") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.AddGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") + + dir.ResetUserGroups(adm) + + shouldNotHasRole(t, dir, adm, "foo") + shouldNotHasRole(t, dir, mod, "foo") + shouldNotHasRole(t, dir, usr, "foo") + shouldNotHasRole(t, dir, cst, "foo") + shouldNotHasPerm(t, dir, adm, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, adm, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, mod, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") +} + func shouldHasRole(t *testing.T, dir *Directory, addr std.Address, role string) { t.Helper() check := dir.HasRole(addr, role) @@ -132,13 +379,3 @@ func shouldNotHasPerm(t *testing.T, dir *Directory, addr std.Address, verb strin check := dir.HasPerm(addr, verb, resource) uassert.Equal(t, false, check, ufmt.Sprintf("%s should not has perm for %s - %s", addr.String(), verb, resource)) } - -func TestAddUserPerms(t *testing.T) { - usr := testutils.TestAddress("user") - - dir := New() - - dir.AddUserPerms(usr, "write", "r/demo/boards:gnolang/1") - - shouldHasPerm(t, dir, usr, "write", "r/demo/boards:gnolang/2") -} From bec2056ebc5b6c155b70c801a5044e8ca32349b7 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 11:39:28 +0200 Subject: [PATCH 06/13] feat: handle duplicates for perms --- examples/gno.land/p/demo/acl/acl.gno | 11 ++++++++--- examples/gno.land/p/demo/acl/perm.gno | 26 ++++++++++++++++++++++++-- examples/gno.land/p/demo/acl/perms.gno | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 2ba449530fa..134d88cf670 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -67,13 +67,15 @@ func (d *Directory) AddUserPerm(addr std.Address, verb, resource string) { func (d *Directory) AddUserPerms(addr std.Address, verbs []string, resource string) { bucket := "u:" + addr.String() + var ps perms for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.addPermsToBucket(bucket, []perm{p}) + ps = append(ps, p) } + d.addPermsToBucket(bucket, ps) } func (d *Directory) AddGroupPerm(name string, verb, resource string) { @@ -87,16 +89,18 @@ func (d *Directory) AddGroupPerm(name string, verb, resource string) { func (d *Directory) AddGroupPerms(name string, verbs []string, resource string) { bucket := "g:" + name + var ps perms for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.addPermsToBucket(bucket, []perm{p}) + ps = append(ps, p) } + d.addPermsToBucket(bucket, ps) } -func (d *Directory) addPermsToBucket(bucket string, p []perm) { +func (d *Directory) addPermsToBucket(bucket string, p perms) { var ps perms existing, ok := d.permBuckets.Get(bucket) @@ -104,6 +108,7 @@ func (d *Directory) addPermsToBucket(bucket string, p []perm) { ps = existing.(perms) } ps = append(ps, p...) + ps = ps.Dedup() d.permBuckets.Set(bucket, ps) } diff --git a/examples/gno.land/p/demo/acl/perm.gno b/examples/gno.land/p/demo/acl/perm.gno index ec4ddd69907..cbc4fca4db9 100644 --- a/examples/gno.land/p/demo/acl/perm.gno +++ b/examples/gno.land/p/demo/acl/perm.gno @@ -1,6 +1,12 @@ package acl -import "regexp" +import ( + "regexp" + "sort" + "strings" + + "gno.land/p/demo/ufmt" +) type perm struct { verbs []string @@ -64,4 +70,20 @@ func (p perm) Equal(p2 perm) bool { } return true -} \ No newline at end of file +} + +func (p perm) String() string { + // Sort the slices to ensure consistent ordering + sortedVerbs := make([]string, len(p.verbs)) + copy(sortedVerbs, p.verbs) + sort.Strings(sortedVerbs) + + sortedResources := make([]string, len(p.resources)) + copy(sortedResources, p.resources) + sort.Strings(sortedResources) + + // Join the slices into a string representation + return ufmt.Sprintf("verbs:[%s] resources:[%s]", + strings.Join(sortedVerbs, ", "), + strings.Join(sortedResources, ", ")) +} diff --git a/examples/gno.land/p/demo/acl/perms.gno b/examples/gno.land/p/demo/acl/perms.gno index 9a0837af287..0cf04b4ae21 100644 --- a/examples/gno.land/p/demo/acl/perms.gno +++ b/examples/gno.land/p/demo/acl/perms.gno @@ -1,5 +1,7 @@ package acl +import "fmt" + type perms []perm func (perms perms) hasPerm(verb, resource string) bool { @@ -10,3 +12,19 @@ func (perms perms) hasPerm(verb, resource string) bool { } return false } + +func (p perms) Dedup() perms { + seen := make(map[string]struct{}) + uniquePerms := make([]perm, 0, len(p)) + + for _, perm := range p { + permStr := perm.String() // Get string representation + if _, ok := seen[permStr]; ok { + continue + } + seen[permStr] = struct{}{} + uniquePerms = append(uniquePerms, perm) + } + + return uniquePerms +} From f547dd03a6db2a7d1c4c85caa6a6f315799d78e0 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 11:46:22 +0200 Subject: [PATCH 07/13] feat: simplify handling of duplicates perms --- examples/gno.land/p/demo/acl/acl.gno | 3 +-- examples/gno.land/p/demo/acl/perm.gno | 15 ------------ examples/gno.land/p/demo/acl/perms.gno | 32 +++++++++++++------------- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 134d88cf670..7e8bd962ad9 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -107,8 +107,7 @@ func (d *Directory) addPermsToBucket(bucket string, p perms) { if ok { ps = existing.(perms) } - ps = append(ps, p...) - ps = ps.Dedup() + ps = ps.appendWithoutDuplicates(p) d.permBuckets.Set(bucket, ps) } diff --git a/examples/gno.land/p/demo/acl/perm.gno b/examples/gno.land/p/demo/acl/perm.gno index cbc4fca4db9..af6286d7bde 100644 --- a/examples/gno.land/p/demo/acl/perm.gno +++ b/examples/gno.land/p/demo/acl/perm.gno @@ -72,18 +72,3 @@ func (p perm) Equal(p2 perm) bool { return true } -func (p perm) String() string { - // Sort the slices to ensure consistent ordering - sortedVerbs := make([]string, len(p.verbs)) - copy(sortedVerbs, p.verbs) - sort.Strings(sortedVerbs) - - sortedResources := make([]string, len(p.resources)) - copy(sortedResources, p.resources) - sort.Strings(sortedResources) - - // Join the slices into a string representation - return ufmt.Sprintf("verbs:[%s] resources:[%s]", - strings.Join(sortedVerbs, ", "), - strings.Join(sortedResources, ", ")) -} diff --git a/examples/gno.land/p/demo/acl/perms.gno b/examples/gno.land/p/demo/acl/perms.gno index 0cf04b4ae21..a6b90b728ff 100644 --- a/examples/gno.land/p/demo/acl/perms.gno +++ b/examples/gno.land/p/demo/acl/perms.gno @@ -1,9 +1,16 @@ package acl -import "fmt" - type perms []perm +func (p perms) Contains(p2 perm) bool { + for _, pd := range p { + if pd.Equal(p2) { + return true + } + } + return false +} + func (perms perms) hasPerm(verb, resource string) bool { for _, perm := range perms { if perm.hasPerm(verb, resource) { @@ -13,18 +20,11 @@ func (perms perms) hasPerm(verb, resource string) bool { return false } -func (p perms) Dedup() perms { - seen := make(map[string]struct{}) - uniquePerms := make([]perm, 0, len(p)) - - for _, perm := range p { - permStr := perm.String() // Get string representation - if _, ok := seen[permStr]; ok { - continue - } - seen[permStr] = struct{}{} - uniquePerms = append(uniquePerms, perm) - } - - return uniquePerms +func (p perms) appendWithoutDuplicates(newPerms perms) perms { + for _, pd := range newPerms { + if !p.Contains(pd) { + p = append(p, pd) + } + } + return p } From a50c56bb1ad4892acd3c78ab81c394d8840c16e4 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 12:23:50 +0200 Subject: [PATCH 08/13] feat: duplicate tests --- examples/gno.land/p/demo/acl/acl_test.gno | 54 +++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/examples/gno.land/p/demo/acl/acl_test.gno b/examples/gno.land/p/demo/acl/acl_test.gno index 685f890c3ff..c76c518e732 100644 --- a/examples/gno.land/p/demo/acl/acl_test.gno +++ b/examples/gno.land/p/demo/acl/acl_test.gno @@ -356,6 +356,60 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") } +func TestPermDuplication(t *testing.T) { + user := testutils.TestAddress("user") + + dir := New() + dir.AddUserPerm(user, "write", "r/demo/boards:gnolang/3") + dir.AddUserPerm(user, "write", "r/demo/boards:gnolang/3") + + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.RemoveUserPerm(user, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.AddUserPerms(user, []string{"write", "write"}, "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.RemoveUserPerm(user, "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + dir.AddUserToGroup(user, "mods") + + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.RemoveGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.AddGroupPerms("mods", []string{"write", "write"}, "r/demo/boards:gnolang/3") + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") + + dir.RemoveGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") +} + +func TestUserDuplication(t *testing.T) { + user := testutils.TestAddress("user") + + dir := New() + dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/4") + dir.AddUserToGroup(user, "mods") + dir.AddUserToGroup(user, "mods") + + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") + + dir.RemoveUserFromGroup(user, "mods") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") + + dir.AddUserToGroups(user, []string{"mods", "mods"}) + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") + + dir.RemoveUserFromGroup(user, "mods") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") +} + func shouldHasRole(t *testing.T, dir *Directory, addr std.Address, role string) { t.Helper() check := dir.HasRole(addr, role) From efd035940645cbfebcca1a74cbb76b9d98f92e25 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 12:24:06 +0200 Subject: [PATCH 09/13] feat: handle duplicates for users --- examples/gno.land/p/demo/acl/acl.gno | 12 ++++++------ examples/gno.land/p/demo/acl/groups.gno | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 examples/gno.land/p/demo/acl/groups.gno diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 7e8bd962ad9..1a89c3407eb 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -118,18 +118,18 @@ func (d *Directory) AddUserToGroup(user std.Address, group string) { if ok { groups = existing.([]string) } - groups = append(groups, group) + groups = appendGroupsWithoutDuplicates(groups, []string{group}) d.userGroups.Set(user.String(), groups) } -func (d *Directory) AddUserToGroups(user std.Address, groups []string) { +func (d *Directory) AddUserToGroups(user std.Address, newGroups []string) { existing, ok := d.userGroups.Get(user.String()) - var existingGroups []string + var groups []string if ok { - existingGroups = existing.([]string) + groups = existing.([]string) } - existingGroups = append(existingGroups, groups...) - d.userGroups.Set(user.String(), existingGroups) + groups = appendGroupsWithoutDuplicates(groups, newGroups) + d.userGroups.Set(user.String(), groups) } func (d *Directory) RemoveUserFromGroup(user std.Address, group string) { diff --git a/examples/gno.land/p/demo/acl/groups.gno b/examples/gno.land/p/demo/acl/groups.gno new file mode 100644 index 00000000000..64070b93e32 --- /dev/null +++ b/examples/gno.land/p/demo/acl/groups.gno @@ -0,0 +1,16 @@ +package acl + +// Helper function to append without duplicates +func appendGroupsWithoutDuplicates(slice []string, items []string) []string { + seen := make(map[string]struct{}) + for _, v := range slice { + seen[v] = struct{}{} + } + for _, item := range items { + if _, exists := seen[item]; !exists { + slice = append(slice, item) + seen[item] = struct{}{} + } + } + return slice +} \ No newline at end of file From 8d52be75ce3a3f1545ea0f7009746295e62ac0ad Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 12:31:59 +0200 Subject: [PATCH 10/13] feat: remove entries in the tree whenever possible --- examples/gno.land/p/demo/acl/acl.gno | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 1a89c3407eb..0cce52ef5e6 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -194,13 +194,15 @@ func (d *Directory) RemoveUserPerm(addr std.Address, verb, resource string) { func (d *Directory) RemoveUserPerms(addr std.Address, verbs []string, resource string) { bucket := "u:" + addr.String() + var ps perms for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.removePermsFromBucket(bucket, []perm{p}) + ps = append(ps, p) } + d.removePermsFromBucket(bucket, ps) } func (d *Directory) RemoveGroupPerm(name string, verb, resource string) { @@ -214,25 +216,27 @@ func (d *Directory) RemoveGroupPerm(name string, verb, resource string) { func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource string) { bucket := "g:" + name + var ps perms for _, verb := range verbs { p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.removePermsFromBucket(bucket, []perm{p}) + ps = append(ps, p) } + d.removePermsFromBucket(bucket, ps) } func (d *Directory) ResetGroupPerms(name string) { bucket := "g:" + name - d.permBuckets.Set(bucket, perms{}) + d.permBuckets.Remove(bucket) } func (d *Directory) ResetUserPerms(addr std.Address) { bucket := "u:" + addr.String() - d.permBuckets.Set(bucket, perms{}) + d.permBuckets.Remove(bucket) } func (d *Directory) ResetUserGroups(addr std.Address) { - d.userGroups.Set(addr.String(), []string{}) + d.userGroups.Remove(addr.String()) } From fa86ffc828888c77fa9bfb1ae5d5fe108c9a1163 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 12:35:58 +0200 Subject: [PATCH 11/13] feat: remove tree entries whenever possible --- examples/gno.land/p/demo/acl/acl.gno | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 0cce52ef5e6..8d3fe79efe1 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -144,7 +144,12 @@ func (d *Directory) RemoveUserFromGroup(user std.Address, group string) { break } } - d.userGroups.Set(user.String(), groups) + + if len(groups) == 0 { + d.userGroups.Remove(user.String()) + } else { + d.userGroups.Set(user.String(), groups) + } } func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) { @@ -161,7 +166,12 @@ func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) { } } } - d.userGroups.Set(user.String(), existingGroups) + + if len(existingGroups) == 0 { + d.userGroups.Remove(user.String()) + } else { + d.userGroups.Set(user.String(), existingGroups) + } } func (d *Directory) removePermsFromBucket(bucket string, p []perm) { @@ -180,7 +190,11 @@ func (d *Directory) removePermsFromBucket(bucket string, p []perm) { } } - d.permBuckets.Set(bucket, ps) + if len(ps) == 0 { + d.permBuckets.Remove(bucket) + } else { + d.permBuckets.Set(bucket, ps) + } } func (d *Directory) RemoveUserPerm(addr std.Address, verb, resource string) { From 8bae6434f4e1f772fec08f4ce3299aa595a31149 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 23 Oct 2024 12:36:06 +0200 Subject: [PATCH 12/13] style: format realms --- examples/gno.land/p/demo/acl/groups.gno | 24 ++++++++++++------------ examples/gno.land/p/demo/acl/perm.gno | 5 ----- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/examples/gno.land/p/demo/acl/groups.gno b/examples/gno.land/p/demo/acl/groups.gno index 64070b93e32..be9a0eac354 100644 --- a/examples/gno.land/p/demo/acl/groups.gno +++ b/examples/gno.land/p/demo/acl/groups.gno @@ -2,15 +2,15 @@ package acl // Helper function to append without duplicates func appendGroupsWithoutDuplicates(slice []string, items []string) []string { - seen := make(map[string]struct{}) - for _, v := range slice { - seen[v] = struct{}{} - } - for _, item := range items { - if _, exists := seen[item]; !exists { - slice = append(slice, item) - seen[item] = struct{}{} - } - } - return slice -} \ No newline at end of file + seen := make(map[string]struct{}) + for _, v := range slice { + seen[v] = struct{}{} + } + for _, item := range items { + if _, exists := seen[item]; !exists { + slice = append(slice, item) + seen[item] = struct{}{} + } + } + return slice +} diff --git a/examples/gno.land/p/demo/acl/perm.gno b/examples/gno.land/p/demo/acl/perm.gno index af6286d7bde..49761c5b3fe 100644 --- a/examples/gno.land/p/demo/acl/perm.gno +++ b/examples/gno.land/p/demo/acl/perm.gno @@ -2,10 +2,6 @@ package acl import ( "regexp" - "sort" - "strings" - - "gno.land/p/demo/ufmt" ) type perm struct { @@ -71,4 +67,3 @@ func (p perm) Equal(p2 perm) bool { return true } - From ad868209e97b855b30aa1ce970cbc1ac10c38f61 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Wed, 8 Jan 2025 17:55:58 +0100 Subject: [PATCH 13/13] feat: return boolean on success of failure for all public functions --- examples/gno.land/p/demo/acl/acl.gno | 74 +++++++---- examples/gno.land/p/demo/acl/acl_test.gno | 152 ++++++++++++++++------ 2 files changed, 161 insertions(+), 65 deletions(-) diff --git a/examples/gno.land/p/demo/acl/acl.gno b/examples/gno.land/p/demo/acl/acl.gno index 8d3fe79efe1..d2621c1ee02 100644 --- a/examples/gno.land/p/demo/acl/acl.gno +++ b/examples/gno.land/p/demo/acl/acl.gno @@ -56,16 +56,17 @@ func (d *Directory) HasRole(addr std.Address, role string) bool { return d.HasPerm(addr, "role", role) } -func (d *Directory) AddUserPerm(addr std.Address, verb, resource string) { +func (d *Directory) AddUserPerm(addr std.Address, verb, resource string) bool { bucket := "u:" + addr.String() p := perm{ verbs: []string{verb}, resources: []string{resource}, } d.addPermsToBucket(bucket, []perm{p}) + return true } -func (d *Directory) AddUserPerms(addr std.Address, verbs []string, resource string) { +func (d *Directory) AddUserPerms(addr std.Address, verbs []string, resource string) bool { bucket := "u:" + addr.String() var ps perms for _, verb := range verbs { @@ -76,18 +77,20 @@ func (d *Directory) AddUserPerms(addr std.Address, verbs []string, resource stri ps = append(ps, p) } d.addPermsToBucket(bucket, ps) + return true } -func (d *Directory) AddGroupPerm(name string, verb, resource string) { +func (d *Directory) AddGroupPerm(name string, verb, resource string) bool { bucket := "g:" + name p := perm{ verbs: []string{verb}, resources: []string{resource}, } d.addPermsToBucket(bucket, []perm{p}) + return true } -func (d *Directory) AddGroupPerms(name string, verbs []string, resource string) { +func (d *Directory) AddGroupPerms(name string, verbs []string, resource string) bool { bucket := "g:" + name var ps perms for _, verb := range verbs { @@ -98,6 +101,7 @@ func (d *Directory) AddGroupPerms(name string, verbs []string, resource string) ps = append(ps, p) } d.addPermsToBucket(bucket, ps) + return true } func (d *Directory) addPermsToBucket(bucket string, p perms) { @@ -112,7 +116,7 @@ func (d *Directory) addPermsToBucket(bucket string, p perms) { d.permBuckets.Set(bucket, ps) } -func (d *Directory) AddUserToGroup(user std.Address, group string) { +func (d *Directory) AddUserToGroup(user std.Address, group string) bool { existing, ok := d.userGroups.Get(user.String()) var groups []string if ok { @@ -120,9 +124,10 @@ func (d *Directory) AddUserToGroup(user std.Address, group string) { } groups = appendGroupsWithoutDuplicates(groups, []string{group}) d.userGroups.Set(user.String(), groups) + return true } -func (d *Directory) AddUserToGroups(user std.Address, newGroups []string) { +func (d *Directory) AddUserToGroups(user std.Address, newGroups []string) bool { existing, ok := d.userGroups.Get(user.String()) var groups []string if ok { @@ -130,83 +135,103 @@ func (d *Directory) AddUserToGroups(user std.Address, newGroups []string) { } groups = appendGroupsWithoutDuplicates(groups, newGroups) d.userGroups.Set(user.String(), groups) + return true } -func (d *Directory) RemoveUserFromGroup(user std.Address, group string) { +func (d *Directory) RemoveUserFromGroup(user std.Address, group string) bool { existing, ok := d.userGroups.Get(user.String()) if !ok { - return + return false } + found := false groups := existing.([]string) for i, g := range groups { if g == group { groups = append(groups[:i], groups[i+1:]...) + found = true break } } + if !found { + return false + } if len(groups) == 0 { d.userGroups.Remove(user.String()) } else { d.userGroups.Set(user.String(), groups) } + return true } -func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) { +func (d *Directory) RemoveUserFromGroups(user std.Address, groups []string) bool { existing, ok := d.userGroups.Get(user.String()) if !ok { - return + return false } existingGroups := existing.([]string) + + foundGroups := 0 for _, group := range groups { for i, g := range existingGroups { if g == group { existingGroups = append(existingGroups[:i], existingGroups[i+1:]...) + foundGroups++ break } } } + if foundGroups == 0 { + return false + } if len(existingGroups) == 0 { d.userGroups.Remove(user.String()) } else { d.userGroups.Set(user.String(), existingGroups) } + return foundGroups == len(groups) } -func (d *Directory) removePermsFromBucket(bucket string, p []perm) { +func (d *Directory) removePermsFromBucket(bucket string, p []perm) bool { existing, ok := d.permBuckets.Get(bucket) if !ok { - return + return false } ps := existing.(perms) + foundPerms := 0 for _, perm := range p { for i, existingPerm := range ps { if perm.Equal(existingPerm) { ps = append(ps[:i], ps[i+1:]...) + foundPerms++ break } } } + if foundPerms == 0 { + return false + } if len(ps) == 0 { d.permBuckets.Remove(bucket) } else { d.permBuckets.Set(bucket, ps) } + return foundPerms == len(p) } -func (d *Directory) RemoveUserPerm(addr std.Address, verb, resource string) { +func (d *Directory) RemoveUserPerm(addr std.Address, verb, resource string) bool { bucket := "u:" + addr.String() p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.removePermsFromBucket(bucket, []perm{p}) + return d.removePermsFromBucket(bucket, []perm{p}) } -func (d *Directory) RemoveUserPerms(addr std.Address, verbs []string, resource string) { +func (d *Directory) RemoveUserPerms(addr std.Address, verbs []string, resource string) bool { bucket := "u:" + addr.String() var ps perms for _, verb := range verbs { @@ -216,19 +241,19 @@ func (d *Directory) RemoveUserPerms(addr std.Address, verbs []string, resource s } ps = append(ps, p) } - d.removePermsFromBucket(bucket, ps) + return d.removePermsFromBucket(bucket, ps) } -func (d *Directory) RemoveGroupPerm(name string, verb, resource string) { +func (d *Directory) RemoveGroupPerm(name string, verb, resource string) bool { bucket := "g:" + name p := perm{ verbs: []string{verb}, resources: []string{resource}, } - d.removePermsFromBucket(bucket, []perm{p}) + return d.removePermsFromBucket(bucket, []perm{p}) } -func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource string) { +func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource string) bool { bucket := "g:" + name var ps perms for _, verb := range verbs { @@ -238,19 +263,22 @@ func (d *Directory) RemoveGroupPerms(name string, verbs []string, resource strin } ps = append(ps, p) } - d.removePermsFromBucket(bucket, ps) + return d.removePermsFromBucket(bucket, ps) } -func (d *Directory) ResetGroupPerms(name string) { +func (d *Directory) ResetGroupPerms(name string) bool { bucket := "g:" + name d.permBuckets.Remove(bucket) + return true } -func (d *Directory) ResetUserPerms(addr std.Address) { +func (d *Directory) ResetUserPerms(addr std.Address) bool { bucket := "u:" + addr.String() d.permBuckets.Remove(bucket) + return true } -func (d *Directory) ResetUserGroups(addr std.Address) { +func (d *Directory) ResetUserGroups(addr std.Address) bool { d.userGroups.Remove(addr.String()) + return true } diff --git a/examples/gno.land/p/demo/acl/acl_test.gno b/examples/gno.land/p/demo/acl/acl_test.gno index c76c518e732..f1d9746fad8 100644 --- a/examples/gno.land/p/demo/acl/acl_test.gno +++ b/examples/gno.land/p/demo/acl/acl_test.gno @@ -32,7 +32,9 @@ func Test(t *testing.T) { shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/1") // adding all the rights to admin. - dir.AddUserPerm(adm, ".*", ".*") + res := dir.AddUserPerm(adm, ".*", ".*") + uassert.True(t, res, "failed to add perm") + shouldHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") shouldNotHasRole(t, dir, usr, "foo") @@ -47,7 +49,9 @@ func Test(t *testing.T) { shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/1") // adding custom regexp rule for user "cst". - dir.AddUserPerm(cst, "write", "r/demo/boards:gnolang/.*") + res2 := dir.AddUserPerm(cst, "write", "r/demo/boards:gnolang/.*") + uassert.True(t, res2, "failed to add perm") + shouldHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") shouldNotHasRole(t, dir, usr, "foo") @@ -63,8 +67,11 @@ func Test(t *testing.T) { // adding a group perm for a new group. // no changes expected. - dir.AddGroupPerm("mods", "role", "moderator") - dir.AddGroupPerm("mods", "write", ".*") + res3 := dir.AddGroupPerm("mods", "role", "moderator") + res4 := dir.AddGroupPerm("mods", "write", ".*") + uassert.True(t, res3, "failed to add group perm") + uassert.True(t, res4, "failed to add group perm") + shouldHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") shouldNotHasRole(t, dir, usr, "foo") @@ -79,7 +86,9 @@ func Test(t *testing.T) { shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/1") // assigning the user "mod" to the "mods" group. - dir.AddUserToGroup(mod, "mods") + res5 := dir.AddUserToGroup(mod, "mods") + uassert.True(t, res5, "failed to add user to group") + shouldHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") shouldNotHasRole(t, dir, usr, "foo") @@ -94,7 +103,9 @@ func Test(t *testing.T) { shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/1") // adding "read" permission for everyone. - dir.AddGroupPerm(Everyone, "read", ".*") + res6 := dir.AddGroupPerm(Everyone, "read", ".*") + uassert.True(t, res6, "failed to add group perm") + shouldHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") shouldNotHasRole(t, dir, usr, "foo") @@ -117,7 +128,8 @@ func TestUserPerms(t *testing.T) { dir := New() - dir.AddUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + res := dir.AddUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + uassert.True(t, res, "failed to add user perms") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -132,7 +144,10 @@ func TestUserPerms(t *testing.T) { shouldHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") - dir.RemoveUserPerm(usr, "write", "r/demo/boards:gnolang/2") + res1 := dir.RemoveUserPerm(usr, "write", "r/demo/boards:gnolang/2") + res2 := dir.RemoveUserPerm(usr, "write", "r/demo/boards:gnolang/2") + uassert.True(t, res1, "failed to remove user perm") + uassert.False(t, res2, "should not remove user perm") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -147,7 +162,8 @@ func TestUserPerms(t *testing.T) { shouldHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") - dir.AddUserPerm(usr, "write", "r/demo/boards:gnolang/2") + res3 := dir.AddUserPerm(usr, "write", "r/demo/boards:gnolang/2") + uassert.True(t, res3, "failed to add user perm") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -162,7 +178,10 @@ func TestUserPerms(t *testing.T) { shouldHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") - dir.RemoveUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + res4 := dir.RemoveUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + res5 := dir.RemoveUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + uassert.True(t, res4, "failed to remove user perms") + uassert.False(t, res5, "should not remove user perms") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -177,8 +196,10 @@ func TestUserPerms(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/2") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/2") - dir.AddUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") - dir.ResetUserPerms(usr) + res6 := dir.AddUserPerms(usr, []string{"write", "read"}, "r/demo/boards:gnolang/2") + res7 := dir.ResetUserPerms(usr) + uassert.True(t, res6, "failed to add user perms") + uassert.True(t, res7, "failed to reset user perms") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -202,8 +223,10 @@ func TestUserGroups(t *testing.T) { dir := New() - dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") - dir.AddUserToGroup(usr, "mods") + res := dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + res2 := dir.AddUserToGroup(usr, "mods") + uassert.True(t, res, "failed to add group perm") + uassert.True(t, res2, "failed to add user to group") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -218,7 +241,8 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.RemoveUserFromGroup(usr, "mods") + res3 := dir.RemoveUserFromGroup(usr, "mods") + uassert.True(t, res3, "failed to remove user from group") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -233,8 +257,10 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.AddGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") - dir.AddUserToGroups(adm, []string{"mods", "admins"}) + res4 := dir.AddGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + res5 := dir.AddUserToGroups(adm, []string{"mods", "admins"}) + uassert.True(t, res4, "failed to add group perms") + uassert.True(t, res5, "failed to add user to groups") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -249,8 +275,12 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.AddGroupPerms("mods", []string{"read", "write"}, "r/demo/boards:gnolang/3") - dir.RemoveUserFromGroups(adm, []string{"mods"}) + res6 := dir.AddGroupPerms("mods", []string{"read", "write"}, "r/demo/boards:gnolang/3") + res7 := dir.RemoveUserFromGroups(adm, []string{"mods"}) + res8 := dir.RemoveUserFromGroups(adm, []string{"mods"}) + uassert.True(t, res6, "failed to add group perms") + uassert.True(t, res7, "failed to remove user from groups") + uassert.False(t, res8, "should not remove user from groups") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -265,7 +295,10 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.RemoveGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + res9 := dir.RemoveGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + res10 := dir.RemoveGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + uassert.True(t, res9, "failed to remove group perms") + uassert.False(t, res10, "should not remove group perms") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -280,7 +313,8 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.AddGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + res11 := dir.AddGroupPerms("admins", []string{"read", "write"}, "r/demo/boards:gnolang/3") + uassert.True(t, res11, "failed to add group perms") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -295,7 +329,10 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.RemoveGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + res12 := dir.RemoveGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + res13 := dir.RemoveGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + uassert.True(t, res12, "failed to remove group perm") + uassert.False(t, res13, "should not remove group perm") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -310,7 +347,8 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.ResetGroupPerms("admins") + res14 := dir.ResetGroupPerms("admins") + uassert.True(t, res14, "failed to reset group perms") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -325,7 +363,8 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.AddGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + res15 := dir.AddGroupPerm("admins", "write", "r/demo/boards:gnolang/3") + uassert.True(t, res15, "failed to add group perm") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -340,7 +379,8 @@ func TestUserGroups(t *testing.T) { shouldNotHasPerm(t, dir, usr, "read", "r/demo/boards:gnolang/3") shouldNotHasPerm(t, dir, cst, "read", "r/demo/boards:gnolang/3") - dir.ResetUserGroups(adm) + res16 := dir.ResetUserGroups(adm) + uassert.True(t, res16, "failed to reset user groups") shouldNotHasRole(t, dir, adm, "foo") shouldNotHasRole(t, dir, mod, "foo") @@ -360,33 +400,50 @@ func TestPermDuplication(t *testing.T) { user := testutils.TestAddress("user") dir := New() - dir.AddUserPerm(user, "write", "r/demo/boards:gnolang/3") - dir.AddUserPerm(user, "write", "r/demo/boards:gnolang/3") + res := dir.AddUserPerm(user, "write", "r/demo/boards:gnolang/3") + res1 := dir.AddUserPerm(user, "write", "r/demo/boards:gnolang/3") + uassert.True(t, res, "failed to add user perm") + uassert.True(t, res1, "failed to add user perm") shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.RemoveUserPerm(user, "write", "r/demo/boards:gnolang/3") + res2 := dir.RemoveUserPerm(user, "write", "r/demo/boards:gnolang/3") + uassert.True(t, res2, "failed to add user perm") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.AddUserPerms(user, []string{"write", "write"}, "r/demo/boards:gnolang/3") + res3 := dir.AddUserPerms(user, []string{"write", "write"}, "r/demo/boards:gnolang/3") + uassert.True(t, res3, "failed to add user perm") + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.RemoveUserPerm(user, "write", "r/demo/boards:gnolang/3") + res4 := dir.RemoveUserPerm(user, "write", "r/demo/boards:gnolang/3") + uassert.True(t, res4, "failed to add user perm") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") - dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") - dir.AddUserToGroup(user, "mods") + res5 := dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + res6 := dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + res7 := dir.AddUserToGroup(user, "mods") + uassert.True(t, res5, "failed to add group perm") + uassert.True(t, res6, "failed to add group perm") + uassert.True(t, res7, "failed to add user to group") shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.RemoveGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + res8 := dir.RemoveGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + uassert.True(t, res8, "failed to add group perm") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.AddGroupPerms("mods", []string{"write", "write"}, "r/demo/boards:gnolang/3") + res9 := dir.AddGroupPerms("mods", []string{"write", "write"}, "r/demo/boards:gnolang/3") + uassert.True(t, res9, "failed to add group perm") + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") - dir.RemoveGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + res10 := dir.RemoveGroupPerm("mods", "write", "r/demo/boards:gnolang/3") + uassert.True(t, res10, "failed to add group perm") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/3") } @@ -394,19 +451,30 @@ func TestUserDuplication(t *testing.T) { user := testutils.TestAddress("user") dir := New() - dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/4") - dir.AddUserToGroup(user, "mods") - dir.AddUserToGroup(user, "mods") + res := dir.AddGroupPerm("mods", "write", "r/demo/boards:gnolang/4") + res1 := dir.AddUserToGroup(user, "mods") + res2 := dir.AddUserToGroup(user, "mods") + uassert.True(t, res, "failed to add group perm") + uassert.True(t, res1, "failed to add user to group") + uassert.True(t, res2, "failed to add user to group") shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") - dir.RemoveUserFromGroup(user, "mods") + res3 := dir.RemoveUserFromGroup(user, "mods") + uassert.True(t, res3, "failed to remove user from group") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") - dir.AddUserToGroups(user, []string{"mods", "mods"}) + res4 := dir.AddUserToGroups(user, []string{"mods", "mods"}) + uassert.True(t, res4, "failed to add user to groups") + shouldHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") - dir.RemoveUserFromGroup(user, "mods") + res5 := dir.RemoveUserFromGroup(user, "mods") + res6 := dir.RemoveUserFromGroup(user, "mods") + uassert.True(t, res5, "failed to remove user from group") + uassert.False(t, res6, "should not remove user from group") + shouldNotHasPerm(t, dir, user, "write", "r/demo/boards:gnolang/4") }