acl.gno
2.13 Kb ยท 102 lines
1package acl
2
3import (
4 "std"
5
6 "gno.land/p/demo/avl"
7)
8
9func New() *Directory {
10 return &Directory{
11 userGroups: avl.Tree{},
12 permBuckets: avl.Tree{},
13 }
14}
15
16type Directory struct {
17 permBuckets avl.Tree // identifier -> perms
18 userGroups avl.Tree // std.Address -> []string
19}
20
21func (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
47func (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
55func (d *Directory) HasRole(addr std.Address, role string) bool {
56 return d.HasPerm(addr, "role", role)
57}
58
59func (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
68func (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
77func (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
89func (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.