Skip to content

门面Enforcer的类型提示 #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c78240b
Merge pull request #8 from php-casbin/develop
leeqvip Dec 25, 2020
5ae9445
refactor: Change the field ptype to p_type
leeqvip Dec 31, 2020
48ff59e
chore: Remove composer cache
leeqvip Dec 31, 2020
b05630b
feat: support Casbin BatchAdapter interface(fix #10)
basakest Mar 8, 2021
ad06ec5
Merge pull request #11 from basakest/BatchAdapter
leeqvip Mar 9, 2021
1fc9463
feat: support Casbin UpdatableAdapter interface
basakest Mar 20, 2021
64d576c
feat: support Casbin UpdatableAdapter interface
basakest Mar 20, 2021
bb56632
Merge pull request #12 from basakest/UpdatableDatabaseAdapter
leeqvip Mar 22, 2021
d929f75
feat: support Casbin FilteredAdapter interface
basakest Apr 1, 2021
cd5eefc
Merge pull request #17 from basakest/FilteredDatabaseAdapter
leeqvip Apr 1, 2021
4e25a6a
fix: fix a typo about updatePolicy method
basakest Apr 4, 2021
be8f709
Merge pull request #18 from basakest/fixUpdatableAdapter
leeqvip Apr 4, 2021
3354b55
perf: Improve performance
donjan-deng Apr 25, 2021
66a8576
fix: Revert "perf: Improve performance" (#21)
leeqvip Apr 25, 2021
cc73dea
perf: Optimize the cache to improve performance
donjan-deng May 6, 2021
f81f206
fix: Amend part logic of removePolicies (#24)
basakest Jul 11, 2021
877f2f2
feat: support updatePolicies method, fix #27 (#28)
basakest Jul 28, 2021
9676f0b
feat: support updateFilteredPolicies method (#29)
basakest Sep 2, 2021
1f0702a
fix: error in updateFilteredPolicies()
leeqvip Sep 2, 2021
be98eed
BREAKING CHANGE: modify column p_type to ptype (#31)
dawn-darkest Sep 7, 2021
8c89548
refactor: Rewrite updateFilteredPolicies method (#35)
basakest Nov 14, 2021
0e5b1f2
fix: Variable identifier type error, fix #36 (#37)
basakest Nov 20, 2021
4872e8f
fix: Use loadPolicyArray instead of loadPolicyLine
leeqvip Jan 5, 2022
a25afdb
feat: compatible with lumen (#39)
leeqvip Jan 28, 2022
491620b
fix: support laravel9
leeqvip Feb 17, 2022
14529ba
Merge pull request #41 from php-casbin/fix/support-laravel9
leeqvip Feb 17, 2022
0e21704
Update Enforcer.php
lanrenbulan May 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ jobs:
- php: 8.0
laravel: 8.*
phpunit: ~9.0
# Laravel 9.x
- php: 8.0
laravel: 9.*
phpunit: ~9.0

name: Laravel${{ matrix.laravel }}-PHP${{ matrix.php }}

Expand All @@ -114,15 +118,6 @@ jobs:
- name: Validate composer.json and composer.lock
run: composer validate

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-${{ matrix.php }}-Laravel${{ matrix.laravel }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.php }}-Laravel${{ matrix.laravel }}

- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: |
Expand Down Expand Up @@ -159,7 +154,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '12'
node-version: '14.17'

- name: Run semantic-release
env:
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@
"license": "Apache-2.0",
"require": {
"php": ">=7.1.0",
"laravel/framework": "~5.5|~6.0|~7.0|~8.0",
"illuminate/support": "~5.5|~6.0|~7.0|~8.0|~9.0",
"illuminate/database": "~5.5|~6.0|~7.0|~8.0|~9.0",
"illuminate/console": "~5.5|~6.0|~7.0|~8.0|~9.0",
"casbin/casbin": "~3.1",
"casbin/psr3-bridge": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "~7.0|~8.0|~9.0",
"php-coveralls/php-coveralls": "^2.4",
"mockery/mockery": "^1.0",
"laravel/laravel": "~5.5|~6.0|~7.0|~8.0"
"laravel/laravel": "~5.5|~6.0|~7.0|~8.0|~9.0"
},
"autoload": {
"psr-4": {
Expand Down
2 changes: 1 addition & 1 deletion config/lauthz.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// Available Settings: "file", "text"
'config_type' => 'file',

'config_file_path' => config_path('lauthz-rbac-model.conf'),
'config_file_path' => __DIR__ . DIRECTORY_SEPARATOR . 'lauthz-rbac-model.conf',

'config_text' => '',
],
Expand Down
244 changes: 223 additions & 21 deletions src/Adapters/DatabaseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,30 @@

use Lauthz\Models\Rule;
use Lauthz\Contracts\DatabaseAdapter as DatabaseAdapterContract;
use Lauthz\Contracts\BatchDatabaseAdapter as BatchDatabaseAdapterContract;
use Lauthz\Contracts\UpdatableDatabaseAdapter as UpdatableDatabaseAdapterContract;
use Lauthz\Contracts\FilteredDatabaseAdapter as FilteredDatabaseAdapterContract;
use Casbin\Persist\Adapters\Filter;
use Casbin\Model\Model;
use Casbin\Persist\AdapterHelper;
use DateTime;
use Casbin\Exceptions\InvalidFilterTypeException;
use Illuminate\Support\Facades\DB;

/**
* DatabaseAdapter.
*
* @author techlee@qq.com
*/
class DatabaseAdapter implements DatabaseAdapterContract
class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterContract, UpdatableDatabaseAdapterContract, FilteredDatabaseAdapterContract
{
use AdapterHelper;

/**
* @var bool
*/
private $filtered = false;

/**
* Rules eloquent model.
*
Expand All @@ -35,6 +47,26 @@ public function __construct(Rule $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.
*
Expand All @@ -61,10 +93,7 @@ public function loadPolicy(Model $model): void
$rows = $this->eloquent->getAllFromCache();

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

Expand Down Expand Up @@ -101,6 +130,33 @@ public function addPolicy(string $sec, string $ptype, array $rule): void
$this->savePolicyLine($ptype, $rule);
}

/**
* Adds a policy rules to the storage.
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param string[][] $rules
*/
public function addPolicies(string $sec, string $ptype, array $rules): void
{
$cols = [];
$i = 0;

foreach($rules as $rule) {
$temp['ptype'] = $ptype;
$temp['created_at'] = new DateTime();
$temp['updated_at'] = $temp['created_at'];
foreach ($rule as $key => $value) {
$temp['v'.strval($key)] = $value;
}
$cols[$i++] = $temp ?? [];
$temp = [];
}
$this->eloquent->insert($cols);
Rule::fireModelEvent('saved');
}

/**
* This is part of the Auto-Save feature.
*
Expand All @@ -110,47 +166,193 @@ public function addPolicy(string $sec, string $ptype, array $rule): void
*/
public function removePolicy(string $sec, string $ptype, array $rule): void
{
$count = 0;

$instance = $this->eloquent->where('ptype', $ptype);

foreach ($rule as $key => $value) {
$instance->where('v'.strval($key), $value);
}

foreach ($instance->get() as $model) {
if ($model->delete()) {
++$count;
}
}
$instance->delete();
Rule::fireModelEvent('deleted');
}

/**
* RemoveFilteredPolicy removes policy rules that match the filter from the storage.
* Removes policy rules from the storage.
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param int $fieldIndex
* @param string ...$fieldValues
* @param string[][] $rules
*/
public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, string ...$fieldValues): void
public function removePolicies(string $sec, string $ptype, array $rules): void
{
$count = 0;
DB::transaction(function () use ($sec, $rules, $ptype) {
foreach ($rules as $rule) {
$this->removePolicy($sec, $ptype, $rule);
}
});
}

/**
* @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]);
$instance->where('v' . strval($value), $fieldValues[$value - $fieldIndex]);
}
}
}

foreach ($instance->get() as $model) {
if ($model->delete()) {
++$count;
$oldP = $instance->get()->makeHidden(['created_at','updated_at', 'id', 'ptype'])->toArray();
foreach ($oldP as &$item) {
$item = $this->filterRule($item);
$removedRules[] = $item;
}

$instance->delete();
Rule::fireModelEvent('deleted');

return $removedRules;
}

/**
* RemoveFilteredPolicy removes policy rules that match the filter from the storage.
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param int $fieldIndex
* @param string|null ...$fieldValues
* @return void
*/
public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, ?string ...$fieldValues): void
{
$this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues);
}

/**
* Updates a policy rule from storage.
* This is part of the Auto-Save feature.
*
* @param string $sec
* @param string $ptype
* @param string[] $oldRule
* @param string[] $newPolicy
*/
public function updatePolicy(string $sec, string $ptype, array $oldRule, array $newPolicy): void
{
$instance = $this->eloquent->where('ptype', $ptype);
foreach($oldRule as $k => $v) {
$instance->where('v' . $k, $v);
}
$instance->first();
$update = [];
foreach($newPolicy as $k => $v) {
$update['v' . $k] = $v;
}
$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
{
DB::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 = [];
DB::transaction(function () use ($sec, $ptype, $fieldIndex, $fieldValues, $newPolicies, &$oldRules) {
$oldRules = $this->_removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues);
$this->addPolicies($sec, $ptype, $newPolicies);
});
return $oldRules;
}

/**
* Loads only policy rules that match the filter.
*
* @param Model $model
* @param mixed $filter
*/
public function loadFilteredPolicy(Model $model, $filter): void
{
$instance = $this->eloquent;

if (is_string($filter)) {
$instance = $instance->whereRaw($filter);
} else if ($filter instanceof Filter) {
foreach($filter->p as $k => $v) {
$where[$v] = $filter->g[$k];
$instance = $instance->where($v, $filter->g[$k]);
}
} else if ($filter instanceof \Closure) {
$instance = $instance->where($filter);
} else {
throw new InvalidFilterTypeException('invalid filter type');
}
$rows = $instance->get()->makeHidden(['created_at','updated_at', 'id'])->toArray();
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);
}));
$this->loadPolicyLine(trim($line), $model);
}
$this->setFiltered(true);
}

/**
* Returns true if the loaded policy has been filtered.
*
* @return bool
*/
public function isFiltered(): bool
{
return $this->filtered;
}

/**
* Sets filtered parameter.
*
* @param bool $filtered
*/
public function setFiltered(bool $filtered): void
{
$this->filtered = $filtered;
}
}
9 changes: 9 additions & 0 deletions src/Contracts/BatchDatabaseAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Lauthz\Contracts;

use Casbin\Persist\BatchAdapter;

interface BatchDatabaseAdapter extends BatchAdapter
{
}
9 changes: 9 additions & 0 deletions src/Contracts/FilteredDatabaseAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Lauthz\Contracts;

use Casbin\Persist\FilteredAdapter;

interface FilteredDatabaseAdapter extends FilteredAdapter
{
}
Loading