Skip to content

Commit dc3224c

Browse files
feat: add wrap IEvaluator for scope. (#183)
* feat: add wrap IEvaluator for scope Signed-off-by: stonex <[email protected]> * fix: copyright Co-authored-by: Yash Pandey (YP) <[email protected]>
1 parent e0cdb29 commit dc3224c

21 files changed

+81513
-272
lines changed

casbin/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(CASBIN_SOURCE_FILES
4343
model/function.cpp
4444
model/model.cpp
4545
model/scope_config.cpp
46+
model/evaluator.cpp
4647
persist/file_adapter/batch_file_adapter.cpp
4748
persist/file_adapter/file_adapter.cpp
4849
persist/file_adapter/filtered_file_adapter.cpp

casbin/enforcer.cpp

Lines changed: 63 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ namespace casbin {
3737
// enforce use a custom matcher to decides whether a "subject" can access a "object"
3838
// with the operation "action", input parameters are usually: (matcher, sub, obj, act),
3939
// use model matcher by default when matcher is "".
40-
bool Enforcer::m_enforce(const std::string& matcher, Scope scope) {
41-
m_func_map.scope = scope;
42-
m_func_map.func_list.clear();
40+
bool Enforcer::m_enforce(const std::string& matcher, std::shared_ptr<IEvaluator> evalator) {
41+
m_func_map.evalator = evalator;
42+
m_func_map.evalator->func_list.clear();
4343
m_func_map.LoadFunctionMap();
4444

4545
if(!m_enabled)
@@ -65,14 +65,13 @@ bool Enforcer::m_enforce(const std::string& matcher, Scope scope) {
6565
if (index != std::string::npos)
6666
exp_string.insert(index + assertion_name.length() + 1, "rm, ");
6767

68-
PushPointer(m_func_map.scope, reinterpret_cast<void *>(rm.get()), "rm");
69-
m_func_map.AddFunction(assertion_name, GFunction, char_count + 1);
68+
m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count + 1);
7069
}
7170
}
7271

7372
// apply function map to current scope.
74-
for(auto func : m_user_func_list)
75-
m_func_map.AddFunction(std::get<0>(func), std::get<1>(func), std::get<2>(func));
73+
// for(auto func : m_user_func_list)
74+
// m_func_map.AddFunction(std::get<0>(func), std::get<1>(func), std::get<2>(func));
7675

7776
bool hasEval = HasEval(exp_string);
7877

@@ -90,21 +89,20 @@ bool Enforcer::m_enforce(const std::string& matcher, Scope scope) {
9089
std::vector<float> matcher_results(policy_len, 0.0f);
9190

9291
if(policy_len != 0) {
93-
if(m_model->m["r"].assertion_map["r"]->tokens.size() != m_func_map.GetRLen())
94-
return false;
92+
// if(m_model->m["r"].assertion_map["r"]->tokens.size() != m_func_map.GetRLen())
93+
// return false;
9594

9695
//TODO
9796
for(int i = 0 ; i < policy_len ; i++) {
9897
std::vector<std::string>& p_vals = m_model->m["p"].assertion_map["p"]->policy[i];
9998
m_log.LogPrint("Policy Rule: ", p_vals);
10099
if(p_tokens.size() != p_vals.size())
101100
return false;
102-
103-
PushObject(m_func_map.scope, "p");
101+
m_func_map.evalator->InitialObject("p");
104102
for(int j = 0 ; j < p_tokens.size() ; j++) {
105103
size_t index = p_tokens[j].find("_");
106104
std::string token = p_tokens[j].substr(index + 1);
107-
PushStringPropToObject(m_func_map.scope, "p", p_vals[j], token);
105+
m_func_map.evalator->PushObjectString("p", token, p_vals[j]);
108106
}
109107

110108
if(hasEval) {
@@ -133,15 +131,14 @@ bool Enforcer::m_enforce(const std::string& matcher, Scope scope) {
133131

134132
//TODO
135133
// log.LogPrint("Result: ", result)
136-
if(CheckType(m_func_map.scope) == Type::Bool) {
137-
bool result = GetBoolean(m_func_map.scope);
138-
if(!result) {
134+
if (m_func_map.evalator->CheckType() == Type::Bool) {
135+
bool result = m_func_map.evalator->GetBoolen();
136+
if (!result) {
139137
policy_effects[i] = Effect::Indeterminate;
140138
continue;
141139
}
142-
}
143-
else if(CheckType(m_func_map.scope) == Type::Float){
144-
float result = GetFloat(m_func_map.scope);
140+
} else if (m_func_map.evalator->CheckType() == Type::Float){
141+
float result = m_func_map.evalator->GetFloat();
145142
if(result == 0.0) {
146143
policy_effects[i] = Effect::Indeterminate;
147144
continue;
@@ -168,13 +165,12 @@ bool Enforcer::m_enforce(const std::string& matcher, Scope scope) {
168165
if(m_model->m["e"].assertion_map["e"]->value == "priority(p_eft) || deny")
169166
break;
170167
}
171-
}
172-
else {
173-
bool isValid = m_func_map.Evaluate(exp_string);
174-
if(!isValid)
168+
} else {
169+
bool isvalid = m_func_map.Evaluate(exp_string);
170+
if (!isvalid) {
175171
return false;
176-
bool result = m_func_map.GetBooleanResult();
177-
172+
}
173+
bool result = m_func_map.evalator->GetBoolen();
178174
//TODO
179175
m_log.LogPrint("Result: ", result);
180176
if (result)
@@ -205,7 +201,7 @@ Enforcer ::Enforcer() {
205201
*/
206202
Enforcer ::Enforcer(const std::string& model_path, const std::string& policy_file)
207203
: Enforcer(model_path, std::make_shared<BatchFileAdapter>(policy_file)) {
208-
}
204+
}
209205

210206
/**
211207
* Enforcer initializes an enforcer with a database adapter.
@@ -297,7 +293,7 @@ void Enforcer::Initialize() {
297293
this->rm = std::make_shared<DefaultRoleManager>(10);
298294
m_eft = std::make_shared<DefaultEffector>();
299295
m_watcher = nullptr;
300-
m_scope = nullptr;
296+
m_evalator = nullptr;
301297

302298
m_enabled = true;
303299
m_auto_save = true;
@@ -310,11 +306,7 @@ void Enforcer::Initialize() {
310306
*
311307
* @step: Release the memory of Enforcer->m_scope
312308
*/
313-
Enforcer::~Enforcer() {
314-
if (this->m_scope != nullptr) {
315-
DeinitializeScope(this->m_scope);
316-
}
317-
}
309+
Enforcer::~Enforcer() {}
318310

319311
// LoadModel reloads the model from the model CONF file.
320312
// Because the policy is attached to a model, so the policy is invalidated and needs
@@ -472,8 +464,8 @@ void Enforcer::BuildIncrementalRoleLinks(policy_op op, const std::string& p_type
472464

473465
// Enforce decides whether a "subject" can access a "object" with the operation "action",
474466
// input parameters are usually: (sub, obj, act).
475-
bool Enforcer::Enforce(Scope scope) {
476-
return this->EnforceWithMatcher("", scope);
467+
bool Enforcer::Enforce(std::shared_ptr<IEvaluator> evalator) {
468+
return this->EnforceWithMatcher("", evalator);
477469
}
478470

479471
// Enforce with a vector param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
@@ -491,8 +483,8 @@ bool Enforcer::Enforce(const DataMap& params) {
491483
}
492484

493485
// 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 "".
494-
bool Enforcer::EnforceWithMatcher(const std::string& matcher, Scope scope) {
495-
return m_enforce(matcher, scope);
486+
bool Enforcer::EnforceWithMatcher(const std::string& matcher, std::shared_ptr<IEvaluator> evalator) {
487+
return m_enforce(matcher, evalator);
496488
}
497489

498490
// 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 "".
@@ -505,40 +497,34 @@ bool Enforcer::EnforceWithMatcher(const std::string& matcher, const DataList& pa
505497
if (cnt != r_cnt)
506498
return false;
507499

508-
if (this->m_scope == nullptr) {
509-
this->m_scope = InitializeScope();
500+
if (this->m_evalator == nullptr) {
501+
this->m_evalator = std::make_shared<DuktapeEvaluator>();
510502
}
511-
Scope scope = this->m_scope;
512503

513-
PushObject(scope, "r");
504+
this->m_evalator->InitialObject("r");
514505

515506
size_t i = 0;
516507

517508
for(const Data& param : params) {
518509
if(const auto string_param = std::get_if<std::string>(&param)) {
519-
PushStringPropToObject(scope, "r", *string_param, r_tokens[i].substr(2, r_tokens[i].size() - 2));
510+
this->m_evalator->PushObjectString("r", r_tokens[i].substr(2, r_tokens[i].size() - 2), *string_param);
520511
} else if (const auto json_param = std::get_if<std::shared_ptr<nlohmann::json>>(&param)) {
521512

522513
auto data_ptr = *json_param;
523514
std::string token_name = r_tokens[i].substr(2, r_tokens[i].size() - 2);
515+
this->m_evalator->PushObjectJson("r", token_name, *data_ptr);
524516

525-
PushObject(scope, token_name);
526-
PushObjectPropFromJson(scope, *data_ptr, token_name);
527-
PushObjectPropToObject(scope, "r", token_name);
528517
}
529518
++i;
530519
}
531520

532-
// for (size_t i = 0; i < cnt; i++) {
533-
// PushStringPropToObject(scope, "r", params[i], r_tokens[i].substr(2, r_tokens[i].size() - 2));
534-
// }
535-
536-
bool result = m_enforce(matcher, scope);
521+
bool result = m_enforce(matcher, m_evalator);
537522

538-
if (scope != nullptr) {
539-
clean_scope("r");
540-
clean_scope("p");
523+
if (m_evalator != nullptr) {
524+
m_evalator->Clean(m_model->m["p"]);
525+
m_evalator->Clean(m_model->m["r"]);
541526
}
527+
542528
return result;
543529
}
544530

@@ -552,70 +538,68 @@ bool Enforcer::EnforceWithMatcher(const std::string& matcher, const DataVector&
552538
if (cnt != r_cnt)
553539
return false;
554540

555-
if (this->m_scope == nullptr) {
556-
this->m_scope = InitializeScope();
541+
if (this->m_evalator == nullptr) {
542+
auto scope = InitializeScope();
543+
this->m_evalator = std::make_shared<DuktapeEvaluator>(scope);
557544
}
558-
Scope scope = this->m_scope;
559-
PushObject(scope, "r");
545+
546+
this->m_evalator->InitialObject("r");
560547

561548
size_t i = 0;
562549

563550
for(const auto& param : params) {
564551
if(const auto string_param = std::get_if<std::string>(&param)) {
565-
PushStringPropToObject(scope, "r", *string_param, r_tokens[i].substr(2, r_tokens[i].size() - 2));
552+
this->m_evalator->PushObjectString("r", r_tokens[i].substr(2, r_tokens[i].size() - 2), *string_param);
566553
} else if (const auto json_param = std::get_if<std::shared_ptr<nlohmann::json>>(&param)) {
567554

568555
auto data_ptr = *json_param;
569556
std::string token_name = r_tokens[i].substr(2, r_tokens[i].size() - 2);
570557

571-
PushObject(scope, token_name);
572-
PushObjectPropFromJson(scope, *data_ptr, token_name);
573-
PushObjectPropToObject(scope, "r", token_name);
558+
this->m_evalator->PushObjectJson("r", token_name, *data_ptr);
574559
}
575560

576561
++i;
577562
}
578563

579-
// for (size_t i = 0; i < cnt; i++) {
580-
// PushStringPropToObject(scope, "r", params[i], r_tokens[i].substr(2, r_tokens[i].size() - 2));
581-
// }
564+
bool result = m_enforce(matcher, m_evalator);
582565

583-
bool result = m_enforce(matcher, scope);
584-
if (scope != nullptr) {
585-
clean_scope("r");
586-
clean_scope("p");
566+
if (m_evalator != nullptr) {
567+
m_evalator->Clean(m_model->m["p"]);
568+
m_evalator->Clean(m_model->m["r"]);
587569
}
570+
588571
return result;
589572
}
590573

591574
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object"
592575
// with the operation "action", input parameters are usually: (matcher, sub, obj, act),
593576
// use model matcher by default when matcher is "".
594577
bool Enforcer::EnforceWithMatcher(const std::string& matcher, const DataMap& params) {
595-
if (this->m_scope == nullptr) {
596-
this->m_scope = InitializeScope();
578+
if (this->m_evalator == nullptr) {
579+
auto scope = InitializeScope();
580+
this->m_evalator = std::make_shared<DuktapeEvaluator>(scope);
597581
}
598-
Scope scope = this->m_scope;
599-
PushObject(scope, "r");
582+
583+
this->m_evalator->InitialObject("r");
600584

601585
for (auto [param_name, param_data] : params) {
602586
if(const auto string_param = std::get_if<std::string>(&param_data)) {
603-
PushStringPropToObject(scope, "r", *string_param, param_name);
587+
this->m_evalator->PushObjectString("r", param_name, *string_param);
604588
} else if (const auto json_param = std::get_if<std::shared_ptr<nlohmann::json>>(&param_data)) {
605589

606590
auto data_ptr = *json_param;
607-
PushObject(scope, param_name);
608-
PushObjectPropFromJson(scope, *data_ptr, param_name);
609-
PushObjectPropToObject(scope, "r", param_name);
591+
this->m_evalator->PushObjectJson("r", param_name, *data_ptr);
610592
}
611593

612594
}
613595

614-
bool result = m_enforce(matcher, scope);
615-
if (scope != nullptr) {
616-
clean_scope("r");
617-
clean_scope("p");
596+
bool result = m_enforce(matcher, m_evalator);
597+
598+
if (m_evalator != nullptr) {
599+
m_evalator->Clean(m_model->m["p"]);
600+
m_evalator->Clean(m_model->m["r"]);
618601
}
602+
619603
return result;
620604
}
621605

@@ -642,16 +626,7 @@ std::vector<bool> Enforcer::BatchEnforceWithMatcher(const std::string& matcher,
642626

643627
// clean scope to prepare next enforce
644628
void Enforcer::clean_scope(std::string section_name) {
645-
auto& section = this->m_model->m[section_name];
646-
for (auto& [assertion_name, assertion]: section.assertion_map) {
647-
std::vector<std::string> raw_tokens = assertion->tokens;
648-
649-
for(int j = 0 ; j < raw_tokens.size() ; j++) {
650-
size_t index = raw_tokens[j].find("_");
651-
std::string token = raw_tokens[j].substr(index + 1);
652-
DeletePropFromObject(this->m_scope, assertion_name, token);
653-
}
654-
}
629+
655630
}
656631

657632
} // namespace casbin

casbin/enforcer.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "./enforcer_interface.h"
2525
#include "./persist/filtered_adapter.h"
2626
#include "./log/log_util.h"
27+
#include "./model/evaluator.h"
2728

2829
namespace casbin {
2930

@@ -39,7 +40,7 @@ class Enforcer : public IEnforcer {
3940

4041
std::shared_ptr<Adapter> m_adapter;
4142
std::shared_ptr<Watcher> m_watcher;
42-
Scope m_scope;
43+
std::shared_ptr<IEvaluator> m_evalator;
4344
LogUtil m_log;
4445

4546
bool m_enabled;
@@ -50,7 +51,7 @@ class Enforcer : public IEnforcer {
5051
// enforce use a custom matcher to decides whether a "subject" can access a "object"
5152
// with the operation "action", input parameters are usually: (matcher, sub, obj, act),
5253
// use model matcher by default when matcher is "".
53-
bool m_enforce(const std::string& matcher, Scope scope);
54+
bool m_enforce(const std::string& matcher, std::shared_ptr<IEvaluator> evalator);
5455
// clean scope to prepare next enforce
5556
void clean_scope(std::string section_name);
5657

@@ -159,15 +160,15 @@ class Enforcer : public IEnforcer {
159160
// BuildIncrementalRoleLinks provides incremental build the role inheritance relations.
160161
void BuildIncrementalRoleLinks(policy_op op, const std::string& p_type, const std::vector<std::vector<std::string>>& rules);
161162
// Enforce decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
162-
bool Enforce(Scope scope);
163+
bool Enforce(std::shared_ptr<IEvaluator> evalator);
163164
// Enforce with a list param, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
164165
bool Enforce(const DataList& params);
165166
// Enforce with a vector param, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
166167
bool Enforce(const DataVector& params);
167168
// Enforce with a map param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
168169
bool Enforce(const DataMap& params);
169170
// 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 "".
170-
bool EnforceWithMatcher(const std::string& matcher, Scope scope);
171+
bool EnforceWithMatcher(const std::string& matcher, std::shared_ptr<IEvaluator> evalator);
171172
// 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 "".
172173
bool EnforceWithMatcher(const std::string& matcher, const DataList& params);
173174
// 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 "".

casbin/enforcer_cached.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ void CachedEnforcer::InvalidateCache() {
144144

145145
// Enforce decides whether a "subject" can access a "object" with the operation
146146
// "action", input parameters are usually: (sub, obj, act).
147-
bool CachedEnforcer ::Enforce(Scope scope) {
148-
return EnforceWithMatcher("", scope);
147+
bool CachedEnforcer ::Enforce(std::shared_ptr<IEvaluator> evalator) {
148+
return EnforceWithMatcher("", evalator);
149149
}
150150

151151
bool CachedEnforcer::Enforce(const DataVector& params) {
@@ -167,8 +167,8 @@ bool CachedEnforcer::Enforce(const DataMap& params) {
167167
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can
168168
// access a "object" with the operation "action", input parameters are usually:
169169
// (matcher, sub, obj, act), use model matcher by default when matcher is "".
170-
bool CachedEnforcer ::EnforceWithMatcher(const std::string& matcher, Scope scope) {
171-
return Enforcer::EnforceWithMatcher(matcher, scope);
170+
bool CachedEnforcer ::EnforceWithMatcher(const std::string& matcher, std::shared_ptr<IEvaluator> evalator) {
171+
return Enforcer::EnforceWithMatcher(matcher, evalator);
172172
}
173173

174174
// EnforceWithMatcher use a custom matcher to decides whether a "subject" can

0 commit comments

Comments
 (0)