// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you 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 ( "encoding/json" "fmt" "testing" "github.com/casbin/casbin/v3/util" ) 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 TestABACMapRequest(t *testing.T) { e, _ := NewEnforcer("examples/abac_model.conf") data1 := map[string]interface{}{ "Name": "data1", "Owner": "alice", } data2 := map[string]interface{}{ "Name": "data2", "Owner": "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 TestABACTypes(t *testing.T) { e, _ := NewEnforcer("examples/abac_model.conf") matcher := `"moderator" IN r.sub.Roles && r.sub.Enabled == true && r.sub.Age >= 21 && r.sub.Name != "foo"` e.GetModel()["m"]["m"].Value = util.RemoveComments(util.EscapeAssertion(matcher)) structRequest := struct { Roles []interface{} Enabled bool Age int Name string }{ Roles: []interface{}{"user", "moderator"}, Enabled: true, Age: 30, Name: "alice", } testEnforce(t, e, structRequest, "", "", true) mapRequest := map[string]interface{}{ "Roles": []interface{}{"user", "moderator"}, "Enabled": true, "Age": 30, "Name": "alice", } testEnforce(t, e, mapRequest, nil, "", true) e.EnableAcceptJsonRequest(true) jsonRequest, _ := json.Marshal(mapRequest) testEnforce(t, e, string(jsonRequest), "", "", true) } func TestABACJsonRequest(t *testing.T) { e, _ := NewEnforcer("examples/abac_model.conf") e.EnableAcceptJsonRequest(true) data1Json := `{ "Name": "data1", "Owner": "alice"}` data2Json := `{ "Name": "data2", "Owner": "bob"}` testEnforce(t, e, "alice", data1Json, "read", true) testEnforce(t, e, "alice", data1Json, "write", true) testEnforce(t, e, "alice", data2Json, "read", false) testEnforce(t, e, "alice", data2Json, "write", false) testEnforce(t, e, "bob", data1Json, "read", false) testEnforce(t, e, "bob", data1Json, "write", false) testEnforce(t, e, "bob", data2Json, "read", true) testEnforce(t, e, "bob", data2Json, "write", true) e, _ = NewEnforcer("examples/abac_not_using_policy_model.conf", "examples/abac_rule_effect_policy.csv") e.EnableAcceptJsonRequest(true) testEnforce(t, e, "alice", data1Json, "read", true) testEnforce(t, e, "alice", data1Json, "write", true) testEnforce(t, e, "alice", data2Json, "read", false) testEnforce(t, e, "alice", data2Json, "write", false) e, _ = NewEnforcer("examples/abac_rule_model.conf", "examples/abac_rule_policy.csv") e.EnableAcceptJsonRequest(true) sub1Json := `{"Name": "alice", "Age": 16}` sub2Json := `{"Name": "alice", "Age": 20}` sub3Json := `{"Name": "alice", "Age": 65}` testEnforce(t, e, sub1Json, "/data1", "read", false) testEnforce(t, e, sub1Json, "/data2", "read", false) testEnforce(t, e, sub1Json, "/data1", "write", false) testEnforce(t, e, sub1Json, "/data2", "write", true) testEnforce(t, e, sub2Json, "/data1", "read", true) testEnforce(t, e, sub2Json, "/data2", "read", false) testEnforce(t, e, sub2Json, "/data1", "write", false) testEnforce(t, e, sub2Json, "/data2", "write", true) testEnforce(t, e, sub3Json, "/data1", "read", true) testEnforce(t, e, sub3Json, "/data2", "read", false) testEnforce(t, e, sub3Json, "/data1", "write", false) testEnforce(t, e, sub3Json, "/data2", "write", false) } type testSub struct { Name string Age int } func newTestSubject(name string, age int) testSub { s := testSub{} s.Name = name s.Age = age return s } func TestABACNotUsingPolicy(t *testing.T) { e, _ := NewEnforcer("examples/abac_not_using_policy_model.conf", "examples/abac_rule_effect_policy.csv") 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) } func TestABACPolicy(t *testing.T) { e, _ := NewEnforcer("examples/abac_rule_model.conf", "examples/abac_rule_policy.csv") m := e.GetModel() for sec, ast := range m { fmt.Println(sec) for ptype, p := range ast { fmt.Println(ptype, p) } } sub1 := newTestSubject("alice", 16) sub2 := newTestSubject("alice", 20) sub3 := newTestSubject("alice", 65) testEnforce(t, e, sub1, "/data1", "read", false) testEnforce(t, e, sub1, "/data2", "read", false) testEnforce(t, e, sub1, "/data1", "write", false) testEnforce(t, e, sub1, "/data2", "write", true) testEnforce(t, e, sub2, "/data1", "read", true) testEnforce(t, e, sub2, "/data2", "read", false) testEnforce(t, e, sub2, "/data1", "write", false) testEnforce(t, e, sub2, "/data2", "write", true) testEnforce(t, e, sub3, "/data1", "read", true) testEnforce(t, e, sub3, "/data2", "read", false) testEnforce(t, e, sub3, "/data1", "write", false) testEnforce(t, e, sub3, "/data2", "write", false) }