Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 40 additions & 14 deletions src/internalEnforcer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export class InternalEnforcer extends CoreEnforcer {
/**
* addPolicyInternal adds a rule to the current policy.
*/
protected async addPolicyInternal(sec: string, ptype: string, rule: string[], useWatcher: boolean): Promise<boolean> {
protected async addPolicyInternal(sec: string, ptype: string, rule: string[], useWatcher: boolean, useAdapter = true): Promise<boolean> {
if (this.model.hasPolicy(sec, ptype, rule)) {
return false;
}

if (this.adapter && this.autoSave) {
if (useAdapter && this.adapter && this.autoSave) {
try {
await this.adapter.addPolicy(sec, ptype, rule);
} catch (e) {
Expand Down Expand Up @@ -60,14 +60,20 @@ export class InternalEnforcer extends CoreEnforcer {

// addPolicies adds rules to the current policy.
// removePolicies removes rules from the current policy.
protected async addPoliciesInternal(sec: string, ptype: string, rules: string[][], useWatcher: boolean): Promise<boolean> {
protected async addPoliciesInternal(
sec: string,
ptype: string,
rules: string[][],
useWatcher: boolean,
useAdapter = true
): Promise<boolean> {
for (const rule of rules) {
if (this.model.hasPolicy(sec, ptype, rule)) {
return false;
}
}

if (this.autoSave) {
if (useAdapter && this.autoSave) {
if ('addPolicies' in this.adapter) {
try {
await this.adapter.addPolicies(sec, ptype, rules);
Expand Down Expand Up @@ -104,7 +110,13 @@ export class InternalEnforcer extends CoreEnforcer {
* Unlike addPoliciesInternal, this method will filter out rules that already exist
* and continue to add the remaining rules instead of returning false immediately.
*/
protected async addPoliciesInternalEx(sec: string, ptype: string, rules: string[][], useWatcher: boolean): Promise<boolean> {
protected async addPoliciesInternalEx(
sec: string,
ptype: string,
rules: string[][],
useWatcher: boolean,
useAdapter = true
): Promise<boolean> {
// Filter out existing rules
const newRules = rules.filter((rule) => !this.model.hasPolicy(sec, ptype, rule));

Expand All @@ -113,7 +125,7 @@ export class InternalEnforcer extends CoreEnforcer {
return false;
}

if (this.autoSave) {
if (useAdapter && this.autoSave) {
if ('addPolicies' in this.adapter) {
try {
await this.adapter.addPolicies(sec, ptype, newRules);
Expand Down Expand Up @@ -153,13 +165,14 @@ export class InternalEnforcer extends CoreEnforcer {
ptype: string,
oldRule: string[],
newRule: string[],
useWatcher: boolean
useWatcher: boolean,
useAdapter = true
): Promise<boolean> {
if (!this.model.hasPolicy(sec, ptype, oldRule)) {
return false;
}

if (this.autoSave) {
if (useAdapter && this.autoSave) {
if ('updatePolicy' in this.adapter) {
try {
await this.adapter.updatePolicy(sec, ptype, oldRule, newRule);
Expand Down Expand Up @@ -195,12 +208,18 @@ export class InternalEnforcer extends CoreEnforcer {
/**
* removePolicyInternal removes a rule from the current policy.
*/
protected async removePolicyInternal(sec: string, ptype: string, rule: string[], useWatcher: boolean): Promise<boolean> {
protected async removePolicyInternal(
sec: string,
ptype: string,
rule: string[],
useWatcher: boolean,
useAdapter = true
): Promise<boolean> {
if (!this.model.hasPolicy(sec, ptype, rule)) {
return false;
}

if (this.adapter && this.autoSave) {
if (useAdapter && this.adapter && this.autoSave) {
try {
await this.adapter.removePolicy(sec, ptype, rule);
} catch (e) {
Expand Down Expand Up @@ -229,14 +248,20 @@ export class InternalEnforcer extends CoreEnforcer {
}

// removePolicies removes rules from the current policy.
protected async removePoliciesInternal(sec: string, ptype: string, rules: string[][], useWatcher: boolean): Promise<boolean> {
protected async removePoliciesInternal(
sec: string,
ptype: string,
rules: string[][],
useWatcher: boolean,
useAdapter = true
): Promise<boolean> {
for (const rule of rules) {
if (!this.model.hasPolicy(sec, ptype, rule)) {
return false;
}
}

if (this.autoSave) {
if (useAdapter && this.autoSave) {
if ('removePolicies' in this.adapter) {
try {
await this.adapter.removePolicies(sec, ptype, rules);
Expand Down Expand Up @@ -276,9 +301,10 @@ export class InternalEnforcer extends CoreEnforcer {
ptype: string,
fieldIndex: number,
fieldValues: string[],
useWatcher: boolean
useWatcher: boolean,
useAdapter = true
): Promise<boolean> {
if (this.adapter && this.autoSave) {
if (useAdapter && this.adapter && this.autoSave) {
try {
await this.adapter.removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues);
} catch (e) {
Expand Down
80 changes: 74 additions & 6 deletions src/managementEnforcer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -590,27 +590,95 @@ export class ManagementEnforcer extends InternalEnforcer {
this.fm.addFunction(name, func);
}

/**
* selfAddPolicy adds an authorization rule to the current policy in memory only.
* This method is intended for use in distributed setups (e.g., inside a Watcher callback)
* where you want to update the local policy cache without triggering database writes
* or watcher notifications, thus preventing infinite loops.
*
* @param sec section, "p" or "g"
* @param ptype the policy type, can be "p", "p2", "p3", .. or "g", "g2", "g3", ..
* @param rule the policy rule to add
* @return succeeds or not
*/
public async selfAddPolicy(sec: string, ptype: string, rule: string[]): Promise<boolean> {
return this.addPolicyInternal(sec, ptype, rule, false);
return this.addPolicyInternal(sec, ptype, rule, false, false);
}

/**
* selfRemovePolicy removes an authorization rule from the current policy in memory only.
* This method is intended for use in distributed setups (e.g., inside a Watcher callback)
* where you want to update the local policy cache without triggering database writes
* or watcher notifications, thus preventing infinite loops.
*
* @param sec section, "p" or "g"
* @param ptype the policy type, can be "p", "p2", "p3", .. or "g", "g2", "g3", ..
* @param rule the policy rule to remove
* @return succeeds or not
*/
public async selfRemovePolicy(sec: string, ptype: string, rule: string[]): Promise<boolean> {
return this.removePolicyInternal(sec, ptype, rule, false);
return this.removePolicyInternal(sec, ptype, rule, false, false);
}

/**
* selfRemoveFilteredPolicy removes authorization rules based on field filters from the current policy in memory only.
* This method is intended for use in distributed setups (e.g., inside a Watcher callback)
* where you want to update the local policy cache without triggering database writes
* or watcher notifications, thus preventing infinite loops.
*
* @param sec section, "p" or "g"
* @param ptype the policy type, can be "p", "p2", "p3", .. or "g", "g2", "g3", ..
* @param fieldIndex the policy rule's start index to be matched
* @param fieldValues the field values to be matched
* @return succeeds or not
*/
public async selfRemoveFilteredPolicy(sec: string, ptype: string, fieldIndex: number, fieldValues: string[]): Promise<boolean> {
return this.removeFilteredPolicyInternal(sec, ptype, fieldIndex, fieldValues, false);
return this.removeFilteredPolicyInternal(sec, ptype, fieldIndex, fieldValues, false, false);
}

/**
* selfUpdatePolicy updates an authorization rule in the current policy in memory only.
* This method is intended for use in distributed setups (e.g., inside a Watcher callback)
* where you want to update the local policy cache without triggering database writes
* or watcher notifications, thus preventing infinite loops.
*
* @param sec section, "p" or "g"
* @param ptype the policy type, can be "p", "p2", "p3", .. or "g", "g2", "g3", ..
* @param oldRule the old policy rule to be replaced
* @param newRule the new policy rule
* @return succeeds or not
*/
public async selfUpdatePolicy(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise<boolean> {
return this.updatePolicyInternal(sec, ptype, oldRule, newRule, false);
return this.updatePolicyInternal(sec, ptype, oldRule, newRule, false, false);
}

/**
* selfAddPolicies adds authorization rules to the current policy in memory only.
* This method is intended for use in distributed setups (e.g., inside a Watcher callback)
* where you want to update the local policy cache without triggering database writes
* or watcher notifications, thus preventing infinite loops.
*
* @param sec section, "p" or "g"
* @param ptype the policy type, can be "p", "p2", "p3", .. or "g", "g2", "g3", ..
* @param rule the policy rules to add
* @return succeeds or not
*/
public async selfAddPolicies(sec: string, ptype: string, rule: string[][]): Promise<boolean> {
return this.addPoliciesInternal(sec, ptype, rule, false);
return this.addPoliciesInternal(sec, ptype, rule, false, false);
}

/**
* selfRemovePolicies removes authorization rules from the current policy in memory only.
* This method is intended for use in distributed setups (e.g., inside a Watcher callback)
* where you want to update the local policy cache without triggering database writes
* or watcher notifications, thus preventing infinite loops.
*
* @param sec section, "p" or "g"
* @param ptype the policy type, can be "p", "p2", "p3", .. or "g", "g2", "g3", ..
* @param rule the policy rules to remove
* @return succeeds or not
*/
public async selfRemovePolicies(sec: string, ptype: string, rule: string[][]): Promise<boolean> {
return this.removePoliciesInternal(sec, ptype, rule, false);
return this.removePoliciesInternal(sec, ptype, rule, false, false);
}
}
Loading
Loading