Compare commits
1 Commits
master
...
revert-19-
Author | SHA1 | Date |
---|---|---|
|
3f3a541809 |
|
@ -27,25 +27,76 @@ jobs:
|
||||||
# laravel: [ ]
|
# laravel: [ ]
|
||||||
# stability: [ prefer-lowest, prefer-stable ]
|
# stability: [ prefer-lowest, prefer-stable ]
|
||||||
include:
|
include:
|
||||||
|
# Laravel 5.5
|
||||||
|
- php: 7.1
|
||||||
|
laravel: 5.5.*
|
||||||
|
phpunit: ~6.0
|
||||||
|
- php: 7.2
|
||||||
|
laravel: 5.5.*
|
||||||
|
phpunit: ~6.0
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 5.5.*
|
||||||
|
phpunit: ~6.0
|
||||||
|
|
||||||
|
# Laravel 5.6
|
||||||
|
- php: 7.1
|
||||||
|
laravel: 5.6.*
|
||||||
|
phpunit: ~7.0
|
||||||
|
- php: 7.2
|
||||||
|
laravel: 5.6.*
|
||||||
|
phpunit: ~7.0
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 5.6.*
|
||||||
|
phpunit: ~7.0
|
||||||
|
|
||||||
|
# Laravel 5.7
|
||||||
|
- php: 7.1
|
||||||
|
laravel: 5.7.*
|
||||||
|
phpunit: ~7.5
|
||||||
|
- php: 7.2
|
||||||
|
laravel: 5.7.*
|
||||||
|
phpunit: ~7.5
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 5.7.*
|
||||||
|
phpunit: ~7.5
|
||||||
|
|
||||||
|
# Laravel 5.8
|
||||||
|
- php: 7.1
|
||||||
|
laravel: 5.8.*
|
||||||
|
phpunit: ~7.5
|
||||||
|
- php: 7.2
|
||||||
|
laravel: 5.8.*
|
||||||
|
phpunit: ~8.0
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 5.8.*
|
||||||
|
phpunit: ~8.0
|
||||||
|
|
||||||
|
# Laravel 6.x
|
||||||
|
- php: 7.2
|
||||||
|
laravel: 6.*
|
||||||
|
phpunit: ~8.0
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 6.*
|
||||||
|
phpunit: ~8.0
|
||||||
|
|
||||||
|
# Laravel 7.x
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 7.*
|
||||||
|
phpunit: ~9.0
|
||||||
|
- php: 7.4
|
||||||
|
laravel: 7.*
|
||||||
|
phpunit: ~9.0
|
||||||
|
|
||||||
# Laravel 8.x
|
# Laravel 8.x
|
||||||
|
- php: 7.3
|
||||||
|
laravel: 8.*
|
||||||
|
phpunit: ~9.0
|
||||||
|
- php: 7.4
|
||||||
|
laravel: 8.*
|
||||||
|
phpunit: ~9.0
|
||||||
- php: 8.0
|
- php: 8.0
|
||||||
laravel: 8.*
|
laravel: 8.*
|
||||||
phpunit: ~9.0
|
phpunit: ~9.0
|
||||||
# Laravel 9.x
|
|
||||||
- php: 8.0
|
|
||||||
laravel: 9.*
|
|
||||||
phpunit: ~9.0
|
|
||||||
# Laravel 10.x
|
|
||||||
- php: 8.1
|
|
||||||
laravel: 10.*
|
|
||||||
phpunit: ~9.0
|
|
||||||
# Laravel 11.x
|
|
||||||
- php: 8.2
|
|
||||||
laravel: 11.*
|
|
||||||
phpunit: ~10.5
|
|
||||||
- php: 8.3
|
|
||||||
laravel: 11.*
|
|
||||||
phpunit: ~10.5
|
|
||||||
|
|
||||||
name: Laravel${{ matrix.laravel }}-PHP${{ matrix.php }}
|
name: Laravel${{ matrix.laravel }}-PHP${{ matrix.php }}
|
||||||
|
|
||||||
|
@ -71,13 +122,8 @@ jobs:
|
||||||
composer install --prefer-dist --no-progress --no-suggest
|
composer install --prefer-dist --no-progress --no-suggest
|
||||||
|
|
||||||
- name: Run test suite
|
- name: Run test suite
|
||||||
if: matrix.laravel != '11.*'
|
|
||||||
run: ./vendor/bin/phpunit -v
|
run: ./vendor/bin/phpunit -v
|
||||||
|
|
||||||
- name: Run test suite laravel 11
|
|
||||||
if: matrix.laravel == '11.*'
|
|
||||||
run: ./vendor/bin/phpunit -c phpunit.10.xml
|
|
||||||
|
|
||||||
- name: Run Coveralls
|
- name: Run Coveralls
|
||||||
env:
|
env:
|
||||||
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
@ -102,9 +148,9 @@ jobs:
|
||||||
needs: [ test, upload-coverage ]
|
needs: [ test, upload-coverage ]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 'lts/*'
|
node-version: '12'
|
||||||
|
|
||||||
- name: Run semantic-release
|
- name: Run semantic-release
|
||||||
env:
|
env:
|
||||||
|
|
22
README.md
22
README.md
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/php-casbin/laravel-authz/actions">
|
<a href="https://github.com/php-casbin/laravel-authz/actions">
|
||||||
<img src="https://github.com/php-casbin/laravel-authz/actions/workflows/build.yml/badge.svg?branch=master" alt="Build Status">
|
<img src="https://github.com/php-casbin/laravel-authz/workflows/build/badge.svg?branch=master" alt="Build Status">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://coveralls.io/github/php-casbin/laravel-authz">
|
<a href="https://coveralls.io/github/php-casbin/laravel-authz">
|
||||||
<img src="https://coveralls.io/repos/github/php-casbin/laravel-authz/badge.svg" alt="Coverage Status">
|
<img src="https://coveralls.io/repos/github/php-casbin/laravel-authz/badge.svg" alt="Coverage Status">
|
||||||
|
@ -35,7 +35,6 @@ All you need to learn to use `Casbin` first.
|
||||||
* [Using a middleware](#using-a-middleware)
|
* [Using a middleware](#using-a-middleware)
|
||||||
* [basic Enforcer Middleware](#basic-enforcer-middleware)
|
* [basic Enforcer Middleware](#basic-enforcer-middleware)
|
||||||
* [HTTP Request Middleware ( RESTful is also supported )](#http-request-middleware--restful-is-also-supported-)
|
* [HTTP Request Middleware ( RESTful is also supported )](#http-request-middleware--restful-is-also-supported-)
|
||||||
* [Using Gates](#using-gates)
|
|
||||||
* [Multiple enforcers](#multiple-enforcers)
|
* [Multiple enforcers](#multiple-enforcers)
|
||||||
* [Using artisan commands](#using-artisan-commands)
|
* [Using artisan commands](#using-artisan-commands)
|
||||||
* [Cache](#using-cache)
|
* [Cache](#using-cache)
|
||||||
|
@ -106,7 +105,7 @@ use Enforcer;
|
||||||
Enforcer::addPermissionForUser('eve', 'articles', 'read');
|
Enforcer::addPermissionForUser('eve', 'articles', 'read');
|
||||||
// adds a role for a user.
|
// adds a role for a user.
|
||||||
Enforcer::addRoleForUser('eve', 'writer');
|
Enforcer::addRoleForUser('eve', 'writer');
|
||||||
// adds permissions to a role
|
// adds permissions to a rule
|
||||||
Enforcer::addPolicy('writer', 'articles','edit');
|
Enforcer::addPolicy('writer', 'articles','edit');
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -223,7 +222,7 @@ Determines whether a user has a permission.
|
||||||
Enforcer::hasPermissionForUser('eve', 'articles', 'read'); // true or false
|
Enforcer::hasPermissionForUser('eve', 'articles', 'read'); // true or false
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Casbin API](https://casbin.org/docs/management-api#reference) for more APIs.
|
See [Casbin API](https://casbin.org/docs/en/management-api) for more APIs.
|
||||||
|
|
||||||
### Using a middleware
|
### Using a middleware
|
||||||
|
|
||||||
|
@ -278,19 +277,6 @@ Route::group(['middleware' => ['http_request']], function () {
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using Gates
|
|
||||||
|
|
||||||
You can use Laravel Gates to check if a user has a permission, provided that you have set an existing user instance as the currently authenticated user.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$user->can('articles,read');
|
|
||||||
// For multiple enforcers
|
|
||||||
$user->can('articles,read', 'second');
|
|
||||||
// The methods cant, cannot, canAny, etc. also work
|
|
||||||
```
|
|
||||||
|
|
||||||
If you require custom Laravel Gates, you can disable the automatic registration by setting `enabled_register_at_gates` to `false` in the lauthz file. After that, you can use `Gates::before` or `Gates::after` in your ServiceProvider to register custom Gates. See [Gates](https://laravel.com/docs/11.x/authorization#gates) for more details.
|
|
||||||
|
|
||||||
### Multiple enforcers
|
### Multiple enforcers
|
||||||
|
|
||||||
If you need multiple permission controls in your project, you can configure multiple enforcers.
|
If you need multiple permission controls in your project, you can configure multiple enforcers.
|
||||||
|
@ -349,8 +335,6 @@ Adds a role for a user:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
php artisan role:assign eve writer
|
php artisan role:assign eve writer
|
||||||
# Specify the ptype of the role assignment by using the --ptype option.
|
|
||||||
php artisan role:assign eve writer --ptype=g2
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using cache
|
### Using cache
|
||||||
|
|
|
@ -20,17 +20,16 @@
|
||||||
],
|
],
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.0",
|
"php": ">=7.1.0",
|
||||||
"illuminate/support": "~8.0|~9.0|~10.0|~11.0",
|
"laravel/framework": "~5.5|~6.0|~7.0|~8.0",
|
||||||
"illuminate/database": "~8.0|~9.0|~10.0|~11.0",
|
"casbin/casbin": "~3.1",
|
||||||
"illuminate/console": "~8.0|~9.0|~10.0|~11.0",
|
"casbin/psr3-bridge": "^1.1"
|
||||||
"casbin/casbin": "~4.0"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~9.0|~10.5",
|
"phpunit/phpunit": "~7.0|~8.0|~9.0",
|
||||||
"php-coveralls/php-coveralls": "^2.7",
|
"php-coveralls/php-coveralls": "^2.4",
|
||||||
"mockery/mockery": "^1.0",
|
"mockery/mockery": "^1.0",
|
||||||
"laravel/laravel": "~9.0|~10.0|~11.0"
|
"laravel/laravel": "~5.5|~6.0|~7.0|~8.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -51,10 +50,5 @@
|
||||||
"Enforcer": "Lauthz\\Facades\\Enforcer"
|
"Enforcer": "Lauthz\\Facades\\Enforcer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"allow-plugins": {
|
|
||||||
"kylekatarnls/update-helper": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,27 +6,17 @@ return [
|
||||||
*/
|
*/
|
||||||
'default' => 'basic',
|
'default' => 'basic',
|
||||||
|
|
||||||
/*
|
|
||||||
* Lauthz Localizer
|
|
||||||
*/
|
|
||||||
'localizer' => [
|
|
||||||
// changes whether enforcer will register at gates.
|
|
||||||
'enabled_register_at_gates' => true
|
|
||||||
],
|
|
||||||
|
|
||||||
'basic' => [
|
'basic' => [
|
||||||
/*
|
/*
|
||||||
* Casbin model setting.
|
* Casbin model setting.
|
||||||
*/
|
*/
|
||||||
'model' => [
|
'model' => [
|
||||||
// Available Settings: "file", "text", "url"
|
// Available Settings: "file", "text"
|
||||||
'config_type' => 'file',
|
'config_type' => 'file',
|
||||||
|
|
||||||
'config_file_path' => __DIR__ . DIRECTORY_SEPARATOR . 'lauthz-rbac-model.conf',
|
'config_file_path' => config_path('lauthz-rbac-model.conf'),
|
||||||
|
|
||||||
'config_text' => '',
|
'config_text' => '',
|
||||||
|
|
||||||
'config_url' => ''
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -13,7 +13,7 @@ class CreateRulesTable extends Migration
|
||||||
$connection = config('lauthz.basic.database.connection') ?: config('database.default');
|
$connection = config('lauthz.basic.database.connection') ?: config('database.default');
|
||||||
Schema::connection($connection)->create(config('lauthz.basic.database.rules_table'), function (Blueprint $table) {
|
Schema::connection($connection)->create(config('lauthz.basic.database.rules_table'), function (Blueprint $table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->string('ptype')->nullable();
|
$table->string('p_type')->nullable();
|
||||||
$table->string('v0')->nullable();
|
$table->string('v0')->nullable();
|
||||||
$table->string('v1')->nullable();
|
$table->string('v1')->nullable();
|
||||||
$table->string('v2')->nullable();
|
$table->string('v2')->nullable();
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
backupGlobals="false"
|
|
||||||
bootstrap="vendor/autoload.php"
|
|
||||||
colors="true"
|
|
||||||
processIsolation="false"
|
|
||||||
stopOnFailure="false"
|
|
||||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd">
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="Application Test Suite">
|
|
||||||
<directory>./tests/</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
|
|
||||||
<coverage includeUncoveredFiles="true"
|
|
||||||
pathCoverage="false"
|
|
||||||
ignoreDeprecatedCodeUnits="true"
|
|
||||||
disableCodeCoverageIgnore="true">
|
|
||||||
<report>
|
|
||||||
<clover outputFile="build/logs/clover.xml"/>
|
|
||||||
<html outputDirectory="build/html" lowUpperBound="50" highLowerBound="90"/>
|
|
||||||
</report>
|
|
||||||
</coverage>
|
|
||||||
|
|
||||||
<source>
|
|
||||||
<include>
|
|
||||||
<directory>./src</directory>
|
|
||||||
</include>
|
|
||||||
</source>
|
|
||||||
|
|
||||||
<php>
|
|
||||||
<env name="APP_ENV" value="testing"/>
|
|
||||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
|
||||||
<env name="CACHE_DRIVER" value="array"/>
|
|
||||||
<env name="MAIL_DRIVER" value="array"/>
|
|
||||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
|
||||||
<env name="SESSION_DRIVER" value="array"/>
|
|
||||||
|
|
||||||
<env name="DB_DATABASE" value="lauthz"/>
|
|
||||||
<env name="DB_USERNAME" value="root"/>
|
|
||||||
</php>
|
|
||||||
</phpunit>
|
|
18
phpunit.xml
18
phpunit.xml
|
@ -1,11 +1,13 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<phpunit backupGlobals="false"
|
||||||
backupGlobals="false"
|
backupStaticAttributes="false"
|
||||||
bootstrap="vendor/autoload.php"
|
bootstrap="vendor/autoload.php"
|
||||||
colors="true"
|
colors="true"
|
||||||
processIsolation="false"
|
convertErrorsToExceptions="true"
|
||||||
stopOnFailure="false"
|
convertNoticesToExceptions="true"
|
||||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd">
|
convertWarningsToExceptions="true"
|
||||||
|
processIsolation="false"
|
||||||
|
stopOnFailure="false">
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="Application Test Suite">
|
<testsuite name="Application Test Suite">
|
||||||
<directory>./tests/</directory>
|
<directory>./tests/</directory>
|
||||||
|
@ -16,12 +18,10 @@
|
||||||
<directory suffix=".php">./src</directory>
|
<directory suffix=".php">./src</directory>
|
||||||
</whitelist>
|
</whitelist>
|
||||||
</filter>
|
</filter>
|
||||||
|
|
||||||
<logging>
|
<logging>
|
||||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||||
<log type="coverage-html" target="build/html"/>
|
<log type="coverage-html" target="build/html"/>
|
||||||
</logging>
|
</logging>
|
||||||
|
|
||||||
<php>
|
<php>
|
||||||
<env name="APP_ENV" value="testing"/>
|
<env name="APP_ENV" value="testing"/>
|
||||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
|
|
|
@ -14,8 +14,6 @@ use Casbin\Model\Model;
|
||||||
use Casbin\Persist\AdapterHelper;
|
use Casbin\Persist\AdapterHelper;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Casbin\Exceptions\InvalidFilterTypeException;
|
use Casbin\Exceptions\InvalidFilterTypeException;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseAdapter.
|
* DatabaseAdapter.
|
||||||
*
|
*
|
||||||
|
@ -47,26 +45,6 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
$this->eloquent = $eloquent;
|
$this->eloquent = $eloquent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* savePolicyLine function.
|
* savePolicyLine function.
|
||||||
*
|
*
|
||||||
|
@ -75,7 +53,7 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
*/
|
*/
|
||||||
public function savePolicyLine(string $ptype, array $rule): void
|
public function savePolicyLine(string $ptype, array $rule): void
|
||||||
{
|
{
|
||||||
$col['ptype'] = $ptype;
|
$col['p_type'] = $ptype;
|
||||||
foreach ($rule as $key => $value) {
|
foreach ($rule as $key => $value) {
|
||||||
$col['v'.strval($key)] = $value;
|
$col['v'.strval($key)] = $value;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +71,10 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
$rows = $this->eloquent->getAllFromCache();
|
$rows = $this->eloquent->getAllFromCache();
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$this->loadPolicyArray($this->filterRule($row), $model);
|
$line = implode(', ', array_filter($row, function ($val) {
|
||||||
|
return '' != $val && !is_null($val);
|
||||||
|
}));
|
||||||
|
$this->loadPolicyLine(trim($line), $model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +125,7 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
$i = 0;
|
$i = 0;
|
||||||
|
|
||||||
foreach($rules as $rule) {
|
foreach($rules as $rule) {
|
||||||
$temp['ptype'] = $ptype;
|
$temp['p_type'] = $ptype;
|
||||||
$temp['created_at'] = new DateTime();
|
$temp['created_at'] = new DateTime();
|
||||||
$temp['updated_at'] = $temp['created_at'];
|
$temp['updated_at'] = $temp['created_at'];
|
||||||
foreach ($rule as $key => $value) {
|
foreach ($rule as $key => $value) {
|
||||||
|
@ -154,7 +135,6 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
$temp = [];
|
$temp = [];
|
||||||
}
|
}
|
||||||
$this->eloquent->insert($cols);
|
$this->eloquent->insert($cols);
|
||||||
Rule::fireModelEvent('saved');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,14 +146,19 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
*/
|
*/
|
||||||
public function removePolicy(string $sec, string $ptype, array $rule): void
|
public function removePolicy(string $sec, string $ptype, array $rule): void
|
||||||
{
|
{
|
||||||
$instance = $this->eloquent->where('ptype', $ptype);
|
$count = 0;
|
||||||
|
|
||||||
|
$instance = $this->eloquent->where('p_type', $ptype);
|
||||||
|
|
||||||
foreach ($rule as $key => $value) {
|
foreach ($rule as $key => $value) {
|
||||||
$instance->where('v'.strval($key), $value);
|
$instance->where('v'.strval($key), $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$instance->delete();
|
foreach ($instance->get() as $model) {
|
||||||
Rule::fireModelEvent('deleted');
|
if ($model->delete()) {
|
||||||
|
++$count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,59 +171,50 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
*/
|
*/
|
||||||
public function removePolicies(string $sec, string $ptype, array $rules): void
|
public function removePolicies(string $sec, string $ptype, array $rules): void
|
||||||
{
|
{
|
||||||
$this->eloquent->getConnection()->transaction(function () use ($sec, $rules, $ptype) {
|
$count = 0;
|
||||||
foreach ($rules as $rule) {
|
$instance = $this->eloquent->where('p_type', $ptype);
|
||||||
$this->removePolicy($sec, $ptype, $rule);
|
foreach($rules as $rule)
|
||||||
}
|
{
|
||||||
});
|
foreach ($rule as $key => $value) {
|
||||||
}
|
$keys[] = 'v'.strval($key);
|
||||||
|
$con['v'.strval($key)][] = $value;
|
||||||
/**
|
|
||||||
* @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 = [];
|
|
||||||
$instance = $this->eloquent->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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$keys = array_unique($keys);
|
||||||
$oldP = $instance->get()->makeHidden(['created_at','updated_at', 'id', 'ptype'])->toArray();
|
foreach($keys as $key){
|
||||||
foreach ($oldP as &$item) {
|
$instance->whereIn($key, $con[$key]);
|
||||||
$item = $this->filterRule($item);
|
|
||||||
$removedRules[] = $item;
|
|
||||||
}
|
}
|
||||||
|
$num = $instance->delete();
|
||||||
$instance->delete();
|
$count += $num;
|
||||||
Rule::fireModelEvent('deleted');
|
|
||||||
|
|
||||||
return $removedRules;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RemoveFilteredPolicy removes policy rules that match the filter from the storage.
|
* RemoveFilteredPolicy removes policy rules that match the filter from the storage.
|
||||||
* This is part of the Auto-Save feature.
|
* This is part of the Auto-Save feature.
|
||||||
*
|
*
|
||||||
* @param string $sec
|
* @param string $sec
|
||||||
* @param string $ptype
|
* @param string $ptype
|
||||||
* @param int $fieldIndex
|
* @param int $fieldIndex
|
||||||
* @param string|null ...$fieldValues
|
* @param string ...$fieldValues
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, ?string ...$fieldValues): void
|
public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, string ...$fieldValues): void
|
||||||
{
|
{
|
||||||
$this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues);
|
$count = 0;
|
||||||
|
|
||||||
|
$instance = $this->eloquent->where('p_type', $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->get() as $model) {
|
||||||
|
if ($model->delete()) {
|
||||||
|
++$count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,59 +228,16 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo
|
||||||
*/
|
*/
|
||||||
public function updatePolicy(string $sec, string $ptype, array $oldRule, array $newPolicy): void
|
public function updatePolicy(string $sec, string $ptype, array $oldRule, array $newPolicy): void
|
||||||
{
|
{
|
||||||
$instance = $this->eloquent->where('ptype', $ptype);
|
$instance = $this->eloquent->where('p_type', $ptype);
|
||||||
foreach($oldRule as $k => $v) {
|
foreach($oldRule as $k => $v) {
|
||||||
$instance->where('v' . $k, $v);
|
$instance->where('v' . $k, $v);
|
||||||
}
|
}
|
||||||
$instance = $instance->first();
|
$instance->first();
|
||||||
if (!$instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$update = [];
|
$update = [];
|
||||||
foreach($newPolicy as $k => $v) {
|
foreach($newPolicy as $k => $v) {
|
||||||
$update['v' . $k] = $v;
|
$update['v' . $k] = $v;
|
||||||
}
|
}
|
||||||
$instance->update($update);
|
$instance->update($update);
|
||||||
Rule::fireModelEvent('saved');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UpdatePolicies updates some policy rules to storage, like db, redis.
|
|
||||||
*
|
|
||||||
* @param string $sec
|
|
||||||
* @param string $ptype
|
|
||||||
* @param string[][] $oldRules
|
|
||||||
* @param string[][] $newRules
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function updatePolicies(string $sec, string $ptype, array $oldRules, array $newRules): void
|
|
||||||
{
|
|
||||||
$this->eloquent->getConnection()->transaction(function () use ($sec, $ptype, $oldRules, $newRules) {
|
|
||||||
foreach ($oldRules as $i => $oldRule) {
|
|
||||||
$this->updatePolicy($sec, $ptype, $oldRule, $newRules[$i]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
{
|
|
||||||
$oldRules = [];
|
|
||||||
$this->eloquent->getConnection()->transaction(function () use ($sec, $ptype, $fieldIndex, $fieldValues, $newPolicies, &$oldRules) {
|
|
||||||
$oldRules = $this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues);
|
|
||||||
$this->addPolicies($sec, $ptype, $newPolicies);
|
|
||||||
});
|
|
||||||
return $oldRules;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,8 +17,7 @@ class RoleAssign extends Command
|
||||||
*/
|
*/
|
||||||
protected $signature = 'role:assign
|
protected $signature = 'role:assign
|
||||||
{user : the identifier of user}
|
{user : the identifier of user}
|
||||||
{role : the name of role}
|
{role : the name of role}';
|
||||||
{--ptype= : the ptype of role}';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
|
@ -36,9 +35,8 @@ class RoleAssign extends Command
|
||||||
{
|
{
|
||||||
$user = $this->argument('user');
|
$user = $this->argument('user');
|
||||||
$role = $this->argument('role');
|
$role = $this->argument('role');
|
||||||
$ptype = $this->option('ptype') ?: 'g';
|
|
||||||
|
|
||||||
$ret = Enforcer::addNamedGroupingPolicy($ptype, $user, $role);
|
$ret = Enforcer::addRoleForUser($user, $role);
|
||||||
if ($ret) {
|
if ($ret) {
|
||||||
$this->info('Added `'.$role.'` role to `'.$user.'` successfully');
|
$this->info('Added `'.$role.'` role to `'.$user.'` successfully');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Contracts;
|
|
||||||
|
|
||||||
|
|
||||||
use Casbin\Model\Model;
|
|
||||||
|
|
||||||
interface ModelLoader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Loads model definitions into the provided model object.
|
|
||||||
*
|
|
||||||
* @param Model $model
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function loadModel(Model $model): void;
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz;
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Auth\Access\Authorizable;
|
|
||||||
use Illuminate\Contracts\Auth\Access\Gate;
|
|
||||||
use Lauthz\Facades\Enforcer;
|
|
||||||
|
|
||||||
class EnforcerLocalizer
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The application instance.
|
|
||||||
*
|
|
||||||
* @var \Illuminate\Foundation\Application
|
|
||||||
*/
|
|
||||||
protected $app;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new localizer instance.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Foundation\Application $app
|
|
||||||
*/
|
|
||||||
public function __construct($app)
|
|
||||||
{
|
|
||||||
$this->app = $app;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the localizer based on the configuration.
|
|
||||||
*/
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
if ($this->app->config->get('lauthz.localizer.enabled_register_at_gates')) {
|
|
||||||
$this->registerAtGate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the localizer at the gate.
|
|
||||||
*/
|
|
||||||
protected function registerAtGate()
|
|
||||||
{
|
|
||||||
$this->app->make(Gate::class)->before(function (Authorizable $user, string $ability, array $guards) {
|
|
||||||
/** @var \Illuminate\Contracts\Auth\Authenticatable $user */
|
|
||||||
$identifier = $user->getAuthIdentifier();
|
|
||||||
if (method_exists($user, 'getAuthzIdentifier')) {
|
|
||||||
/** @var \Lauthz\Tests\Models\User $user */
|
|
||||||
$identifier = $user->getAuthzIdentifier();
|
|
||||||
}
|
|
||||||
$identifier = strval($identifier);
|
|
||||||
$ability = explode(',', $ability);
|
|
||||||
if (empty($guards)) {
|
|
||||||
return Enforcer::enforce($identifier, ...$ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($guards as $guard) {
|
|
||||||
return Enforcer::guard($guard)->enforce($identifier, ...$ability);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,15 +2,14 @@
|
||||||
|
|
||||||
namespace Lauthz;
|
namespace Lauthz;
|
||||||
|
|
||||||
|
use Casbin\Bridge\Logger\LoggerBridge;
|
||||||
use Casbin\Enforcer;
|
use Casbin\Enforcer;
|
||||||
use Casbin\Model\Model;
|
use Casbin\Model\Model;
|
||||||
use Casbin\Log\Log;
|
use Casbin\Log\Log;
|
||||||
use Casbin\Log\Logger\DefaultLogger;
|
|
||||||
use Lauthz\Contracts\Factory;
|
use Lauthz\Contracts\Factory;
|
||||||
use Lauthz\Models\Rule;
|
use Lauthz\Models\Rule;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Lauthz\Loaders\ModelLoaderManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @mixin \Casbin\Enforcer
|
* @mixin \Casbin\Enforcer
|
||||||
|
@ -80,17 +79,19 @@ class EnforcerManager implements Factory
|
||||||
|
|
||||||
if ($logger = Arr::get($config, 'log.logger')) {
|
if ($logger = Arr::get($config, 'log.logger')) {
|
||||||
if (is_string($logger)) {
|
if (is_string($logger)) {
|
||||||
$logger = new DefaultLogger($this->app->make($logger));
|
$logger = $this->app->make($logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::setLogger($logger);
|
Log::setLogger(new LoggerBridge($logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
$model = new Model();
|
$model = new Model();
|
||||||
$loader = $this->app->make(ModelLoaderManager::class);
|
$configType = Arr::get($config, 'model.config_type');
|
||||||
$loader->initFromConfig($config);
|
if ('file' == $configType) {
|
||||||
$loader->loadModel($model);
|
$model->loadModel(Arr::get($config, 'model.config_file_path', ''));
|
||||||
|
} elseif ('text' == $configType) {
|
||||||
|
$model->loadModelFromText(Arr::get($config, 'model.config_text', ''));
|
||||||
|
}
|
||||||
$adapter = Arr::get($config, 'adapter');
|
$adapter = Arr::get($config, 'adapter');
|
||||||
if (!is_null($adapter)) {
|
if (!is_null($adapter)) {
|
||||||
$adapter = $this->app->make($adapter, [
|
$adapter = $this->app->make($adapter, [
|
||||||
|
@ -98,7 +99,7 @@ class EnforcerManager implements Factory
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Enforcer($model, $adapter, $logger, Arr::get($config, 'log.enabled', false));
|
return new Enforcer($model, $adapter, Arr::get($config, 'log.enabled', false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,36 +6,6 @@ use Illuminate\Support\Facades\Facade;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \Casbin\Enforcer
|
* @see \Casbin\Enforcer
|
||||||
* @method static string[] getRolesForUser(string $name, string ...$domain)
|
|
||||||
* @method static string[] getUsersForRole(string $name, string ...$domain)
|
|
||||||
* @method static bool hasRoleForUser(string $name, string $role, string ...$domain)
|
|
||||||
* @method static bool addRoleForUser(string $user, string $role, string ...$domain)
|
|
||||||
* @method static bool addRolesForUser(string $user, array $roles, string ...$domain)
|
|
||||||
* @method static bool deleteRoleForUser(string $user, string $role, string ...$domain)
|
|
||||||
* @method static bool deleteRolesForUser(string $user, string ...$domain)
|
|
||||||
* @method static bool deleteUser(string $user)
|
|
||||||
* @method static bool deleteRole(string $role)
|
|
||||||
* @method static bool deletePermission(string ...$permission)
|
|
||||||
* @method static bool addPermissionForUser(string $user, string ...$permission)
|
|
||||||
* @method static bool addPermissionsForUser(string $user, array ...$permissions)
|
|
||||||
* @method static bool deletePermissionForUser(string $user, string ...$permission)
|
|
||||||
* @method static bool deletePermissionsForUser(string $user)
|
|
||||||
* @method static array getPermissionsForUser(string $user, string ...$domain)
|
|
||||||
* @method static bool hasPermissionForUser(string $user, string ...$permission)
|
|
||||||
* @method static array getImplicitRolesForUser(string $name, string ...$domain)
|
|
||||||
* @method static array getImplicitUsersForRole(string $name, string ...$domain)
|
|
||||||
* @method static array getImplicitResourcesForUser(string $user, string ...$domain)
|
|
||||||
* @method static array getImplicitPermissionsForUser(string $user, string ...$domain)
|
|
||||||
* @method static array getImplicitUsersForPermission(string ...$permission)
|
|
||||||
* @method static string[] getAllUsersByDomain(string $domain)
|
|
||||||
* @method static array getUsersForRoleInDomain(string $name, string $domain)
|
|
||||||
* @method static array getRolesForUserInDomain(string $name, string $domain)
|
|
||||||
* @method static array getPermissionsForUserInDomain(string $name, string $domain)
|
|
||||||
* @method static bool addRoleForUserInDomain(string $user, string $role, string $domain)
|
|
||||||
* @method static bool deleteRoleForUserInDomain(string $user, string $role, string $domain)
|
|
||||||
* @method static bool deleteRolesForUserInDomain(string $user, string $domain)
|
|
||||||
* @method static bool deleteAllUsersByDomain(string $domain)
|
|
||||||
* @method static bool deleteDomains(string ...$domains)
|
|
||||||
*/
|
*/
|
||||||
class Enforcer extends Facade
|
class Enforcer extends Facade
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
namespace Lauthz;
|
namespace Lauthz;
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Lauthz\EnforcerLocalizer;
|
|
||||||
use Lauthz\Loaders\ModelLoaderManager;
|
|
||||||
use Lauthz\Models\Rule;
|
use Lauthz\Models\Rule;
|
||||||
use Lauthz\Observers\RuleObserver;
|
use Lauthz\Observers\RuleObserver;
|
||||||
|
|
||||||
|
@ -17,10 +15,8 @@ class LauthzServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->publishes([__DIR__ . '/../database/migrations' => database_path('migrations')], 'laravel-lauthz-migrations');
|
$this->publishes([__DIR__ . '/../database/migrations' => database_path('migrations')], 'laravel-lauthz-migrations');
|
||||||
$this->publishes([
|
$this->publishes([__DIR__ . '/../config/lauthz-rbac-model.conf' => config_path('lauthz-rbac-model.conf')], 'laravel-lauthz-config');
|
||||||
__DIR__ . '/../config/lauthz-rbac-model.conf' => $this->app->basePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . ('lauthz-rbac-model.conf'),
|
$this->publishes([__DIR__ . '/../config/lauthz.php' => config_path('lauthz.php')], 'laravel-lauthz-config');
|
||||||
__DIR__ . '/../config/lauthz.php' => $this->app->basePath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . ('lauthz.php'),
|
|
||||||
], 'laravel-lauthz-config');
|
|
||||||
|
|
||||||
$this->commands([
|
$this->commands([
|
||||||
Commands\GroupAdd::class,
|
Commands\GroupAdd::class,
|
||||||
|
@ -32,8 +28,6 @@ class LauthzServiceProvider extends ServiceProvider
|
||||||
$this->mergeConfigFrom(__DIR__ . '/../config/lauthz.php', 'lauthz');
|
$this->mergeConfigFrom(__DIR__ . '/../config/lauthz.php', 'lauthz');
|
||||||
|
|
||||||
$this->bootObserver();
|
$this->bootObserver();
|
||||||
|
|
||||||
$this->registerLocalizer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,23 +48,5 @@ class LauthzServiceProvider extends ServiceProvider
|
||||||
$this->app->singleton('enforcer', function ($app) {
|
$this->app->singleton('enforcer', function ($app) {
|
||||||
return new EnforcerManager($app);
|
return new EnforcerManager($app);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->app->singleton(ModelLoaderManager::class, function ($app) {
|
|
||||||
return new ModelLoaderManager($app);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->app->singleton(EnforcerLocalizer::class, function ($app) {
|
|
||||||
return new EnforcerLocalizer($app);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a gate that allows users to use Laravel's built-in Gate to call Enforcer.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function registerLocalizer()
|
|
||||||
{
|
|
||||||
$this->app->make(EnforcerLocalizer::class)->register();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Loaders;
|
|
||||||
|
|
||||||
use Casbin\Model\Model;
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Lauthz\Contracts\ModelLoader;
|
|
||||||
|
|
||||||
class FileLoader implements ModelLoader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The path to the model file.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $filePath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to initialize the file path.
|
|
||||||
*
|
|
||||||
* @param array $config
|
|
||||||
*/
|
|
||||||
public function __construct(array $config)
|
|
||||||
{
|
|
||||||
$this->filePath = Arr::get($config, 'model.config_file_path', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads model from file.
|
|
||||||
*
|
|
||||||
* @param Model $model
|
|
||||||
* @return void
|
|
||||||
* @throws \Casbin\Exceptions\CasbinException
|
|
||||||
*/
|
|
||||||
public function loadModel(Model $model): void
|
|
||||||
{
|
|
||||||
$model->loadModel($this->filePath);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Loaders;
|
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Support\Manager;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The model loader manager.
|
|
||||||
*
|
|
||||||
* A model loader is responsible for a loading model from an arbitrary source.
|
|
||||||
* Developers can customize loading behavior by implementing
|
|
||||||
* and register the custom loader in AppServiceProvider through `app(LoaderManager::class)->extend()`.
|
|
||||||
*
|
|
||||||
* Built-in loader implementations include:
|
|
||||||
* - FileLoader: For loading model from file.
|
|
||||||
* - TextLoader: Suitable for model defined as a multi-line string.
|
|
||||||
* - UrlLoader: Handles model loading from URL.
|
|
||||||
*
|
|
||||||
* To utilize a built-in or custom loader, set 'model.config_type' in the configuration to match one of the above types.
|
|
||||||
*/
|
|
||||||
class ModelLoaderManager extends Manager
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The array of the lauthz driver configuration.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize configuration for the loader manager instance.
|
|
||||||
*
|
|
||||||
* @param array $config the lauthz driver configuration.
|
|
||||||
*/
|
|
||||||
public function initFromConfig(array $config)
|
|
||||||
{
|
|
||||||
$this->config = $config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the default driver from the configuration.
|
|
||||||
*
|
|
||||||
* @return string The default driver name.
|
|
||||||
*/
|
|
||||||
public function getDefaultDriver()
|
|
||||||
{
|
|
||||||
return Arr::get($this->config, 'model.config_type', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new TextLoader instance.
|
|
||||||
*
|
|
||||||
* @return TextLoader
|
|
||||||
*/
|
|
||||||
public function createTextDriver()
|
|
||||||
{
|
|
||||||
return new TextLoader($this->config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new UrlLoader instance.
|
|
||||||
*
|
|
||||||
* @return UrlLoader
|
|
||||||
*/
|
|
||||||
public function createUrlDriver()
|
|
||||||
{
|
|
||||||
return new UrlLoader($this->config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new FileLoader instance.
|
|
||||||
*
|
|
||||||
* @return FileLoader
|
|
||||||
*/
|
|
||||||
public function createFileDriver()
|
|
||||||
{
|
|
||||||
return new FileLoader($this->config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new driver instance.
|
|
||||||
*
|
|
||||||
* @param string $driver
|
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
|
||||||
protected function createDriver($driver)
|
|
||||||
{
|
|
||||||
if(empty($driver)) {
|
|
||||||
throw new InvalidArgumentException('Unsupported empty model loader type.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($this->customCreators[$driver])) {
|
|
||||||
return $this->callCustomCreator($driver);
|
|
||||||
}
|
|
||||||
$method = 'create' . Str::studly($driver) . 'Driver';
|
|
||||||
if (method_exists($this, $method)) {
|
|
||||||
return $this->$method();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidArgumentException("Unsupported model loader type: {$driver}.");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Loaders;
|
|
||||||
|
|
||||||
use Casbin\Model\Model;
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Lauthz\Contracts\ModelLoader;
|
|
||||||
|
|
||||||
class TextLoader implements ModelLoader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Model text.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $text;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to initialize the model text.
|
|
||||||
*
|
|
||||||
* @param array $config
|
|
||||||
*/
|
|
||||||
public function __construct(array $config)
|
|
||||||
{
|
|
||||||
$this->text = Arr::get($config, 'model.config_text', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads model from text.
|
|
||||||
*
|
|
||||||
* @param Model $model
|
|
||||||
* @return void
|
|
||||||
* @throws \Casbin\Exceptions\CasbinException
|
|
||||||
*/
|
|
||||||
public function loadModel(Model $model): void
|
|
||||||
{
|
|
||||||
$model->loadModelFromText($this->text);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Loaders;
|
|
||||||
|
|
||||||
use Casbin\Model\Model;
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Lauthz\Contracts\ModelLoader;
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
class UrlLoader implements ModelLoader
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The url to fetch the remote model string.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to initialize the url path.
|
|
||||||
*
|
|
||||||
* @param array $config
|
|
||||||
*/
|
|
||||||
public function __construct(array $config)
|
|
||||||
{
|
|
||||||
$this->url = Arr::get($config, 'model.config_url', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads model from remote url.
|
|
||||||
*
|
|
||||||
* @param Model $model
|
|
||||||
* @return void
|
|
||||||
* @throws \Casbin\Exceptions\CasbinException
|
|
||||||
* @throws RuntimeException
|
|
||||||
*/
|
|
||||||
public function loadModel(Model $model): void
|
|
||||||
{
|
|
||||||
$contextOptions = [
|
|
||||||
'http' => [
|
|
||||||
'method' => 'GET',
|
|
||||||
'header' => "Accept: text/plain\r\n",
|
|
||||||
'timeout' => 3
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$context = stream_context_create($contextOptions);
|
|
||||||
$response = @file_get_contents($this->url, false, $context);
|
|
||||||
if ($response === false) {
|
|
||||||
$error = error_get_last();
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Failed to fetch remote model " . $this->url . ": " . $error['message']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->loadModelFromText($response);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,10 +31,8 @@ class EnforcerMiddleware
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
$identifier = $user->getAuthIdentifier();
|
$identifier = $user->getAuthIdentifier();
|
||||||
if (method_exists($user, 'getAuthzIdentifier')) {
|
if (method_exists($user, 'getAuthzIdentifier')) {
|
||||||
/** @var \Lauthz\Tests\Models\User $user */
|
|
||||||
$identifier = $user->getAuthzIdentifier();
|
$identifier = $user->getAuthzIdentifier();
|
||||||
}
|
}
|
||||||
$identifier = strval($identifier);
|
|
||||||
|
|
||||||
if (!Enforcer::enforce($identifier, ...$args)) {
|
if (!Enforcer::enforce($identifier, ...$args)) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
|
|
|
@ -48,7 +48,6 @@ class RequestMiddleware
|
||||||
if (method_exists($user, 'getAuthzIdentifier')) {
|
if (method_exists($user, 'getAuthzIdentifier')) {
|
||||||
$identifier = $user->getAuthzIdentifier();
|
$identifier = $user->getAuthzIdentifier();
|
||||||
}
|
}
|
||||||
$identifier = strval($identifier);
|
|
||||||
|
|
||||||
if (empty($guards)) {
|
if (empty($guards)) {
|
||||||
if (Enforcer::enforce($identifier, $request->getPathInfo(), $request->method())) {
|
if (Enforcer::enforce($identifier, $request->getPathInfo(), $request->method())) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Rule extends Model
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
|
protected $fillable = ['p_type', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Eloquent model instance.
|
* Create a new Eloquent model instance.
|
||||||
|
@ -62,7 +62,7 @@ class Rule extends Model
|
||||||
public function getAllFromCache()
|
public function getAllFromCache()
|
||||||
{
|
{
|
||||||
$get = function () {
|
$get = function () {
|
||||||
return $this->select('ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5')->get()->toArray();
|
return $this->select('p_type', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5')->get()->toArray();
|
||||||
};
|
};
|
||||||
if (!$this->config('cache.enabled', false)) {
|
if (!$this->config('cache.enabled', false)) {
|
||||||
return $get();
|
return $get();
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace Lauthz\Tests\Commands;
|
namespace Lauthz\Tests\Commands;
|
||||||
|
|
||||||
use Casbin\Model\Model;
|
|
||||||
use Lauthz\Facades\Enforcer;
|
use Lauthz\Facades\Enforcer;
|
||||||
use Lauthz\Tests\TestCase;
|
use Lauthz\Tests\TestCase;
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||||
|
@ -20,21 +19,5 @@ class RoleAssignTest extends TestCase
|
||||||
$exitCode = Artisan::call('role:assign', ['user' => 'eve', 'role' => 'writer']);
|
$exitCode = Artisan::call('role:assign', ['user' => 'eve', 'role' => 'writer']);
|
||||||
$this->assertFalse(0 === $exitCode);
|
$this->assertFalse(0 === $exitCode);
|
||||||
$this->assertTrue(Enforcer::hasRoleForUser('eve', 'writer'));
|
$this->assertTrue(Enforcer::hasRoleForUser('eve', 'writer'));
|
||||||
|
|
||||||
$model = Model::newModel();
|
|
||||||
$model->addDef('r', 'r', 'sub, obj, act');
|
|
||||||
$model->addDef('p', 'p', 'sub, obj, act');
|
|
||||||
$model->addDef('g', 'g', '_, _');
|
|
||||||
$model->addDef('g', 'g2', '_, _');
|
|
||||||
$model->addDef('e', 'e', 'some(where (p.eft == allow))');
|
|
||||||
$model->addDef('m', 'm', 'g(r.sub, p.sub) && g2(r.obj, p.obj) && r.act == p.act');
|
|
||||||
Enforcer::setModel($model);
|
|
||||||
Enforcer::loadPolicy();
|
|
||||||
$this->assertFalse(Enforcer::hasNamedGroupingPolicy('g2', 'eve', 'writer'));
|
|
||||||
$exitCode = Artisan::call('role:assign', ['user' => 'eve', 'role' => 'writer', '--ptype' => 'g2']);
|
|
||||||
$this->assertTrue(0 === $exitCode);
|
|
||||||
$exitCode = Artisan::call('role:assign', ['user' => 'eve', 'role' => 'writer', '--ptype' => 'g2']);
|
|
||||||
$this->assertFalse(0 === $exitCode);
|
|
||||||
$this->assertTrue(Enforcer::hasNamedGroupingPolicy('g2', 'eve', 'writer'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Tests;
|
|
||||||
|
|
||||||
use Lauthz\Models\Rule;
|
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
|
||||||
use Lauthz\Facades\Enforcer;
|
|
||||||
|
|
||||||
class DatabaseAdapterForCacheTest extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
use DatabaseMigrations;
|
|
||||||
|
|
||||||
public function testAddPolicy()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$this->assertFalse(Enforcer::enforce('eve', 'data3', 'read'));
|
|
||||||
Enforcer::addPermissionForUser('eve', 'data3', 'read');
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertTrue(Enforcer::enforce('eve', 'data3', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testAddPolicies()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$policies = [
|
|
||||||
['u1', 'd1', 'read'],
|
|
||||||
['u2', 'd2', 'read'],
|
|
||||||
['u3', 'd3', 'read'],
|
|
||||||
];
|
|
||||||
$this->refreshPolicies();
|
|
||||||
Rule::truncate();
|
|
||||||
Enforcer::addPolicies($policies);
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertEquals($policies, Enforcer::getPolicy());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testSavePolicy()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data4', 'read'));
|
|
||||||
|
|
||||||
$model = Enforcer::getModel();
|
|
||||||
$model->clearPolicy();
|
|
||||||
$model->addPolicy('p', 'p', ['alice', 'data4', 'read']);
|
|
||||||
|
|
||||||
$adapter = Enforcer::getAdapter();
|
|
||||||
$adapter->savePolicy($model);
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data4', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRemovePolicy()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data5', 'read'));
|
|
||||||
|
|
||||||
Enforcer::addPermissionForUser('alice', 'data5', 'read');
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data5', 'read'));
|
|
||||||
|
|
||||||
Enforcer::deletePermissionForUser('alice', 'data5', 'read');
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data5', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRemovePolicies()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
Enforcer::removePolicies([
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
]);
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write']
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRemoveFilteredPolicy()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data1', 'read'));
|
|
||||||
Enforcer::removeFilteredPolicy(1, 'data1');
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data1', 'read'));
|
|
||||||
$this->assertTrue(Enforcer::enforce('bob', 'data2', 'write'));
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data2', 'read'));
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data2', 'write'));
|
|
||||||
Enforcer::removeFilteredPolicy(1, 'data2', 'read');
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertTrue(Enforcer::enforce('bob', 'data2', 'write'));
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data2', 'read'));
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data2', 'write'));
|
|
||||||
Enforcer::removeFilteredPolicy(2, 'write');
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertFalse(Enforcer::enforce('bob', 'data2', 'write'));
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data2', 'write'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUpdatePolicy()
|
|
||||||
{
|
|
||||||
$this->enableCache();
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
Enforcer::updatePolicy(
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['alice', 'data1', 'write']
|
|
||||||
);
|
|
||||||
|
|
||||||
Enforcer::updatePolicy(
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['bob', 'data2', 'read']
|
|
||||||
);
|
|
||||||
$this->refreshPolicies();
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'write'],
|
|
||||||
['bob', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function refreshPolicies()
|
|
||||||
{
|
|
||||||
Enforcer::loadPolicy();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function enableCache()
|
|
||||||
{
|
|
||||||
$this->app['config']->set('lauthz.basic.cache.enabled', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
namespace Lauthz\Tests;
|
namespace Lauthz\Tests;
|
||||||
|
|
||||||
|
use Enforcer;
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||||
use Casbin\Persist\Adapters\Filter;
|
use Casbin\Persist\Adapters\Filter;
|
||||||
use Casbin\Exceptions\InvalidFilterTypeException;
|
use Casbin\Exceptions\InvalidFilterTypeException;
|
||||||
use Lauthz\Facades\Enforcer;
|
|
||||||
|
|
||||||
class DatabaseAdapterTest extends TestCase
|
class DatabaseAdapterTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -131,159 +131,6 @@ class DatabaseAdapterTest extends TestCase
|
||||||
], Enforcer::getPolicy());
|
], Enforcer::getPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUpdatePolicies()
|
|
||||||
{
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
$oldPolicies = [
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write']
|
|
||||||
];
|
|
||||||
$newPolicies = [
|
|
||||||
['alice', 'data1', 'write'],
|
|
||||||
['bob', 'data2', 'read']
|
|
||||||
];
|
|
||||||
|
|
||||||
Enforcer::updatePolicies($oldPolicies, $newPolicies);
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'write'],
|
|
||||||
['bob', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
], Enforcer::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()
|
|
||||||
{
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
Enforcer::updateFilteredPolicies([["alice", "data1", "write"]], 0, "alice", "data1", "read");
|
|
||||||
Enforcer::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, Enforcer::getPolicy());
|
|
||||||
|
|
||||||
// test use updateFilteredPolicies to update all policies of a user
|
|
||||||
$this->initTable();
|
|
||||||
Enforcer::loadPolicy();
|
|
||||||
$policies = [
|
|
||||||
['alice', 'data2', 'write'],
|
|
||||||
['bob', 'data1', 'read']
|
|
||||||
];
|
|
||||||
Enforcer::addPolicies($policies);
|
|
||||||
|
|
||||||
$this->arrayEqualsWithoutOrder([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
['alice', 'data2', 'write'],
|
|
||||||
['bob', 'data1', 'read']
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
Enforcer::updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice');
|
|
||||||
Enforcer::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, Enforcer::getPolicy());
|
|
||||||
|
|
||||||
// test if $fieldValues contains empty string
|
|
||||||
$this->initTable();
|
|
||||||
Enforcer::loadPolicy();
|
|
||||||
$policies = [
|
|
||||||
['alice', 'data2', 'write'],
|
|
||||||
['bob', 'data1', 'read']
|
|
||||||
];
|
|
||||||
Enforcer::addPolicies($policies);
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
['alice', 'data2', 'write'],
|
|
||||||
['bob', 'data1', 'read']
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
Enforcer::updateFilteredPolicies([['alice', 'data1', 'write'], ['alice', 'data2', 'read']], 0, 'alice', '', '');
|
|
||||||
Enforcer::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, Enforcer::getPolicy());
|
|
||||||
|
|
||||||
// test if $fieldIndex is not zero
|
|
||||||
$this->initTable();
|
|
||||||
Enforcer::loadPolicy();
|
|
||||||
$policies = [
|
|
||||||
['alice', 'data2', 'write'],
|
|
||||||
['bob', 'data1', 'read']
|
|
||||||
];
|
|
||||||
Enforcer::addPolicies($policies);
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
['alice', 'data1', 'read'],
|
|
||||||
['bob', 'data2', 'write'],
|
|
||||||
['data2_admin', 'data2', 'read'],
|
|
||||||
['data2_admin', 'data2', 'write'],
|
|
||||||
['alice', 'data2', 'write'],
|
|
||||||
['bob', 'data1', 'read']
|
|
||||||
], Enforcer::getPolicy());
|
|
||||||
|
|
||||||
Enforcer::updateFilteredPolicies([['alice', 'data1', 'write'], ['bob', 'data1', 'write']], 2, 'read');
|
|
||||||
Enforcer::updateFilteredPolicies([['alice', 'data2', 'read'], ["bob", "data2", "read"]], 2, 'write');
|
|
||||||
|
|
||||||
$policies = [
|
|
||||||
['alice', 'data2', 'read'],
|
|
||||||
['bob', 'data2', 'read'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->arrayEqualsWithoutOrder($policies, Enforcer::getPolicy());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoadFilteredPolicy()
|
public function testLoadFilteredPolicy()
|
||||||
{
|
{
|
||||||
$this->initTable();
|
$this->initTable();
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Auth\Access\Gate;
|
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
|
||||||
use Lauthz\Tests\TestCase;
|
|
||||||
|
|
||||||
class EnforcerCustomLocalizerTest extends TestCase
|
|
||||||
{
|
|
||||||
use DatabaseMigrations;
|
|
||||||
|
|
||||||
public function testCustomRegisterAtGatesBefore()
|
|
||||||
{
|
|
||||||
$user = $this->user("alice");
|
|
||||||
$this->assertFalse($user->can('data3,read'));
|
|
||||||
|
|
||||||
app(Gate::class)->before(function () {
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->assertTrue($user->can('data3,read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCustomRegisterAtGatesDefine()
|
|
||||||
{
|
|
||||||
$user = $this->user("alice");
|
|
||||||
$this->assertFalse($user->can('data3,read'));
|
|
||||||
|
|
||||||
app(Gate::class)->define('data3,read', function () {
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->assertTrue($user->can('data3,read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initConfig()
|
|
||||||
{
|
|
||||||
parent::initConfig();
|
|
||||||
$this->app['config']->set('lauthz.localizer.enabled_register_at_gates', false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Auth\Access\Gate;
|
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
|
||||||
use Lauthz\Facades\Enforcer;
|
|
||||||
use Lauthz\Tests\TestCase;
|
|
||||||
|
|
||||||
class EnforcerLocalizerTest extends TestCase
|
|
||||||
{
|
|
||||||
use DatabaseMigrations;
|
|
||||||
|
|
||||||
public function testRegisterAtGates()
|
|
||||||
{
|
|
||||||
$user = $this->user('alice');
|
|
||||||
$this->assertTrue($user->can('data1,read'));
|
|
||||||
$this->assertFalse($user->can('data1,write'));
|
|
||||||
$this->assertFalse($user->cannot('data2,read'));
|
|
||||||
|
|
||||||
Enforcer::guard('second')->addPolicy('alice', 'data1', 'read');
|
|
||||||
$this->assertTrue($user->can('data1,read', 'second'));
|
|
||||||
$this->assertFalse($user->can('data3,read', 'second'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNotLogin()
|
|
||||||
{
|
|
||||||
$this->assertFalse(app(Gate::class)->allows('data1,read'));
|
|
||||||
$this->assertTrue(app(Gate::class)->forUser($this->user('alice'))->allows('data1,read'));
|
|
||||||
$this->assertFalse(app(Gate::class)->forUser($this->user('bob'))->allows('data1,read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testAfterLogin()
|
|
||||||
{
|
|
||||||
$this->login('alice');
|
|
||||||
$this->assertTrue(app(Gate::class)->allows('data1,read'));
|
|
||||||
$this->assertTrue(app(Gate::class)->allows('data2,read'));
|
|
||||||
$this->assertTrue(app(Gate::class)->allows('data2,write'));
|
|
||||||
|
|
||||||
$this->login('bob');
|
|
||||||
$this->assertFalse(app(Gate::class)->allows('data1,read'));
|
|
||||||
$this->assertTrue(app(Gate::class)->allows('data2,write'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initConfig()
|
|
||||||
{
|
|
||||||
parent::initConfig();
|
|
||||||
$this->app['config']->set('lauthz.second.model.config_type', 'text');
|
|
||||||
$this->app['config']->set(
|
|
||||||
'lauthz.second.model.config_text',
|
|
||||||
$this->getModelText()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getModelText(): string
|
|
||||||
{
|
|
||||||
return <<<EOT
|
|
||||||
[request_definition]
|
|
||||||
r = sub, obj, act
|
|
||||||
|
|
||||||
[policy_definition]
|
|
||||||
p = sub, obj, act
|
|
||||||
|
|
||||||
[policy_effect]
|
|
||||||
e = some(where (p.eft == allow))
|
|
||||||
|
|
||||||
[matchers]
|
|
||||||
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
|
|
||||||
EOT;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Lauthz\Tests;
|
|
||||||
|
|
||||||
use Lauthz\Facades\Enforcer;
|
|
||||||
use Lauthz\Loaders\ModelLoaderManager;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
|
|
||||||
class ModelLoaderTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testUrlLoader(): void
|
|
||||||
{
|
|
||||||
$this->initUrlConfig();
|
|
||||||
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
|
|
||||||
Enforcer::addPolicy('data_admin', 'data', 'read');
|
|
||||||
Enforcer::addRoleForUser('alice', 'data_admin');
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testTextLoader(): void
|
|
||||||
{
|
|
||||||
$this->initTextConfig();
|
|
||||||
|
|
||||||
Enforcer::addPolicy('data_admin', 'data', 'read');
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
$this->assertTrue(Enforcer::enforce('data_admin', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFileLoader(): void
|
|
||||||
{
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
|
|
||||||
Enforcer::addPolicy('data_admin', 'data', 'read');
|
|
||||||
Enforcer::addRoleForUser('alice', 'data_admin');
|
|
||||||
$this->assertTrue(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCustomLoader(): void
|
|
||||||
{
|
|
||||||
$this->initCustomConfig();
|
|
||||||
Enforcer::guard('second')->addPolicy('data_admin', 'data', 'read');
|
|
||||||
$this->assertFalse(Enforcer::guard('second')->enforce('alice', 'data', 'read'));
|
|
||||||
$this->assertTrue(Enforcer::guard('second')->enforce('data_admin', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testMultipleLoader(): void
|
|
||||||
{
|
|
||||||
$this->testFileLoader();
|
|
||||||
$this->testCustomLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testEmptyModel(): void
|
|
||||||
{
|
|
||||||
Enforcer::shouldUse('third');
|
|
||||||
$this->expectException(InvalidArgumentException::class);
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testEmptyLoaderType(): void
|
|
||||||
{
|
|
||||||
$this->app['config']->set('lauthz.basic.model.config_type', '');
|
|
||||||
$this->expectException(InvalidArgumentException::class);
|
|
||||||
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNotExistLoaderType(): void
|
|
||||||
{
|
|
||||||
$this->app['config']->set('lauthz.basic.model.config_type', 'not_exist');
|
|
||||||
$this->expectException(InvalidArgumentException::class);
|
|
||||||
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testBadUrlConnection(): void
|
|
||||||
{
|
|
||||||
$this->initUrlConfig();
|
|
||||||
$this->app['config']->set('lauthz.basic.model.config_url', 'http://filenoexists');
|
|
||||||
$this->expectException(RuntimeException::class);
|
|
||||||
|
|
||||||
$this->assertFalse(Enforcer::enforce('alice', 'data', 'read'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function initUrlConfig(): void
|
|
||||||
{
|
|
||||||
$this->app['config']->set('lauthz.basic.model.config_type', 'url');
|
|
||||||
$this->app['config']->set(
|
|
||||||
'lauthz.basic.model.config_url',
|
|
||||||
'https://raw.githubusercontent.com/casbin/casbin/master/examples/rbac_model.conf'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function initTextConfig(): void
|
|
||||||
{
|
|
||||||
$this->app['config']->set('lauthz.basic.model.config_type', 'text');
|
|
||||||
$this->app['config']->set(
|
|
||||||
'lauthz.basic.model.config_text',
|
|
||||||
$this->getModelText()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function initCustomConfig(): void
|
|
||||||
{
|
|
||||||
$this->app['config']->set('lauthz.second.model.config_type', 'custom');
|
|
||||||
$this->app['config']->set(
|
|
||||||
'lauthz.second.model.config_text',
|
|
||||||
$this->getModelText()
|
|
||||||
);
|
|
||||||
|
|
||||||
$config = $this->app['config']->get('lauthz.second');
|
|
||||||
$loader = $this->app->make(ModelLoaderManager::class);
|
|
||||||
|
|
||||||
$loader->extend('custom', function () use ($config) {
|
|
||||||
return new \Lauthz\Loaders\TextLoader($config);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getModelText(): string
|
|
||||||
{
|
|
||||||
return <<<EOT
|
|
||||||
[request_definition]
|
|
||||||
r = sub, obj, act
|
|
||||||
|
|
||||||
[policy_definition]
|
|
||||||
p = sub, obj, act
|
|
||||||
|
|
||||||
[policy_effect]
|
|
||||||
e = some(where (p.eft == allow))
|
|
||||||
|
|
||||||
[matchers]
|
|
||||||
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
|
|
||||||
EOT;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ namespace Lauthz\Tests;
|
||||||
use Lauthz\Middlewares\RequestMiddleware;
|
use Lauthz\Middlewares\RequestMiddleware;
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Lauthz\Facades\Enforcer;
|
|
||||||
use Lauthz\Models\Rule;
|
use Lauthz\Models\Rule;
|
||||||
|
|
||||||
class RequestMiddlewareTest extends TestCase
|
class RequestMiddlewareTest extends TestCase
|
||||||
|
@ -35,19 +34,11 @@ class RequestMiddlewareTest extends TestCase
|
||||||
$this->assertEquals($this->middleware(Request::create('/foo1/123', 'PUT')), 'Unauthorized Exception');
|
$this->assertEquals($this->middleware(Request::create('/foo1/123', 'PUT')), 'Unauthorized Exception');
|
||||||
|
|
||||||
$this->assertEquals($this->middleware(Request::create('/proxy', 'GET')), 'Unauthorized Exception');
|
$this->assertEquals($this->middleware(Request::create('/proxy', 'GET')), 'Unauthorized Exception');
|
||||||
|
|
||||||
Enforcer::guard('second')->addPolicy('alice', '/foo1/*', '(GET|POST)');
|
|
||||||
|
|
||||||
$this->assertEquals($this->middleware(Request::create('/foo1/123', 'GET'), 'second'), 200);
|
|
||||||
$this->assertEquals($this->middleware(Request::create('/foo1/123', 'POST'), 'second'), 200);
|
|
||||||
$this->assertEquals($this->middleware(Request::create('/foo1/123', 'PUT'), 'second'), 'Unauthorized Exception');
|
|
||||||
|
|
||||||
$this->assertEquals($this->middleware(Request::create('/proxy', 'GET'), 'second'), 'Unauthorized Exception');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function middleware($request, ...$guards)
|
protected function middleware($request)
|
||||||
{
|
{
|
||||||
return parent::runMiddleware(RequestMiddleware::class, $request, ...$guards);
|
return parent::runMiddleware(RequestMiddleware::class, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initConfig()
|
protected function initConfig()
|
||||||
|
@ -71,19 +62,17 @@ e = some(where (p.eft == allow))
|
||||||
m = g(r.sub, p.sub) && r.sub == p.sub && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
|
m = g(r.sub, p.sub) && r.sub == p.sub && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
|
||||||
EOT;
|
EOT;
|
||||||
$this->app['config']->set('lauthz.basic.model.config_text', $text);
|
$this->app['config']->set('lauthz.basic.model.config_text', $text);
|
||||||
$this->app['config']->set('lauthz.second.model.config_type', 'text');
|
|
||||||
$this->app['config']->set('lauthz.second.model.config_text', $text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initTable()
|
protected function initTable()
|
||||||
{
|
{
|
||||||
Rule::truncate();
|
Rule::truncate();
|
||||||
|
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => '/foo', 'v2' => 'GET']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => '/foo', 'v2' => 'GET']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => '/foo/:id', 'v2' => 'GET']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => '/foo/:id', 'v2' => 'GET']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => '/foo', 'v2' => 'POST']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => '/foo', 'v2' => 'POST']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => '/foo/:id', 'v2' => 'PUT']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => '/foo/:id', 'v2' => 'PUT']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => '/foo/:id', 'v2' => 'DELETE']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => '/foo/:id', 'v2' => 'DELETE']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => '/foo1/*', 'v2' => '(GET)|(POST)']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => '/foo1/*', 'v2' => '(GET)|(POST)']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ class RuleCacheTest extends TestCase
|
||||||
app(Rule::class)->getAllFromCache();
|
app(Rule::class)->getAllFromCache();
|
||||||
$this->assertCount(0, DB::getQueryLog());
|
$this->assertCount(0, DB::getQueryLog());
|
||||||
|
|
||||||
$rule = Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']);
|
$rule = Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']);
|
||||||
app(Rule::class)->getAllFromCache();
|
app(Rule::class)->getAllFromCache();
|
||||||
$this->assertCount(2, DB::getQueryLog());
|
$this->assertCount(2, DB::getQueryLog());
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class RuleCacheTest extends TestCase
|
||||||
app(Rule::class)->getAllFromCache();
|
app(Rule::class)->getAllFromCache();
|
||||||
$this->assertCount(1, DB::getQueryLog());
|
$this->assertCount(1, DB::getQueryLog());
|
||||||
|
|
||||||
$rule = Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']);
|
$rule = Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']);
|
||||||
app(Rule::class)->getAllFromCache();
|
app(Rule::class)->getAllFromCache();
|
||||||
$this->assertCount(3, DB::getQueryLog());
|
$this->assertCount(3, DB::getQueryLog());
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ abstract class TestCase extends BaseTestCase
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->app->make(Kernel::class)->bootstrap();
|
$this->app->make(Kernel::class)->bootstrap();
|
||||||
$this->initConfig();
|
|
||||||
|
|
||||||
$this->app->register(\Lauthz\LauthzServiceProvider::class);
|
$this->app->register(\Lauthz\LauthzServiceProvider::class);
|
||||||
|
$this->initConfig();
|
||||||
|
|
||||||
$this->artisan('vendor:publish', ['--provider' => 'Lauthz\LauthzServiceProvider']);
|
$this->artisan('vendor:publish', ['--provider' => 'Lauthz\LauthzServiceProvider']);
|
||||||
$this->artisan('migrate', ['--force' => true]);
|
$this->artisan('migrate', ['--force' => true]);
|
||||||
|
@ -46,7 +46,6 @@ abstract class TestCase extends BaseTestCase
|
||||||
$this->app['config']->set('database.default', 'mysql');
|
$this->app['config']->set('database.default', 'mysql');
|
||||||
$this->app['config']->set('database.connections.mysql.charset', 'utf8');
|
$this->app['config']->set('database.connections.mysql.charset', 'utf8');
|
||||||
$this->app['config']->set('database.connections.mysql.collation', 'utf8_unicode_ci');
|
$this->app['config']->set('database.connections.mysql.collation', 'utf8_unicode_ci');
|
||||||
$this->app['config']->set('cache.default', 'array');
|
|
||||||
// $app['config']->set('lauthz.log.enabled', true);
|
// $app['config']->set('lauthz.log.enabled', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +53,12 @@ abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
Rule::truncate();
|
Rule::truncate();
|
||||||
|
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']);
|
Rule::create(['p_type' => 'p', 'v0' => 'alice', 'v1' => 'data1', 'v2' => 'read']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'bob', 'v1' => 'data2', 'v2' => 'write']);
|
Rule::create(['p_type' => 'p', 'v0' => 'bob', 'v1' => 'data2', 'v2' => 'write']);
|
||||||
|
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'data2_admin', 'v1' => 'data2', 'v2' => 'read']);
|
Rule::create(['p_type' => 'p', 'v0' => 'data2_admin', 'v1' => 'data2', 'v2' => 'read']);
|
||||||
Rule::create(['ptype' => 'p', 'v0' => 'data2_admin', 'v1' => 'data2', 'v2' => 'write']);
|
Rule::create(['p_type' => 'p', 'v0' => 'data2_admin', 'v1' => 'data2', 'v2' => 'write']);
|
||||||
Rule::create(['ptype' => 'g', 'v0' => 'alice', 'v1' => 'data2_admin']);
|
Rule::create(['p_type' => 'g', 'v0' => 'alice', 'v1' => 'data2_admin']);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function runMiddleware($middleware, $request, ...$args)
|
protected function runMiddleware($middleware, $request, ...$args)
|
||||||
|
|
Loading…
Reference in New Issue