Skip to content

Commit

Permalink
Merge pull request #4 from php-casbin/develop
Browse files Browse the repository at this point in the history
feat: implements updateFilteredPolicies
  • Loading branch information
leeqvip committed Sep 9, 2021
2 parents 5f101c0 + 2563953 commit 42952a9
Show file tree
Hide file tree
Showing 7 changed files with 401 additions and 225 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: Default

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
on: [push, pull_request]

jobs:
test:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ composer.lock
*.iml

# coverage report
/build
/build

.phpunit.*
1 change: 0 additions & 1 deletion .phpunit.result.cache

This file was deleted.

125 changes: 102 additions & 23 deletions src/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
use Casbin\Persist\UpdatableAdapter;
use Closure;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Query\Expression\CompositeExpression;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\Schema;
use Throwable;

/**
Expand Down Expand Up @@ -47,6 +49,11 @@ class Adapter implements FilteredAdapter, BatchAdapter, UpdatableAdapter
*/
private $filtered = false;

/**
* @var string[]
*/
protected $columns = ['p_type', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];

/**
* Adapter constructor.
*
Expand Down Expand Up @@ -93,7 +100,7 @@ public function initTable()
{
$sm = $this->connection->getSchemaManager();
if (!$sm->tablesExist([$this->policyTableName])) {
$schema = new \Doctrine\DBAL\Schema\Schema();
$schema = new Schema();
$table = $schema->createTable($this->policyTableName);
$table->addColumn('id', 'integer', array('autoincrement' => true));
$table->addColumn('p_type', 'string', ['notnull' => false]);
Expand Down Expand Up @@ -144,10 +151,7 @@ public function loadPolicy(Model $model): void
$stmt = $queryBuilder->select('p_type', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5')->from($this->policyTableName)->execute();

while ($row = $this->fetch($stmt)) {
$line = implode(', ', array_filter($row, function ($val) {
return '' != $val && !is_null($val);
}));
$this->loadPolicyLine(trim($line), $model);
$this->loadPolicyArray($this->filterRule($row), $model);
}
}

Expand Down Expand Up @@ -228,8 +232,7 @@ public function addPolicy(string $sec, string $ptype, array $rule): void
* @param string $ptype
* @param string[][] $rules
*
* @throws Exception
* @throws \Doctrine\DBAL\DBALException
* @throws DBALException
*/
public function addPolicies(string $sec, string $ptype, array $rules): void
{
Expand Down Expand Up @@ -306,6 +309,41 @@ public function removePolicies(string $sec, string $ptype, array $rules): void
});
}

/**
* @param string $sec
* @param string $ptype
* @param int $fieldIndex
* @param string|null ...$fieldValues
* @return array
* @throws Throwable
*/
public function _removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, ?string ...$fieldValues): array
{
$removedRules = [];
$this->connection->transactional(function (Connection $conn) use ($ptype, $fieldIndex, $fieldValues, &$removedRules) {
$queryBuilder = $conn->createQueryBuilder();
$queryBuilder->where('p_type = :ptype')->setParameter('ptype', $ptype);

foreach ($fieldValues as $value) {
if (!is_null($value) && $value !== '') {
$key = 'v' . strval($fieldIndex);
$queryBuilder->andWhere($key . ' = :' . $key)->setParameter($key, $value);
}
$fieldIndex++;
}

$stmt = $queryBuilder->select(...$this->columns)->from($this->policyTableName)->execute();

while ($row = $this->fetch($stmt)) {
$removedRules[] = $this->filterRule($row);
}

$queryBuilder->delete($this->policyTableName)->execute();
});

return $removedRules;
}

/**
* RemoveFilteredPolicy removes policy rules that match the filter from the storage.
* This is part of the Auto-Save feature.
Expand All @@ -314,23 +352,11 @@ public function removePolicies(string $sec, string $ptype, array $rules): void
* @param string $ptype
* @param int $fieldIndex
* @param string ...$fieldValues
* @throws Exception
* @throws Exception|Throwable
*/
public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, string ...$fieldValues): void
{
$queryBuilder = $this->connection->createQueryBuilder();
$queryBuilder->where('p_type = :ptype')->setParameter('ptype', $ptype);

foreach (range(0, 5) as $value) {
if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) {
if ('' != $val = $fieldValues[$value - $fieldIndex]) {
$key = 'v' . strval($value);
$queryBuilder->andWhere($key . ' = :' . $key)->setParameter($key, $val);
}
}
}

$queryBuilder->delete($this->policyTableName)->execute();
$this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues);
}

/**
Expand Down Expand Up @@ -369,6 +395,7 @@ public function updatePolicy(string $sec, string $ptype, array $oldRule, array $
* @param string[][] $oldRules
* @param string[][] $newRules
* @return void
* @throws Throwable
*/
public function updatePolicies(string $sec, string $ptype, array $oldRules, array $newRules): void
{
Expand All @@ -379,6 +406,46 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
});
}

/**
* @param string $sec
* @param string $ptype
* @param array $newRules
* @param int $fieldIndex
* @param string ...$fieldValues
* @return array
* @throws Throwable
*/
public function updateFilteredPolicies(string $sec, string $ptype, array $newRules, int $fieldIndex, ?string ...$fieldValues): array
{
$oldRules = [];
$this->getConnection()->transactional(function ($conn) use ($sec, $ptype, $newRules, $fieldIndex, $fieldValues, &$oldRules) {
$oldRules = $this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues);
$this->addPolicies($sec, $ptype, $newRules);
});

return $oldRules;
}

/**
* Filter the rule.
*
* @param array $rule
* @return array
*/
public function filterRule(array $rule): array
{
$rule = array_values($rule);

$i = count($rule) - 1;
for (; $i >= 0; $i--) {
if ($rule[$i] != "" && !is_null($rule[$i])) {
break;
}
}

return array_slice($rule, 0, $i + 1);
}

/**
* Returns true if the loaded policy has been filtered.
*
Expand Down Expand Up @@ -409,17 +476,29 @@ public function getConnection(): Connection
return $this->connection;
}

/**
* Gets columns.
*
* @return string[]
*/
public function getColumns(): array
{
return $this->columns;
}

/**
* @param mixed $stmt
*
* @return mixed
* @throws Exception
*/
private function fetch($stmt)
private function fetch(Result $stmt)
{
if (method_exists($stmt, 'fetchAssociative')) {
return $stmt->fetchAssociative();
}

return $stmt->fetch();
}

}
Loading

0 comments on commit 42952a9

Please sign in to comment.