6 Star 21 Fork 2

hsluoyz/casbin

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
model_test.go 20.52 KB
一键复制 编辑 原始数据 按行查看 历史
// Copyright 2017 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package casbin
import (
"testing"
"github.com/casbin/casbin/persist/file-adapter"
"github.com/casbin/casbin/rbac"
"github.com/casbin/casbin/rbac/default-role-manager"
"github.com/casbin/casbin/util"
)
func testEnforce(t *testing.T, e *Enforcer, sub string, obj interface{}, act string, res bool) {
t.Helper()
if e.Enforce(sub, obj, act) != res {
t.Errorf("%s, %v, %s: %t, supposed to be %t", sub, obj, act, !res, res)
}
}
func testEnforceWithoutUsers(t *testing.T, e *Enforcer, obj string, act string, res bool) {
t.Helper()
if e.Enforce(obj, act) != res {
t.Errorf("%s, %s: %t, supposed to be %t", obj, act, !res, res)
}
}
func testDomainEnforce(t *testing.T, e *Enforcer, sub string, dom string, obj string, act string, res bool) {
t.Helper()
if e.Enforce(sub, dom, obj, act) != res {
t.Errorf("%s, %s, %s, %s: %t, supposed to be %t", sub, dom, obj, act, !res, res)
}
}
func TestBasicModel(t *testing.T) {
e := NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", false)
testEnforce(t, e, "alice", "data2", "write", false)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
func TestBasicModelNoPolicy(t *testing.T) {
e := NewEnforcer("examples/basic_model.conf")
testEnforce(t, e, "alice", "data1", "read", false)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", false)
testEnforce(t, e, "alice", "data2", "write", false)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", false)
}
func TestBasicModelWithRoot(t *testing.T) {
e := NewEnforcer("examples/basic_with_root_model.conf", "examples/basic_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", false)
testEnforce(t, e, "alice", "data2", "write", false)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
testEnforce(t, e, "root", "data1", "read", true)
testEnforce(t, e, "root", "data1", "write", true)
testEnforce(t, e, "root", "data2", "read", true)
testEnforce(t, e, "root", "data2", "write", true)
}
func TestBasicModelWithRootNoPolicy(t *testing.T) {
e := NewEnforcer("examples/basic_with_root_model.conf")
testEnforce(t, e, "alice", "data1", "read", false)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", false)
testEnforce(t, e, "alice", "data2", "write", false)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", false)
testEnforce(t, e, "root", "data1", "read", true)
testEnforce(t, e, "root", "data1", "write", true)
testEnforce(t, e, "root", "data2", "read", true)
testEnforce(t, e, "root", "data2", "write", true)
}
func TestBasicModelWithoutUsers(t *testing.T) {
e := NewEnforcer("examples/basic_without_users_model.conf", "examples/basic_without_users_policy.csv")
testEnforceWithoutUsers(t, e, "data1", "read", true)
testEnforceWithoutUsers(t, e, "data1", "write", false)
testEnforceWithoutUsers(t, e, "data2", "read", false)
testEnforceWithoutUsers(t, e, "data2", "write", true)
}
func TestBasicModelWithoutResources(t *testing.T) {
e := NewEnforcer("examples/basic_without_resources_model.conf", "examples/basic_without_resources_policy.csv")
testEnforceWithoutUsers(t, e, "alice", "read", true)
testEnforceWithoutUsers(t, e, "alice", "write", false)
testEnforceWithoutUsers(t, e, "bob", "read", false)
testEnforceWithoutUsers(t, e, "bob", "write", true)
}
func TestRBACModel(t *testing.T) {
e := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", true)
testEnforce(t, e, "alice", "data2", "write", true)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
func TestRBACModelWithResourceRoles(t *testing.T) {
e := NewEnforcer("examples/rbac_with_resource_roles_model.conf", "examples/rbac_with_resource_roles_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", true)
testEnforce(t, e, "alice", "data2", "read", false)
testEnforce(t, e, "alice", "data2", "write", true)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
func TestRBACModelWithDomains(t *testing.T) {
e := NewEnforcer("examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv")
testDomainEnforce(t, e, "alice", "domain1", "data1", "read", true)
testDomainEnforce(t, e, "alice", "domain1", "data1", "write", true)
testDomainEnforce(t, e, "alice", "domain1", "data2", "read", false)
testDomainEnforce(t, e, "alice", "domain1", "data2", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "read", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data2", "read", true)
testDomainEnforce(t, e, "bob", "domain2", "data2", "write", true)
}
func TestRBACModelWithDomainsAtRuntime(t *testing.T) {
e := NewEnforcer("examples/rbac_with_domains_model.conf")
e.AddPolicy("admin", "domain1", "data1", "read")
e.AddPolicy("admin", "domain1", "data1", "write")
e.AddPolicy("admin", "domain2", "data2", "read")
e.AddPolicy("admin", "domain2", "data2", "write")
e.AddGroupingPolicy("alice", "admin", "domain1")
e.AddGroupingPolicy("bob", "admin", "domain2")
testDomainEnforce(t, e, "alice", "domain1", "data1", "read", true)
testDomainEnforce(t, e, "alice", "domain1", "data1", "write", true)
testDomainEnforce(t, e, "alice", "domain1", "data2", "read", false)
testDomainEnforce(t, e, "alice", "domain1", "data2", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "read", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data2", "read", true)
testDomainEnforce(t, e, "bob", "domain2", "data2", "write", true)
// Remove all policy rules related to domain1 and data1.
e.RemoveFilteredPolicy(1, "domain1", "data1")
testDomainEnforce(t, e, "alice", "domain1", "data1", "read", false)
testDomainEnforce(t, e, "alice", "domain1", "data1", "write", false)
testDomainEnforce(t, e, "alice", "domain1", "data2", "read", false)
testDomainEnforce(t, e, "alice", "domain1", "data2", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "read", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data2", "read", true)
testDomainEnforce(t, e, "bob", "domain2", "data2", "write", true)
// Remove the specified policy rule.
e.RemovePolicy("admin", "domain2", "data2", "read")
testDomainEnforce(t, e, "alice", "domain1", "data1", "read", false)
testDomainEnforce(t, e, "alice", "domain1", "data1", "write", false)
testDomainEnforce(t, e, "alice", "domain1", "data2", "read", false)
testDomainEnforce(t, e, "alice", "domain1", "data2", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "read", false)
testDomainEnforce(t, e, "bob", "domain2", "data1", "write", false)
testDomainEnforce(t, e, "bob", "domain2", "data2", "read", false)
testDomainEnforce(t, e, "bob", "domain2", "data2", "write", true)
}
func TestRBACModelWithDomainsAtRuntimeMockAdapter(t *testing.T) {
adapter := fileadapter.NewAdapterMock("examples/rbac_with_domains_policy.csv")
e := NewEnforcer("examples/rbac_with_domains_model.conf", adapter)
e.AddPolicy("admin", "domain3", "data1", "read")
e.AddGroupingPolicy("alice", "admin", "domain3")
testDomainEnforce(t, e, "alice", "domain3", "data1", "read", true)
testDomainEnforce(t, e, "alice", "domain1", "data1", "read", true)
e.RemoveFilteredPolicy(1, "domain1", "data1")
testDomainEnforce(t, e, "alice", "domain1", "data1", "read", false)
testDomainEnforce(t, e, "bob", "domain2", "data2", "read", true)
e.RemovePolicy("admin", "domain2", "data2", "read")
testDomainEnforce(t, e, "bob", "domain2", "data2", "read", false)
}
func TestRBACModelWithDeny(t *testing.T) {
e := NewEnforcer("examples/rbac_with_deny_model.conf", "examples/rbac_with_deny_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", true)
testEnforce(t, e, "alice", "data2", "write", false)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
func TestRBACModelWithOnlyDeny(t *testing.T) {
e := NewEnforcer("examples/rbac_with_not_deny_model.conf", "examples/rbac_with_deny_policy.csv")
testEnforce(t, e, "alice", "data2", "write", false)
}
func TestRBACModelWithCustomData(t *testing.T) {
e := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
// You can add custom data to a grouping policy, Casbin will ignore it. It is only meaningful to the caller.
// This feature can be used to store information like whether "bob" is an end user (so no subject will inherit "bob")
// For Casbin, it is equivalent to: e.AddGroupingPolicy("bob", "data2_admin")
e.AddGroupingPolicy("bob", "data2_admin", "custom_data")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", true)
testEnforce(t, e, "alice", "data2", "write", true)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", true)
testEnforce(t, e, "bob", "data2", "write", true)
// You should also take the custom data as a parameter when deleting a grouping policy.
// e.RemoveGroupingPolicy("bob", "data2_admin") won't work.
// Or you can remove it by using RemoveFilteredGroupingPolicy().
e.RemoveGroupingPolicy("bob", "data2_admin", "custom_data")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", true)
testEnforce(t, e, "alice", "data2", "write", true)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
func TestRBACModelWithPattern(t *testing.T) {
e := NewEnforcer("examples/rbac_with_pattern_model.conf", "examples/rbac_with_pattern_policy.csv")
// Here's a little confusing: the matching function here is not the custom function used in matcher.
// It is the matching function used by "g" (and "g2", "g3" if any..)
// You can see in policy that: "g2, /book/:id, book_group", so in "g2()" function in the matcher, instead
// of checking whether "/book/:id" equals the obj: "/book/1", it checks whether the pattern matches.
// You can see it as normal RBAC: "/book/:id" == "/book/1" becomes KeyMatch2("/book/:id", "/book/1")
e.rm.(*defaultrolemanager.RoleManager).AddMatchingFunc("KeyMatch2", util.KeyMatch2)
testEnforce(t, e, "alice", "/book/1", "GET", true)
testEnforce(t, e, "alice", "/book/2", "GET", true)
testEnforce(t, e, "alice", "/pen/1", "GET", true)
testEnforce(t, e, "alice", "/pen/2", "GET", false)
testEnforce(t, e, "bob", "/book/1", "GET", false)
testEnforce(t, e, "bob", "/book/2", "GET", false)
testEnforce(t, e, "bob", "/pen/1", "GET", true)
testEnforce(t, e, "bob", "/pen/2", "GET", true)
// AddMatchingFunc() is actually setting a function because only one function is allowed,
// so when we set "KeyMatch3", we are actually replacing "KeyMatch2" with "KeyMatch3".
e.rm.(*defaultrolemanager.RoleManager).AddMatchingFunc("KeyMatch3", util.KeyMatch3)
testEnforce(t, e, "alice", "/book2/1", "GET", true)
testEnforce(t, e, "alice", "/book2/2", "GET", true)
testEnforce(t, e, "alice", "/pen2/1", "GET", true)
testEnforce(t, e, "alice", "/pen2/2", "GET", false)
testEnforce(t, e, "bob", "/book2/1", "GET", false)
testEnforce(t, e, "bob", "/book2/2", "GET", false)
testEnforce(t, e, "bob", "/pen2/1", "GET", true)
testEnforce(t, e, "bob", "/pen2/2", "GET", true)
}
type testCustomRoleManager struct{}
func NewRoleManager() rbac.RoleManager {
return &testCustomRoleManager{}
}
func (rm *testCustomRoleManager) Clear() error { return nil }
func (rm *testCustomRoleManager) AddLink(name1 string, name2 string, domain ...string) error {
return nil
}
func (rm *testCustomRoleManager) DeleteLink(name1 string, name2 string, domain ...string) error {
return nil
}
func (rm *testCustomRoleManager) HasLink(name1 string, name2 string, domain ...string) (bool, error) {
if name1 == "alice" && name2 == "alice" {
return true, nil
} else if name1 == "alice" && name2 == "data2_admin" {
return true, nil
} else if name1 == "bob" && name2 == "bob" {
return true, nil
}
return false, nil
}
func (rm *testCustomRoleManager) GetRoles(name string, domain ...string) ([]string, error) {
return []string{}, nil
}
func (rm *testCustomRoleManager) GetUsers(name string, domain ...string) ([]string, error) {
return []string{}, nil
}
func (rm *testCustomRoleManager) PrintRoles() error { return nil }
func TestRBACModelWithCustomRoleManager(t *testing.T) {
e := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
e.SetRoleManager(NewRoleManager())
e.LoadModel()
_ = e.LoadPolicy()
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", true)
testEnforce(t, e, "alice", "data2", "write", true)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
type testResource struct {
Name string
Owner string
}
func newTestResource(name string, owner string) testResource {
r := testResource{}
r.Name = name
r.Owner = owner
return r
}
func TestABACModel(t *testing.T) {
e := NewEnforcer("examples/abac_model.conf")
data1 := newTestResource("data1", "alice")
data2 := newTestResource("data2", "bob")
testEnforce(t, e, "alice", data1, "read", true)
testEnforce(t, e, "alice", data1, "write", true)
testEnforce(t, e, "alice", data2, "read", false)
testEnforce(t, e, "alice", data2, "write", false)
testEnforce(t, e, "bob", data1, "read", false)
testEnforce(t, e, "bob", data1, "write", false)
testEnforce(t, e, "bob", data2, "read", true)
testEnforce(t, e, "bob", data2, "write", true)
}
func TestKeyMatchModel(t *testing.T) {
e := NewEnforcer("examples/keymatch_model.conf", "examples/keymatch_policy.csv")
testEnforce(t, e, "alice", "/alice_data/resource1", "GET", true)
testEnforce(t, e, "alice", "/alice_data/resource1", "POST", true)
testEnforce(t, e, "alice", "/alice_data/resource2", "GET", true)
testEnforce(t, e, "alice", "/alice_data/resource2", "POST", false)
testEnforce(t, e, "alice", "/bob_data/resource1", "GET", false)
testEnforce(t, e, "alice", "/bob_data/resource1", "POST", false)
testEnforce(t, e, "alice", "/bob_data/resource2", "GET", false)
testEnforce(t, e, "alice", "/bob_data/resource2", "POST", false)
testEnforce(t, e, "bob", "/alice_data/resource1", "GET", false)
testEnforce(t, e, "bob", "/alice_data/resource1", "POST", false)
testEnforce(t, e, "bob", "/alice_data/resource2", "GET", true)
testEnforce(t, e, "bob", "/alice_data/resource2", "POST", false)
testEnforce(t, e, "bob", "/bob_data/resource1", "GET", false)
testEnforce(t, e, "bob", "/bob_data/resource1", "POST", true)
testEnforce(t, e, "bob", "/bob_data/resource2", "GET", false)
testEnforce(t, e, "bob", "/bob_data/resource2", "POST", true)
testEnforce(t, e, "cathy", "/cathy_data", "GET", true)
testEnforce(t, e, "cathy", "/cathy_data", "POST", true)
testEnforce(t, e, "cathy", "/cathy_data", "DELETE", false)
}
func TestKeyMatch2Model(t *testing.T) {
e := NewEnforcer("examples/keymatch2_model.conf", "examples/keymatch2_policy.csv")
testEnforce(t, e, "alice", "/alice_data", "GET", false)
testEnforce(t, e, "alice", "/alice_data/resource1", "GET", true)
testEnforce(t, e, "alice", "/alice_data2/myid", "GET", false)
testEnforce(t, e, "alice", "/alice_data2/myid/using/res_id", "GET", true)
}
func CustomFunction(key1 string, key2 string) bool {
if key1 == "/alice_data2/myid/using/res_id" && key2 == "/alice_data/:resource" {
return true
} else if key1 == "/alice_data2/myid/using/res_id" && key2 == "/alice_data2/:id/using/:resId" {
return true
} else {
return false
}
}
func CustomFunctionWrapper(args ...interface{}) (interface{}, error) {
key1 := args[0].(string)
key2 := args[1].(string)
return bool(CustomFunction(key1, key2)), nil
}
func TestKeyMatchCustomModel(t *testing.T) {
e := NewEnforcer("examples/keymatch_custom_model.conf", "examples/keymatch2_policy.csv")
e.AddFunction("keyMatchCustom", CustomFunctionWrapper)
testEnforce(t, e, "alice", "/alice_data2/myid", "GET", false)
testEnforce(t, e, "alice", "/alice_data2/myid/using/res_id", "GET", true)
}
func TestIPMatchModel(t *testing.T) {
e := NewEnforcer("examples/ipmatch_model.conf", "examples/ipmatch_policy.csv")
testEnforce(t, e, "192.168.2.123", "data1", "read", true)
testEnforce(t, e, "192.168.2.123", "data1", "write", false)
testEnforce(t, e, "192.168.2.123", "data2", "read", false)
testEnforce(t, e, "192.168.2.123", "data2", "write", false)
testEnforce(t, e, "192.168.0.123", "data1", "read", false)
testEnforce(t, e, "192.168.0.123", "data1", "write", false)
testEnforce(t, e, "192.168.0.123", "data2", "read", false)
testEnforce(t, e, "192.168.0.123", "data2", "write", false)
testEnforce(t, e, "10.0.0.5", "data1", "read", false)
testEnforce(t, e, "10.0.0.5", "data1", "write", false)
testEnforce(t, e, "10.0.0.5", "data2", "read", false)
testEnforce(t, e, "10.0.0.5", "data2", "write", true)
testEnforce(t, e, "192.168.0.1", "data1", "read", false)
testEnforce(t, e, "192.168.0.1", "data1", "write", false)
testEnforce(t, e, "192.168.0.1", "data2", "read", false)
testEnforce(t, e, "192.168.0.1", "data2", "write", false)
}
func TestPriorityModel(t *testing.T) {
e := NewEnforcer("examples/priority_model.conf", "examples/priority_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", false)
testEnforce(t, e, "alice", "data2", "write", false)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", true)
testEnforce(t, e, "bob", "data2", "write", false)
}
func TestPriorityModelIndeterminate(t *testing.T) {
e := NewEnforcer("examples/priority_model.conf", "examples/priority_indeterminate_policy.csv")
testEnforce(t, e, "alice", "data1", "read", false)
}
func TestRBACModelInMultiLines(t *testing.T) {
e := NewEnforcer("examples/rbac_model_in_multi_line.conf", "examples/rbac_policy.csv")
testEnforce(t, e, "alice", "data1", "read", true)
testEnforce(t, e, "alice", "data1", "write", false)
testEnforce(t, e, "alice", "data2", "read", true)
testEnforce(t, e, "alice", "data2", "write", true)
testEnforce(t, e, "bob", "data1", "read", false)
testEnforce(t, e, "bob", "data1", "write", false)
testEnforce(t, e, "bob", "data2", "read", false)
testEnforce(t, e, "bob", "data2", "write", true)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/hsluoyz/casbin.git
git@gitee.com:hsluoyz/casbin.git
hsluoyz
casbin
casbin
master

搜索帮助