Skip to content

Commit 78435a5

Browse files
committed
feat: support updateFilteredPolicies method
1 parent 0b1507f commit 78435a5

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

src/Adapter.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,55 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
306306
});
307307
}
308308

309+
/**
310+
* UpdateFilteredPolicies deletes old rules and adds new rules.
311+
*
312+
* @param string $sec
313+
* @param string $ptype
314+
* @param array $newPolicies
315+
* @param integer $fieldIndex
316+
* @param string ...$fieldValues
317+
* @return array
318+
*/
319+
public function updateFilteredPolicies(string $sec, string $ptype, array $newPolicies, int $fieldIndex, string ...$fieldValues): array
320+
{
321+
$where['ptype'] = $ptype;
322+
foreach ($fieldValues as $fieldValue) {
323+
$suffix = $fieldIndex++;
324+
if (!is_null($fieldValue) && $fieldValue !== '') {
325+
$where['v'. $suffix] = $fieldValue;
326+
}
327+
}
328+
329+
$newP = [];
330+
$oldP = [];
331+
foreach ($newPolicies as $newRule) {
332+
$col['ptype'] = $ptype;
333+
foreach ($newRule as $key => $value) {
334+
$col['v' . strval($key)] = $value;
335+
}
336+
$newP[] = $col;
337+
}
338+
339+
$this->database->action(function () use ($newP, $where, &$oldP) {
340+
$columns = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
341+
$oldP = $this->database->select($this->casbinRuleTableName, $columns, $where);
342+
343+
foreach ($oldP as &$item) {
344+
$item = array_filter($item, function ($value) {
345+
return !is_null($value) && $value !== '';
346+
});
347+
unset($item['ptype']);
348+
}
349+
350+
$this->database->delete($this->casbinRuleTableName, ['AND' => $where]);
351+
$this->database->insert($this->casbinRuleTableName, $newP);
352+
});
353+
354+
// return deleted rules
355+
return $oldP;
356+
}
357+
309358
/**
310359
* Loads only policy rules that match the filter.
311360
*

tests/AdapterTest.php

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,132 @@ public function testUpdatePolicies()
228228
], $e->getPolicy());
229229
}
230230

231+
public function arrayEqualsWithoutOrder(array $expected, array $actual)
232+
{
233+
if (method_exists($this, 'assertEqualsCanonicalizing')) {
234+
$this->assertEqualsCanonicalizing($expected, $actual);
235+
} else {
236+
array_multisort($expected);
237+
array_multisort($actual);
238+
$this->assertEquals($expected, $actual);
239+
}
240+
}
241+
242+
public function testUpdateFilteredPolicies()
243+
{
244+
$e = $this->getEnforcer();
245+
$this->assertEquals([
246+
['alice', 'data1', 'read'],
247+
['bob', 'data2', 'write'],
248+
['data2_admin', 'data2', 'read'],
249+
['data2_admin', 'data2', 'write'],
250+
], $e->getPolicy());
251+
252+
$e->updateFilteredPolicies([["alice", "data1", "write"]], 0, "alice", "data1", "read");
253+
$e->updateFilteredPolicies([["bob", "data2", "read"]], 0, "bob", "data2", "write");
254+
255+
$policies = [
256+
['alice', 'data1', 'write'],
257+
['bob', 'data2', 'read'],
258+
['data2_admin', 'data2', 'read'],
259+
['data2_admin', 'data2', 'write']
260+
];
261+
262+
$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());
263+
264+
// test use updateFilteredPolicies to update all policies of a user
265+
$e = $this->getEnforcer();
266+
$policies = [
267+
['alice', 'data2', 'write'],
268+
['bob', 'data1', 'read']
269+
];
270+
271+
$e->addPolicies($policies);
272+
273+
$this->arrayEqualsWithoutOrder([
274+
['alice', 'data1', 'read'],
275+
['bob', 'data2', 'write'],
276+
['data2_admin', 'data2', 'read'],
277+
['data2_admin', 'data2', 'write'],
278+
['alice', 'data2', 'write'],
279+
['bob', 'data1', 'read']
280+
], $e->getPolicy());
281+
282+
$e->updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice');
283+
$e->updateFilteredPolicies([['bob', 'data1', 'write'], ["bob", "data2", "read"]], 0, 'bob');
284+
285+
$policies = [
286+
['alice', 'data1', 'write'],
287+
['alice', 'data2', 'read'],
288+
['bob', 'data1', 'write'],
289+
['bob', 'data2', 'read'],
290+
['data2_admin', 'data2', 'read'],
291+
['data2_admin', 'data2', 'write']
292+
];
293+
294+
$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());
295+
296+
// test if $fieldValues contains empty string
297+
$e = $this->getEnforcer();
298+
$policies = [
299+
['alice', 'data2', 'write'],
300+
['bob', 'data1', 'read']
301+
];
302+
$e->addPolicies($policies);
303+
304+
$this->assertEquals([
305+
['alice', 'data1', 'read'],
306+
['bob', 'data2', 'write'],
307+
['data2_admin', 'data2', 'read'],
308+
['data2_admin', 'data2', 'write'],
309+
['alice', 'data2', 'write'],
310+
['bob', 'data1', 'read']
311+
], $e->getPolicy());
312+
313+
$e->updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice', '', '');
314+
$e->updateFilteredPolicies([['bob', 'data1', 'write'], ["bob", "data2", "read"]], 0, 'bob', '', '');
315+
316+
$policies = [
317+
['alice', 'data1', 'write'],
318+
['alice', 'data2', 'read'],
319+
['bob', 'data1', 'write'],
320+
['bob', 'data2', 'read'],
321+
['data2_admin', 'data2', 'read'],
322+
['data2_admin', 'data2', 'write']
323+
];
324+
325+
$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());
326+
327+
// test if $fieldIndex is not zero
328+
$e = $this->getEnforcer();
329+
$policies = [
330+
['alice', 'data2', 'write'],
331+
['bob', 'data1', 'read']
332+
];
333+
$e->addPolicies($policies);
334+
335+
$this->assertEquals([
336+
['alice', 'data1', 'read'],
337+
['bob', 'data2', 'write'],
338+
['data2_admin', 'data2', 'read'],
339+
['data2_admin', 'data2', 'write'],
340+
['alice', 'data2', 'write'],
341+
['bob', 'data1', 'read']
342+
], $e->getPolicy());
343+
344+
$e->updateFilteredPolicies([['alice', 'data1', 'edit'], ['bob', 'data1', 'edit']], 2, 'read');
345+
$e->updateFilteredPolicies([['alice', 'data2', 'read'], ["bob", "data2", "read"]], 2, 'write');
346+
347+
$policies = [
348+
['alice', 'data1', 'edit'],
349+
['alice', 'data2', 'read'],
350+
['bob', 'data1', 'edit'],
351+
['bob', 'data2', 'read'],
352+
];
353+
354+
$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());
355+
}
356+
231357
public function testLoadFilteredPolicy()
232358
{
233359
$e = $this->getEnforcer();

0 commit comments

Comments
 (0)