Skip to content

Commit

Permalink
Merge dc8e359 into 4a15756
Browse files Browse the repository at this point in the history
  • Loading branch information
rushitote committed Jun 1, 2021
2 parents 4a15756 + dc8e359 commit 89894dd
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Setup-OpenResty.md
Expand Up @@ -59,7 +59,7 @@ Since the project isn't a LuaRocks/OPM module yet, you need to clone it to use i
**NOTE**: You may need to add the `nginx` command to your path by adding `export PATH="/usr/local/openresty/nginx/sbin/:$PATH"` to your `.bashrc` or similar file.
You can create a lua module for OpenResty applications as shown [here](https://blog.openresty.com/en/or-lua-module/) or add it to your existing lua module by following these steps:

- In your module, clone the Lua Casbin repo at the top level (`/`) of your application (along with the `conf` director) with `git clone https://github.com/casbin/lua-casbin.git`.
- In your module, clone the Lua Casbin repo at the top level (`/`) of your application (along with the `conf` directory) with `git clone https://github.com/casbin/lua-casbin.git`.
- In your module's `conf/nginx.conf` file append the `lua_package_path` with `$prefix/lua-casbin/?.lua;` so that it becomes something like this: `lua_package_path "$prefix/lua/?.lua;$prefix/lua-casbin/?.lua;;";`.
- In the file where you want to use Casbin, use `local Enforcer = require("src/main/Enforcer")` inside the `content_by_lua_block`. Here is a sample describing usage for basic model/policy and ABAC model/policy:

Expand Down
4 changes: 2 additions & 2 deletions src/main/Enforcer.lua
Expand Up @@ -12,9 +12,9 @@
--See the License for the specific language governing permissions and
--limitations under the License.

require("src.main.CoreEnforcer")
require("src.main.InternalEnforcer")

Enforcer = {}
setmetatable(Enforcer, CoreEnforcer)
setmetatable(Enforcer, InternalEnforcer)

return Enforcer
66 changes: 36 additions & 30 deletions src/main/InternalEnforcer.lua
Expand Up @@ -34,8 +34,9 @@ function InternalEnforcer:addPolicy(sec, ptype, rule)
if self.adapter and self.autoSave then

local status, err = pcall(function () self.adapter:addPolicy(sec, ptype, rule) end)
if status == false then
Util.logPrintf("method not implemented or "..err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end
Expand All @@ -49,7 +50,7 @@ function InternalEnforcer:addPolicy(sec, ptype, rule)
end

return true
--TODO: update watcher
--TODO: update watcher, add logger
end

--[[
Expand All @@ -67,8 +68,9 @@ function InternalEnforcer:addPolicies(sec, ptype, rules)
self.adapter:addPolicies(sec, ptype, rules)
end
end)
if status == false then
Util.logPrintf("method not implemented or "..err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end
Expand All @@ -80,7 +82,7 @@ function InternalEnforcer:addPolicies(sec, ptype, rules)
end

return true
--TODO: update watcher
--TODO: update watcher, add logger
end

--[[
Expand All @@ -90,7 +92,7 @@ end
* @param rules the rules.
]]
function InternalEnforcer:buildIncrementalRoleLinks(op, ptype, rules)
self.model:buildIncrementalRoleLinks(self.rm, op, "g", ptype, rules)
self.model:buildIncrementalRoleLinks(self.rmMap[ptype], op, "g", ptype, rules)
end

--[[
Expand All @@ -100,8 +102,9 @@ function InternalEnforcer:removePolicy(sec, ptype, rule)
if self.adapter and self.autoSave then

local status, err = pcall(function () self.adapter:removePolicy(sec, ptype, rule) end)
if status == false then
Util.logPrintf("method not implemented or "..err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end
Expand All @@ -119,7 +122,7 @@ function InternalEnforcer:removePolicy(sec, ptype, rule)
end

return true
-- TODO: update watcher
-- TODO: update watcher, add logger
end

--[[
Expand All @@ -132,12 +135,13 @@ end
]]
function InternalEnforcer:updatePolicy(sec, ptype, oldRule, newRule)
-- TODO: update dispatcher

if self.adapter and self.autoSave then

local status, err = pcall(function () self.adapter:updatePolicy(sec, ptype, oldRule, newRule) end)
if status == false then
Util.logPrintf("method not implemented or "..err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end
Expand All @@ -154,8 +158,9 @@ function InternalEnforcer:updatePolicy(sec, ptype, oldRule, newRule)
table.insert(oldRules, oldRule)
self:buildIncrementalRoleLinks(self.model.PolicyOperations.POLICY_REMOVE, ptype, oldRules)
end)
if status == false then
Util.logPrintf(err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end

Expand All @@ -164,21 +169,22 @@ function InternalEnforcer:updatePolicy(sec, ptype, oldRule, newRule)
table.insert(newRules, newRule)
self:buildIncrementalRoleLinks(self.model.PolicyOperations.POLICY_ADD, ptype, newRules)
end)
if status == false then
Util.logPrintf(err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end

return true
-- TODO: update watcher
-- TODO: update watcher, add logger
end

--[[
* removePolicies removes rules from the current policy.
]]
function InternalEnforcer:removePolicies(sec, ptype, rules)
if self.model:hasPolicies(sec, ptype, rules) then
if not self.model:hasPolicies(sec, ptype, rules) then
return false
end

Expand All @@ -189,8 +195,9 @@ function InternalEnforcer:removePolicies(sec, ptype, rules)
self.adapter:removePolicies(sec, ptype, rules)
end
end)
if status == false then
Util.logPrintf("method not implemented or "..err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end
Expand All @@ -206,38 +213,37 @@ function InternalEnforcer:removePolicies(sec, ptype, rules)
end

return true
-- TODO: update watcher
-- TODO: update watcher, add logger
end

--[[
* removeFilteredPolicy removes rules based on field filters from the current policy.
]]
function InternalEnforcer:removeFilteredPolicy(sec, ptype, fieldIndex, fieldValues)
if fieldValues == nil or #fieldValues == 0 then
Util.logPrintf("Invaild fieldValues parameter")
return false
end

if self.adapter and self.autoSave then

local status, err = pcall(function () self.adapter:removeFilteredPolicy(sec, ptype, fieldIndex, fieldValues) end)
if status == false then
Util.logPrintf("method not implemented or "..err)
if status == false and string.sub(err, -15) == "not implemented" then
-- log, continue
elseif status == false then
return false
end
end

local effects = self.model:removeFilteredPolicyReturnsEffects(sec, ptype, fieldIndex, fieldValues)
local ruleRemoved = #effects > 0
local isRuleRemoved, effects = self.model:removeFilteredPolicy(sec, ptype, fieldIndex, fieldValues)

if not ruleRemoved then
if not isRuleRemoved then
return false
end

if sec == "g" then
self:buildIncrementalRoleLinks(self.model.PolicyOperations.POLICY_ADD, ptype, effects)
self:buildIncrementalRoleLinks(self.model.PolicyOperations.POLICY_REMOVE, ptype, effects)
end

return true
-- TODO: update watcher
-- TODO: update watcher, add logger
end
8 changes: 5 additions & 3 deletions src/model/Policy.lua
Expand Up @@ -222,6 +222,7 @@ function Policy:updatePolicy(sec, ptype, oldRule, newRule)
if Util.arrayEquals(oldRule, v) then
table.remove(self.model[sec][ptype].policy, k)
table.insert(self.model[sec][ptype].policy, newRule)
return true
end
end
end
Expand Down Expand Up @@ -305,10 +306,10 @@ end
* means not to match this field.
* @return succeeds or not.
]]
function Policy:removeFilteredPolicy(sec, ptype, fieldIndex, ...)
function Policy:removeFilteredPolicy(sec, ptype, fieldIndex, fieldValues)
local tmp = {}
local res = false
local fieldValues = {...}
local effects = {}

if not self.model[sec] then return res end
if not self.model[sec][ptype] then return res end
Expand All @@ -323,14 +324,15 @@ function Policy:removeFilteredPolicy(sec, ptype, fieldIndex, ...)
end

if matched then
table.insert(effects, rule)
res = true
else
table.insert(tmp, rule)
end
end

self.model[sec][ptype].policy = tmp
return res
return res, effects
end

--[[
Expand Down
7 changes: 7 additions & 0 deletions src/persist/file_adapter/FileAdapter.lua
Expand Up @@ -97,6 +97,13 @@ function FileAdapter:removePolicy(sec, ptype, rule)
error("not implemented")
end

--[[
* updatePolicy updates a policy rule from the storage
]]
function FileAdapter:updatePolicy(sec, ptype, oldRule, newRule)
error("not implemented")
end

--[[
* removeFilteredPolicy removes policy rules that match the filter from the storage.
]]
Expand Down
128 changes: 128 additions & 0 deletions tests/main/internal_api_spec.lua
@@ -0,0 +1,128 @@
--Copyright 2021 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.

local enforcer_module = require("src.main.Enforcer")
local path = os.getenv("PWD") or io.popen("cd"):read()

describe("Internal API tests", function ()
it("Add Policy test", function ()
local model = path .. "/examples/rbac_model.conf"
local policy = path .. "/examples/rbac_policy.csv"

local e = Enforcer:new(model, policy)

assert.is.False(e:enforce("alice", "data1", "write"))
e:addPolicy("p", "p", {"alice", "data1", "write"})
assert.is.True(e:enforce("alice", "data1", "write"))

assert.is.False(e:enforce("bob", "data2", "read"))
e:addPolicy("g", "g", {"bob", "data2_admin"})
assert.is.True(e:enforce("bob", "data2", "read"))
end)

it("Remove Policy tests", function ()
local model = path .. "/examples/rbac_model.conf"
local policy = path .. "/examples/rbac_policy.csv"

local e = Enforcer:new(model, policy)

assert.is.True(e:enforce("alice", "data1", "read"))
e:removePolicy("p", "p", {"alice", "data1", "read"})
assert.is.False(e:enforce("alice", "data1", "read"))

assert.is.True(e:enforce("alice", "data2", "read"))
assert.is.True(e:enforce("alice", "data2", "write"))
e:removePolicy("g", "g", {"alice", "data2_admin"})
assert.is.False(e:enforce("alice", "data2", "read"))
assert.is.False(e:enforce("alice", "data2", "write"))
end)

it("Update Policy tests", function ()
local model = path .. "/examples/rbac_model.conf"
local policy = path .. "/examples/rbac_policy.csv"

local e = Enforcer:new(model, policy)

assert.is.True(e:enforce("alice", "data1", "read"))
assert.is.False(e:enforce("alice", "data1", "write"))
e:updatePolicy("p", "p", {"alice", "data1", "read"}, {"alice", "data1", "write"})
assert.is.False(e:enforce("alice", "data1", "read"))
assert.is.True(e:enforce("alice", "data1", "write"))

assert.is.True(e:enforce("alice", "data2", "read"))
assert.is.False(e:enforce("bob", "data2", "read"))
e:updatePolicy("g", "g", {"alice", "data2_admin"}, {"bob", "data2_admin"})
assert.is.False(e:enforce("alice", "data2", "read"))
assert.is.True(e:enforce("bob", "data2", "read"))
end)

it("Add/Remove Policies test", function ()
local model = path .. "/examples/rbac_model.conf"
local policy = path .. "/examples/rbac_policy.csv"

local e = Enforcer:new(model, policy)

local rules = {
{"cathy", "data1", "read"},
{"cathy", "data1", "write"}
}
assert.is.False(e:enforce("cathy", "data1", "read"))
assert.is.False(e:enforce("cathy", "data1", "write"))
e:addPolicies("p", "p", rules)
assert.is.True(e:enforce("cathy", "data1", "read"))
assert.is.True(e:enforce("cathy", "data1", "write"))

e:removePolicies("p", "p", rules)
assert.is.False(e:enforce("cathy", "data1", "read"))
assert.is.False(e:enforce("cathy", "data1", "write"))

rules = {
{"cathy", "data2_admin"}
}

assert.is.False(e:enforce("cathy", "data2", "read"))
assert.is.False(e:enforce("cathy", "data2", "write"))
e:addPolicies("g", "g", rules)
assert.is.True(e:enforce("cathy", "data2", "read"))
assert.is.True(e:enforce("cathy", "data2", "write"))
end)

it("removeFilteredPolicy test", function ()
local model = path .. "/examples/rbac_model.conf"
local policy = path .. "/examples/rbac_policy.csv"

local e = Enforcer:new(model, policy)

local rules = {
{"cathy", "data1", "read"},
{"cathy", "data1", "write"}
}
e:addPolicies("p", "p", rules)

assert.is.True(e:enforce("cathy", "data1", "read"))
assert.is.True(e:enforce("cathy", "data1", "write"))

e:removeFilteredPolicy("p", "p", 0, {"cathy"})
assert.is.False(e:enforce("cathy", "data1", "read"))
assert.is.False(e:enforce("cathy", "data1", "write"))

assert.is.True(e:enforce("alice", "data2", "read"))
assert.is.True(e:enforce("alice", "data2", "write"))

e:removeFilteredPolicy("g", "g", 0, {"alice"})
e.model:printPolicy()
assert.is.False(e:enforce("alice", "data2", "read"))
assert.is.False(e:enforce("alice", "data2", "write"))
end)
end)

0 comments on commit 89894dd

Please sign in to comment.