diff --git a/src/Adapters/DatabaseAdapter.php b/src/Adapters/DatabaseAdapter.php index 740c610..72e2d21 100755 --- a/src/Adapters/DatabaseAdapter.php +++ b/src/Adapters/DatabaseAdapter.php @@ -6,15 +6,16 @@ namespace Lauthz\Adapters; use Lauthz\Models\Rule; use Lauthz\Contracts\DatabaseAdapter as DatabaseAdapterContract; +use Lauthz\Contracts\BatchDatabaseAdapter as BatchDatabaseAdapterContract; use Casbin\Model\Model; use Casbin\Persist\AdapterHelper; - +use DateTime; /** * DatabaseAdapter. * * @author techlee@qq.com */ -class DatabaseAdapter implements DatabaseAdapterContract +class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterContract { use AdapterHelper; @@ -101,6 +102,32 @@ class DatabaseAdapter implements DatabaseAdapterContract $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['p_type'] = $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); + } + /** * This is part of the Auto-Save feature. * @@ -125,6 +152,33 @@ class DatabaseAdapter implements DatabaseAdapterContract } } + /** + * Removes policy rules from the storage. + * This is part of the Auto-Save feature. + * + * @param string $sec + * @param string $ptype + * @param string[][] $rules + */ + public function removePolicies(string $sec, string $ptype, array $rules): void + { + $count = 0; + $instance = $this->eloquent->where('p_type', $ptype); + foreach($rules as $rule) + { + foreach ($rule as $key => $value) { + $keys[] = 'v'.strval($key); + $con['v'.strval($key)][] = $value; + } + } + $keys = array_unique($keys); + foreach($keys as $key){ + $instance->whereIn($key, $con[$key]); + } + $num = $instance->delete(); + $count += $num; + } + /** * RemoveFilteredPolicy removes policy rules that match the filter from the storage. * This is part of the Auto-Save feature. diff --git a/src/Contracts/BatchDatabaseAdapter.php b/src/Contracts/BatchDatabaseAdapter.php new file mode 100644 index 0000000..983f78f --- /dev/null +++ b/src/Contracts/BatchDatabaseAdapter.php @@ -0,0 +1,9 @@ +assertTrue(Enforcer::enforce('eve', 'data3', 'read')); } + public function testAddPolicies() + { + $policies = [ + ['u1', 'd1', 'read'], + ['u2', 'd2', 'read'], + ['u3', 'd3', 'read'], + ]; + Enforcer::clearPolicy(); + $this->initTable(); + $this->assertEquals([], Enforcer::getPolicy()); + Enforcer::addPolicies($policies); + $this->assertEquals($policies, Enforcer::getPolicy()); + } + public function testSavePolicy() { $this->assertFalse(Enforcer::enforce('alice', 'data4', 'read')); @@ -51,6 +65,26 @@ class DatabaseAdapterTest extends TestCase $this->assertFalse(Enforcer::enforce('alice', 'data5', 'read')); } + public function testRemovePolicies() + { + $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->assertEquals([ + ['alice', 'data1', 'read'], + ['bob', 'data2', 'write'] + ], Enforcer::getPolicy()); + } + public function testRemoveFilteredPolicy() { $this->assertTrue(Enforcer::enforce('alice', 'data1', 'read'));