Skip to content

Commit 28553b6

Browse files
authored
feat: exprtk evaluator RBAC with domain (#188)
Signed-off-by: stonex <[email protected]>
1 parent b037fa4 commit 28553b6

File tree

5 files changed

+272
-142
lines changed

5 files changed

+272
-142
lines changed

casbin/enforcer.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,17 @@ bool Enforcer::m_enforce(const std::string& matcher, std::shared_ptr<IEvaluator>
5959
for (auto [assertion_name, assertion] : m_model->m["g"].assertion_map) {
6060
std::shared_ptr<RoleManager>& rm = assertion->rm;
6161

62-
if (dynamic_cast<DuktapeEvaluator*>(m_func_map.evalator.get()) != nullptr) {
6362
int char_count = static_cast<int>(std::count(assertion->value.begin(), assertion->value.end(), '_'));
6463
size_t index = exp_string.find(assertion_name + "(");
6564

66-
if (index != std::string::npos)
67-
exp_string.insert(index + assertion_name.length() + 1, "rm, ");
68-
69-
m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count + 1);
70-
} else {
71-
m_func_map.evalator->LoadGFunction(rm, assertion_name, 0);
72-
}
65+
if (dynamic_cast<DuktapeEvaluator*>(m_func_map.evalator.get()) != nullptr) {
66+
if (index != std::string::npos)
67+
exp_string.insert(index + assertion_name.length() + 1, "rm, ");
7368

69+
m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count + 1);
70+
} else {
71+
m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count);
72+
}
7473
}
7574
}
7675

casbin/model/evaluator.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <regex>
1717

1818
#include "casbin/model/evaluator.h"
19-
#include "casbin/model/exprtk_config.h"
2019
#include "casbin/util/util.h"
2120

2221
namespace casbin {
@@ -50,7 +49,7 @@ namespace casbin {
5049
}
5150

5251
void ExprtkEvaluator::LoadGFunction(std::shared_ptr<RoleManager> rm, const std::string& name, int narg) {
53-
std::shared_ptr<exprtk_func_t> func = std::make_shared<ExprtkGFunction<numerical_type>>(rm);
52+
auto func = ExprtkFunctionFactory::GetExprtkFunction(ExprtkFunctionType::Gfunction, narg, rm);
5453
this->AddFunction(name, func);
5554
}
5655

@@ -59,6 +58,9 @@ namespace casbin {
5958
}
6059

6160
Type ExprtkEvaluator::CheckType() {
61+
if (parser.error_count() != 0) {
62+
throw parser.error();
63+
}
6264
if (expression.value() == float(0) || expression.value() == float(1)) {
6365
return Type::Bool;
6466
} else {

include/casbin/model/evaluator.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,10 @@
2525
#include "../exprtk/exprtk.hpp"
2626
#include "./scope_config.h"
2727
#include "./model.h"
28+
#include "./exprtk_config.h"
2829

2930
namespace casbin {
3031

31-
using numerical_type = float;
32-
33-
using symbol_table_t = exprtk::symbol_table<numerical_type>;
34-
using expression_t = exprtk::expression<numerical_type>;
35-
using parser_t = exprtk::parser<numerical_type>;
36-
using exprtk_func_t = exprtk::igeneric_function<numerical_type>;
37-
3832
class IEvaluator {
3933
public:
4034
std::list<std::string> func_list;

include/casbin/model/exprtk_config.h

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,33 @@
2323
#include "casbin/rbac/role_manager.h"
2424

2525
namespace casbin {
26+
using numerical_type = float;
2627

27-
template <typename T>
28-
struct ExprtkGFunction : public exprtk::igeneric_function<T>
28+
using symbol_table_t = exprtk::symbol_table<numerical_type>;
29+
using expression_t = exprtk::expression<numerical_type>;
30+
using parser_t = exprtk::parser<numerical_type>;
31+
using exprtk_func_t = exprtk::igeneric_function<numerical_type>;
32+
33+
struct ExprtkGFunction : public exprtk::igeneric_function<numerical_type>
2934
{
30-
typedef typename exprtk::igeneric_function<T>::generic_type
35+
typedef typename exprtk::igeneric_function<numerical_type>::generic_type
3136
generic_type;
3237

3338
typedef typename generic_type::scalar_view scalar_t;
3439
typedef typename generic_type::vector_view vector_t;
3540
typedef typename generic_type::string_view string_t;
3641

37-
typedef typename exprtk::igeneric_function<T>::parameter_list_t
42+
typedef typename exprtk::igeneric_function<numerical_type>::parameter_list_t
3843
parameter_list_t;
3944
private:
4045
std::shared_ptr<casbin::RoleManager> rm_;
4146
public:
42-
ExprtkGFunction()
43-
: exprtk::igeneric_function<T>("SS"), rm_(nullptr)
47+
ExprtkGFunction(const std::string& idenfier)
48+
: exprtk::igeneric_function<numerical_type>(idenfier), rm_(nullptr)
4449
{}
4550

46-
ExprtkGFunction(std::shared_ptr<RoleManager> rm)
47-
: exprtk::igeneric_function<T>("SS"), rm_(rm)
51+
ExprtkGFunction(const std::string& idenfier, std::shared_ptr<RoleManager> rm)
52+
: exprtk::igeneric_function<numerical_type>(idenfier), rm_(rm)
4853
{}
4954

5055
bool UpdateRoleManager(std::shared_ptr<RoleManager> rm) {
@@ -53,23 +58,23 @@ namespace casbin {
5358
return true;
5459
}
5560

56-
inline T operator()(parameter_list_t parameters) {
61+
inline numerical_type operator()(parameter_list_t parameters) {
5762
bool res = false;
5863

5964
// check value cnt
60-
if (parameters.size() < 2 || parameters.size() > 3) {
61-
return T(res);
65+
if (parameters.size() != 2 && parameters.size() != 3) {
66+
return numerical_type(res);
6267
}
6368

6469
// check value type
6570
for (std::size_t i = 0; i < parameters.size(); ++i) {
6671
generic_type& gt = parameters[i];
6772

6873
if (generic_type::e_scalar == gt.type) {
69-
return T(res);
74+
return numerical_type(res);
7075
}
7176
else if (generic_type::e_vector == gt.type) {
72-
return T(res);
77+
return numerical_type(res);
7378
}
7479
}
7580

@@ -89,9 +94,25 @@ namespace casbin {
8994
res = rm_->HasLink(name1, name2, domains);
9095
}
9196

92-
return T(res);
97+
return numerical_type(res);
9398
}
9499
};
100+
101+
enum class ExprtkFunctionType {
102+
Gfunction,
103+
};
104+
105+
class ExprtkFunctionFactory {
106+
public:
107+
static std::shared_ptr<exprtk_func_t> GetExprtkFunction(ExprtkFunctionType type, int narg, std::shared_ptr<RoleManager> rm = nullptr) {
108+
if (type == ExprtkFunctionType::Gfunction) {
109+
std::string idenfier(narg, 'S');
110+
return std::make_shared<ExprtkGFunction>(idenfier, rm);
111+
} else {
112+
return nullptr;
113+
}
114+
}
115+
};
95116
}
96117

97118

0 commit comments

Comments
 (0)