Skip to content

Commit e14c507

Browse files
committed
add unit test
1 parent dc1fc93 commit e14c507

File tree

3 files changed

+136
-50
lines changed

3 files changed

+136
-50
lines changed

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ before_install:
1818
install:
1919
- travis_retry composer install --no-suggest --no-interaction
2020

21+
before_script:
22+
- export XDEBUG_MODE=coverage
23+
2124
script:
2225
- vendor/bin/phpunit --version
2326
- mkdir -p build/logs
24-
- XDEBUG_MODE=coverage vendor/bin/phpunit
27+
- vendor/bin/phpunit
2528

2629
after_script:
2730
- travis_retry vendor/bin/php-coveralls -v

src/Adapter.php

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Casbin\Persist\FilteredAdapter;
1010
use Casbin\Persist\Adapters\Filter;
1111
use Casbin\Exceptions\InvalidFilterTypeException;
12+
use Closure;
1213

1314
/**
1415
* DatabaseAdapter.
@@ -27,6 +28,8 @@ class Adapter implements AdapterContract, FilteredAdapter
2728

2829
public $casbinRuleTableName = 'casbin_rule';
2930

31+
public $rows = [];
32+
3033
public function __construct(array $config)
3134
{
3235
$this->config = $config;
@@ -45,6 +48,16 @@ public function isFiltered(): bool
4548
return $this->filtered;
4649
}
4750

51+
/**
52+
* Sets filtered parameter.
53+
*
54+
* @param bool $filtered
55+
*/
56+
public function setFiltered(bool $filtered): void
57+
{
58+
$this->filtered = $filtered;
59+
}
60+
4861
public static function newAdapter(array $config)
4962
{
5063
return new static($config);
@@ -90,55 +103,6 @@ public function loadPolicy(Model $model): void
90103
}
91104
}
92105

93-
/**
94-
* Loads only policy rules that match the filter from storage.
95-
*
96-
* @param Model $model
97-
* @param mixed $filter
98-
*
99-
* @throws CasbinException
100-
*/
101-
public function loadFilteredPolicy(Model $model, $filter): void
102-
{
103-
// if $filter is empty, load all policies
104-
if (is_null($filter)) {
105-
$this->loadPolicy($model);
106-
return;
107-
}
108-
// validate $filter is a instance of Filter
109-
if (!$filter instanceof Filter) {
110-
throw new InvalidFilterTypeException('invalid filter type');
111-
}
112-
$type = '';
113-
$filter = (array) $filter;
114-
// choose which ptype to use
115-
foreach($filter as $i => $v) {
116-
if (!empty($v)) {
117-
array_unshift($filter[$i], $i);
118-
$type = $i;
119-
break;
120-
}
121-
}
122-
$sql = 'SELECT ptype, v0, v1, v2, v3, v4, v5 FROM '.$this->casbinRuleTableName . ' WHERE ';
123-
$items = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
124-
$temp = [];
125-
$values = [];
126-
foreach($items as $i => $item) {
127-
if (isset($filter[$type][$i]) && !empty($filter[$type][$i])) {
128-
array_push($temp, $item . '=:' . $item);
129-
$values[$item] = $filter[$type][$i];
130-
}
131-
}
132-
$sql .= implode(' and ', $temp);
133-
$rows = $this->connection->query($sql, $values);
134-
foreach($rows as $row) {
135-
$line = implode(', ', $row);
136-
$this->loadPolicyLine($line, $model);
137-
}
138-
139-
$this->filtered = true;
140-
}
141-
142106
/**
143107
* saves all policy rules to the storage.
144108
*
@@ -219,4 +183,61 @@ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex
219183

220184
$this->connection->execute($sql, $where);
221185
}
186+
187+
/**
188+
* Loads only policy rules that match the filter from storage.
189+
*
190+
* @param Model $model
191+
* @param mixed $filter
192+
*
193+
* @throws CasbinException
194+
*/
195+
public function loadFilteredPolicy(Model $model, $filter): void
196+
{
197+
// if $filter is empty, load all policies
198+
if (is_null($filter)) {
199+
$this->loadPolicy($model);
200+
return;
201+
}
202+
// the basic sql
203+
$sql = 'SELECT ptype, v0, v1, v2, v3, v4, v5 FROM '.$this->casbinRuleTableName . ' WHERE ';
204+
205+
if ($filter instanceof Filter) {
206+
$type = '';
207+
$filter = (array) $filter;
208+
// choose which ptype to use
209+
foreach($filter as $i => $v) {
210+
if (!empty($v)) {
211+
array_unshift($filter[$i], $i);
212+
$type = $i;
213+
break;
214+
}
215+
}
216+
$items = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
217+
$temp = [];
218+
$values = [];
219+
foreach($items as $i => $item) {
220+
if (isset($filter[$type][$i]) && !empty($filter[$type][$i])) {
221+
array_push($temp, $item . '=:' . $item);
222+
$values[$item] = $filter[$type][$i];
223+
}
224+
}
225+
$sql .= implode(' and ', $temp);
226+
$rows = $this->connection->query($sql, $values);
227+
} elseif (is_string($filter)) {
228+
$sql .= $filter;
229+
$rows = $this->connection->query($sql);
230+
} else if ($filter instanceof Closure) {
231+
$filter($this->connection, $sql, $this->rows);
232+
} else {
233+
throw new InvalidFilterTypeException('invalid filter type');
234+
}
235+
236+
$rows = $rows ?? $this->rows;
237+
foreach($rows as $row) {
238+
$line = implode(', ', $row);
239+
$this->loadPolicyLine($line, $model);
240+
}
241+
$this->filtered = true;
242+
}
222243
}

tests/AdapterTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
namespace Tests;
44

55
use Casbin\Enforcer;
6+
use Casbin\Model\Model;
7+
use Casbin\Persist\Adapter;
68
use CasbinAdapter\Database\Adapter as DatabaseAdapter;
79
use PHPUnit\Framework\TestCase;
810
use TechOne\Database\Manager;
11+
use Casbin\Persist\Adapters\Filter;
912

1013
class AdapterTest extends TestCase
1114
{
@@ -44,6 +47,31 @@ protected function getEnforcer()
4447
return new Enforcer(__DIR__.'/rbac_model.conf', $adapter);
4548
}
4649

50+
protected function getEnforcerWithAdapter(Adapter $adapter): Enforcer
51+
{
52+
$this->adapter = $adapter;
53+
$this->initDb($this->adapter);
54+
$model = Model::newModelFromString(
55+
<<<'EOT'
56+
[request_definition]
57+
r = sub, obj, act
58+
59+
[policy_definition]
60+
p = sub, obj, act
61+
62+
[role_definition]
63+
g = _, _
64+
65+
[policy_effect]
66+
e = some(where (p.eft == allow))
67+
68+
[matchers]
69+
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
70+
EOT
71+
);
72+
return new Enforcer($model, $this->adapter);
73+
}
74+
4775
public function testLoadPolicy()
4876
{
4977
$e = $this->getEnforcer();
@@ -54,6 +82,40 @@ public function testLoadPolicy()
5482
$this->assertTrue($e->enforce('alice', 'data2', 'write'));
5583
}
5684

85+
public function testLoadFilteredPolicy()
86+
{
87+
$this->initConfig();
88+
$adapter = DatabaseAdapter::newAdapter($this->config);
89+
$adapter->setFiltered(true);
90+
$e = $this->getEnforcerWithAdapter($adapter);
91+
$this->assertEquals([], $e->getPolicy());
92+
93+
// string
94+
$filter = "v0 = 'bob'";
95+
$e->loadFilteredPolicy($filter);
96+
$this->assertEquals([
97+
//
98+
['bob', 'data2', 'write', '', '', '']
99+
], $e->getPolicy());
100+
101+
// Filter
102+
$filter = new Filter(['', '', 'read']);
103+
$e->loadFilteredPolicy($filter);
104+
$this->assertEquals([
105+
['alice', 'data1', 'read', '', '', ''],
106+
['data2_admin', 'data2', 'read', '', '', ''],
107+
], $e->getPolicy());
108+
109+
// Closure
110+
$e->loadFilteredPolicy(function ($connection, $sql, &$rows) {
111+
$rows = $connection->query($sql . "v0 = 'alice'");
112+
});
113+
114+
$this->assertEquals([
115+
['alice', 'data1', 'read', '', '', ''],
116+
], $e->getPolicy());
117+
}
118+
57119
public function testAddPolicy()
58120
{
59121
$e = $this->getEnforcer();

0 commit comments

Comments
 (0)