Skip to content

Commit 75165bd

Browse files
committed
refactor: replicated the solution using the go version
1 parent d8a7cba commit 75165bd

2 files changed

Lines changed: 144 additions & 19 deletions

File tree

src/internalEnforcer.ts

Lines changed: 130 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class InternalEnforcer extends CoreEnforcer {
2929
return false;
3030
}
3131

32+
// Persist when an adapter is configured and autoSave is enabled.
3233
if (this.adapter && this.autoSave) {
3334
try {
3435
await this.adapter.addPolicy(sec, ptype, rule);
@@ -67,7 +68,8 @@ export class InternalEnforcer extends CoreEnforcer {
6768
}
6869
}
6970

70-
if (this.autoSave) {
71+
// Persist when an adapter is configured and autoSave is enabled.
72+
if (this.adapter && this.autoSave) {
7173
if ('addPolicies' in this.adapter) {
7274
try {
7375
await this.adapter.addPolicies(sec, ptype, rules);
@@ -104,7 +106,12 @@ export class InternalEnforcer extends CoreEnforcer {
104106
* Unlike addPoliciesInternal, this method will filter out rules that already exist
105107
* and continue to add the remaining rules instead of returning false immediately.
106108
*/
107-
protected async addPoliciesInternalEx(sec: string, ptype: string, rules: string[][], useWatcher: boolean): Promise<boolean> {
109+
protected async addPoliciesInternalEx(
110+
sec: string,
111+
ptype: string,
112+
rules: string[][],
113+
useWatcher: boolean
114+
): Promise<boolean> {
108115
// Filter out existing rules
109116
const newRules = rules.filter((rule) => !this.model.hasPolicy(sec, ptype, rule));
110117

@@ -113,7 +120,8 @@ export class InternalEnforcer extends CoreEnforcer {
113120
return false;
114121
}
115122

116-
if (this.autoSave) {
123+
// Persist when an adapter is configured and autoSave is enabled.
124+
if (this.adapter && this.autoSave) {
117125
if ('addPolicies' in this.adapter) {
118126
try {
119127
await this.adapter.addPolicies(sec, ptype, newRules);
@@ -158,8 +166,8 @@ export class InternalEnforcer extends CoreEnforcer {
158166
if (!this.model.hasPolicy(sec, ptype, oldRule)) {
159167
return false;
160168
}
161-
162-
if (this.autoSave) {
169+
// Persist when an adapter is configured and autoSave is enabled.
170+
if (this.adapter && this.autoSave) {
163171
if ('updatePolicy' in this.adapter) {
164172
try {
165173
await this.adapter.updatePolicy(sec, ptype, oldRule, newRule);
@@ -195,11 +203,17 @@ export class InternalEnforcer extends CoreEnforcer {
195203
/**
196204
* removePolicyInternal removes a rule from the current policy.
197205
*/
198-
protected async removePolicyInternal(sec: string, ptype: string, rule: string[], useWatcher: boolean): Promise<boolean> {
206+
protected async removePolicyInternal(
207+
sec: string,
208+
ptype: string,
209+
rule: string[],
210+
useWatcher: boolean
211+
): Promise<boolean> {
199212
if (!this.model.hasPolicy(sec, ptype, rule)) {
200213
return false;
201214
}
202215

216+
// Persist when an adapter is configured and autoSave is enabled.
203217
if (this.adapter && this.autoSave) {
204218
try {
205219
await this.adapter.removePolicy(sec, ptype, rule);
@@ -229,14 +243,20 @@ export class InternalEnforcer extends CoreEnforcer {
229243
}
230244

231245
// removePolicies removes rules from the current policy.
232-
protected async removePoliciesInternal(sec: string, ptype: string, rules: string[][], useWatcher: boolean): Promise<boolean> {
246+
protected async removePoliciesInternal(
247+
sec: string,
248+
ptype: string,
249+
rules: string[][],
250+
useWatcher: boolean
251+
): Promise<boolean> {
233252
for (const rule of rules) {
234253
if (!this.model.hasPolicy(sec, ptype, rule)) {
235254
return false;
236255
}
237256
}
238257

239-
if (this.autoSave) {
258+
// Persist when an adapter is configured and autoSave is enabled.
259+
if (this.adapter && this.autoSave) {
240260
if ('removePolicies' in this.adapter) {
241261
try {
242262
await this.adapter.removePolicies(sec, ptype, rules);
@@ -278,6 +298,7 @@ export class InternalEnforcer extends CoreEnforcer {
278298
fieldValues: string[],
279299
useWatcher: boolean
280300
): Promise<boolean> {
301+
// Persist when an adapter is configured and autoSave is enabled.
281302
if (this.adapter && this.autoSave) {
282303
try {
283304
await this.adapter.removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues);
@@ -320,4 +341,105 @@ export class InternalEnforcer extends CoreEnforcer {
320341
const assertion = this.model.model.get('p')?.get(ptype);
321342
assertion?.fieldIndexMap.set(field, index);
322343
}
344+
345+
protected async addPolicyWithoutNotify(sec: string, ptype: string, rule: string[]): Promise<boolean> {
346+
if (this.model.hasPolicy(sec, ptype, rule)) {
347+
return false;
348+
}
349+
350+
const ok = this.model.addPolicy(sec, ptype, rule);
351+
if (sec === 'g' && ok) {
352+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, [rule]);
353+
}
354+
return ok;
355+
}
356+
357+
protected async addPoliciesWithoutNotify(sec: string, ptype: string, rules: string[][]): Promise<boolean> {
358+
for (const rule of rules) {
359+
if (this.model.hasPolicy(sec, ptype, rule)) {
360+
return false;
361+
}
362+
}
363+
364+
const [ok, effects] = await this.model.addPolicies(sec, ptype, rules);
365+
if (sec === 'g' && ok && effects?.length) {
366+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, effects);
367+
}
368+
return ok;
369+
}
370+
371+
protected async addPoliciesWithoutNotifyEx(sec: string, ptype: string, rules: string[][]): Promise<boolean> {
372+
const newRules = rules.filter((rule) => !this.model.hasPolicy(sec, ptype, rule));
373+
if (newRules.length === 0) {
374+
return false;
375+
}
376+
377+
const [ok, effects] = await this.model.addPolicies(sec, ptype, newRules);
378+
if (sec === 'g' && ok && effects?.length) {
379+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, effects);
380+
}
381+
return ok;
382+
}
383+
384+
protected async updatePolicyWithoutNotify(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise<boolean> {
385+
if (!this.model.hasPolicy(sec, ptype, oldRule)) {
386+
return false;
387+
}
388+
389+
const ok = this.model.updatePolicy(sec, ptype, oldRule, newRule);
390+
if (sec === 'g' && ok) {
391+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, [oldRule]);
392+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, [newRule]);
393+
}
394+
return ok;
395+
}
396+
397+
protected async removePolicyWithoutNotify(sec: string, ptype: string, rule: string[]): Promise<boolean> {
398+
if (!this.model.hasPolicy(sec, ptype, rule)) {
399+
return false;
400+
}
401+
402+
const ok = await this.model.removePolicy(sec, ptype, rule);
403+
if (sec === 'g' && ok) {
404+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, [rule]);
405+
}
406+
return ok;
407+
}
408+
409+
protected async removePoliciesWithoutNotify(sec: string, ptype: string, rules: string[][]): Promise<boolean> {
410+
for (const rule of rules) {
411+
if (!this.model.hasPolicy(sec, ptype, rule)) {
412+
return false;
413+
}
414+
}
415+
416+
const [ok, effects] = this.model.removePolicies(sec, ptype, rules);
417+
if (sec === 'g' && ok && effects?.length) {
418+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, effects);
419+
}
420+
return ok;
421+
}
422+
423+
protected async removeFilteredPolicyWithoutNotify(sec: string, ptype: string, fieldIndex: number, fieldValues: string[]): Promise<boolean> {
424+
const [ok, effects] = this.model.removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues);
425+
if (sec === 'g' && ok && effects?.length) {
426+
await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, effects);
427+
}
428+
return ok;
429+
}
430+
431+
protected async updatePoliciesWithoutNotify(sec: string, ptype: string, oldRules: string[][], newRules: string[][]): Promise<boolean> {
432+
// Mirror the Go updatePoliciesWithoutNotify; reuse the existing internal flow.
433+
// Because updatePoliciesInternal isn't implemented yet, fall back to per-item updates.
434+
if (oldRules.length !== newRules.length) {
435+
throw new Error('the length of oldRules should be equal to the length of newRules');
436+
}
437+
for (let i = 0; i < oldRules.length; i++) {
438+
const ok = await this.updatePolicyWithoutNotify(sec, ptype, oldRules[i], newRules[i]);
439+
if (!ok) {
440+
return false;
441+
}
442+
}
443+
return true;
444+
}
323445
}

src/managementEnforcer.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -589,28 +589,31 @@ export class ManagementEnforcer extends InternalEnforcer {
589589
public async addFunction(name: string, func: MatchingFunction): Promise<void> {
590590
this.fm.addFunction(name, func);
591591
}
592-
593592
public async selfAddPolicy(sec: string, ptype: string, rule: string[]): Promise<boolean> {
594-
return this.addPolicyInternal(sec, ptype, rule, false);
593+
return this.addPolicyWithoutNotify(sec, ptype, rule);
594+
}
595+
596+
public async selfAddPolicies(sec: string, ptype: string, rules: string[][]): Promise<boolean> {
597+
return this.addPoliciesWithoutNotify(sec, ptype, rules);
595598
}
596599

597600
public async selfRemovePolicy(sec: string, ptype: string, rule: string[]): Promise<boolean> {
598-
return this.removePolicyInternal(sec, ptype, rule, false);
601+
return this.removePolicyWithoutNotify(sec, ptype, rule);
599602
}
600603

601-
public async selfRemoveFilteredPolicy(sec: string, ptype: string, fieldIndex: number, fieldValues: string[]): Promise<boolean> {
602-
return this.removeFilteredPolicyInternal(sec, ptype, fieldIndex, fieldValues, false);
604+
public async selfRemovePolicies(sec: string, ptype: string, rules: string[][]): Promise<boolean> {
605+
return this.removePoliciesWithoutNotify(sec, ptype, rules);
603606
}
604607

605-
public async selfUpdatePolicy(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise<boolean> {
606-
return this.updatePolicyInternal(sec, ptype, oldRule, newRule, false);
608+
public async selfRemoveFilteredPolicy(sec: string, ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {
609+
return this.removeFilteredPolicyWithoutNotify(sec, ptype, fieldIndex, fieldValues);
607610
}
608611

609-
public async selfAddPolicies(sec: string, ptype: string, rule: string[][]): Promise<boolean> {
610-
return this.addPoliciesInternal(sec, ptype, rule, false);
612+
public async selfUpdatePolicy(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise<boolean> {
613+
return this.updatePolicyWithoutNotify(sec, ptype, oldRule, newRule);
611614
}
612615

613-
public async selfRemovePolicies(sec: string, ptype: string, rule: string[][]): Promise<boolean> {
614-
return this.removePoliciesInternal(sec, ptype, rule, false);
616+
public async selfUpdatePolicies(sec: string, ptype: string, oldRules: string[][], newRules: string[][]): Promise<boolean> {
617+
return this.updatePoliciesWithoutNotify(sec, ptype, oldRules, newRules);
615618
}
616619
}

0 commit comments

Comments
 (0)