c1978265ab
* Auth Wildcard Endpoints * Fix joinkey bug, improve tests * Change joinKey Co-authored-by: Ben Toogood <ben@micro.mu>
75 lines
1.6 KiB
Go
75 lines
1.6 KiB
Go
package store
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"github.com/micro/go-micro/v2/auth"
|
|
"github.com/micro/go-micro/v2/store"
|
|
)
|
|
|
|
// Rule is an access control rule
|
|
type Rule struct {
|
|
Role string `json:"rule"`
|
|
Resource *auth.Resource `json:"resource"`
|
|
}
|
|
|
|
var joinKey = ":"
|
|
|
|
// Key to be used when written to the store
|
|
func (r *Rule) Key() string {
|
|
comps := []string{r.Resource.Type, r.Resource.Name, r.Resource.Endpoint, r.Role}
|
|
return strings.Join(comps, joinKey)
|
|
}
|
|
|
|
// Bytes returns json encoded bytes
|
|
func (r *Rule) Bytes() []byte {
|
|
bytes, _ := json.Marshal(r)
|
|
return bytes
|
|
}
|
|
|
|
// isValidRule returns a bool, indicating if a rule permits access to a
|
|
// resource for a given account
|
|
func isValidRule(rule Rule, acc *auth.Account, res *auth.Resource) bool {
|
|
if rule.Role == "*" {
|
|
return true
|
|
}
|
|
|
|
for _, role := range acc.Roles {
|
|
if rule.Role == role {
|
|
return true
|
|
}
|
|
|
|
// allow user.anything if role is user.*
|
|
if strings.HasSuffix(rule.Role, ".*") && strings.HasPrefix(rule.Role, role+".") {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// listRules gets all the rules from the store which have a key
|
|
// prefix matching the filters
|
|
func (s *Store) listRules(filters ...string) ([]Rule, error) {
|
|
// get the records from the store
|
|
prefix := strings.Join(filters, joinKey)
|
|
recs, err := s.opts.Store.Read(prefix, store.ReadPrefix())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// unmarshal the records
|
|
rules := make([]Rule, 0, len(recs))
|
|
for _, rec := range recs {
|
|
var r Rule
|
|
if err := json.Unmarshal(rec.Value, &r); err != nil {
|
|
return nil, err
|
|
}
|
|
rules = append(rules, r)
|
|
}
|
|
|
|
// return the rules
|
|
return rules, nil
|
|
}
|