Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions src/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Casbin\Persist\Adapter as AdapterContract;
use Casbin\Persist\BatchAdapter as BatchAdapterContract;
use Casbin\Persist\FilteredAdapter as FilteredAdapterContract;
use Casbin\Persist\UpdatableAdapter as UpdatableAdapterContract;
use Casbin\Persist\AdapterHelper;
use Laminas\Db\Adapter\AdapterInterface as LaminasDbAdapterInterface;
use Laminas\Db\Adapter\Adapter as LaminasDbAdapter;
Expand All @@ -20,7 +21,7 @@
*
* @author [email protected]
*/
class Adapter implements AdapterContract, BatchAdapterContract, FilteredAdapterContract
class Adapter implements AdapterContract, BatchAdapterContract, FilteredAdapterContract, UpdatableAdapterContract
{
use AdapterHelper;

Expand Down Expand Up @@ -214,11 +215,16 @@ public function removePolicy($sec, $ptype, $rule): void
*/
public function removePolicies(string $sec, string $ptype, array $rules): void
{
$this->tableGateway->adapter->getDriver()->getConnection()->beginTransaction(function () use ($sec, $ptype, $rules) {
try {
$connection = $this->tableGateway->adapter->getDriver()->getConnection();
$connection->beginTransaction();
foreach ($rules as $rule) {
$this->removePolicy($sec, $ptype, $rule);
}
});
$connection->commit();
} catch (\Exception $e) {
$connection->rollback();
}
}

/**
Expand Down Expand Up @@ -296,4 +302,50 @@ public function setFiltered(bool $filtered): void
{
$this->filtered = $filtered;
}

/**
* Updates a policy rule from storage.
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param string[] $oldRule
* @param string[] $newPolicy
*/
public function updatePolicy(string $sec, string $ptype, array $oldRule, array $newPolicy): void
{
$where['ptype'] = $ptype;
foreach ($oldRule as $k => $v) {
$where['v' . $k] = $v;
}

$data = [];
foreach ($newPolicy as $k => $v) {
$data['v' . $k] = $v;
}
$this->tableGateway->update($data, $where);
}

/**
* UpdatePolicies updates some policy rules to storage, like db, redis.
*
* @param string $sec
* @param string $ptype
* @param string[][] $oldRules
* @param string[][] $newRules
* @return void
*/
public function updatePolicies(string $sec, string $ptype, array $oldRules, array $newRules): void
{
try {
$connection = $this->tableGateway->adapter->getDriver()->getConnection();
$connection->beginTransaction();
foreach ($oldRules as $i => $oldRule) {
$this->updatePolicy($sec, $ptype, $oldRule, $newRules[$i]);
}
$connection->commit();
} catch (\Exception $e) {
$connection->rollback();
}
}
}
57 changes: 57 additions & 0 deletions tests/AdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,63 @@ public function testLoadFilteredPolicy()
], $e->getPolicy());
}

public function testUpdatePolicy()
{
$e = $this->getEnforcer();
$this->assertEquals([
['alice', 'data1', 'read'],
['bob', 'data2', 'write'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write'],
], $e->getPolicy());

$e->updatePolicy(
['alice', 'data1', 'read'],
['alice', 'data1', 'write']
);

$e->updatePolicy(
['bob', 'data2', 'write'],
['bob', 'data2', 'read']
);

$this->assertEquals([
['alice', 'data1', 'write'],
['bob', 'data2', 'read'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write'],
], $e->getPolicy());
}

public function testUpdatePolicies()
{
$e = $this->getEnforcer();
$this->assertEquals([
['alice', 'data1', 'read'],
['bob', 'data2', 'write'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write'],
], $e->getPolicy());

$oldPolicies = [
['alice', 'data1', 'read'],
['bob', 'data2', 'write']
];
$newPolicies = [
['alice', 'data1', 'write'],
['bob', 'data2', 'read']
];

$e->updatePolicies($oldPolicies, $newPolicies);

$this->assertEquals([
['alice', 'data1', 'write'],
['bob', 'data2', 'read'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write'],
], $e->getPolicy());
}

protected function env($key, $default = null)
{
$value = getenv($key);
Expand Down