From cc73dea28aa92dd7757cd7b7da63ee69835b6325 Mon Sep 17 00:00:00 2001 From: Donjan <8256490+donjan-deng@users.noreply.github.com> Date: Thu, 6 May 2021 16:17:40 +0800 Subject: [PATCH] perf: Optimize the cache to improve performance * Improve performance * Trigger event * add DatabaseAdapterForCacheTest.php Co-authored-by: Donjan --- src/Adapters/DatabaseAdapter.php | 28 ++--- tests/DatabaseAdapterForCacheTest.php | 149 ++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 18 deletions(-) create mode 100644 tests/DatabaseAdapterForCacheTest.php diff --git a/src/Adapters/DatabaseAdapter.php b/src/Adapters/DatabaseAdapter.php index befe236..652d133 100755 --- a/src/Adapters/DatabaseAdapter.php +++ b/src/Adapters/DatabaseAdapter.php @@ -135,6 +135,7 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo $temp = []; } $this->eloquent->insert($cols); + Rule::fireModelEvent('saved'); } /** @@ -146,19 +147,14 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo */ public function removePolicy(string $sec, string $ptype, array $rule): void { - $count = 0; - $instance = $this->eloquent->where('p_type', $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'); } /** @@ -171,7 +167,6 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo */ public function removePolicies(string $sec, string $ptype, array $rules): void { - $count = 0; $instance = $this->eloquent->where('p_type', $ptype); foreach($rules as $rule) { @@ -184,8 +179,8 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo foreach($keys as $key){ $instance->whereIn($key, $con[$key]); } - $num = $instance->delete(); - $count += $num; + $instance->delete(); + Rule::fireModelEvent('deleted'); } /** @@ -199,9 +194,8 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo */ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex, string ...$fieldValues): void { - $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]) { @@ -209,12 +203,9 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo } } } - - foreach ($instance->get() as $model) { - if ($model->delete()) { - ++$count; - } - } + + $instance->delete(); + Rule::fireModelEvent('deleted'); } /** @@ -238,6 +229,7 @@ class DatabaseAdapter implements DatabaseAdapterContract, BatchDatabaseAdapterCo $update['v' . $k] = $v; } $instance->update($update); + Rule::fireModelEvent('saved'); } /** diff --git a/tests/DatabaseAdapterForCacheTest.php b/tests/DatabaseAdapterForCacheTest.php new file mode 100644 index 0000000..dca8d0e --- /dev/null +++ b/tests/DatabaseAdapterForCacheTest.php @@ -0,0 +1,149 @@ +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); + } + +}