Skip to content

Commit edde050

Browse files
committed
feat: Added bindings for synced enforcer
Signed-off-by: Yash Pandey (YP) <[email protected]>
1 parent 24d43ce commit edde050

14 files changed

+356
-25
lines changed

bindings/python/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ set(SOURCES
1818
py_enforcer.cpp
1919
py_abac_data.cpp
2020
py_model.cpp
21-
py_config.cpp)
21+
py_config.cpp
22+
py_synced_enforcer.cpp
23+
)
2224

2325
set(HEADERS
2426
py_casbin.h

bindings/python/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ PYBIND11_MODULE(pycasbin, m) {
3939
bindABACData(m);
4040
bindPyModel(m);
4141
bindPyConfig(m);
42+
bindPySyncedEnforcer(m);
4243

4344
m.attr("__version__") = PY_CASBIN_VERSION;
4445
}

bindings/python/py_cached_enforcer.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ void bindPyCachedEnforcer(py::module &m) {
5353
@param enable_log whether to enable Casbin's log.
5454
)doc")
5555

56-
// .def("Enforce", py::overload_cast<casbin::Scope>(&casbin::CachedEnforcer::Enforce), R"doc(
57-
// Enforce with a vector param,decides whether a "subject" can access a
58-
// "object" with the operation "action", input parameters are usually: (sub,
59-
// obj, act).
60-
// )doc")
56+
.def("InvalidateCache", &casbin::CachedEnforcer::InvalidateCache)
57+
58+
.def("Enforce", py::overload_cast<const casbin::DataVector&>(&casbin::CachedEnforcer::Enforce), R"doc(
59+
Enforce with a map param,decides whether a "subject" can access a "object"
60+
with the operation "action", input parameters are usually: (sub, obj, act).
61+
)doc")
6162
.def("Enforce", py::overload_cast<const casbin::DataList &>(&casbin::CachedEnforcer::Enforce), R"doc(
6263
Enforce with a map param,decides whether a "subject" can access a "object"
6364
with the operation "action", input parameters are usually: (sub, obj, act).
@@ -66,12 +67,7 @@ void bindPyCachedEnforcer(py::module &m) {
6667
Enforce with a map param,decides whether a "subject" can access a "object"
6768
with the operation "action", input parameters are usually: (sub, obj, act).
6869
)doc")
69-
// .def("EnforceWithMatcher", py::overload_cast<const std::string &, casbin::Scope>(&casbin::CachedEnforcer::EnforceWithMatcher), R"doc(
70-
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
71-
// access a "object" with the operation "action", input parameters are
72-
// usually: (matcher, sub, obj, act), use model matcher by default when
73-
// matcher is "".
74-
// )doc")
70+
7571
.def("EnforceWithMatcher", py::overload_cast<const std::string &, const casbin::DataList &>(&casbin::CachedEnforcer::EnforceWithMatcher), R"doc(
7672
EnforceWithMatcher use a custom matcher to decides whether a "subject" can
7773
access a "object" with the operation "action", input parameters are

bindings/python/py_casbin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ void bindPyCachedEnforcer(py::module &m);
2323
void bindABACData(py::module &m);
2424
void bindPyModel(py::module &m);
2525
void bindPyConfig(py::module &m);
26+
void bindPySyncedEnforcer(py::module& m);

bindings/python/py_enforcer.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ namespace py = pybind11;
2424

2525
void bindPyEnforcer(py::module& m) {
2626
py::class_<casbin::Enforcer>(m, "Enforcer")
27-
.def(py::init<>())
28-
.def(py::init<const std::string &, const std::string &>())
29-
.def(py::init<const std::string &, std::shared_ptr<casbin::Adapter>>())
30-
.def(py::init<std::shared_ptr<casbin::Model>, std::shared_ptr<casbin::Adapter>>())
31-
.def(py::init<std::shared_ptr<casbin::Model>>())
32-
.def(py::init<const std::string &>())
33-
.def(py::init<const std::string &, const std::string &, bool>())
27+
.def(py::init<>(), "")
28+
.def(py::init<const std::string &, const std::string &>(), "")
29+
.def(py::init<const std::string &, std::shared_ptr<casbin::Adapter>>(), "")
30+
.def(py::init<std::shared_ptr<casbin::Model>, std::shared_ptr<casbin::Adapter>>(), "")
31+
.def(py::init<std::shared_ptr<casbin::Model>>(), "")
32+
.def(py::init<const std::string &>(), "")
33+
.def(py::init<const std::string &, const std::string &, bool>(), "")
34+
3435
.def("InitWithFile", &casbin::Enforcer::InitWithFile, "InitWithFile initializes an enforcer with a model file and a policy file.")
3536
.def("InitWithAdapter", &casbin::Enforcer::InitWithAdapter, "InitWithAdapter initializes an enforcer with a database adapter.")
3637
.def("InitWithModelAndAdapter", &casbin::Enforcer::InitWithModelAndAdapter, "InitWithModelAndAdapter initializes an enforcer with a model and a database adapter.")
@@ -40,6 +41,7 @@ void bindPyEnforcer(py::module& m) {
4041
Because the policy is attached to a model, so the policy is invalidated and
4142
needs to be reloaded by calling LoadPolicy().
4243
)doc")
44+
4345
.def("GetModel", &casbin::Enforcer::GetModel, "GetModel gets the current model.")
4446
.def("SetModel", &casbin::Enforcer::SetModel, "SetModel sets the current model.")
4547
.def("GetAdapter", &casbin::Enforcer::GetAdapter, "GetAdapter gets the current adapter.")
@@ -60,10 +62,8 @@ void bindPyEnforcer(py::module& m) {
6062
.def("EnableAutoBuildRoleLinks", &casbin::Enforcer::EnableAutoBuildRoleLinks, "EnableAutoBuildRoleLinks controls whether to rebuild the role inheritance relations when a role is added or deleted.")
6163
.def("BuildRoleLinks", &casbin::Enforcer::BuildRoleLinks, "BuildRoleLinks manually rebuild the role inheritance relations.")
6264
.def("BuildIncrementalRoleLinks", &casbin::Enforcer::BuildIncrementalRoleLinks, "BuildIncrementalRoleLinks provides incremental build the role inheritance relations.")
63-
// .def("Enforce", py::overload_cast<casbin::Scope>(&casbin::Enforcer::Enforce), "Enforce decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (sub, obj, act).")
6465
.def("Enforce", py::overload_cast<const casbin::DataVector &>(&casbin::Enforcer::Enforce), "Enforce with a vector param, decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (sub, obj, act).")
6566
.def("Enforce", py::overload_cast<const casbin::DataMap &>(&casbin::Enforcer::Enforce), "Enforce with a map param, decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (sub, obj, act).")
66-
// .def("EnforceWithMatcher", py::overload_cast<const std::string &, casbin::Scope>(&casbin::Enforcer::EnforceWithMatcher), "EnforceWithMatcher use a custom matcher to decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is \"\".")
6767
.def("EnforceWithMatcher", py::overload_cast<const std::string &, const casbin::DataList &>(&casbin::Enforcer::EnforceWithMatcher), "EnforceWithMatcher use a custom matcher to decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is \"\".")
6868
.def("EnforceWithMatcher", py::overload_cast<const std::string &, const casbin::DataMap &>(&casbin::Enforcer::EnforceWithMatcher), "EnforceWithMatcher use a custom matcher to decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is \"\".")
6969
.def("BatchEnforce", &casbin::Enforcer::BatchEnforce, "BatchEnforce enforce in batches")
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright 2021 The casbin Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <pybind11/pybind11.h>
18+
#include <pybind11/stl.h>
19+
#include <pybind11/chrono.h>
20+
#include <casbin/casbin.h>
21+
22+
#include "py_casbin.h"
23+
24+
namespace py = pybind11;
25+
26+
void bindPySyncedEnforcer(py::module& m) {
27+
py::class_<casbin::SyncedEnforcer, casbin::Enforcer>(m, "SyncedEnforcer")
28+
.def(py::init<>(), "Enforcer is the default constructor.")
29+
.def(py::init<const std::string &, const std::string &>(), R"doc(
30+
Enforcer initializes an enforcer with a model file and a policy file.
31+
@param model_path the path of the model file.
32+
@param policy_file the path of the policy file.
33+
)doc")
34+
.def(py::init<const std::string &, std::shared_ptr<casbin::Adapter>>(), R"doc(
35+
Enforcer initializes an enforcer with a database adapter.
36+
@param model_path the path of the model file.
37+
@param adapter the adapter.
38+
)doc")
39+
.def(py::init<std::shared_ptr<casbin::Model>, std::shared_ptr<casbin::Adapter>>(), R"doc(
40+
Enforcer initializes an enforcer with a model and a database adapter.
41+
@param m the model.
42+
@param adapter the adapter.
43+
)doc")
44+
.def(py::init<std::shared_ptr<casbin::Model>>(), R"doc(
45+
Enforcer initializes an enforcer with a model.
46+
@param m the model.
47+
)doc")
48+
.def(py::init<const std::string &>(), R"doc(
49+
Enforcer initializes an enforcer with a model file.
50+
@param model_path the path of the model file.
51+
)doc")
52+
.def(py::init<const std::string &, const std::string &, bool>(), R"doc(
53+
Enforcer initializes an enforcer with a model file, a policy file and an enable log flag.
54+
@param model_path the path of the model file.
55+
@param policy_file the path of the policy file.
56+
@param enable_log whether to enable Casbin's log.
57+
)doc")
58+
59+
.def("StartAutoLoadPolicy", &casbin::SyncedEnforcer::StartAutoLoadPolicy, "StartAutoLoadPolicy starts a thread that will go through every specified duration call LoadPolicy")
60+
.def("IsAutoLoadingRunning", &casbin::SyncedEnforcer::IsAutoLoadingRunning, "IsAutoLoadingRunning check if SyncedEnforcer is auto loading policies")
61+
.def("StopAutoLoadPolicy", &casbin::SyncedEnforcer::StopAutoLoadPolicy, "StopAutoLoadPolicy causes the thread to exit")
62+
.def("SetWatcher", &casbin::SyncedEnforcer::SetWatcher, "SetWatcher sets the current watcher.")
63+
.def("LoadModel", &casbin::SyncedEnforcer::LoadModel, "LoadModel reloads the model from the model CONF file.")
64+
.def("ClearPolicy", &casbin::SyncedEnforcer::ClearPolicy, "ClearPolicy clears all policy.")
65+
.def("LoadPolicy", &casbin::SyncedEnforcer::LoadPolicy, "LoadPolicy reloads the policy from file/database.")
66+
// .def("LoadFilteredPolicy", &casbin::SyncedEnforcer::LoadFilteredPolicy, "LoadFilteredPolicy reloads a filtered policy from file/database.")
67+
.def("SavePolicy", &casbin::SyncedEnforcer::SavePolicy, "SavePolicy saves the current policy (usually after changed with Casbin API) back to file/database.")
68+
.def("BuildRoleLinks", &casbin::SyncedEnforcer::BuildRoleLinks, "BuildRoleLinks manually rebuild the role inheritance relations.")
69+
.def("Enforce", py::overload_cast<const casbin::DataVector &>(&casbin::SyncedEnforcer::Enforce), "Enforce with a vector param, decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (sub, obj, act).")
70+
.def("Enforce", py::overload_cast<const casbin::DataMap &>(&casbin::SyncedEnforcer::Enforce), "Enforce with a map param, decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (sub, obj, act).")
71+
.def("BatchEnforce", &casbin::SyncedEnforcer::BatchEnforce, "BatchEnforce enforce in batches")
72+
.def("BatchEnforceWithMatcher", &casbin::SyncedEnforcer::BatchEnforceWithMatcher, "BatchEnforceWithMatcher enforce with matcher in batches")
73+
74+
/* Management API member functions. */
75+
76+
.def("GetAllSubjects", &casbin::SyncedEnforcer::GetAllSubjects)
77+
.def("GetAllNamedSubjects", &casbin::SyncedEnforcer::GetAllNamedSubjects)
78+
.def("GetAllObjects", &casbin::SyncedEnforcer::GetAllObjects)
79+
.def("GetAllNamedObjects", &casbin::SyncedEnforcer::GetAllNamedObjects)
80+
.def("GetAllNamedActions", &casbin::SyncedEnforcer::GetAllNamedActions)
81+
.def("GetAllRoles", &casbin::SyncedEnforcer::GetAllRoles)
82+
.def("GetAllNamedRoles", &casbin::SyncedEnforcer::GetAllNamedRoles)
83+
.def("GetPolicy", &casbin::SyncedEnforcer::GetPolicy)
84+
.def("GetNamedPolicy", &casbin::SyncedEnforcer::GetNamedPolicy)
85+
.def("GetFilteredNamedPolicy", &casbin::SyncedEnforcer::GetFilteredNamedPolicy)
86+
.def("GetGroupingPolicy", &casbin::SyncedEnforcer::GetGroupingPolicy)
87+
.def("GetFilteredGroupingPolicy", &casbin::SyncedEnforcer::GetFilteredGroupingPolicy)
88+
.def("GetNamedGroupingPolicy", &casbin::SyncedEnforcer::GetNamedGroupingPolicy)
89+
.def("GetFilteredNamedGroupingPolicy", &casbin::SyncedEnforcer::GetFilteredNamedGroupingPolicy)
90+
91+
.def("HasPolicy", &casbin::SyncedEnforcer::HasPolicy)
92+
.def("HasNamedPolicy", &casbin::SyncedEnforcer::HasNamedPolicy)
93+
.def("AddPolicy", &casbin::SyncedEnforcer::AddPolicy)
94+
.def("AddNamedPolicy", &casbin::SyncedEnforcer::AddNamedPolicy)
95+
.def("AddNamedPolicies", &casbin::SyncedEnforcer::AddNamedPolicies)
96+
.def("RemovePolicy", &casbin::SyncedEnforcer::RemovePolicy)
97+
.def("RemovePolicies", &casbin::SyncedEnforcer::RemovePolicies)
98+
.def("RemoveFilteredPolicy", &casbin::SyncedEnforcer::RemoveFilteredPolicy)
99+
.def("RemoveNamedPolicies", &casbin::SyncedEnforcer::RemoveNamedPolicies)
100+
.def("RemoveFilteredNamedPolicy", &casbin::SyncedEnforcer::RemoveFilteredNamedPolicy)
101+
.def("HasNamedGroupingPolicy", &casbin::SyncedEnforcer::HasNamedGroupingPolicy)
102+
.def("AddGroupingPolicy", &casbin::SyncedEnforcer::AddGroupingPolicy)
103+
.def("AddGroupingPolicies", &casbin::SyncedEnforcer::AddGroupingPolicies)
104+
.def("AddNamedGroupingPolicy", &casbin::SyncedEnforcer::AddNamedGroupingPolicy)
105+
.def("AddNamedGroupingPolicies", &casbin::SyncedEnforcer::AddNamedGroupingPolicies)
106+
.def("RemoveGroupingPolicy", &casbin::SyncedEnforcer::RemoveGroupingPolicy)
107+
.def("RemoveGroupingPolicies", &casbin::SyncedEnforcer::RemoveGroupingPolicies)
108+
.def("RemoveFilteredGroupingPolicy", &casbin::SyncedEnforcer::RemoveFilteredGroupingPolicy)
109+
.def("RemoveNamedGroupingPolicy", &casbin::SyncedEnforcer::RemoveNamedGroupingPolicy)
110+
.def("RemoveNamedGroupingPolicies", &casbin::SyncedEnforcer::RemoveNamedGroupingPolicies)
111+
.def("RemoveFilteredNamedGroupingPolicy", &casbin::SyncedEnforcer::RemoveFilteredNamedGroupingPolicy)
112+
.def("AddFunction", &casbin::SyncedEnforcer::AddFunction)
113+
.def("UpdateGroupingPolicy", &casbin::SyncedEnforcer::UpdateGroupingPolicy)
114+
.def("UpdateNamedGroupingPolicy", &casbin::SyncedEnforcer::UpdateNamedGroupingPolicy)
115+
.def("UpdatePolicy", &casbin::SyncedEnforcer::UpdatePolicy)
116+
.def("UpdateNamedPolicy", &casbin::SyncedEnforcer::UpdateNamedPolicy)
117+
.def("UpdatePolicies", &casbin::SyncedEnforcer::UpdatePolicies)
118+
.def("UpdateNamedPolicies", &casbin::SyncedEnforcer::UpdateNamedPolicies);
119+
}

casbin/enforcer_cached.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ bool CachedEnforcer ::Enforce(Scope scope) {
148148
return EnforceWithMatcher("", scope);
149149
}
150150

151+
bool CachedEnforcer::Enforce(const DataVector& params) {
152+
return EnforceWithMatcher("", params);
153+
}
154+
151155
// Enforce with a vector param,decides whether a "subject" can access a "object"
152156
// with the operation "action", input parameters are usually: (sub, obj, act).
153157
bool CachedEnforcer::Enforce(const DataList& params) {
@@ -167,6 +171,47 @@ bool CachedEnforcer ::EnforceWithMatcher(const std::string& matcher, Scope scope
167171
return Enforcer::EnforceWithMatcher(matcher, scope);
168172
}
169173

174+
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
175+
// access a "object" with the operation "action", input parameters are usually:
176+
// (matcher, sub, obj, act), use model matcher by default when matcher is "".
177+
bool CachedEnforcer::EnforceWithMatcher(const std::string& matcher, const DataVector& params) {
178+
if (!enableCache) {
179+
return Enforcer::EnforceWithMatcher(matcher, params);
180+
}
181+
182+
std::string key;
183+
for (const auto& r : params) {
184+
if(const auto string_param = std::get_if<std::string>(&r))
185+
key += *string_param;
186+
else if(const auto abac_param = std::get_if<std::shared_ptr<ABACData>>(&r)) {
187+
auto data_ptr = *abac_param;
188+
for(auto [_, attrib_value] : data_ptr->GetAttributes()) {
189+
if(auto string_value = std::get_if<std::string>(&attrib_value))
190+
key += *string_value + "$";
191+
else if(auto int_value = std::get_if<int32_t>(&attrib_value))
192+
key += std::to_string(*int_value) + "$";
193+
else if(auto double_value = std::get_if<double>(&attrib_value))
194+
key += std::to_string(*double_value) + "$";
195+
else if(auto float_value = std::get_if<float>(&attrib_value))
196+
key += std::to_string(*float_value) + "$";
197+
}
198+
}
199+
key += "$$";
200+
}
201+
key += matcher;
202+
key += "$";
203+
204+
std::pair<bool, bool> res_ok = getCachedResult(key);
205+
206+
if (res_ok.second) {
207+
return res_ok.first;
208+
}
209+
210+
bool res = Enforcer::EnforceWithMatcher(matcher, params);
211+
setCachedResult(key, res);
212+
return res;
213+
}
214+
170215
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
171216
// access a "object" with the operation "action", input parameters are usually:
172217
// (matcher, sub, obj, act), use model matcher by default when matcher is "".

casbin/enforcer_cached.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,39 @@ class CachedEnforcer : public Enforcer {
8585
CachedEnforcer(const std::string& model_path, const std::string& policy_file, bool enable_log);
8686

8787
bool Enforce(Scope scope);
88+
89+
// Enforce with a vector param,decides whether a "subject" can access a
90+
// "object" with the operation "action", input parameters are usually: (sub,
91+
// obj, act).
92+
bool Enforce(const DataVector& params);
93+
8894
// Enforce with a vector param,decides whether a "subject" can access a
8995
// "object" with the operation "action", input parameters are usually: (sub,
9096
// obj, act).
9197
bool Enforce(const DataList& params);
98+
9299
// Enforce with a map param,decides whether a "subject" can access a "object"
93100
// with the operation "action", input parameters are usually: (sub, obj, act).
94101
bool Enforce(const DataMap& params);
102+
95103
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
96104
// access a "object" with the operation "action", input parameters are
97105
// usually: (matcher, sub, obj, act), use model matcher by default when
98106
// matcher is "".
99107
bool EnforceWithMatcher(const std::string& matcher, Scope scope);
108+
109+
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
110+
// access a "object" with the operation "action", input parameters are
111+
// usually: (matcher, sub, obj, act), use model matcher by default when
112+
// matcher is "".
113+
bool EnforceWithMatcher(const std::string& matcher, const DataVector& params);
114+
100115
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
101116
// access a "object" with the operation "action", input parameters are
102117
// usually: (matcher, sub, obj, act), use model matcher by default when
103118
// matcher is "".
104119
bool EnforceWithMatcher(const std::string& matcher, const DataList& params);
120+
105121
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
106122
// access a "object" with the operation "action", input parameters are
107123
// usually: (matcher, sub, obj, act), use model matcher by default when

0 commit comments

Comments
 (0)