Skip to content
Merged
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: 3 additions & 1 deletion bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ set(SOURCES
py_enforcer.cpp
py_abac_data.cpp
py_model.cpp
py_config.cpp)
py_config.cpp
py_synced_enforcer.cpp
)

set(HEADERS
py_casbin.h
Expand Down
1 change: 1 addition & 0 deletions bindings/python/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ PYBIND11_MODULE(pycasbin, m) {
bindABACData(m);
bindPyModel(m);
bindPyConfig(m);
bindPySyncedEnforcer(m);

m.attr("__version__") = PY_CASBIN_VERSION;
}
18 changes: 7 additions & 11 deletions bindings/python/py_cached_enforcer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ void bindPyCachedEnforcer(py::module &m) {
@param enable_log whether to enable Casbin's log.
)doc")

// .def("Enforce", py::overload_cast<casbin::Scope>(&casbin::CachedEnforcer::Enforce), R"doc(
// Enforce with a vector param,decides whether a "subject" can access a
// "object" with the operation "action", input parameters are usually: (sub,
// obj, act).
// )doc")
.def("InvalidateCache", &casbin::CachedEnforcer::InvalidateCache)

.def("Enforce", py::overload_cast<const casbin::DataVector&>(&casbin::CachedEnforcer::Enforce), R"doc(
Enforce with a map param,decides whether a "subject" can access a "object"
with the operation "action", input parameters are usually: (sub, obj, act).
)doc")
.def("Enforce", py::overload_cast<const casbin::DataList &>(&casbin::CachedEnforcer::Enforce), R"doc(
Enforce with a map param,decides whether a "subject" can access a "object"
with the operation "action", input parameters are usually: (sub, obj, act).
Expand All @@ -66,12 +67,7 @@ void bindPyCachedEnforcer(py::module &m) {
Enforce with a map param,decides whether a "subject" can access a "object"
with the operation "action", input parameters are usually: (sub, obj, act).
)doc")
// .def("EnforceWithMatcher", py::overload_cast<const std::string &, casbin::Scope>(&casbin::CachedEnforcer::EnforceWithMatcher), R"doc(
// 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 "".
// )doc")

.def("EnforceWithMatcher", py::overload_cast<const std::string &, const casbin::DataList &>(&casbin::CachedEnforcer::EnforceWithMatcher), R"doc(
EnforceWithMatcher use a custom matcher to decides whether a "subject" can
access a "object" with the operation "action", input parameters are
Expand Down
1 change: 1 addition & 0 deletions bindings/python/py_casbin.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ void bindPyCachedEnforcer(py::module &m);
void bindABACData(py::module &m);
void bindPyModel(py::module &m);
void bindPyConfig(py::module &m);
void bindPySyncedEnforcer(py::module& m);
18 changes: 9 additions & 9 deletions bindings/python/py_enforcer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ namespace py = pybind11;

void bindPyEnforcer(py::module& m) {
py::class_<casbin::Enforcer>(m, "Enforcer")
.def(py::init<>())
.def(py::init<const std::string &, const std::string &>())
.def(py::init<const std::string &, std::shared_ptr<casbin::Adapter>>())
.def(py::init<std::shared_ptr<casbin::Model>, std::shared_ptr<casbin::Adapter>>())
.def(py::init<std::shared_ptr<casbin::Model>>())
.def(py::init<const std::string &>())
.def(py::init<const std::string &, const std::string &, bool>())
.def(py::init<>(), "")
.def(py::init<const std::string &, const std::string &>(), "")
.def(py::init<const std::string &, std::shared_ptr<casbin::Adapter>>(), "")
.def(py::init<std::shared_ptr<casbin::Model>, std::shared_ptr<casbin::Adapter>>(), "")
.def(py::init<std::shared_ptr<casbin::Model>>(), "")
.def(py::init<const std::string &>(), "")
.def(py::init<const std::string &, const std::string &, bool>(), "")

.def("InitWithFile", &casbin::Enforcer::InitWithFile, "InitWithFile initializes an enforcer with a model file and a policy file.")
.def("InitWithAdapter", &casbin::Enforcer::InitWithAdapter, "InitWithAdapter initializes an enforcer with a database adapter.")
.def("InitWithModelAndAdapter", &casbin::Enforcer::InitWithModelAndAdapter, "InitWithModelAndAdapter initializes an enforcer with a model and a database adapter.")
Expand All @@ -40,6 +41,7 @@ void bindPyEnforcer(py::module& m) {
Because the policy is attached to a model, so the policy is invalidated and
needs to be reloaded by calling LoadPolicy().
)doc")

.def("GetModel", &casbin::Enforcer::GetModel, "GetModel gets the current model.")
.def("SetModel", &casbin::Enforcer::SetModel, "SetModel sets the current model.")
.def("GetAdapter", &casbin::Enforcer::GetAdapter, "GetAdapter gets the current adapter.")
Expand All @@ -60,10 +62,8 @@ void bindPyEnforcer(py::module& m) {
.def("EnableAutoBuildRoleLinks", &casbin::Enforcer::EnableAutoBuildRoleLinks, "EnableAutoBuildRoleLinks controls whether to rebuild the role inheritance relations when a role is added or deleted.")
.def("BuildRoleLinks", &casbin::Enforcer::BuildRoleLinks, "BuildRoleLinks manually rebuild the role inheritance relations.")
.def("BuildIncrementalRoleLinks", &casbin::Enforcer::BuildIncrementalRoleLinks, "BuildIncrementalRoleLinks provides incremental build the role inheritance relations.")
// .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).")
.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).")
.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).")
// .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 \"\".")
.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 \"\".")
.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 \"\".")
.def("BatchEnforce", &casbin::Enforcer::BatchEnforce, "BatchEnforce enforce in batches")
Expand Down
119 changes: 119 additions & 0 deletions bindings/python/py_synced_enforcer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* 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.
*/

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/chrono.h>
#include <casbin/casbin.h>

#include "py_casbin.h"

namespace py = pybind11;

void bindPySyncedEnforcer(py::module& m) {
py::class_<casbin::SyncedEnforcer, casbin::Enforcer>(m, "SyncedEnforcer")
.def(py::init<>(), "Enforcer is the default constructor.")
.def(py::init<const std::string &, const std::string &>(), R"doc(
Enforcer initializes an enforcer with a model file and a policy file.
@param model_path the path of the model file.
@param policy_file the path of the policy file.
)doc")
.def(py::init<const std::string &, std::shared_ptr<casbin::Adapter>>(), R"doc(
Enforcer initializes an enforcer with a database adapter.
@param model_path the path of the model file.
@param adapter the adapter.
)doc")
.def(py::init<std::shared_ptr<casbin::Model>, std::shared_ptr<casbin::Adapter>>(), R"doc(
Enforcer initializes an enforcer with a model and a database adapter.
@param m the model.
@param adapter the adapter.
)doc")
.def(py::init<std::shared_ptr<casbin::Model>>(), R"doc(
Enforcer initializes an enforcer with a model.
@param m the model.
)doc")
.def(py::init<const std::string &>(), R"doc(
Enforcer initializes an enforcer with a model file.
@param model_path the path of the model file.
)doc")
.def(py::init<const std::string &, const std::string &, bool>(), R"doc(
Enforcer initializes an enforcer with a model file, a policy file and an enable log flag.
@param model_path the path of the model file.
@param policy_file the path of the policy file.
@param enable_log whether to enable Casbin's log.
)doc")

.def("StartAutoLoadPolicy", &casbin::SyncedEnforcer::StartAutoLoadPolicy, "StartAutoLoadPolicy starts a thread that will go through every specified duration call LoadPolicy")
.def("IsAutoLoadingRunning", &casbin::SyncedEnforcer::IsAutoLoadingRunning, "IsAutoLoadingRunning check if SyncedEnforcer is auto loading policies")
.def("StopAutoLoadPolicy", &casbin::SyncedEnforcer::StopAutoLoadPolicy, "StopAutoLoadPolicy causes the thread to exit")
.def("SetWatcher", &casbin::SyncedEnforcer::SetWatcher, "SetWatcher sets the current watcher.")
.def("LoadModel", &casbin::SyncedEnforcer::LoadModel, "LoadModel reloads the model from the model CONF file.")
.def("ClearPolicy", &casbin::SyncedEnforcer::ClearPolicy, "ClearPolicy clears all policy.")
.def("LoadPolicy", &casbin::SyncedEnforcer::LoadPolicy, "LoadPolicy reloads the policy from file/database.")
// .def("LoadFilteredPolicy", &casbin::SyncedEnforcer::LoadFilteredPolicy, "LoadFilteredPolicy reloads a filtered policy from file/database.")
.def("SavePolicy", &casbin::SyncedEnforcer::SavePolicy, "SavePolicy saves the current policy (usually after changed with Casbin API) back to file/database.")
.def("BuildRoleLinks", &casbin::SyncedEnforcer::BuildRoleLinks, "BuildRoleLinks manually rebuild the role inheritance relations.")
.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).")
.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).")
.def("BatchEnforce", &casbin::SyncedEnforcer::BatchEnforce, "BatchEnforce enforce in batches")
.def("BatchEnforceWithMatcher", &casbin::SyncedEnforcer::BatchEnforceWithMatcher, "BatchEnforceWithMatcher enforce with matcher in batches")

/* Management API member functions. */

.def("GetAllSubjects", &casbin::SyncedEnforcer::GetAllSubjects)
.def("GetAllNamedSubjects", &casbin::SyncedEnforcer::GetAllNamedSubjects)
.def("GetAllObjects", &casbin::SyncedEnforcer::GetAllObjects)
.def("GetAllNamedObjects", &casbin::SyncedEnforcer::GetAllNamedObjects)
.def("GetAllNamedActions", &casbin::SyncedEnforcer::GetAllNamedActions)
.def("GetAllRoles", &casbin::SyncedEnforcer::GetAllRoles)
.def("GetAllNamedRoles", &casbin::SyncedEnforcer::GetAllNamedRoles)
.def("GetPolicy", &casbin::SyncedEnforcer::GetPolicy)
.def("GetNamedPolicy", &casbin::SyncedEnforcer::GetNamedPolicy)
.def("GetFilteredNamedPolicy", &casbin::SyncedEnforcer::GetFilteredNamedPolicy)
.def("GetGroupingPolicy", &casbin::SyncedEnforcer::GetGroupingPolicy)
.def("GetFilteredGroupingPolicy", &casbin::SyncedEnforcer::GetFilteredGroupingPolicy)
.def("GetNamedGroupingPolicy", &casbin::SyncedEnforcer::GetNamedGroupingPolicy)
.def("GetFilteredNamedGroupingPolicy", &casbin::SyncedEnforcer::GetFilteredNamedGroupingPolicy)

.def("HasPolicy", &casbin::SyncedEnforcer::HasPolicy)
.def("HasNamedPolicy", &casbin::SyncedEnforcer::HasNamedPolicy)
.def("AddPolicy", &casbin::SyncedEnforcer::AddPolicy)
.def("AddNamedPolicy", &casbin::SyncedEnforcer::AddNamedPolicy)
.def("AddNamedPolicies", &casbin::SyncedEnforcer::AddNamedPolicies)
.def("RemovePolicy", &casbin::SyncedEnforcer::RemovePolicy)
.def("RemovePolicies", &casbin::SyncedEnforcer::RemovePolicies)
.def("RemoveFilteredPolicy", &casbin::SyncedEnforcer::RemoveFilteredPolicy)
.def("RemoveNamedPolicies", &casbin::SyncedEnforcer::RemoveNamedPolicies)
.def("RemoveFilteredNamedPolicy", &casbin::SyncedEnforcer::RemoveFilteredNamedPolicy)
.def("HasNamedGroupingPolicy", &casbin::SyncedEnforcer::HasNamedGroupingPolicy)
.def("AddGroupingPolicy", &casbin::SyncedEnforcer::AddGroupingPolicy)
.def("AddGroupingPolicies", &casbin::SyncedEnforcer::AddGroupingPolicies)
.def("AddNamedGroupingPolicy", &casbin::SyncedEnforcer::AddNamedGroupingPolicy)
.def("AddNamedGroupingPolicies", &casbin::SyncedEnforcer::AddNamedGroupingPolicies)
.def("RemoveGroupingPolicy", &casbin::SyncedEnforcer::RemoveGroupingPolicy)
.def("RemoveGroupingPolicies", &casbin::SyncedEnforcer::RemoveGroupingPolicies)
.def("RemoveFilteredGroupingPolicy", &casbin::SyncedEnforcer::RemoveFilteredGroupingPolicy)
.def("RemoveNamedGroupingPolicy", &casbin::SyncedEnforcer::RemoveNamedGroupingPolicy)
.def("RemoveNamedGroupingPolicies", &casbin::SyncedEnforcer::RemoveNamedGroupingPolicies)
.def("RemoveFilteredNamedGroupingPolicy", &casbin::SyncedEnforcer::RemoveFilteredNamedGroupingPolicy)
.def("AddFunction", &casbin::SyncedEnforcer::AddFunction)
.def("UpdateGroupingPolicy", &casbin::SyncedEnforcer::UpdateGroupingPolicy)
.def("UpdateNamedGroupingPolicy", &casbin::SyncedEnforcer::UpdateNamedGroupingPolicy)
.def("UpdatePolicy", &casbin::SyncedEnforcer::UpdatePolicy)
.def("UpdateNamedPolicy", &casbin::SyncedEnforcer::UpdateNamedPolicy)
.def("UpdatePolicies", &casbin::SyncedEnforcer::UpdatePolicies)
.def("UpdateNamedPolicies", &casbin::SyncedEnforcer::UpdateNamedPolicies);
}
45 changes: 45 additions & 0 deletions casbin/enforcer_cached.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ bool CachedEnforcer ::Enforce(Scope scope) {
return EnforceWithMatcher("", scope);
}

bool CachedEnforcer::Enforce(const DataVector& params) {
return EnforceWithMatcher("", params);
}

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

// 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 "".
bool CachedEnforcer::EnforceWithMatcher(const std::string& matcher, const DataVector& params) {
if (!enableCache) {
return Enforcer::EnforceWithMatcher(matcher, params);
}

std::string key;
for (const auto& r : params) {
if(const auto string_param = std::get_if<std::string>(&r))
key += *string_param;
else if(const auto abac_param = std::get_if<std::shared_ptr<ABACData>>(&r)) {
auto data_ptr = *abac_param;
for(auto [_, attrib_value] : data_ptr->GetAttributes()) {
if(auto string_value = std::get_if<std::string>(&attrib_value))
key += *string_value + "$";
else if(auto int_value = std::get_if<int32_t>(&attrib_value))
key += std::to_string(*int_value) + "$";
else if(auto double_value = std::get_if<double>(&attrib_value))
key += std::to_string(*double_value) + "$";
else if(auto float_value = std::get_if<float>(&attrib_value))
key += std::to_string(*float_value) + "$";
}
}
key += "$$";
}
key += matcher;
key += "$";

std::pair<bool, bool> res_ok = getCachedResult(key);

if (res_ok.second) {
return res_ok.first;
}

bool res = Enforcer::EnforceWithMatcher(matcher, params);
setCachedResult(key, res);
return res;
}

// 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 "".
Expand Down
16 changes: 16 additions & 0 deletions casbin/enforcer_cached.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,39 @@ class CachedEnforcer : public Enforcer {
CachedEnforcer(const std::string& model_path, const std::string& policy_file, bool enable_log);

bool Enforce(Scope scope);

// Enforce with a vector param,decides whether a "subject" can access a
// "object" with the operation "action", input parameters are usually: (sub,
// obj, act).
bool Enforce(const DataVector& params);

// Enforce with a vector param,decides whether a "subject" can access a
// "object" with the operation "action", input parameters are usually: (sub,
// obj, act).
bool Enforce(const DataList& params);

// Enforce with a map param,decides whether a "subject" can access a "object"
// with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforce(const DataMap& params);

// 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 "".
bool EnforceWithMatcher(const std::string& matcher, Scope scope);

// 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 "".
bool EnforceWithMatcher(const std::string& matcher, const DataVector& params);

// 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 "".
bool EnforceWithMatcher(const std::string& matcher, const DataList& params);

// 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
Expand Down
Loading