github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/acl/acl.gno (about) 1 package acl 2 3 import ( 4 "std" 5 6 "gno.land/p/demo/avl" 7 ) 8 9 func New() *Directory { 10 return &Directory{ 11 userGroups: avl.Tree{}, 12 permBuckets: avl.Tree{}, 13 } 14 } 15 16 type Directory struct { 17 permBuckets avl.Tree // identifier -> perms 18 userGroups avl.Tree // std.Address -> []string 19 } 20 21 func (d *Directory) HasPerm(addr std.Address, verb, resource string) bool { 22 // FIXME: consider memoize. 23 24 // user perms 25 if d.getBucketPerms("u:"+addr.String()).hasPerm(verb, resource) { 26 return true 27 } 28 29 // everyone's perms. 30 if d.getBucketPerms("g:"+Everyone).hasPerm(verb, resource) { 31 return true 32 } 33 34 // user groups' perms. 35 groups, ok := d.userGroups.Get(addr.String()) 36 if ok { 37 for _, group := range groups.([]string) { 38 if d.getBucketPerms("g:"+group).hasPerm(verb, resource) { 39 return true 40 } 41 } 42 } 43 44 return false 45 } 46 47 func (d *Directory) getBucketPerms(bucket string) perms { 48 res, ok := d.permBuckets.Get(bucket) 49 if ok { 50 return res.(perms) 51 } 52 return perms{} 53 } 54 55 func (d *Directory) HasRole(addr std.Address, role string) bool { 56 return d.HasPerm(addr, "role", role) 57 } 58 59 func (d *Directory) AddUserPerm(addr std.Address, verb, resource string) { 60 bucket := "u:" + addr.String() 61 p := perm{ 62 verbs: []string{verb}, 63 resources: []string{resource}, 64 } 65 d.addPermToBucket(bucket, p) 66 } 67 68 func (d *Directory) AddGroupPerm(name string, verb, resource string) { 69 bucket := "g:" + name 70 p := perm{ 71 verbs: []string{verb}, 72 resources: []string{resource}, 73 } 74 d.addPermToBucket(bucket, p) 75 } 76 77 func (d *Directory) addPermToBucket(bucket string, p perm) { 78 var ps perms 79 80 existing, ok := d.permBuckets.Get(bucket) 81 if ok { 82 ps = existing.(perms) 83 } 84 ps = append(ps, p) 85 86 d.permBuckets.Set(bucket, ps) 87 } 88 89 func (d *Directory) AddUserToGroup(user std.Address, group string) { 90 existing, ok := d.userGroups.Get(user.String()) 91 var groups []string 92 if ok { 93 groups = existing.([]string) 94 } 95 groups = append(groups, group) 96 d.userGroups.Set(user.String(), groups) 97 } 98 99 // TODO: helpers to remove permissions. 100 // TODO: helpers to adds multiple permissions at once -> {verbs: []string{"read","write"}}. 101 // TODO: helpers to delete users from gorups. 102 // TODO: helpers to quickly reset states.