Skip to content

Commit 4371da5

Browse files
authored
feat: add pycasbin adopter and test. (#164)
* fix: fix FileAdapter::SavePolicy Signed-off-by: stonex <[email protected]> * feat: add pycasbin::Adopter and test Signed-off-by: stonex <[email protected]>
1 parent 7790669 commit 4371da5

File tree

13 files changed

+172
-6
lines changed

13 files changed

+172
-6
lines changed

bindings/python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ set(SOURCES
2222
py_model.cpp
2323
py_config.cpp
2424
py_synced_enforcer.cpp
25+
py_adapter.cpp
2526
)
2627

2728
set(HEADERS

bindings/python/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ PYBIND11_MODULE(pycasbin, m) {
4040
bindPyModel(m);
4141
bindPyConfig(m);
4242
bindPySyncedEnforcer(m);
43+
bindPyAdapter(m);
4344

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

bindings/python/py_adapter.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 <casbin/casbin.h>
20+
21+
#include "py_casbin.h"
22+
23+
namespace py = pybind11;
24+
25+
void bindPyBaseAdapter(py::module& m) {
26+
// Base Adapter use shared_ptr to manage
27+
// must expose this interface for enforcer build
28+
py::class_<casbin::Adapter, std::shared_ptr<casbin::Adapter>>(m, "Adapter")
29+
.def("LoadPolicy", &casbin::Adapter::LoadPolicy, "LoadPolicy loads all policy rules from the storage.")
30+
.def("SavePolicy", &casbin::Adapter::SavePolicy, "SavePolicy saves all policy rules to the storage.")
31+
.def("AddPolicy", &casbin::Adapter::AddPolicy, "AddPolicy adds a policy rule to the storage.")
32+
.def("RemovePolicy", &casbin::Adapter::RemovePolicy, "RemovePolicy removes a policy rule from the storage.")
33+
.def("RemoveFilteredPolicy", &casbin::Adapter::RemoveFilteredPolicy, "RemoveFilteredPolicy removes policy rules that match the filter from the storage.")
34+
.def("IsFiltered", &casbin::Adapter::IsFiltered, "IsFiltered returns true if the loaded policy has been filtered.");
35+
}
36+
37+
void bindPyBatchAdapter(py::module &m) {
38+
py::class_<casbin::BatchAdapter, casbin::Adapter, std::shared_ptr<casbin::BatchAdapter>>(m, "BatchAdapter")
39+
.def("AddPolicies", &casbin::BatchAdapter::AddPolicies, "")
40+
.def("RemovePolicies", &casbin::BatchAdapter::RemovePolicies, "");
41+
}
42+
43+
void bindPyFileAdapter(py::module &m) {
44+
// File adapter inhert base adapter and use shared_ptr to manage
45+
py::class_<casbin::FileAdapter, casbin::Adapter, std::shared_ptr<casbin::FileAdapter>>(m, "FileAdapter")
46+
.def(py::init<std::string>(), "")
47+
.def_static("NewFileAdapter", &casbin::FileAdapter::NewFileAdapter, "")
48+
.def("LoadPolicy", &casbin::FileAdapter::LoadPolicy, "LoadPolicy loads all policy rules from the storage.")
49+
.def("SavePolicy", &casbin::FileAdapter::SavePolicy, "SavePolicy saves all policy rules to the storage.")
50+
.def("AddPolicy", &casbin::FileAdapter::AddPolicy, "AddPolicy adds a policy rule to the storage.")
51+
.def("RemovePolicy", &casbin::FileAdapter::RemovePolicy, "RemovePolicy removes a policy rule from the storage.")
52+
.def("RemoveFilteredPolicy", &casbin::FileAdapter::RemoveFilteredPolicy, "RemoveFilteredPolicy removes policy rules that match the filter from the storage.")
53+
.def("IsFiltered", &casbin::FileAdapter::IsFiltered, "IsFiltered returns true if the loaded policy has been filtered.");
54+
}
55+
56+
void bindPyBatchFileAdapter(py::module &m) {
57+
// Batch Adapter is virtual interface, maybe don't expose its' interface is ok.
58+
py::class_<casbin::BatchFileAdapter, casbin::BatchAdapter, casbin::FileAdapter, std::shared_ptr<casbin::BatchFileAdapter>>(m, "BatchFileAdapter")
59+
.def(py::init<std::string>(), "")
60+
.def_static("NewBatchFileAdapter", &casbin::BatchFileAdapter::NewBatchFileAdapter, "")
61+
.def("AddPolicies", &casbin::BatchFileAdapter::AddPolicies, "")
62+
.def("RemovePolicies", &casbin::BatchFileAdapter::RemovePolicies, "");
63+
}
64+
65+
void bindPyAdapter(py::module& m) {
66+
bindPyBaseAdapter(m);
67+
bindPyBatchAdapter(m);
68+
bindPyFileAdapter(m);
69+
bindPyBatchFileAdapter(m);
70+
}

bindings/python/py_casbin.h

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

casbin/persist/file_adapter/batch_file_adapter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ namespace casbin {
1313
BatchFileAdapter :: BatchFileAdapter(std::string file_path): FileAdapter(file_path) {
1414
}
1515

16+
std::shared_ptr<BatchFileAdapter> BatchFileAdapter :: NewBatchFileAdapter(std::string file_path) {
17+
return std::make_shared<BatchFileAdapter>(file_path);
18+
}
19+
1620
void BatchFileAdapter :: AddPolicies(std::string sec, std::string p_type, std::vector<std::vector<std::string>> rules) {
1721
throw UnsupportedOperationException("not implemented hello");
1822
}

casbin/persist/file_adapter/batch_file_adapter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class BatchFileAdapter: public BatchAdapter, public FileAdapter {
1212
// NewAdapter is the constructor for Adapter.
1313
BatchFileAdapter(std::string file_path);
1414

15+
static std::shared_ptr<BatchFileAdapter> NewBatchFileAdapter(std::string file_path);
16+
1517
void AddPolicies(std::string sec, std::string p_type, std::vector<std::vector<std::string>> rules);
1618

1719
void RemovePolicies(std::string sec, std::string p_type, std::vector<std::vector<std::string>> rules);

casbin/persist/file_adapter/file_adapter.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ FileAdapter :: FileAdapter(std::string file_path) {
2020
this->filtered = false;
2121
}
2222

23+
std::shared_ptr<casbin::FileAdapter> FileAdapter::NewFileAdapter(std::string file_path) {
24+
return std::make_shared<FileAdapter>(file_path);
25+
}
26+
2327
// LoadPolicy loads all policy rules from the storage.
2428
void FileAdapter :: LoadPolicy(const std::shared_ptr<Model>& model) {
2529
if (this->file_path == "")
@@ -36,15 +40,15 @@ void FileAdapter :: SavePolicy(const std::shared_ptr<Model>& model) {
3640

3741
std::string tmp;
3842

39-
for (std::unordered_map<std::string, std::shared_ptr<Assertion>> :: iterator it = model->m["p"].assertion_map.begin() ; it != model->m["p"].assertion_map.begin() ; it++){
43+
for (std::unordered_map<std::string, std::shared_ptr<Assertion>> :: iterator it = model->m["p"].assertion_map.begin() ; it != model->m["p"].assertion_map.end() ; it++){
4044
for (int i = 0 ; i < it->second->policy.size() ; i++){
4145
tmp += it->first + ", ";
4246
tmp += ArrayToString(it->second->policy[i]);
4347
tmp += "\n";
4448
}
4549
}
4650

47-
for (std::unordered_map <std::string, std::shared_ptr<Assertion>> :: iterator it = model->m["g"].assertion_map.begin() ; it != model->m["g"].assertion_map.begin() ; it++){
51+
for (std::unordered_map <std::string, std::shared_ptr<Assertion>> :: iterator it = model->m["g"].assertion_map.begin() ; it != model->m["g"].assertion_map.end() ; it++){
4852
for (int i = 0 ; i < it->second->policy.size() ; i++){
4953
tmp += it->first + ", ";
5054
tmp += ArrayToString(it->second->policy[i]);
@@ -74,14 +78,18 @@ void FileAdapter :: LoadPolicyFile(const std::shared_ptr<Model>& model, std::fun
7478

7579
void FileAdapter :: SavePolicyFile(std::string text) {
7680
std::ofstream out_file;
77-
out_file.open(this->file_path, std::ios::out);
81+
7882
try {
7983
out_file.open(this->file_path, std::ios::out);
8084
} catch (const std::ifstream::failure e) {
8185
throw IOException("Cannot open file.");
8286
}
8387

84-
out_file<<text;
88+
if (out_file.is_open() == false) {
89+
throw IOException("Don't exit adapter file");
90+
}
91+
92+
out_file << text;
8593

8694
out_file.close();
8795
}

casbin/persist/file_adapter/file_adapter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class FileAdapter : virtual public Adapter {
1313
// NewAdapter is the constructor for Adapter.
1414
FileAdapter(std::string file_path);
1515

16+
static std::shared_ptr<FileAdapter> NewFileAdapter(std::string file_path);
17+
1618
// LoadPolicy loads all policy rules from the storage.
1719
void LoadPolicy(const std::shared_ptr<Model>& model);
1820

casbin/util/array_to_string.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
namespace casbin {
2626

2727
std::string ArrayToString(const std::vector<std::string>& arr){
28-
std::string res = arr[0];
28+
std::string res = "";
2929
for (const std::string& it : arr)
3030
res += ", " + it;
31-
return res;
31+
return res.substr(2);
3232
}
3333

3434
} // namespace casbin

include/casbin/casbin_helpers.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,8 @@ namespace casbin {
434434
// NewAdapter is the constructor for Adapter.
435435
FileAdapter(std::string file_path);
436436

437+
static std::shared_ptr<FileAdapter> NewFileAdapter(std::string file_path);
438+
437439
// LoadPolicy loads all policy rules from the storage.
438440
void LoadPolicy(const std::shared_ptr<Model>& model);
439441

@@ -463,6 +465,8 @@ namespace casbin {
463465
// NewAdapter is the constructor for Adapter.
464466
BatchFileAdapter(std::string file_path);
465467

468+
static std::shared_ptr<BatchFileAdapter> NewBatchFileAdapter(std::string file_path);
469+
466470
void AddPolicies(std::string sec, std::string p_type, std::vector<std::vector<std::string>> rules);
467471

468472
void RemovePolicies(std::string sec, std::string p_type, std::vector<std::vector<std::string>> rules);

0 commit comments

Comments
 (0)