Skip to content

Commit

Permalink
feat: exprtk evaluator RBAC with domain (#188)
Browse files Browse the repository at this point in the history
Signed-off-by: stonex <1479765922@qq.com>
  • Loading branch information
sheny1xuan authored Mar 13, 2022
1 parent b037fa4 commit 28553b6
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 142 deletions.
15 changes: 7 additions & 8 deletions casbin/enforcer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,17 @@ bool Enforcer::m_enforce(const std::string& matcher, std::shared_ptr<IEvaluator>
for (auto [assertion_name, assertion] : m_model->m["g"].assertion_map) {
std::shared_ptr<RoleManager>& rm = assertion->rm;

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

if (index != std::string::npos)
exp_string.insert(index + assertion_name.length() + 1, "rm, ");

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

m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count + 1);
} else {
m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count);
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions casbin/model/evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <regex>

#include "casbin/model/evaluator.h"
#include "casbin/model/exprtk_config.h"
#include "casbin/util/util.h"

namespace casbin {
Expand Down Expand Up @@ -50,7 +49,7 @@ namespace casbin {
}

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

Expand All @@ -59,6 +58,9 @@ namespace casbin {
}

Type ExprtkEvaluator::CheckType() {
if (parser.error_count() != 0) {
throw parser.error();
}
if (expression.value() == float(0) || expression.value() == float(1)) {
return Type::Bool;
} else {
Expand Down
8 changes: 1 addition & 7 deletions include/casbin/model/evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,10 @@
#include "../exprtk/exprtk.hpp"
#include "./scope_config.h"
#include "./model.h"
#include "./exprtk_config.h"

namespace casbin {

using numerical_type = float;

using symbol_table_t = exprtk::symbol_table<numerical_type>;
using expression_t = exprtk::expression<numerical_type>;
using parser_t = exprtk::parser<numerical_type>;
using exprtk_func_t = exprtk::igeneric_function<numerical_type>;

class IEvaluator {
public:
std::list<std::string> func_list;
Expand Down
49 changes: 35 additions & 14 deletions include/casbin/model/exprtk_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,33 @@
#include "casbin/rbac/role_manager.h"

namespace casbin {
using numerical_type = float;

template <typename T>
struct ExprtkGFunction : public exprtk::igeneric_function<T>
using symbol_table_t = exprtk::symbol_table<numerical_type>;
using expression_t = exprtk::expression<numerical_type>;
using parser_t = exprtk::parser<numerical_type>;
using exprtk_func_t = exprtk::igeneric_function<numerical_type>;

struct ExprtkGFunction : public exprtk::igeneric_function<numerical_type>
{
typedef typename exprtk::igeneric_function<T>::generic_type
typedef typename exprtk::igeneric_function<numerical_type>::generic_type
generic_type;

typedef typename generic_type::scalar_view scalar_t;
typedef typename generic_type::vector_view vector_t;
typedef typename generic_type::string_view string_t;

typedef typename exprtk::igeneric_function<T>::parameter_list_t
typedef typename exprtk::igeneric_function<numerical_type>::parameter_list_t
parameter_list_t;
private:
std::shared_ptr<casbin::RoleManager> rm_;
public:
ExprtkGFunction()
: exprtk::igeneric_function<T>("SS"), rm_(nullptr)
ExprtkGFunction(const std::string& idenfier)
: exprtk::igeneric_function<numerical_type>(idenfier), rm_(nullptr)
{}

ExprtkGFunction(std::shared_ptr<RoleManager> rm)
: exprtk::igeneric_function<T>("SS"), rm_(rm)
ExprtkGFunction(const std::string& idenfier, std::shared_ptr<RoleManager> rm)
: exprtk::igeneric_function<numerical_type>(idenfier), rm_(rm)
{}

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

inline T operator()(parameter_list_t parameters) {
inline numerical_type operator()(parameter_list_t parameters) {
bool res = false;

// check value cnt
if (parameters.size() < 2 || parameters.size() > 3) {
return T(res);
if (parameters.size() != 2 && parameters.size() != 3) {
return numerical_type(res);
}

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

if (generic_type::e_scalar == gt.type) {
return T(res);
return numerical_type(res);
}
else if (generic_type::e_vector == gt.type) {
return T(res);
return numerical_type(res);
}
}

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

return T(res);
return numerical_type(res);
}
};

enum class ExprtkFunctionType {
Gfunction,
};

class ExprtkFunctionFactory {
public:
static std::shared_ptr<exprtk_func_t> GetExprtkFunction(ExprtkFunctionType type, int narg, std::shared_ptr<RoleManager> rm = nullptr) {
if (type == ExprtkFunctionType::Gfunction) {
std::string idenfier(narg, 'S');
return std::make_shared<ExprtkGFunction>(idenfier, rm);
} else {
return nullptr;
}
}
};
}


Expand Down
Loading

0 comments on commit 28553b6

Please sign in to comment.