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.