Skip to content

Commit

Permalink
Merge 0338251 into 322f077
Browse files Browse the repository at this point in the history
  • Loading branch information
basakest committed Sep 2, 2021
2 parents 322f077 + 0338251 commit 2c215ca
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .gitignore
Expand Up @@ -6,4 +6,6 @@ composer.lock
*.iml

# coverage report
/build
/build

.phpunit.*
64 changes: 64 additions & 0 deletions src/Adapter.php
Expand Up @@ -328,4 +328,68 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
throw $e;
}
}

/**
* UpdateFilteredPolicies deletes old rules and adds new rules.
*
* @param string $sec
* @param string $ptype
* @param array $newPolicies
* @param integer $fieldIndex
* @param string ...$fieldValues
* @return array
*/
public function updateFilteredPolicies(string $sec, string $ptype, array $newPolicies, int $fieldIndex, string ...$fieldValues): array
{
$deleteWhere['ptype'] = $ptype;
$deleteCondition[] = 'ptype = :ptype';
foreach ($fieldValues as $value) {
if (!is_null($value) && $value !== '') {
$key = $fieldIndex++;
$placeholder = "v" . strval($key);
$deleteWhere['v' . strval($key)] = $value;
$deleteCondition[] = 'v' . strval($key) . ' = :' . $placeholder;
}
}
$deleteSql = "DELETE FROM {$this->casbinRuleTableName} WHERE " . implode(' AND ', $deleteCondition);

$selectSql = "SELECT * FROM {$this->casbinRuleTableName} WHERE " . implode(' AND ', $deleteCondition);
$oldP = $this->connection->query($selectSql, $deleteWhere);
foreach ($oldP as &$item) {
$item = array_filter($item, function ($value) {
return !is_null($value) && $value !== '';
});
unset($item['ptype']);
unset($item['id']);
}

$columns = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
$values = [];
$sets = [];
$columnsCount = count($columns);
foreach ($newPolicies as $newPolicy) {
array_unshift($newPolicy, $ptype);
$values = array_merge($values, array_pad($newPolicy, $columnsCount, null));
$sets[] = array_pad([], $columnsCount, '?');
}
$valuesStr = implode(', ', array_map(function ($set) {
return '(' . implode(', ', $set) . ')';
}, $sets));
$insertSql = 'INSERT INTO ' . $this->casbinRuleTableName . ' (' . implode(', ', $columns) . ')' . ' VALUES ' . $valuesStr;

// start transaction
$this->connection->getPdo()->beginTransaction();
try {
// delete old data
$this->connection->execute($deleteSql, $deleteWhere);
// insert new data
$this->connection->execute($insertSql, $values);
$this->connection->getPdo()->commit();
} catch (Throwable $e) {
$this->connection->getPdo()->rollback();
throw $e;
}

return $oldP;
}
}
125 changes: 125 additions & 0 deletions tests/AdapterTest.php
Expand Up @@ -273,6 +273,131 @@ public function testUpdatePolicies()
], $e->getPolicy());
}

public function arrayEqualsWithoutOrder(array $expected, array $actual)
{
if (method_exists($this, 'assertEqualsCanonicalizing')) {
$this->assertEqualsCanonicalizing($expected, $actual);
} else {
array_multisort($expected);
array_multisort($actual);
$this->assertEquals($expected, $actual);
}
}

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

$e->updateFilteredPolicies([["alice", "data1", "write"]], 0, "alice", "data1", "read");
$e->updateFilteredPolicies([["bob", "data2", "read"]], 0, "bob", "data2", "write");

$policies = [
['alice', 'data1', 'write'],
['bob', 'data2', 'read'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write']
];

$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());

// test use updateFilteredPolicies to update all policies of a user
$e = $this->getEnforcer();
$policies = [
['alice', 'data2', 'write'],
['bob', 'data1', 'read']
];
$e->addPolicies($policies);

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

$e->updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice');
$e->updateFilteredPolicies([['bob', 'data1', 'write'], ["bob", "data2", "read"]], 0, 'bob');

$policies = [
['alice', 'data1', 'write'],
['alice', 'data2', 'read'],
['bob', 'data1', 'write'],
['bob', 'data2', 'read'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write']
];

$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());

// test if $fieldValues contains empty string
$e = $this->getEnforcer();
$policies = [
['alice', 'data2', 'write'],
['bob', 'data1', 'read']
];
$e->addPolicies($policies);

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

$e->updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice', '', '');
$e->updateFilteredPolicies([['bob', 'data1', 'write'], ["bob", "data2", "read"]], 0, 'bob', '', '');

$policies = [
['alice', 'data1', 'write'],
['alice', 'data2', 'read'],
['bob', 'data1', 'write'],
['bob', 'data2', 'read'],
['data2_admin', 'data2', 'read'],
['data2_admin', 'data2', 'write']
];

$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());

// test if $fieldIndex is not zero
$e = $this->getEnforcer();
$policies = [
['alice', 'data2', 'write'],
['bob', 'data1', 'read']
];
$e->addPolicies($policies);

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

$e->updateFilteredPolicies([['alice', 'data1', 'edit'], ['bob', 'data1', 'edit']], 2, 'read');
$e->updateFilteredPolicies([['alice', 'data2', 'read'], ["bob", "data2", "read"]], 2, 'write');

$policies = [
['alice', 'data1', 'edit'],
['alice', 'data2', 'read'],
['bob', 'data1', 'edit'],
['bob', 'data2', 'read'],
];

$this->arrayEqualsWithoutOrder($policies, $e->getPolicy());
}

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

0 comments on commit 2c215ca

Please sign in to comment.