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.