@@ -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}
0 commit comments