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