Skip to content

Commit 9676f0b

Browse files
authored
feat: support updateFilteredPolicies method (#29)
feat: support updateFilteredPolicies method
1 parent 877f2f2 commit 9676f0b

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

src/Adapters/DatabaseAdapter.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use DateTime;
1616
use Casbin\Exceptions\InvalidFilterTypeException;
1717
use Illuminate\Support\Facades\DB;
18+
1819
/**
1920
* DatabaseAdapter.
2021
*
@@ -242,6 +243,54 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
242243
});
243244
}
244245

246+
/**
247+
* UpdateFilteredPolicies deletes old rules and adds new rules.
248+
*
249+
* @param string $sec
250+
* @param string $ptype
251+
* @param array $newPolicies
252+
* @param integer $fieldIndex
253+
* @param string ...$fieldValues
254+
* @return array
255+
*/
256+
public function updateFilteredPolicies(string $sec, string $ptype, array $newPolicies, int $fieldIndex, string ...$fieldValues): array
257+
{
258+
$where['p_type'] = $ptype;
259+
foreach ($fieldValues as $fieldValue) {
260+
if (!is_null($fieldValue) && $fieldValue !== '') {
261+
$where['v'. $fieldIndex++] = $fieldValue;
262+
}
263+
}
264+
265+
$newP = [];
266+
$oldP = [];
267+
foreach ($newPolicies as $newRule) {
268+
$col['p_type'] = $ptype;
269+
foreach ($newRule as $key => $value) {
270+
$col['v' . strval($key)] = $value;
271+
}
272+
$newP[] = $col;
273+
}
274+
275+
DB::transaction(function () use ($newP, $where, &$oldP) {
276+
$oldRules = $this->eloquent->where($where);
277+
$oldP = $oldRules->get()->makeHidden(['created_at','updated_at', 'id'])->toArray();
278+
279+
foreach ($oldP as &$item) {
280+
$item = array_filter($item, function ($value) {
281+
return !is_null($value) && $value !== '';
282+
});
283+
unset($item['p_type']);
284+
}
285+
286+
$oldRules->delete();
287+
$this->eloquent->create($newP);
288+
});
289+
290+
// return deleted rules
291+
return $oldP;
292+
}
293+
245294
/**
246295
* Loads only policy rules that match the filter.
247296
*

tests/DatabaseAdapterTest.php

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,133 @@ public function testUpdatePolicies()
159159
], Enforcer::getPolicy());
160160
}
161161

162+
public function arrayEqualsWithoutOrder(array $expected, array $actual)
163+
{
164+
if (method_exists($this, 'assertEqualsCanonicalizing')) {
165+
$this->assertEqualsCanonicalizing($expected, $actual);
166+
} else {
167+
array_multisort($expected);
168+
array_multisort($actual);
169+
$this->assertEquals($expected, $actual);
170+
}
171+
}
172+
173+
public function testUpdateFilteredPolicies()
174+
{
175+
$this->assertEquals([
176+
['alice', 'data1', 'read'],
177+
['bob', 'data2', 'write'],
178+
['data2_admin', 'data2', 'read'],
179+
['data2_admin', 'data2', 'write'],
180+
], Enforcer::getPolicy());
181+
182+
Enforcer::updateFilteredPolicies([["alice", "data1", "write"]], 0, "alice", "data1", "read");
183+
Enforcer::updateFilteredPolicies([["bob", "data2", "read"]], 0, "bob", "data2", "write");
184+
185+
$policies = [
186+
['alice', 'data1', 'write'],
187+
['bob', 'data2', 'read'],
188+
['data2_admin', 'data2', 'read'],
189+
['data2_admin', 'data2', 'write']
190+
];
191+
192+
$this->arrayEqualsWithoutOrder($policies, Enforcer::getPolicy());
193+
194+
// test use updateFilteredPolicies to update all policies of a user
195+
$this->initTable();
196+
Enforcer::loadPolicy();
197+
$policies = [
198+
['alice', 'data2', 'write'],
199+
['bob', 'data1', 'read']
200+
];
201+
Enforcer::addPolicies($policies);
202+
203+
$this->arrayEqualsWithoutOrder([
204+
['alice', 'data1', 'read'],
205+
['bob', 'data2', 'write'],
206+
['data2_admin', 'data2', 'read'],
207+
['data2_admin', 'data2', 'write'],
208+
['alice', 'data2', 'write'],
209+
['bob', 'data1', 'read']
210+
], Enforcer::getPolicy());
211+
212+
Enforcer::updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice');
213+
Enforcer::updateFilteredPolicies([['bob', 'data1', 'write'], ["bob", "data2", "read"]], 0, 'bob');
214+
215+
$policies = [
216+
['alice', 'data1', 'write'],
217+
['alice', 'data2', 'read'],
218+
['bob', 'data1', 'write'],
219+
['bob', 'data2', 'read'],
220+
['data2_admin', 'data2', 'read'],
221+
['data2_admin', 'data2', 'write']
222+
];
223+
224+
$this->arrayEqualsWithoutOrder($policies, Enforcer::getPolicy());
225+
226+
// test if $fieldValues contains empty string
227+
$this->initTable();
228+
Enforcer::loadPolicy();
229+
$policies = [
230+
['alice', 'data2', 'write'],
231+
['bob', 'data1', 'read']
232+
];
233+
Enforcer::addPolicies($policies);
234+
235+
$this->assertEquals([
236+
['alice', 'data1', 'read'],
237+
['bob', 'data2', 'write'],
238+
['data2_admin', 'data2', 'read'],
239+
['data2_admin', 'data2', 'write'],
240+
['alice', 'data2', 'write'],
241+
['bob', 'data1', 'read']
242+
], Enforcer::getPolicy());
243+
244+
Enforcer::updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice', '', '');
245+
Enforcer::updateFilteredPolicies([['bob', 'data1', 'write'], ["bob", "data2", "read"]], 0, 'bob', '', '');
246+
247+
$policies = [
248+
['alice', 'data1', 'write'],
249+
['alice', 'data2', 'read'],
250+
['bob', 'data1', 'write'],
251+
['bob', 'data2', 'read'],
252+
['data2_admin', 'data2', 'read'],
253+
['data2_admin', 'data2', 'write']
254+
];
255+
256+
$this->arrayEqualsWithoutOrder($policies, Enforcer::getPolicy());
257+
258+
// test if $fieldIndex is not zero
259+
$this->initTable();
260+
Enforcer::loadPolicy();
261+
$policies = [
262+
['alice', 'data2', 'write'],
263+
['bob', 'data1', 'read']
264+
];
265+
Enforcer::addPolicies($policies);
266+
267+
$this->assertEquals([
268+
['alice', 'data1', 'read'],
269+
['bob', 'data2', 'write'],
270+
['data2_admin', 'data2', 'read'],
271+
['data2_admin', 'data2', 'write'],
272+
['alice', 'data2', 'write'],
273+
['bob', 'data1', 'read']
274+
], Enforcer::getPolicy());
275+
276+
Enforcer::updateFilteredPolicies([['alice', 'data1', 'write'], ['bob', 'data1', 'write']], 2, 'read');
277+
Enforcer::updateFilteredPolicies([['alice', 'data2', 'read'], ["bob", "data2", "read"]], 2, 'write');
278+
279+
$policies = [
280+
['alice', 'data1', 'write'],
281+
['alice', 'data2', 'read'],
282+
['bob', 'data1', 'write'],
283+
['bob', 'data2', 'read'],
284+
];
285+
286+
$this->arrayEqualsWithoutOrder($policies, Enforcer::getPolicy());
287+
}
288+
162289
public function testLoadFilteredPolicy()
163290
{
164291
$this->initTable();

0 commit comments

Comments
 (0)