Fix RBAC rule filtering
This commit is contained in:
@@ -60,23 +60,23 @@ func (set RuleSet) FilterAccess(a Access) (out RuleSet) {
|
||||
return out
|
||||
}
|
||||
|
||||
// FilterResource returns rules that match given list of resources
|
||||
// Wildcards are not used!
|
||||
//
|
||||
// Note that empty resource list will return ALL rules!
|
||||
func (set RuleSet) FilterResource(rr ...Resource) (out RuleSet) {
|
||||
var (
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
)
|
||||
if len(rr) == 0 {
|
||||
return set
|
||||
}
|
||||
|
||||
for _, res := range rr {
|
||||
for _, rule := range set {
|
||||
if !matchResource(res.RbacResource(), rule.Resource) {
|
||||
out = RuleSet{}
|
||||
for _, rule := range set {
|
||||
for _, res := range rr {
|
||||
if res.RbacResource() != rule.Resource {
|
||||
continue
|
||||
}
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
|
||||
out = append(out, rule)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,3 +38,17 @@ func TestRuleSetSort(t *testing.T) {
|
||||
req.Equal(":::/1/*/*", rr[i()].Resource)
|
||||
req.Equal(":::/*/*/*", rr[i()].Resource)
|
||||
}
|
||||
|
||||
func TestRuleSet_FilterResource(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
rr = RuleSet{
|
||||
{Resource: ":::/*/*/*"},
|
||||
{Resource: ":::/1/2/3"},
|
||||
}
|
||||
)
|
||||
|
||||
req.Len(rr.FilterResource(NewResource(":::/1/2/3")), 1)
|
||||
req.Len(rr.FilterResource(NewResource(":::/*/*/*")), 1)
|
||||
req.Len(rr.FilterResource(NewResource(":::/*")), 0)
|
||||
}
|
||||
|
||||
@@ -69,28 +69,28 @@ func TestPermissionsReadWithFilter(t *testing.T) {
|
||||
helpers.AllowMe(h, types.UserRbacResource(testID), "read")
|
||||
helpers.AllowMe(h, types.UserRbacResource(id.Next()), "update")
|
||||
|
||||
// all rules
|
||||
t.Log("all component-level and wildcard rules")
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response`, 4)).
|
||||
End()
|
||||
|
||||
// Resource related rules
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("resource", "corteza::system:user/*").
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response`, 2)).
|
||||
End()
|
||||
|
||||
// Only specific resource rules with `specific: 2` filter
|
||||
t.Log("no rules for all-users")
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("resource", "corteza::system:user/*").
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response`, 0)).
|
||||
End()
|
||||
|
||||
t.Log("1 rule for specific user")
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("resource", fmt.Sprintf("corteza::system:user/%d", testID)).
|
||||
|
||||
Reference in New Issue
Block a user