1+ /*
2+ * Copyright 2020 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+ #pragma once
18+
19+ #include " pch.h"
20+
21+ #include " ./enforcer_cached.h"
22+ #include " ./persist/watcher_ex.h"
23+ #include " ./persist/file_adapter/file_adapter.h"
24+ #include " ./rbac/default_role_manager.h"
25+ #include " ./effect/default_effector.h"
26+ #include " ./exception/casbin_adapter_exception.h"
27+ #include " ./exception/casbin_enforcer_exception.h"
28+ #include " ./util/util.h"
29+ using namespace std ;
30+
31+
32+ /* *
33+ * Enforcer is the default constructor.
34+ */
35+ CachedEnforcer ::CachedEnforcer () {
36+ this ->enableCache = true ;
37+ }
38+
39+ /* *
40+ * Enforcer initializes an enforcer with a model file and a policy file.
41+ *
42+ * @param model_path the path of the model file.
43+ * @param policyFile the path of the policy file.
44+ */
45+ CachedEnforcer ::CachedEnforcer (string model_path, string policy_file): Enforcer(model_path, policy_file) {
46+ this ->enableCache = true ;
47+ }
48+
49+ /* *
50+ * Enforcer initializes an enforcer with a database adapter.
51+ *
52+ * @param model_path the path of the model file.
53+ * @param adapter the adapter.
54+ */
55+ CachedEnforcer ::CachedEnforcer (string model_path, shared_ptr<Adapter> adapter): Enforcer(model_path,adapter) {
56+ this ->enableCache = true ;
57+ }
58+
59+ /* *
60+ * Enforcer initializes an enforcer with a model and a database adapter.
61+ *
62+ * @param m the model.
63+ * @param adapter the adapter.
64+ */
65+ CachedEnforcer :: CachedEnforcer(shared_ptr<Model> m, shared_ptr<Adapter> adapter): Enforcer(m,adapter) {
66+ this ->enableCache = true ;
67+ }
68+
69+ /* *
70+ * Enforcer initializes an enforcer with a model.
71+ *
72+ * @param m the model.
73+ */
74+ CachedEnforcer ::CachedEnforcer (shared_ptr<Model> m): Enforcer(m) {
75+ this ->enableCache = true ;
76+ }
77+
78+ /* *
79+ * Enforcer initializes an enforcer with a model file.
80+ *
81+ * @param model_path the path of the model file.
82+ */
83+ CachedEnforcer ::CachedEnforcer (string model_path): Enforcer(model_path) {
84+ this ->enableCache = true ;
85+ }
86+
87+ /* *
88+ * Enforcer initializes an enforcer with a model file, a policy file and an enable log flag.
89+ *
90+ * @param model_path the path of the model file.
91+ * @param policyFile the path of the policy file.
92+ * @param enableLog whether to enable Casbin's log.
93+ */
94+ CachedEnforcer :: CachedEnforcer(string model_path, string policy_file, bool enable_log): Enforcer(model_path,policy_file,enable_log) {
95+ this ->enableCache = true ;
96+ }
97+
98+ CachedEnforcer::CachedEnforcer (const CachedEnforcer& ce):Enforcer(ce){
99+ this ->m = ce.m ;
100+ this ->enableCache = ce.enableCache ;
101+ }
102+
103+ CachedEnforcer::CachedEnforcer (CachedEnforcer&& ce):Enforcer(ce){
104+ this ->m = move (ce.m );
105+ this ->enableCache = ce.enableCache ;
106+ }
107+
108+
109+ void CachedEnforcer::EnableCache (const bool & enableCache) {
110+ this ->enableCache = enableCache;
111+ }
112+
113+ pair<bool , bool > CachedEnforcer::getCachedResult (const string& key) {
114+ locker.lock ();
115+ bool ok = m.count (key);
116+ if (!ok) {
117+ locker.unlock ();
118+ return pair<bool , bool >(false , false );
119+ }
120+
121+ pair<bool , bool > res_ok (m[key], ok);
122+ locker.unlock ();
123+ return res_ok;
124+ }
125+
126+ void CachedEnforcer::setCachedResult (const string& key, const bool & res) {
127+ locker.lock ();
128+ m[key] = res;
129+ locker.unlock ();
130+ }
131+
132+ void CachedEnforcer::InvalidateCache () {
133+ m.clear ();
134+ }
135+
136+ // Enforce decides whether a "subject" can access a "object" with the operation
137+ // "action", input parameters are usually: (sub, obj, act).
138+ bool CachedEnforcer ::Enforce (Scope scope) {
139+ return EnforceWithMatcher (" " , scope);
140+ }
141+
142+ // Enforce with a vector param,decides whether a "subject" can access a "object"
143+ // with the operation "action", input parameters are usually: (sub, obj, act).
144+ bool CachedEnforcer::Enforce (vector<string> params) {
145+ return EnforceWithMatcher (" " , params);
146+ }
147+
148+ // Enforce with a map param,decides whether a "subject" can access a "object"
149+ // with the operation "action", input parameters are usually: (sub, obj, act).
150+ bool CachedEnforcer::Enforce (unordered_map<string, string> params) {
151+ return EnforceWithMatcher (" " , params);
152+ }
153+
154+ // EnforceWithMatcher use a custom matcher to decides whether a "subject" can
155+ // access a "object" with the operation "action", input parameters are usually:
156+ // (matcher, sub, obj, act), use model matcher by default when matcher is "".
157+ bool CachedEnforcer ::EnforceWithMatcher (string matcher, Scope scope) {
158+ return Enforcer::EnforceWithMatcher (matcher, scope);
159+ }
160+
161+ // EnforceWithMatcher use a custom matcher to decides whether a "subject" can
162+ // access a "object" with the operation "action", input parameters are usually:
163+ // (matcher, sub, obj, act), use model matcher by default when matcher is "".
164+ bool CachedEnforcer::EnforceWithMatcher (string matcher, vector<string> params) {
165+ if (!enableCache) {
166+ return Enforcer::EnforceWithMatcher (matcher,params);
167+ }
168+
169+ string key;
170+ for (auto r : params) {
171+ key += r;
172+ key += " $$" ;
173+ }
174+ key += matcher;
175+ key += " $" ;
176+
177+ pair<bool , bool > res_ok = getCachedResult (key);
178+
179+ if (res_ok.second ) {
180+ return res_ok.first ;
181+ }
182+
183+ bool res = Enforcer::EnforceWithMatcher (matcher,params);
184+ setCachedResult (key, res);
185+ return res;
186+ }
187+
188+ // EnforceWithMatcher use a custom matcher to decides whether a "subject" can
189+ // access a "object" with the operation "action", input parameters are usually:
190+ // (matcher, sub, obj, act), use model matcher by default when matcher is "".
191+ bool CachedEnforcer::EnforceWithMatcher (string matcher, unordered_map<string, string> params) {
192+ if (!enableCache) {
193+ return Enforcer::EnforceWithMatcher (matcher,params);
194+ }
195+
196+ string key;
197+ for (auto r : params) {
198+ key += r.second ;
199+ key += " $$" ;
200+ }
201+ key += matcher;
202+ key += " $" ;
203+
204+ pair<bool , bool > res_ok = getCachedResult (key);
205+
206+ if (res_ok.second ) {
207+ return res_ok.first ;
208+ }
209+
210+ bool res = Enforcer::EnforceWithMatcher (matcher,params);
211+ setCachedResult (key, res);
212+ return res;
213+ }
0 commit comments