Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions enforcer_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,14 @@ type IEnforcer interface {
GetFilteredPolicy(fieldIndex int, fieldValues ...string) ([][]string, error)
GetNamedPolicy(ptype string) ([][]string, error)
GetFilteredNamedPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error)
GetStrictFilteredPolicy(fieldIndex int, fieldValues ...string) ([][]string, error)
GetStrictFilteredNamedPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error)
GetGroupingPolicy() ([][]string, error)
GetFilteredGroupingPolicy(fieldIndex int, fieldValues ...string) ([][]string, error)
GetNamedGroupingPolicy(ptype string) ([][]string, error)
GetFilteredNamedGroupingPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error)
GetStrictFilteredGroupingPolicy(fieldIndex int, fieldValues ...string) ([][]string, error)
GetStrictFilteredNamedGroupingPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error)
HasPolicy(params ...interface{}) (bool, error)
HasNamedPolicy(ptype string, params ...interface{}) (bool, error)
AddPolicy(params ...interface{}) (bool, error)
Expand Down
36 changes: 36 additions & 0 deletions enforcer_synced.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,24 @@ func (e *SyncedEnforcer) GetFilteredNamedPolicy(ptype string, fieldIndex int, fi
return e.Enforcer.GetFilteredNamedPolicy(ptype, fieldIndex, fieldValues...)
}

// GetStrictFilteredPolicy gets all the authorization rules in the policy, field filters can be specified.
// In contrast to GetFilteredPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *SyncedEnforcer) GetStrictFilteredPolicy(fieldIndex int, fieldValues ...string) ([][]string, error) {
e.m.RLock()
defer e.m.RUnlock()
return e.Enforcer.GetStrictFilteredPolicy(fieldIndex, fieldValues...)
}

// GetStrictFilteredNamedPolicy gets all the authorization rules in the named policy, field filters can be specified.
// In contrast to GetFilteredNamedPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *SyncedEnforcer) GetStrictFilteredNamedPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error) {
e.m.RLock()
defer e.m.RUnlock()
return e.Enforcer.GetStrictFilteredNamedPolicy(ptype, fieldIndex, fieldValues...)
}

// GetGroupingPolicy gets all the role inheritance rules in the policy.
func (e *SyncedEnforcer) GetGroupingPolicy() ([][]string, error) {
e.m.RLock()
Expand Down Expand Up @@ -348,6 +366,24 @@ func (e *SyncedEnforcer) GetFilteredNamedGroupingPolicy(ptype string, fieldIndex
return e.Enforcer.GetFilteredNamedGroupingPolicy(ptype, fieldIndex, fieldValues...)
}

// GetStrictFilteredGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.
// In contrast to GetFilteredGroupingPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *SyncedEnforcer) GetStrictFilteredGroupingPolicy(fieldIndex int, fieldValues ...string) ([][]string, error) {
e.m.RLock()
defer e.m.RUnlock()
return e.Enforcer.GetStrictFilteredGroupingPolicy(fieldIndex, fieldValues...)
}

// GetStrictFilteredNamedGroupingPolicy gets all the role inheritance rules in the named policy, field filters can be specified.
// In contrast to GetFilteredNamedGroupingPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *SyncedEnforcer) GetStrictFilteredNamedGroupingPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error) {
e.m.RLock()
defer e.m.RUnlock()
return e.Enforcer.GetStrictFilteredNamedGroupingPolicy(ptype, fieldIndex, fieldValues...)
}

// HasPolicy determines whether an authorization rule exists.
func (e *SyncedEnforcer) HasPolicy(params ...interface{}) (bool, error) {
e.m.RLock()
Expand Down
28 changes: 28 additions & 0 deletions management_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ func (e *Enforcer) GetFilteredNamedPolicy(ptype string, fieldIndex int, fieldVal
return e.model.GetFilteredPolicy("p", ptype, fieldIndex, fieldValues...)
}

// GetStrictFilteredPolicy gets all the authorization rules in the policy, field filters can be specified.
// In contrast to GetFilteredPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *Enforcer) GetStrictFilteredPolicy(fieldIndex int, fieldValues ...string) ([][]string, error) {
return e.GetStrictFilteredNamedPolicy("p", fieldIndex, fieldValues...)
}

// GetStrictFilteredNamedPolicy gets all the authorization rules in the named policy, field filters can be specified.
// In contrast to GetFilteredNamedPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *Enforcer) GetStrictFilteredNamedPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error) {
return e.model.GetStrictFilteredPolicy("p", ptype, fieldIndex, fieldValues...)
}

// GetGroupingPolicy gets all the role inheritance rules in the policy.
func (e *Enforcer) GetGroupingPolicy() ([][]string, error) {
return e.GetNamedGroupingPolicy("g")
Expand All @@ -133,6 +147,20 @@ func (e *Enforcer) GetFilteredNamedGroupingPolicy(ptype string, fieldIndex int,
return e.model.GetFilteredPolicy("g", ptype, fieldIndex, fieldValues...)
}

// GetStrictFilteredGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.
// In contrast to GetFilteredGroupingPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *Enforcer) GetStrictFilteredGroupingPolicy(fieldIndex int, fieldValues ...string) ([][]string, error) {
return e.GetStrictFilteredNamedGroupingPolicy("g", fieldIndex, fieldValues...)
}

// GetStrictFilteredNamedGroupingPolicy gets all the role inheritance rules in the named policy, field filters can be specified.
// In contrast to GetFilteredNamedGroupingPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (e *Enforcer) GetStrictFilteredNamedGroupingPolicy(ptype string, fieldIndex int, fieldValues ...string) ([][]string, error) {
return e.model.GetStrictFilteredPolicy("g", ptype, fieldIndex, fieldValues...)
}

// GetFilteredNamedPolicyWithMatcher gets rules based on matcher from the policy.
func (e *Enforcer) GetFilteredNamedPolicyWithMatcher(ptype string, matcher string) ([][]string, error) {
var res [][]string
Expand Down
45 changes: 45 additions & 0 deletions management_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,51 @@ func TestGetPolicyAPI(t *testing.T) {
testHasGroupingPolicy(t, e, []string{"bob", "data2_admin"}, false)
}

func TestGetStrictFilteredPolicyAPI(t *testing.T) {
e, _ := NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")

// Add a policy with an empty string field to test strict matching.
_, _ = e.AddPolicy("", "data1", "read")

// "*" acts as wildcard - matches any value in the field.
myRes, err := e.GetStrictFilteredPolicy(0, "*")
if err != nil {
t.Error(err)
}
// All rules (alice and the empty-subject rule) should be returned.
if len(myRes) != 3 {
t.Errorf("Expected 3 rules with wildcard, got %d: %v", len(myRes), myRes)
}

// "" matches only rules where the subject is literally an empty string.
myRes, err = e.GetStrictFilteredPolicy(0, "")
if err != nil {
t.Error(err)
}
if len(myRes) != 1 || myRes[0][0] != "" {
t.Errorf("Expected 1 rule with empty subject, got %d: %v", len(myRes), myRes)
}

// "alice" matches only the alice rule.
myRes, err = e.GetStrictFilteredPolicy(0, "alice")
if err != nil {
t.Error(err)
}
if len(myRes) != 1 || myRes[0][0] != "alice" {
t.Errorf("Expected 1 rule for alice, got %d: %v", len(myRes), myRes)
}

// Mix: "*" wildcard for subject, specific action.
myRes, err = e.GetStrictFilteredPolicy(0, "*", "data1", "read")
if err != nil {
t.Error(err)
}
// Both alice->data1->read and ""->data1->read should match.
if len(myRes) != 2 {
t.Errorf("Expected 2 rules, got %d: %v", len(myRes), myRes)
}
}

func TestModifyPolicyAPI(t *testing.T) {
e, _ := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")

Expand Down
31 changes: 31 additions & 0 deletions model/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,37 @@ func (model Model) GetFilteredPolicy(sec string, ptype string, fieldIndex int, f
return res, nil
}

// GetStrictFilteredPolicy gets rules based on field filters from a policy.
// In contrast to GetFilteredPolicy, "" (empty string) is treated as a literal empty string match,
// and "*" is treated as a wildcard that matches any value.
func (model Model) GetStrictFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) ([][]string, error) {
_, err := model.GetAssertion(sec, ptype)
if err != nil {
return nil, err
}
res := [][]string{}

for _, rule := range model[sec][ptype].Policy {
matched := true
for i, fieldValue := range fieldValues {
if fieldIndex+i >= len(rule) {
matched = false
break
}
if fieldValue != "*" && rule[fieldIndex+i] != fieldValue {
matched = false
break
}
}

if matched {
res = append(res, rule)
}
}

return res, nil
}

// HasPolicyEx determines whether a model has the specified policy rule with error.
func (model Model) HasPolicyEx(sec string, ptype string, rule []string) (bool, error) {
assertion, err := model.GetAssertion(sec, ptype)
Expand Down
Loading