Skip to content

Commit 5fa40e0

Browse files
committed
Improve test code and add removeFilteredPolicy
1 parent f8d4b40 commit 5fa40e0

13 files changed

+293
-61
lines changed

.travis.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
language: php
2+
sudo: false
3+
4+
php:
5+
- 5.6
6+
- 7.0
7+
- 7.1
8+
- 7.2
9+
- 7.3
10+
11+
services:
12+
- mysql
13+
- postgresql
14+
15+
before_install:
16+
- travis_retry composer self-update
17+
- mysql -e 'create database if not exists casbin;'
18+
- psql -c 'create database casbin;' -U postgres
19+
20+
install:
21+
- travis_retry composer install --no-suggest --no-interaction
22+
23+
script:
24+
- vendor/bin/phpunit --version
25+
- mkdir -p build/logs
26+
- vendor/bin/phpunit
27+
28+
after_script:
29+
- travis_retry vendor/bin/php-coveralls -v

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Database adapter for php-casbin
22

3+
[![Build Status](https://travis-ci.org/php-casbin/database-adapter.svg?branch=master)](https://travis-ci.org/php-casbin/database-adapter)
4+
[![Coverage Status](https://coveralls.io/repos/github/php-casbin/database-adapter/badge.svg)](https://coveralls.io/github/php-casbin/database-adapter)
35
[![Latest Stable Version](https://poser.pugx.org/casbin/database-adapter/v/stable)](https://packagist.org/packages/casbin/database-adapter)
46
[![Total Downloads](https://poser.pugx.org/casbin/database-adapter/downloads)](https://packagist.org/packages/casbin/database-adapter)
57
[![License](https://poser.pugx.org/casbin/database-adapter/license)](https://packagist.org/packages/casbin/database-adapter)

composer.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,21 @@
1010
],
1111
"license": "Apache-2.0",
1212
"require": {
13-
"casbin/casbin": ">=0.1.4",
13+
"casbin/casbin": ">=0.2",
1414
"techone/database": ">=0.2.0"
1515
},
16+
"require-dev": {
17+
"phpunit/phpunit": "~5.7|~6.0",
18+
"php-coveralls/php-coveralls": "^2.1"
19+
},
1620
"autoload": {
1721
"psr-4": {
1822
"CasbinAdapter\\Database\\": "src/"
1923
}
24+
},
25+
"autoload-dev": {
26+
"psr-4": {
27+
"Tests\\": "tests/"
28+
}
2029
}
2130
}

migrations/mysql.sql

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CREATE TABLE IF NOT EXISTS `%table_name%` (
2+
`id` int(11) NOT NULL AUTO_INCREMENT,
3+
`ptype` varchar(255) NOT NULL,
4+
`v0` varchar(255) DEFAULT NULL,
5+
`v1` varchar(255) DEFAULT NULL,
6+
`v2` varchar(255) DEFAULT NULL,
7+
`v3` varchar(255) DEFAULT NULL,
8+
`v4` varchar(255) DEFAULT NULL,
9+
`v5` varchar(255) DEFAULT NULL,
10+
PRIMARY KEY (`id`)
11+
);

migrations/pgsql.sql

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CREATE TABLE IF NOT EXISTS %table_name% (
2+
id bigserial NOT NULL,
3+
ptype varchar(255) NOT NULL,
4+
v0 varchar(255) DEFAULT NULL,
5+
v1 varchar(255) DEFAULT NULL,
6+
v2 varchar(255) DEFAULT NULL,
7+
v3 varchar(255) DEFAULT NULL,
8+
v4 varchar(255) DEFAULT NULL,
9+
v5 varchar(255) DEFAULT NULL,
10+
PRIMARY KEY (id)
11+
);

migrations/sqlite.sql

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CREATE TABLE IF NOT EXISTS `%table_name%` (
2+
`id` INTEGER PRIMARY KEY AUTOINCREMENT ,
3+
`ptype` varchar(255) NOT NULL,
4+
`v0` varchar(255) DEFAULT NULL,
5+
`v1` varchar(255) DEFAULT NULL,
6+
`v2` varchar(255) DEFAULT NULL,
7+
`v3` varchar(255) DEFAULT NULL,
8+
`v4` varchar(255) DEFAULT NULL,
9+
`v5` varchar(255) DEFAULT NULL
10+
);

migrations/sqlsrv.sql

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CREATE TABLE IF NOT EXISTS %table_name% (
2+
id int IDENTITY(1,1),
3+
ptype varchar(255) NOT NULL,
4+
v0 varchar(255) DEFAULT NULL,
5+
v1 varchar(255) DEFAULT NULL,
6+
v2 varchar(255) DEFAULT NULL,
7+
v3 varchar(255) DEFAULT NULL,
8+
v4 varchar(255) DEFAULT NULL,
9+
v5 varchar(255) DEFAULT NULL
10+
);

phpunit.xml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
<testsuites>
12+
<testsuite name="Application Test Suite">
13+
<directory>./tests/</directory>
14+
</testsuite>
15+
</testsuites>
16+
<filter>
17+
<whitelist processUncoveredFilesFromWhitelist="true">
18+
<directory suffix=".php">./src</directory>
19+
</whitelist>
20+
</filter>
21+
<logging>
22+
<log type="coverage-clover" target="build/logs/clover.xml"/>
23+
<log type="coverage-html" target="build/html"/>
24+
</logging>
25+
<php>
26+
<env name="DB_DATABASE" value="casbin"/>
27+
</php>
28+
</phpunit>

src/Adapter.php

+14-60
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace CasbinAdapter\Database;
44

5-
use Casbin\Exceptions\CasbinException;
65
use Casbin\Persist\Adapter as AdapterContract;
76
use TechOne\Database\Manager;
87
use Casbin\Persist\AdapterHelper;
@@ -36,61 +35,8 @@ public static function newAdapter(array $config)
3635

3736
public function initTable()
3837
{
39-
if ('pgsql' == $this->config['type']) {
40-
$sql = <<<EOT
41-
CREATE TABLE IF NOT EXISTS $this->casbinRuleTableName (
42-
id bigserial NOT NULL,
43-
ptype varchar(255) NOT NULL,
44-
v0 varchar(255) DEFAULT NULL,
45-
v1 varchar(255) DEFAULT NULL,
46-
v2 varchar(255) DEFAULT NULL,
47-
v3 varchar(255) DEFAULT NULL,
48-
v4 varchar(255) DEFAULT NULL,
49-
v5 varchar(255) DEFAULT NULL,
50-
PRIMARY KEY (id)
51-
);
52-
EOT;
53-
} elseif ('sqlite' == $this->config['type']) {
54-
$sql = <<<EOT
55-
CREATE TABLE IF NOT EXISTS `$this->casbinRuleTableName` (
56-
`id` INTEGER PRIMARY KEY AUTOINCREMENT ,
57-
`ptype` varchar(255) NOT NULL,
58-
`v0` varchar(255) DEFAULT NULL,
59-
`v1` varchar(255) DEFAULT NULL,
60-
`v2` varchar(255) DEFAULT NULL,
61-
`v3` varchar(255) DEFAULT NULL,
62-
`v4` varchar(255) DEFAULT NULL,
63-
`v5` varchar(255) DEFAULT NULL
64-
);
65-
EOT;
66-
} elseif ('sqlsrv' == $this->config['type']) {
67-
$sql = <<<EOT
68-
CREATE TABLE IF NOT EXISTS `$this->casbinRuleTableName` (
69-
id int IDENTITY(1,1),
70-
ptype varchar(255) NOT NULL,
71-
v0 varchar(255) DEFAULT NULL,
72-
v1 varchar(255) DEFAULT NULL,
73-
v2 varchar(255) DEFAULT NULL,
74-
v3 varchar(255) DEFAULT NULL,
75-
v4 varchar(255) DEFAULT NULL,
76-
v5 varchar(255) DEFAULT NULL
77-
);
78-
EOT;
79-
} else {
80-
$sql = <<<EOT
81-
CREATE TABLE IF NOT EXISTS `$this->casbinRuleTableName` (
82-
`id` int(11) NOT NULL AUTO_INCREMENT,
83-
`ptype` varchar(255) NOT NULL,
84-
`v0` varchar(255) DEFAULT NULL,
85-
`v1` varchar(255) DEFAULT NULL,
86-
`v2` varchar(255) DEFAULT NULL,
87-
`v3` varchar(255) DEFAULT NULL,
88-
`v4` varchar(255) DEFAULT NULL,
89-
`v5` varchar(255) DEFAULT NULL,
90-
PRIMARY KEY (`id`)
91-
);
92-
EOT;
93-
}
38+
$sql = file_get_contents(__DIR__.'/../migrations/'.$this->config['type'].'.sql');
39+
$sql = str_replace('%table_name%', $this->casbinRuleTableName, $sql);
9440
$this->connection->execute($sql, []);
9541
}
9642

@@ -150,9 +96,6 @@ public function removePolicy($sec, $ptype, $rule)
15096
$where['v'.strval($key)] = $value;
15197
$condition[] = 'v'.strval($key).' = :'.'v'.strval($key);
15298
}
153-
if (empty($condition)) {
154-
return;
155-
}
15699

157100
$sql = 'DELETE FROM '.$this->casbinRuleTableName.' WHERE '.implode(' AND ', $condition);
158101

@@ -161,6 +104,17 @@ public function removePolicy($sec, $ptype, $rule)
161104

162105
public function removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues)
163106
{
164-
throw new CasbinException('not implemented');
107+
$where['ptype'] = $ptype;
108+
$condition[] = 'ptype = :ptype';
109+
foreach (range(0, 5) as $value) {
110+
if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) {
111+
$where['v'.strval($value)] = $fieldValues[$value - $fieldIndex];
112+
$condition[] = 'v'.strval($value).' = :'.'v'.strval($value);
113+
}
114+
}
115+
116+
$sql = 'DELETE FROM '.$this->casbinRuleTableName.' WHERE '.implode(' AND ', $condition);
117+
118+
return $this->connection->execute($sql, $where);
165119
}
166120
}

tests/AdapterPgsqlTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
class AdapterPgsqlTest extends AdapterTest
6+
{
7+
protected function initConfig()
8+
{
9+
$this->config = [
10+
'type' => 'pgsql', // mysql,pgsql,sqlite,sqlsrv
11+
'hostname' => $this->env('DB_PORT', '127.0.0.1'),
12+
'database' => $this->env('DB_DATABASE', 'casbin'),
13+
'username' => $this->env('DB_USERNAME', 'postgres'),
14+
'password' => $this->env('DB_PASSWORD', ''),
15+
'hostport' => $this->env('DB_PORT', 5432),
16+
];
17+
}
18+
}

tests/AdapterSqliteTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
class AdapterSqliteTest extends AdapterTest
6+
{
7+
protected function initConfig()
8+
{
9+
$this->config = [
10+
'type' => 'sqlite',
11+
'database' => __DIR__.'/'.$this->env('DB_DATABASE', 'casbin').'.db',
12+
];
13+
}
14+
}

tests/AdapterTest.php

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Casbin\Enforcer;
6+
use CasbinAdapter\Database\Adapter as DatabaseAdapter;
7+
use PHPUnit\Framework\TestCase;
8+
use TechOne\Database\Manager;
9+
10+
class AdapterTest extends TestCase
11+
{
12+
protected $config = [];
13+
14+
protected function initConfig()
15+
{
16+
$this->config = [
17+
'type' => 'mysql', // mysql,pgsql,sqlite,sqlsrv
18+
'hostname' => $this->env('DB_PORT', '127.0.0.1'),
19+
'database' => $this->env('DB_DATABASE', 'casbin'),
20+
'username' => $this->env('DB_USERNAME', 'root'),
21+
'password' => $this->env('DB_PASSWORD', ''),
22+
'hostport' => $this->env('DB_PORT', 3306),
23+
];
24+
}
25+
26+
protected function initDb()
27+
{
28+
$tableName = 'casbin_rule';
29+
$conn = (new Manager($this->config))->getConnection();
30+
$conn->execute('DELETE FROM '.$tableName);
31+
$conn->execute('INSERT INTO '.$tableName.' (ptype, v0, v1, v2) VALUES ( \'p\', \'alice\', \'data1\', \'read\') ');
32+
$conn->execute('INSERT INTO '.$tableName.' (ptype, v0, v1, v2) VALUES ( \'p\', \'bob\', \'data2\', \'write\') ');
33+
$conn->execute('INSERT INTO '.$tableName.' (ptype, v0, v1, v2) VALUES ( \'p\', \'data2_admin\', \'data2\', \'read\') ');
34+
$conn->execute('INSERT INTO '.$tableName.' (ptype, v0, v1, v2) VALUES ( \'p\', \'data2_admin\', \'data2\', \'write\') ');
35+
$conn->execute('INSERT INTO '.$tableName.' (ptype, v0, v1) VALUES ( \'g\', \'alice\', \'data2_admin\') ');
36+
}
37+
38+
protected function getEnforcer()
39+
{
40+
$this->initConfig();
41+
$adapter = DatabaseAdapter::newAdapter($this->config);
42+
$this->initDb();
43+
44+
return new Enforcer(__DIR__.'/rbac_model.conf', $adapter);
45+
}
46+
47+
public function testLoadPolicy()
48+
{
49+
$e = $this->getEnforcer();
50+
$this->assertTrue($e->enforce('alice', 'data1', 'read'));
51+
$this->assertFalse($e->enforce('bob', 'data1', 'read'));
52+
$this->assertTrue($e->enforce('bob', 'data2', 'write'));
53+
$this->assertTrue($e->enforce('alice', 'data2', 'read'));
54+
$this->assertTrue($e->enforce('alice', 'data2', 'write'));
55+
}
56+
57+
public function testAddPolicy()
58+
{
59+
$e = $this->getEnforcer();
60+
$this->assertFalse($e->enforce('eve', 'data3', 'read'));
61+
62+
$e->addPermissionForUser('eve', 'data3', 'read');
63+
$this->assertTrue($e->enforce('eve', 'data3', 'read'));
64+
}
65+
66+
public function testSavePolicy()
67+
{
68+
$e = $this->getEnforcer();
69+
$this->assertFalse($e->enforce('alice', 'data4', 'read'));
70+
71+
$model = $e->getModel();
72+
$model->clearPolicy();
73+
$model->addPolicy('p', 'p', ['alice', 'data4', 'read']);
74+
75+
$adapter = $e->getAdapter();
76+
$adapter->savePolicy($model);
77+
$this->assertTrue($e->enforce('alice', 'data4', 'read'));
78+
}
79+
80+
public function testRemovePolicy()
81+
{
82+
$e = $this->getEnforcer();
83+
$this->assertFalse($e->enforce('alice', 'data5', 'read'));
84+
$e->addPermissionForUser('alice', 'data5', 'read');
85+
$this->assertTrue($e->enforce('alice', 'data5', 'read'));
86+
$e->deletePermissionForUser('alice', 'data5', 'read');
87+
$this->assertFalse($e->enforce('alice', 'data5', 'read'));
88+
}
89+
90+
public function testRemoveFilteredPolicy()
91+
{
92+
$e = $this->getEnforcer();
93+
$this->assertTrue($e->enforce('alice', 'data1', 'read'));
94+
$e->removeFilteredPolicy(1, 'data1');
95+
$this->assertFalse($e->enforce('alice', 'data1', 'read'));
96+
97+
$this->assertTrue($e->enforce('bob', 'data2', 'write'));
98+
$this->assertTrue($e->enforce('alice', 'data2', 'read'));
99+
$this->assertTrue($e->enforce('alice', 'data2', 'write'));
100+
101+
$e->removeFilteredPolicy(1, 'data2', 'read');
102+
103+
$this->assertTrue($e->enforce('bob', 'data2', 'write'));
104+
$this->assertFalse($e->enforce('alice', 'data2', 'read'));
105+
$this->assertTrue($e->enforce('alice', 'data2', 'write'));
106+
107+
$e->removeFilteredPolicy(2, 'write');
108+
109+
$this->assertFalse($e->enforce('bob', 'data2', 'write'));
110+
$this->assertFalse($e->enforce('alice', 'data2', 'write'));
111+
}
112+
113+
protected function env($key, $default = null)
114+
{
115+
$value = getenv($key);
116+
if (is_null($default)) {
117+
return $value;
118+
}
119+
120+
return false === $value ? $default : $value;
121+
}
122+
}

0 commit comments

Comments
 (0)