diff --git a/.gitignore b/.gitignore index 67c6bbb..451f38a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ vendor .idea .vscode .phpunit* -composer.lock \ No newline at end of file +composer.lock +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 6b7c5c7..6fe0c24 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,23 @@ if (Permission::enforce("eve", "articles", "edit")) { } ``` +多套配置 +```php +$permission = Permission::client("other_conf") +// adds permissions to a user +$permission->addPermissionForUser('eve', 'articles', 'read'); +// adds a role for a user. +$permission->addRoleForUser('eve', 'writer'); +// adds permissions to a rule +$permission->addPolicy('writer', 'articles','edit'); + +if ($permission->enforce("eve", "articles", "edit")) { + echo '恭喜你!通过权限认证'; +} else { + echo '对不起,您没有该资源访问权限'; +} +``` + 更多 `API` 参考 [Casbin API](https://casbin.org/docs/en/management-api) 。 ## 感谢 @@ -140,4 +157,4 @@ if (is_null(static::$_manager)) { } ``` 耦合太高,不建议这么搞,更多了解:https://www.workerman.net/doc/webman/di.html - + \ No newline at end of file diff --git a/composer.json b/composer.json index 87388db..7098058 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "casbin/casbin": "^3.20", "topthink/think-orm": "^2.0", "php-di/php-di": "^6.3", + "doctrine/annotations": "^1.13", "workerman/redis": "^1.0" }, "autoload": { @@ -41,7 +42,12 @@ "phpunit/phpunit": "~7.0|~8.0|~9.0", "php-coveralls/php-coveralls": "^2.1", "workerman/webman": "^1.0", + "vlucas/phpdotenv": "^5.5", + "psr/container": "^1.1.1", "illuminate/database": "^8.83", - "illuminate/cache": "^8.83" + "illuminate/pagination": "^8.83", + "illuminate/events": "^8.83", + "symfony/var-dumper": "^6.2", + "webman/think-orm": "^1.0" } } diff --git a/src/Adapter/DatabaseAdapter.php b/src/Adapter/DatabaseAdapter.php index 0d0b7a5..01187b3 100644 --- a/src/Adapter/DatabaseAdapter.php +++ b/src/Adapter/DatabaseAdapter.php @@ -45,11 +45,11 @@ class DatabaseAdapter implements Adapter, UpdatableAdapter, BatchAdapter, Filter /** * the DatabaseAdapter constructor. * - * @param RuleModel $model + * @param string|null $driver */ - public function __construct(RuleModel $model) + public function __construct(?string $driver = null) { - $this->model = $model; + $this->model = new RuleModel([], $driver); } /** @@ -371,4 +371,4 @@ public function loadFilteredPolicy(Model $model, $filter): void } $this->setFiltered(true); } -} \ No newline at end of file +} diff --git a/src/Adapter/LaravelDatabaseAdapter.php b/src/Adapter/LaravelDatabaseAdapter.php index 49175ed..39a3c3b 100644 --- a/src/Adapter/LaravelDatabaseAdapter.php +++ b/src/Adapter/LaravelDatabaseAdapter.php @@ -19,6 +19,8 @@ use Casbin\Persist\Adapters\Filter; use Casbin\Exceptions\InvalidFilterTypeException; use Casbin\WebmanPermission\Model\LaravelRuleModel; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\DB; use Throwable; @@ -45,11 +47,12 @@ class LaravelDatabaseAdapter implements Adapter, UpdatableAdapter, BatchAdapter, /** * LaravelDatabaseAdapter constructor. - * @param LaravelRuleModel $model + * + * @param string|null $driver */ - public function __construct(LaravelRuleModel $model) + public function __construct(?string $driver = null) { - $this->model = $model; + $this->model = new LaravelRuleModel([],$driver); } /** @@ -84,9 +87,9 @@ public function savePolicyLine(string $ptype, array $rule) { $col['ptype'] = $ptype; foreach ($rule as $key => $value) { - $col['v' . strval($key) . ''] = $value; + $col['v' . $key] = $value; } - $this->model->create($col); + $this->model->updateOrCreate($col); } /** @@ -96,7 +99,7 @@ public function savePolicyLine(string $ptype, array $rule) */ public function loadPolicy(Model $model): void { - $rows = $this->model->getAllFromCache(); + $rows = $this->model->select(['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'])->get()->toArray();; foreach ($rows as $row) { $this->loadPolicyArray($this->filterRule($row), $model); } @@ -145,21 +148,13 @@ public function addPolicy(string $sec, string $ptype, array $rule): void */ public function addPolicies(string $sec, string $ptype, array $rules): void { - $cols = []; - $i = 0; - foreach ($rules as $rule) { - $temp['ptype'] = $ptype; - $temp['created_at'] = date("Y-m-d h:m:i"); - $temp['updated_at'] = $temp['created_at']; + $temp = ['ptype' => $ptype]; foreach ($rule as $key => $value) { - $temp['v' . strval($key)] = $value; + $temp['v' . $key] = $value; } - $cols[$i++] = $temp ?? []; - $temp = []; + $this->model->updateOrCreate($temp); } - $this->model->insert($cols); - LaravelRuleModel::fireModelEvent('saved'); } /** @@ -173,10 +168,12 @@ public function removePolicy(string $sec, string $ptype, array $rule): void { $instance = $this->model->where('ptype', $ptype); foreach ($rule as $key => $value) { - $instance->where('v' . strval($key), $value); + $instance->where('v' . $key, $value); + } + $data = $instance->get(); + foreach ($data as $item) { + $item->delete(); } - $instance->delete(); - LaravelRuleModel::fireModelEvent('deleted'); } /** @@ -189,25 +186,13 @@ public function removePolicy(string $sec, string $ptype, array $rule): void */ public function _removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, ?string ...$fieldValues): array { - $count = 0; $removedRules = []; + $data = $this->getCollection($ptype, $fieldIndex, $fieldValues); - $instance = $this->model->where('ptype', $ptype); - foreach (range(0, 5) as $value) { - if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) { - if ('' != $fieldValues[$value - $fieldIndex]) { - $instance->where('v' . strval($value), $fieldValues[$value - $fieldIndex]); - } - } - } - - foreach ($instance->select() as $model) { - $item = $model->hidden(['id', 'ptype'])->toArray(); - $item = $this->filterRule($item); + foreach ($data as $model) { + $item = $model->hidden(['id', 'ptype'])->toArray(); + $item = $this->filterRule($item); $removedRules[] = $item; - if ($model->cache('tauthz')->delete()) { - ++$count; - } } return $removedRules; @@ -241,22 +226,10 @@ public function removePolicies(string $sec, string $ptype, array $rules): void */ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, string ...$fieldValues): void { - $instance = $this->model->where('ptype', $ptype); - foreach (range(0, 5) as $value) { - if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) { - if ('' != $fieldValues[$value - $fieldIndex]) { - $instance->where('v' . strval($value), $fieldValues[$value - $fieldIndex]); - } - } - } - - $oldP = $instance->get()->makeHidden(['created_at','updated_at', 'id', 'ptype'])->toArray(); - foreach ($oldP as &$item) { - $item = $this->filterRule($item); - $removedRules[] = $item; + $data = $this->getCollection($ptype, $fieldIndex, $fieldValues); + foreach ($data as $item) { + $item->delete(); } - $instance->delete(); - LaravelRuleModel::fireModelEvent('deleted'); } /** @@ -272,7 +245,7 @@ public function updatePolicy(string $sec, string $ptype, array $oldRule, array $ { $instance = $this->model->where('ptype', $ptype); foreach ($oldRule as $key => $value) { - $instance->where('v' . strval($key), $value); + $instance->where('v' . $key, $value); } $instance = $instance->first(); @@ -281,8 +254,8 @@ public function updatePolicy(string $sec, string $ptype, array $oldRule, array $ $update['v' . $key] = $value; } - $instance->update($update); - LaravelRuleModel::fireModelEvent('saved'); + $instance->fill($update); + $instance->save(); } /** @@ -316,7 +289,7 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra public function updateFilteredPolicies(string $sec, string $ptype, array $newPolicies, int $fieldIndex, string ...$fieldValues): array { $oldRules = []; - \Illuminate\Support\Facades\DB::transaction(function () use ($sec, $ptype, $fieldIndex, $fieldValues, $newPolicies, &$oldRules) { + DB::transaction(function () use ($sec, $ptype, $fieldIndex, $fieldValues, $newPolicies, &$oldRules) { $oldRules = $this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues); $this->addPolicies($sec, $ptype, $newPolicies); }); @@ -346,34 +319,67 @@ public function setFiltered(bool $filtered): void /** * Loads only policy rules that match the filter. * - * @param Model $model - * @param mixed $filter + * @param Model $model + * @param mixed $filter + * + * @throws InvalidFilterTypeException */ public function loadFilteredPolicy(Model $model, $filter): void { $instance = $this->model; if (is_string($filter)) { - $instance = $instance->whereRaw($filter); - } elseif ($filter instanceof Filter) { + $instance->whereRaw($filter); + } + elseif ($filter instanceof Filter) { + $where = []; foreach ($filter->p as $k => $v) { $where[$v] = $filter->g[$k]; - $instance = $instance->where($v, $filter->g[$k]); } - } elseif ($filter instanceof \Closure) { + $instance->where($where); + } + elseif ($filter instanceof Closure) { $instance = $instance->where($filter); - } else { + } + else { throw new InvalidFilterTypeException('invalid filter type'); } - $rows = $instance->get()->makeHidden(['created_at','updated_at', 'id'])->toArray(); + $rows = $instance->get()->makeHidden(['created_at', 'updated_at', 'id'])->toArray(); if ($rows) { foreach ($rows as $row) { - $row = array_filter($row, function($value) { return !is_null($value) && $value !== ''; }); - $line = implode(', ', array_filter($row, function ($val) { - return '' != $val && !is_null($val); - })); + $row = array_filter($row, function ($value) { + return !is_null($value) && $value !== ''; + }); + $line = implode( + ', ', + array_filter($row, function ($val) { + return '' != $val && !is_null($val); + }) + ); $this->loadPolicyLine(trim($line), $model); } } $this->setFiltered(true); } + + /** + * @param string $ptype + * @param int $fieldIndex + * @param array $fieldValues + * + * @return Builder[]|Collection + */ + protected function getCollection(string $ptype, int $fieldIndex, array $fieldValues) { + $where = [ + 'ptype' => $ptype, + ]; + foreach (range(0, 5) as $value) { + if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) { + if ('' != $fieldValues[$value - $fieldIndex]) { + $where['v' . $value] = $fieldValues[$value - $fieldIndex]; + } + } + } + + return $this->model->where($where)->get(); + } } \ No newline at end of file diff --git a/src/Model/LaravelRuleModel.php b/src/Model/LaravelRuleModel.php index c5518c7..72180ff 100644 --- a/src/Model/LaravelRuleModel.php +++ b/src/Model/LaravelRuleModel.php @@ -10,11 +10,12 @@ namespace Casbin\WebmanPermission\Model; -use Illuminate\Cache\Repository; use Illuminate\Database\Eloquent\Model; /** * RuleModel Model + * + * @inheritDoc */ class LaravelRuleModel extends Model { @@ -25,13 +26,6 @@ class LaravelRuleModel extends Model */ public $timestamps = false; - /** - * a cache store. - * - * @var Repository - */ - protected Repository $store; - /** * Fillable. * @@ -39,20 +33,18 @@ class LaravelRuleModel extends Model */ protected $fillable = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5']; - /** - * the guard for lauthz. - * - * @var string - */ - protected string $guard; + + /** @var string $driver */ + protected string $driver; /** * 架构函数 * @access public * @param array $data 数据 */ - public function __construct(array $data = []) + public function __construct(array $data = [], ?string $driver = null) { + $this->driver = $driver; $connection = $this->config('database.connection') ?: config('database.default'); $this->setConnection($connection); $this->setTable($this->config('database.rules_table')); @@ -69,24 +61,7 @@ public function __construct(array $data = []) */ protected function config(string $key = null, $default = null) { - $driver = config('plugin.casbin.webman-permission.permission.default'); + $driver = $this->driver ?? config('plugin.casbin.webman-permission.permission.default'); return config('plugin.casbin.webman-permission.permission.' . $driver . '.' . $key, $default); } - - /** - * Gets rules from caches. - * - * @return mixed - */ - public function getAllFromCache() - { - $get = function () { - return $this->select('ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5')->get()->toArray(); - }; - if (!$this->config('cache.enabled', false)) { - return $get(); - } - - return $this->store->remember($this->config('cache.key'), $this->config('cache.ttl'), $get); - } -} +} \ No newline at end of file diff --git a/src/Model/RuleModel.php b/src/Model/RuleModel.php index f61ee44..39c305f 100644 --- a/src/Model/RuleModel.php +++ b/src/Model/RuleModel.php @@ -34,13 +34,17 @@ class RuleModel extends Model implements Arrayable 'v5' => 'string' ]; + /** @var string $driver */ + protected string $driver; + /** * 架构函数 * @access public * @param array $data 数据 */ - public function __construct(array $data = []) + public function __construct(array $data = [], ?string $driver = null) { + $this->driver = $driver; $this->connection = $this->config('database.connection') ?: ''; $this->table = $this->config('database.rules_table'); $this->name = $this->config('database.rules_name'); @@ -57,7 +61,7 @@ public function __construct(array $data = []) */ protected function config(string $key = null, $default = null) { - $driver = config('plugin.casbin.webman-permission.permission.default'); + $driver = $this->driver ?? config('plugin.casbin.webman-permission.permission.default'); return config('plugin.casbin.webman-permission.permission.' . $driver . '.' . $key, $default); } -} +} \ No newline at end of file diff --git a/src/Permission.php b/src/Permission.php index 1165d0c..44276af 100644 --- a/src/Permission.php +++ b/src/Permission.php @@ -15,8 +15,6 @@ use Casbin\Model\Model; use support\Container; use Casbin\WebmanPermission\Watcher\RedisWatcher; -use Workerman\Worker; -use Webman\Bootstrap; /** * @see \Casbin\Enforcer @@ -45,50 +43,52 @@ * @method static getImplicitPermissionsForUser(string $username, string ...$domain) 获取用户具有的隐式权限 * @method static addFunction(string $name, \Closure $func) 添加一个自定义函数 */ -class Permission implements Bootstrap +class Permission { - /** - * @var Enforcer|null $_manager - */ - protected static ?Enforcer $_manager = null; + /** @var Enforcer[] $_manager */ + protected static array $_manager = []; /** - * @param Worker $worker - * @return void + * @param string|null $driver + * @return Enforcer * @throws CasbinException - * @author Tinywan(ShaoBo Wan) + * @author Lyt8384 */ - public static function start($worker) + public static function client(?string $driver = null): Enforcer { - if ($worker) { - $driver = config('plugin.casbin.webman-permission.permission.default'); - $config = config('plugin.casbin.webman-permission.permission.'.$driver); - $model = new Model(); - if ('file' == $config['model']['config_type']) { - $model->loadModel($config['model']['config_file_path']); - } elseif ('text' == $config['model']['config_type']) { - $model->loadModel($config['model']['config_text']); - } - if (is_null(static::$_manager)) { - static::$_manager = new Enforcer($model, Container::get($config['adapter']),false); - } + $driver = $driver ?? config('plugin.casbin.webman-permission.permission.default'); + $config = config('plugin.casbin.webman-permission.permission.'.$driver); + + if(isset(static::$_manager[$driver])){ + return static::$_manager[$driver]; + } - $watcher = new RedisWatcher(config('redis.default')); - static::$_manager->setWatcher($watcher); - $watcher->setUpdateCallback(function () { - static::$_manager->loadPolicy(); - }); + $model = new Model(); + if ('file' == $config['model']['config_type']) { + $model->loadModel($config['model']['config_file_path']); + } elseif ('text' == $config['model']['config_type']) { + $model->loadModel($config['model']['config_text']); } + static::$_manager[$driver] = new Enforcer($model, Container::make($config['adapter'],[$driver]),false); + + $watcher = new RedisWatcher(config('redis.default'), $driver); + static::$_manager[$driver]->setWatcher($watcher); + $watcher->setUpdateCallback(function () use ($driver) { + static::$_manager[$driver]->loadPolicy(); + }); + return static::$_manager[$driver]; } /** * @param $name * @param $arguments + * * @return mixed + * @throws CasbinException * @author Tinywan(ShaoBo Wan) */ public static function __callStatic($name, $arguments) { - return static::$_manager->{$name}(...$arguments); + return self::client()->{$name}(...$arguments); } -} \ No newline at end of file +} diff --git a/src/Watcher/RedisWatcher.php b/src/Watcher/RedisWatcher.php index 1fb457a..44c950f 100644 --- a/src/Watcher/RedisWatcher.php +++ b/src/Watcher/RedisWatcher.php @@ -35,11 +35,11 @@ class RedisWatcher implements Watcher * 'channel' => '/casbin', * ] */ - public function __construct(array $config) + public function __construct(array $config, string $driver) { $this->pubRedis = $this->createRedisClient($config); $this->subRedis = $this->createRedisClient($config); - $this->channel = $config['channel'] ?? '/casbin'; + $this->channel = ($config['channel'] ?? '/casbin') . '/' . $driver; $this->subRedis->subscribe([$this->channel], function ($channel, $message) { if ($this->callback) { diff --git a/src/config/plugin/casbin/webman-permission/bootstrap.php b/src/config/plugin/casbin/webman-permission/bootstrap.php deleted file mode 100644 index ca1a131..0000000 --- a/src/config/plugin/casbin/webman-permission/bootstrap.php +++ /dev/null @@ -1,4 +0,0 @@ -assertTrue(Permission::client('other')->addPolicy('writer', 'articles', 'edit')); + $this->assertTrue(Permission::client('other')->addPolicies([ + ['writer', 'articles', 'list'], + ['writer', 'articles', 'delete'], + ])); + + $this->assertFalse(Permission::client('other')->addPolicies([ + ['writer', 'articles', 'list'], + ['writer', 'articles', 'delete'], + ])); + + $this->assertTrue(Permission::client('other')->enforce('writer', 'articles', 'edit')); + $this->assertTrue(Permission::client('other')->enforce('writer', 'articles', 'delete')); + $this->assertFalse(Permission::client('other')->enforce('writer', 'articles', 'other')); + + $this->assertTrue(Permission::client('other')->hasPolicy('writer', 'articles', 'edit')); + $this->assertFalse(Permission::client('other')->hasPolicy('writer', 'articles', 'other')); + + $this->assertTrue(Permission::client('other')->removePolicy('writer', 'articles', 'edit')); + $this->assertFalse(Permission::client('other')->hasPolicy('writer', 'articles', 'edit')); + $this->assertFalse(Permission::client('other')->enforce('writer', 'articles', 'edit')); + } + + public function testAddOtherRoleForUser() + { + $this->assertFalse(Permission::client('other')->hasRoleForUser('eve', 'data2')); + Permission::client('other')->addRoleForUser('eve', 'data2'); + $this->assertTrue(in_array('data2', Permission::client('other')->getAllRoles())); + $this->assertTrue(Permission::client('other')->hasRoleForUser('eve', 'data2')); + } + + public function testAddPermissionForUser() + { + $this->assertFalse(Permission::enforce('eve', 'data1', 'read')); + Permission::addPermissionForUser('eve', 'data1', 'read'); + $this->assertTrue(Permission::enforce('eve', 'data1', 'read')); + } + + public function testAddPolicy() + { + $this->assertTrue(Permission::addPolicy('writer', 'articles', 'edit')); + $this->assertTrue(Permission::addPolicies([ + ['writer', 'articles', 'list'], + ['writer', 'articles', 'delete'], + ])); + + $this->assertFalse(Permission::addPolicies([ + ['writer', 'articles', 'list'], + ['writer', 'articles', 'delete'], + ])); + + $this->assertTrue(Permission::enforce('writer', 'articles', 'edit')); + $this->assertTrue(Permission::enforce('writer', 'articles', 'delete')); + $this->assertFalse(Permission::enforce('writer', 'articles', 'other')); + + $this->assertTrue(Permission::hasPolicy('writer', 'articles', 'edit')); + $this->assertFalse(Permission::hasPolicy('writer', 'articles', 'other')); + + $this->assertTrue(Permission::removePolicy('writer', 'articles', 'edit')); + $this->assertFalse(Permission::hasPolicy('writer', 'articles', 'edit')); + $this->assertFalse(Permission::enforce('writer', 'articles', 'edit')); + } + + public function testAddRoleForUser() + { + $this->assertFalse(Permission::hasRoleForUser('eve', 'data2')); + Permission::addRoleForUser('eve', 'data2'); + $this->assertTrue(in_array('data2', Permission::getAllRoles())); + $this->assertTrue(Permission::hasRoleForUser('eve', 'data2')); + } + + public function testOtherAddPermissionForUser() + { + $this->assertFalse(Permission::client('other')->enforce('eve', 'data1', 'read')); + Permission::client('other')->addPermissionForUser('eve', 'data1', 'read'); + $this->assertTrue(Permission::client('other')->enforce('eve', 'data1', 'read')); + } +} diff --git a/tests/LaravelDatabase/LaravelDatabaseAdapterTest.php b/tests/LaravelDatabase/LaravelDatabaseAdapterTest.php new file mode 100644 index 0000000..e396dab --- /dev/null +++ b/tests/LaravelDatabase/LaravelDatabaseAdapterTest.php @@ -0,0 +1,10 @@ +initDb(); + $this->initOtherDb(); + Permission::clear(); + } + + public function initDb() + { + $sql = << true, +]; \ No newline at end of file diff --git a/tests/LaravelDatabase/config/plugin/casbin/webman-permission/permission.php b/tests/LaravelDatabase/config/plugin/casbin/webman-permission/permission.php new file mode 100644 index 0000000..b9e1336 --- /dev/null +++ b/tests/LaravelDatabase/config/plugin/casbin/webman-permission/permission.php @@ -0,0 +1,38 @@ + 'basic', + // 基础配置 + 'basic' => [ + // 策略模型Model设置 + 'model' => [ + 'config_type' => 'file', + 'config_file_path' => __DIR__.'/rbac-model.conf', + 'config_text' => '', + ], + // 适配器 + 'adapter' => Casbin\WebmanPermission\Adapter\LaravelDatabaseAdapter::class, // Laravel 适配器 + // 数据库设置 + 'database' => [ + 'connection' => '', + 'rules_table' => 'casbin_rule', + 'rules_name' => null, + ], + ], + 'other' => [ + // 策略模型Model设置 + 'model' => [ + 'config_type' => 'file', + 'config_file_path' => __DIR__.'/rbac-model.conf', + 'config_text' => '', + ], + // 适配器 + 'adapter' => Casbin\WebmanPermission\Adapter\LaravelDatabaseAdapter::class, // Laravel 适配器 + // 数据库设置 + 'database' => [ + 'connection' => '', + 'rules_table' => 'other_casbin_rule', + 'rules_name' => null, + ], + ], +]; diff --git a/tests/LaravelDatabase/config/plugin/casbin/webman-permission/rbac-model.conf b/tests/LaravelDatabase/config/plugin/casbin/webman-permission/rbac-model.conf new file mode 100644 index 0000000..71159e3 --- /dev/null +++ b/tests/LaravelDatabase/config/plugin/casbin/webman-permission/rbac-model.conf @@ -0,0 +1,14 @@ +[request_definition] +r = sub, obj, act + +[policy_definition] +p = sub, obj, act + +[role_definition] +g = _, _ + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php deleted file mode 100644 index 78822ba..0000000 --- a/tests/TestCase.php +++ /dev/null @@ -1,36 +0,0 @@ -delete(); - RuleModel::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']); - RuleModel::create(['ptype' => 'p', 'v0' => 'bob', 'v1' => 'data2', 'v2' => 'write']); - RuleModel::create(['ptype' => 'p', 'v0' => 'data2_admin', 'v1' => 'data2', 'v2' => 'read']); - RuleModel::create(['ptype' => 'p', 'v0' => 'data2_admin', 'v1' => 'data2', 'v2' => 'write']); - RuleModel::create(['ptype' => 'g', 'v0' => 'alice', 'v1' => 'data2_admin']); - } - - protected function _setUp() - { - $this->initTable(); - $this->start(); - } - -} \ No newline at end of file diff --git a/tests/ThinkphpDatabase/DatabaseAdapterTest.php b/tests/ThinkphpDatabase/DatabaseAdapterTest.php new file mode 100644 index 0000000..cf21353 --- /dev/null +++ b/tests/ThinkphpDatabase/DatabaseAdapterTest.php @@ -0,0 +1,10 @@ +initDb(); + $this->initOtherDb(); + Permission::clear(); + } + + public function initDb() + { + $sql = << true, +]; \ No newline at end of file diff --git a/tests/ThinkphpDatabase/config/plugin/casbin/webman-permission/permission.php b/tests/ThinkphpDatabase/config/plugin/casbin/webman-permission/permission.php new file mode 100644 index 0000000..9b4ee2e --- /dev/null +++ b/tests/ThinkphpDatabase/config/plugin/casbin/webman-permission/permission.php @@ -0,0 +1,38 @@ + 'basic', + // 基础配置 + 'basic' => [ + // 策略模型Model设置 + 'model' => [ + 'config_type' => 'file', + 'config_file_path' => __DIR__.'/rbac-model.conf', + 'config_text' => '', + ], + // 适配器 + 'adapter' => Casbin\WebmanPermission\Adapter\DatabaseAdapter::class, // ThinkORM 适配器 + // 数据库设置 + 'database' => [ + 'connection' => '', + 'rules_table' => 'casbin_rule', + 'rules_name' => null, + ], + ], + 'other' => [ + // 策略模型Model设置 + 'model' => [ + 'config_type' => 'file', + 'config_file_path' => __DIR__.'/rbac-model.conf', + 'config_text' => '', + ], + // 适配器 + 'adapter' => Casbin\WebmanPermission\Adapter\DatabaseAdapter::class, // ThinkORM 适配器 + // 数据库设置 + 'database' => [ + 'connection' => '', + 'rules_table' => 'other_casbin_rule', + 'rules_name' => null, + ], + ], +]; diff --git a/tests/ThinkphpDatabase/config/plugin/casbin/webman-permission/rbac-model.conf b/tests/ThinkphpDatabase/config/plugin/casbin/webman-permission/rbac-model.conf new file mode 100644 index 0000000..71159e3 --- /dev/null +++ b/tests/ThinkphpDatabase/config/plugin/casbin/webman-permission/rbac-model.conf @@ -0,0 +1,14 @@ +[request_definition] +r = sub, obj, act + +[policy_definition] +p = sub, obj, act + +[role_definition] +g = _, _ + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act \ No newline at end of file diff --git a/tests/config/app.php b/tests/config/app.php new file mode 100644 index 0000000..5a51252 --- /dev/null +++ b/tests/config/app.php @@ -0,0 +1,29 @@ + + * + * @copyright walkor + * + * @see http://www.workerman.net/ + * + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +use support\Request; + +return [ + 'debug' => true, + 'error_reporting' => E_ALL, + 'default_timezone' => 'Asia/Shanghai', + 'request_class' => Request::class, + 'public_path' => base_path().DIRECTORY_SEPARATOR.'public', + 'runtime_path' => base_path(false).DIRECTORY_SEPARATOR.'runtime', + 'controller_suffix' => 'Controller', + 'controller_reuse' => false, +]; diff --git a/tests/config/container.php b/tests/config/container.php new file mode 100644 index 0000000..d82eb2c --- /dev/null +++ b/tests/config/container.php @@ -0,0 +1,22 @@ + + * + * @copyright walkor + * + * @see http://www.workerman.net/ + * + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ +$builder = new \DI\ContainerBuilder(); +$builder->addDefinitions(config('dependence', [])); +$builder->useAutowiring(true); +$builder->useAnnotations(true); + +return $builder->build(); diff --git a/tests/config/database.php b/tests/config/database.php new file mode 100644 index 0000000..3a2174f --- /dev/null +++ b/tests/config/database.php @@ -0,0 +1,39 @@ + + * + * @copyright walkor + * + * @see http://www.workerman.net/ + * + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + // 默认数据库 + 'default' => 'mysql', + + // 各种数据库配置 + 'connections' => [ + 'mysql' => [ + 'driver' => 'mysql', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', 3306), + 'database' => env('DB_NAME', 'test'), + 'username' => env('DB_USER', 'root'), + 'password' => env('DB_PASSWORD', 'test'), + 'unix_socket' => '', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + 'strict' => true, + 'engine' => null, + ], + ], +]; diff --git a/tests/config/redis.php b/tests/config/redis.php new file mode 100644 index 0000000..e5e9dad --- /dev/null +++ b/tests/config/redis.php @@ -0,0 +1,25 @@ + + * + * @copyright walkor + * + * @see http://www.workerman.net/ + * + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + 'default' => [ + 'host' => env('REDIS_HOST') ?: '127.0.0.1', + 'password' => env('REDIS_PASSWORD') ?: null, + 'port' => env('REDIS_PORT') ?: 6379, + 'database' => env('REDIS_DB') ?: 0, + ], +]; diff --git a/tests/config/thinkorm.php b/tests/config/thinkorm.php new file mode 100644 index 0000000..77d42e2 --- /dev/null +++ b/tests/config/thinkorm.php @@ -0,0 +1,31 @@ + 'mysql', + 'connections' => [ + 'mysql' => [ + // 数据库类型 + 'type' => 'mysql', + // 服务器地址 + 'hostname' => env('DB_HOST', '127.0.0.1'), + // 数据库名 + 'database' => env('DB_NAME', 'test'), + // 数据库用户名 + 'username' => env('DB_USER', 'root'), + // 数据库密码 + 'password' => env('DB_PASSWORD', 'test'), + // 数据库连接端口 + 'hostport' => env('DB_PORT', 3306), + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => '', + // 断线重连 + 'break_reconnect' => true, + // 关闭SQL监听日志 + 'trigger_sql' => false, + ], + ], +];