Skip to content

Commit 69eae24

Browse files
authored
feat: support Casbin UpdatableAdapter interface (#25)
1 parent 1c2691f commit 69eae24

File tree

2 files changed

+106
-2
lines changed

2 files changed

+106
-2
lines changed

src/adapter/DatabaseAdapter.php

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
use Casbin\Model\Model;
77
use Casbin\Persist\Adapter;
88
use Casbin\Persist\AdapterHelper;
9+
use Casbin\Persist\UpdatableAdapter;
10+
use think\facade\Db;
911

1012
/**
1113
* DatabaseAdapter.
1214
*
1315
1416
*/
15-
class DatabaseAdapter implements Adapter
17+
class DatabaseAdapter implements Adapter, UpdatableAdapter
1618
{
1719
use AdapterHelper;
1820

@@ -151,4 +153,47 @@ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex
151153
}
152154
}
153155
}
156+
157+
/**
158+
* Updates a policy rule from storage.
159+
* This is part of the Auto-Save feature.
160+
*
161+
* @param string $sec
162+
* @param string $ptype
163+
* @param string[] $oldRule
164+
* @param string[] $newPolicy
165+
*/
166+
public function updatePolicy(string $sec, string $ptype, array $oldRule, array $newPolicy): void
167+
{
168+
$instance = $this->model->where('ptype', $ptype);
169+
foreach ($oldRule as $key => $value) {
170+
$instance->where('v' . strval($key), $value);
171+
}
172+
$instance = $instance->find();
173+
174+
foreach ($newPolicy as $key => $value) {
175+
$column = 'v' . strval($key);
176+
$instance->$column = $value;
177+
}
178+
179+
$instance->save();
180+
}
181+
182+
/**
183+
* UpdatePolicies updates some policy rules to storage, like db, redis.
184+
*
185+
* @param string $sec
186+
* @param string $ptype
187+
* @param string[][] $oldRules
188+
* @param string[][] $newRules
189+
* @return void
190+
*/
191+
public function updatePolicies(string $sec, string $ptype, array $oldRules, array $newRules): void
192+
{
193+
Db::transaction(function () use ($sec, $ptype, $oldRules, $newRules) {
194+
foreach ($oldRules as $i => $oldRule) {
195+
$this->updatePolicy($sec, $ptype, $oldRule, $newRules[$i]);
196+
}
197+
});
198+
}
154199
}

tests/DatabaseAdapterTest.php

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,63 @@ public function testRemoveFilteredPolicy()
7676
$this->assertFalse(Enforcer::enforce('alice', 'data2', 'write'));
7777
});
7878
}
79-
}
79+
80+
public function testUpdatePolicy()
81+
{
82+
$this->testing(function () {
83+
$this->assertEquals([
84+
['alice', 'data1', 'read'],
85+
['bob', 'data2', 'write'],
86+
['data2_admin', 'data2', 'read'],
87+
['data2_admin', 'data2', 'write'],
88+
], Enforcer::getPolicy());
89+
90+
Enforcer::updatePolicy(
91+
['alice', 'data1', 'read'],
92+
['alice', 'data1', 'write']
93+
);
94+
95+
Enforcer::updatePolicy(
96+
['bob', 'data2', 'write'],
97+
['bob', 'data2', 'read']
98+
);
99+
100+
$this->assertEquals([
101+
['alice', 'data1', 'write'],
102+
['bob', 'data2', 'read'],
103+
['data2_admin', 'data2', 'read'],
104+
['data2_admin', 'data2', 'write'],
105+
], Enforcer::getPolicy());
106+
});
107+
}
108+
109+
public function testUpdatePolicies()
110+
{
111+
$this->testing(function () {
112+
$this->assertEquals([
113+
['alice', 'data1', 'read'],
114+
['bob', 'data2', 'write'],
115+
['data2_admin', 'data2', 'read'],
116+
['data2_admin', 'data2', 'write'],
117+
], Enforcer::getPolicy());
118+
119+
$oldPolicies = [
120+
['alice', 'data1', 'read'],
121+
['bob', 'data2', 'write']
122+
];
123+
$newPolicies = [
124+
['alice', 'data1', 'write'],
125+
['bob', 'data2', 'read']
126+
];
127+
128+
Enforcer::updatePolicies($oldPolicies, $newPolicies);
129+
130+
$this->assertEquals([
131+
['alice', 'data1', 'write'],
132+
['bob', 'data2', 'read'],
133+
['data2_admin', 'data2', 'read'],
134+
['data2_admin', 'data2', 'write'],
135+
], Enforcer::getPolicy());
136+
});
137+
}
138+
}

0 commit comments

Comments
 (0)