Skip to content

Commit

Permalink
Merge 8b3cd3e into bb56632
Browse files Browse the repository at this point in the history
  • Loading branch information
basakest committed Mar 25, 2021
2 parents bb56632 + 8b3cd3e commit 80bc33b
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 3 deletions.
67 changes: 65 additions & 2 deletions src/Adapters/DatabaseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,27 @@
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\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;
/**
* DatabaseAdapter.
*
* @author techlee@qq.com
*/
class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterContract, UpdatableDatabaseAdapterContract
class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterContract, UpdatableDatabaseAdapterContract, FilteredDatabaseAdapterContract
{
use AdapterHelper;

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

/**
* Rules eloquent model.
*
Expand Down Expand Up @@ -232,4 +240,59 @@ public function updatePolicy(string $sec, string $ptype, array $oldRule, array $
}
$instance->update($update);
}

/**
* 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)) {
$filter = str_replace(' ', '', $filter);
$filter = explode('=', $filter);
$instance = $instance->where($filter[0], $filter[1]);
} 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) {
$filter($instance);
} 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/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
{
}
48 changes: 47 additions & 1 deletion tests/DatabaseAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use Enforcer;
use Illuminate\Foundation\Testing\DatabaseMigrations;

use Casbin\Persist\Adapters\Filter;
use Lauthz\Models\Rule;
use Casbin\Exceptions\InvalidFilterTypeException;
class DatabaseAdapterTest extends TestCase
{
use DatabaseMigrations;
Expand Down Expand Up @@ -128,4 +130,48 @@ public function testUpdatePolicy()
['data2_admin', 'data2', 'write'],
], Enforcer::getPolicy());
}

public function testLoadFilteredPolicy()
{
$this->initTable();
Enforcer::clearPolicy();
$this->initConfig();
$adapter = Enforcer::getAdapter();
$adapter->setFiltered(true);
$this->assertEquals([], Enforcer::getPolicy());

// invalid filter type
try {
$filter = ['alice', 'data1', 'read'];
Enforcer::loadFilteredPolicy($filter);
$e = InvalidFilterTypeException::class;
$this->fail("Expected exception $e not thrown");
} catch (InvalidFilterTypeException $e) {
$this->assertEquals("invalid filter type", $e->getMessage());
}

// string
$filter = "v0 = bob";
Enforcer::loadFilteredPolicy($filter);
$this->assertEquals([
['bob', 'data2', 'write']
], Enforcer::getPolicy());

// Filter
$filter = new Filter(['v2'], ['read']);
Enforcer::loadFilteredPolicy($filter);
$this->assertEquals([
['alice', 'data1', 'read'],
['data2_admin', 'data2', 'read'],
], Enforcer::getPolicy());

// Closure
Enforcer::loadFilteredPolicy(function (Rule &$rule) {
$rule = $rule->where('v1', 'data1');
});

$this->assertEquals([
['alice', 'data1', 'read'],
], Enforcer::getPolicy());
}
}

0 comments on commit 80bc33b

Please sign in to comment.