diff --git a/src/internalEnforcer.ts b/src/internalEnforcer.ts index 569d9c9..49c73e4 100644 --- a/src/internalEnforcer.ts +++ b/src/internalEnforcer.ts @@ -24,12 +24,18 @@ 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 { + protected async addPolicyInternal( + sec: string, + ptype: string, + rule: string[], + useWatcher: boolean, + useAdapter: boolean + ): Promise { if (this.model.hasPolicy(sec, ptype, rule)) { return false; } - if (this.adapter && this.autoSave) { + if (this.adapter && this.autoSave && useAdapter) { try { await this.adapter.addPolicy(sec, ptype, rule); } catch (e) { @@ -60,14 +66,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 { + protected async addPoliciesInternal( + sec: string, + ptype: string, + rules: string[][], + useWatcher: boolean, + useAdapter: boolean + ): Promise { for (const rule of rules) { if (this.model.hasPolicy(sec, ptype, rule)) { return false; } } - if (this.autoSave) { + if (this.autoSave && useAdapter) { if ('addPolicies' in this.adapter) { try { await this.adapter.addPolicies(sec, ptype, rules); @@ -107,13 +119,14 @@ export class InternalEnforcer extends CoreEnforcer { ptype: string, oldRule: string[], newRule: string[], - useWatcher: boolean + useWatcher: boolean, + useAdapter: boolean ): Promise { if (!this.model.hasPolicy(sec, ptype, oldRule)) { return false; } - if (this.autoSave) { + if (this.autoSave && useAdapter) { if ('updatePolicy' in this.adapter) { try { await this.adapter.updatePolicy(sec, ptype, oldRule, newRule); @@ -149,12 +162,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 { + protected async removePolicyInternal( + sec: string, + ptype: string, + rule: string[], + useWatcher: boolean, + useAdapter: boolean + ): Promise { if (!this.model.hasPolicy(sec, ptype, rule)) { return false; } - if (this.adapter && this.autoSave) { + if (this.adapter && this.autoSave && useAdapter) { try { await this.adapter.removePolicy(sec, ptype, rule); } catch (e) { @@ -183,14 +202,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 { + protected async removePoliciesInternal( + sec: string, + ptype: string, + rules: string[][], + useWatcher: boolean, + useAdapter: boolean + ): Promise { for (const rule of rules) { if (!this.model.hasPolicy(sec, ptype, rule)) { return false; } } - if (this.autoSave) { + if (this.autoSave && useAdapter) { if ('removePolicies' in this.adapter) { try { await this.adapter.removePolicies(sec, ptype, rules); @@ -230,9 +255,10 @@ export class InternalEnforcer extends CoreEnforcer { ptype: string, fieldIndex: number, fieldValues: string[], - useWatcher: boolean + useWatcher: boolean, + useAdapter: boolean ): Promise { - if (this.adapter && this.autoSave) { + if (this.adapter && this.autoSave && useAdapter) { try { await this.adapter.removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues); } catch (e) { diff --git a/src/managementEnforcer.ts b/src/managementEnforcer.ts index 1393c0d..442d157 100644 --- a/src/managementEnforcer.ts +++ b/src/managementEnforcer.ts @@ -260,7 +260,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async addNamedPolicy(ptype: string, ...params: string[]): Promise { - return this.addPolicyInternal('p', ptype, params, true); + return this.addPolicyInternal('p', ptype, params, true, true); } /** @@ -273,7 +273,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async addNamedPolicies(ptype: string, rules: string[][]): Promise { - return this.addPoliciesInternal('p', ptype, rules, true); + return this.addPoliciesInternal('p', ptype, rules, true, true); } /** @@ -300,7 +300,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async updateNamedPolicy(ptype: string, oldRule: string[], newRule: string[]): Promise { - return this.updatePolicyInternal('p', ptype, oldRule, newRule, true); + return this.updatePolicyInternal('p', ptype, oldRule, newRule, true, true); } /** @@ -343,7 +343,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async removeNamedPolicy(ptype: string, ...params: string[]): Promise { - return this.removePolicyInternal('p', ptype, params, true); + return this.removePolicyInternal('p', ptype, params, true, true); } /** @@ -354,7 +354,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async removeNamedPolicies(ptype: string, rules: string[][]): Promise { - return this.removePoliciesInternal('p', ptype, rules, true); + return this.removePoliciesInternal('p', ptype, rules, true, true); } /** @@ -367,7 +367,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async removeFilteredNamedPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise { - return this.removeFilteredPolicyInternal('p', ptype, fieldIndex, fieldValues, true); + return this.removeFilteredPolicyInternal('p', ptype, fieldIndex, fieldValues, true, true); } /** @@ -425,7 +425,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async addNamedGroupingPolicy(ptype: string, ...params: string[]): Promise { - return this.addPolicyInternal('g', ptype, params, true); + return this.addPolicyInternal('g', ptype, params, true, true); } /** @@ -438,7 +438,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async addNamedGroupingPolicies(ptype: string, rules: string[][]): Promise { - return this.addPoliciesInternal('g', ptype, rules, true); + return this.addPoliciesInternal('g', ptype, rules, true, true); } /** @@ -481,7 +481,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async removeNamedGroupingPolicy(ptype: string, ...params: string[]): Promise { - return this.removePolicyInternal('g', ptype, params, true); + return this.removePolicyInternal('g', ptype, params, true, true); } /** @@ -492,7 +492,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async removeNamedGroupingPolicies(ptype: string, rules: string[][]): Promise { - return this.removePoliciesInternal('g', ptype, rules, true); + return this.removePoliciesInternal('g', ptype, rules, true, true); } /** @@ -505,7 +505,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async removeFilteredNamedGroupingPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise { - return this.removeFilteredPolicyInternal('g', ptype, fieldIndex, fieldValues, true); + return this.removeFilteredPolicyInternal('g', ptype, fieldIndex, fieldValues, true, true); } /** @@ -528,7 +528,7 @@ export class ManagementEnforcer extends InternalEnforcer { * @return succeeds or not. */ public async updateNamedGroupingPolicy(ptype: string, oldRule: string[], newRule: string[]): Promise { - return this.updatePolicyInternal('g', ptype, oldRule, newRule, true); + return this.updatePolicyInternal('g', ptype, oldRule, newRule, true, true); } /** @@ -541,26 +541,356 @@ export class ManagementEnforcer extends InternalEnforcer { } public async selfAddPolicy(sec: string, ptype: string, rule: string[]): Promise { - return this.addPolicyInternal(sec, ptype, rule, false); + return this.addPolicyInternal(sec, ptype, rule, false, true); } public async selfRemovePolicy(sec: string, ptype: string, rule: string[]): Promise { - return this.removePolicyInternal(sec, ptype, rule, false); + return this.removePolicyInternal(sec, ptype, rule, false, true); } public async selfRemoveFilteredPolicy(sec: string, ptype: string, fieldIndex: number, fieldValues: string[]): Promise { - return this.removeFilteredPolicyInternal(sec, ptype, fieldIndex, fieldValues, false); + return this.removeFilteredPolicyInternal(sec, ptype, fieldIndex, fieldValues, false, true); } public async selfUpdatePolicy(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise { - return this.updatePolicyInternal(sec, ptype, oldRule, newRule, false); + return this.updatePolicyInternal(sec, ptype, oldRule, newRule, false, true); } public async selfAddPolicies(sec: string, ptype: string, rule: string[][]): Promise { - return this.addPoliciesInternal(sec, ptype, rule, false); + return this.addPoliciesInternal(sec, ptype, rule, false, true); } public async selfRemovePolicies(sec: string, ptype: string, rule: string[][]): Promise { - return this.removePoliciesInternal(sec, ptype, rule, false); + return this.removePoliciesInternal(sec, ptype, rule, false, true); + } + + /** + * addPolicyLocally adds an authorization rule to the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rule will not be added. + * Otherwise the function returns true by adding the new rule. + * + * @param params the "p" policy rule, ptype "p" is implicitly used. + * @return succeeds or not. + */ + public async addPolicyLocally(...params: string[]): Promise { + return this.addNamedPolicyLocally('p', ...params); + } + + /** + * addPoliciesLocally adds authorization rules to the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rules will not be added. + * Otherwise the function returns true by adding the new rules. + * + * @param rules the "p" policy rules, ptype "p" is implicitly used. + * @return succeeds or not. + */ + public async addPoliciesLocally(rules: string[][]): Promise { + return this.addNamedPoliciesLocally('p', rules); + } + + /** + * addNamedPolicyLocally adds an authorization rule to the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rule will not be added. + * Otherwise the function returns true by adding the new rule. + * + * @param ptype the policy type, can be "p", "p2", "p3", .. + * @param params the "p" policy rule. + * @return succeeds or not. + */ + public async addNamedPolicyLocally(ptype: string, ...params: string[]): Promise { + return this.addPolicyInternal('p', ptype, params, false, false); + } + + /** + * addNamedPoliciesLocally adds authorization rules to the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rules will not be added. + * Otherwise the function returns true by adding the new rules. + * + * @param ptype the policy type, can be "p", "p2", "p3", .. + * @param rules the "p" policy rules. + * @return succeeds or not. + */ + public async addNamedPoliciesLocally(ptype: string, rules: string[][]): Promise { + return this.addPoliciesInternal('p', ptype, rules, false, false); + } + + /** + * updatePolicyLocally updates an authorization rule from the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule not exists, the function returns false. + * Otherwise the function returns true by changing it to the new rule. + * + * @return succeeds or not. + * @param oldRule the policy will be remove + * @param newRule the policy will be added + */ + public async updatePolicyLocally(oldRule: string[], newRule: string[]): Promise { + return this.updateNamedPolicyLocally('p', oldRule, newRule); + } + + /** + * updateNamedPolicyLocally updates an authorization rule from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule not exists, the function returns false. + * Otherwise the function returns true by changing it to the new rule. + * + * @param ptype the policy type, can be "p", "p2", "p3", .. + * @param oldRule the policy rule will be remove + * @param newRule the policy rule will be added + * @return succeeds or not. + */ + public async updateNamedPolicyLocally(ptype: string, oldRule: string[], newRule: string[]): Promise { + return this.updatePolicyInternal('p', ptype, oldRule, newRule, false, false); + } + + /** + * removePolicyLocally removes an authorization rule from the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param params the "p" policy rule, ptype "p" is implicitly used. + * @return succeeds or not. + */ + public async removePolicyLocally(...params: string[]): Promise { + return this.removeNamedPolicyLocally('p', ...params); + } + + /** + * removePoliciesLocally removes authorization rules from the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param rules the "p" policy rules, ptype "p" is implicitly used. + * @return succeeds or not. + */ + public async removePoliciesLocally(rules: string[][]): Promise { + return this.removeNamedPoliciesLocally('p', rules); + } + + /** + * removeFilteredPolicy removes an authorization rule from the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * Field filters can be specified. + * + * @param fieldIndex the policy rule's start index to be matched. + * @param fieldValues the field values to be matched, value "" + * means not to match this field. + * @return succeeds or not. + */ + public async removeFilteredPolicyLocally(fieldIndex: number, ...fieldValues: string[]): Promise { + return this.removeFilteredNamedPolicyLocally('p', fieldIndex, ...fieldValues); + } + + /** + * removeNamedPolicyLocally removes an authorization rule from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param ptype the policy type, can be "p", "p2", "p3", .. + * @param params the "p" policy rule. + * @return succeeds or not. + */ + public async removeNamedPolicyLocally(ptype: string, ...params: string[]): Promise { + return this.removePolicyInternal('p', ptype, params, false, false); + } + + /** + * removeNamedPoliciesLocally removes authorization rules from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param ptype the policy type, can be "p", "p2", "p3", .. + * @param rules the "p" policy rules. + * @return succeeds or not. + */ + public async removeNamedPoliciesLocally(ptype: string, rules: string[][]): Promise { + return this.removePoliciesInternal('p', ptype, rules, false, false); + } + + /** + * removeFilteredNamedPolicyLocally removes an authorization rule from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * Field filters can be specified. + * + * @param ptype the policy type, can be "p", "p2", "p3", .. + * @param fieldIndex the policy rule's start index to be matched. + * @param fieldValues the field values to be matched, value "" + * means not to match this field. + * @return succeeds or not. + */ + public async removeFilteredNamedPolicyLocally(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise { + return this.removeFilteredPolicyInternal('p', ptype, fieldIndex, fieldValues, false, false); + } + + /** + * addGroupingPolicyLocally adds a role inheritance rule to the current policy. + * If the rule already exists, the function returns false and the rule will not be added. + * Otherwise the function returns true by adding the new rule. + * + * @param params the "g" policy rule, ptype "g" is implicitly used. + * @return succeeds or not. + */ + public async addGroupingPolicyLocally(...params: string[]): Promise { + return this.addNamedGroupingPolicyLocally('g', ...params); + } + + /** + * addGroupingPoliciesLocally adds a role inheritance rules to the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rules will not be added. + * Otherwise the function returns true by adding the new rules. + * + * @param rules the "g" policy rules, ptype "g" is implicitly used. + * @return succeeds or not. + */ + public async addGroupingPoliciesLocally(rules: string[][]): Promise { + return this.addNamedGroupingPoliciesLocally('g', rules); + } + + /** + * addNamedGroupingPolicyLocally adds a named role inheritance rule to the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rule will not be added. + * Otherwise the function returns true by adding the new rule. + * + * @param ptype the policy type, can be "g", "g2", "g3", .. + * @param params the "g" policy rule. + * @return succeeds or not. + */ + public async addNamedGroupingPolicyLocally(ptype: string, ...params: string[]): Promise { + return this.addPolicyInternal('g', ptype, params, false, false); + } + + /** + * addNamedGroupingPoliciesLocally adds named role inheritance rules to the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * If the rule already exists, the function returns false and the rules will not be added. + * Otherwise the function returns true by adding the new rules. + * + * @param ptype the policy type, can be "g", "g2", "g3", .. + * @param rules the "g" policy rule. + * @return succeeds or not. + */ + public async addNamedGroupingPoliciesLocally(ptype: string, rules: string[][]): Promise { + return this.addPoliciesInternal('g', ptype, rules, false, false); + } + + /** + * removeGroupingPolicyLocally removes a role inheritance rule from the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param params the "g" policy rule, ptype "g" is implicitly used. + * @return succeeds or not. + */ + public async removeGroupingPolicyLocally(...params: string[]): Promise { + return this.removeNamedGroupingPolicyLocally('g', ...params); + } + + /** + * removeGroupingPoliciesLocally removes role inheritance rules from the current policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param rules the "g" policy rules, ptype "g" is implicitly used. + * @return succeeds or not. + */ + public async removeGroupingPoliciesLocally(rules: string[][]): Promise { + return this.removeNamedGroupingPoliciesLocally('g', rules); + } + + /** + * removeFilteredGroupingPolicyLocally removes a role inheritance rule from the current policy, field filters can be specified without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param fieldIndex the policy rule's start index to be matched. + * @param fieldValues the field values to be matched, value "" + * means not to match this field. + * @return succeeds or not. + */ + public async removeFilteredGroupingPolicyLocally(fieldIndex: number, ...fieldValues: string[]): Promise { + return this.removeFilteredNamedGroupingPolicyLocally('g', fieldIndex, ...fieldValues); + } + + /** + * removeNamedGroupingPolicyLocally removes a role inheritance rule from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param ptype the policy type, can be "g", "g2", "g3", .. + * @param params the "g" policy rule. + * @return succeeds or not. + */ + public async removeNamedGroupingPolicyLocally(ptype: string, ...params: string[]): Promise { + return this.removePolicyInternal('g', ptype, params, false, false); + } + + /** + * removeNamedGroupingPoliciesLocally removes role inheritance rules from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param ptype the policy type, can be "g", "g2", "g3", .. + * @param rules the "g" policy rules. + * @return succeeds or not. + */ + public async removeNamedGroupingPoliciesLocally(ptype: string, rules: string[][]): Promise { + return this.removePoliciesInternal('g', ptype, rules, false, false); + } + + /** + * removeFilteredNamedGroupingPolicyLocally removes a role inheritance rule from the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * Field filters can be specified. + * + * @param ptype the policy type, can be "g", "g2", "g3", .. + * @param fieldIndex the policy rule's start index to be matched. + * @param fieldValues the field values to be matched, value "" + * means not to match this field. + * @return succeeds or not. + */ + public async removeFilteredNamedGroupingPolicyLocally(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise { + return this.removeFilteredPolicyInternal('g', ptype, fieldIndex, fieldValues, false, false); + } + + /** + * UpdateGroupingPolicyLocally updates an rule to the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param oldRule the old rule. + * @param newRule the new rule. + * @return succeeds or not. + */ + public async updateGroupingPolicyLocally(oldRule: string[], newRule: string[]): Promise { + return this.updateNamedGroupingPolicyLocally('g', oldRule, newRule); + } + + /** + * updateNamedGroupingPolicyLocally updates an rule to the current named policy without + * persistence via the adapter and without calling the update() function of the watcher. + * + * @param ptype the policy type, can be "g", "g2", "g3", .. + * @param oldRule the old rule. + * @param newRule the new rule. + * @return succeeds or not. + */ + public async updateNamedGroupingPolicyLocally(ptype: string, oldRule: string[], newRule: string[]): Promise { + return this.updatePolicyInternal('g', ptype, oldRule, newRule, false, false); + } + + public async selfRemovePolicyLocally(sec: string, ptype: string, rule: string[]): Promise { + return this.removePolicyInternal(sec, ptype, rule, false, false); + } + + public async selfRemoveFilteredPolicyLocally(sec: string, ptype: string, fieldIndex: number, fieldValues: string[]): Promise { + return this.removeFilteredPolicyInternal(sec, ptype, fieldIndex, fieldValues, false, false); + } + + public async selfUpdatePolicyLocally(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise { + return this.updatePolicyInternal(sec, ptype, oldRule, newRule, false, false); + } + + public async selfAddPoliciesLocally(sec: string, ptype: string, rule: string[][]): Promise { + return this.addPoliciesInternal(sec, ptype, rule, false, false); + } + + public async selfRemovePoliciesLocally(sec: string, ptype: string, rule: string[][]): Promise { + return this.removePoliciesInternal(sec, ptype, rule, false, false); } } diff --git a/src/syncedEnforcer.ts b/src/syncedEnforcer.ts index bbc1146..aaec212 100644 --- a/src/syncedEnforcer.ts +++ b/src/syncedEnforcer.ts @@ -366,7 +366,7 @@ export class SyncedEnforcer extends Enforcer { */ public async removeNamedPolicy(ptype: string, ...params: string[]): Promise { await this.lock.acquireAsync(); - return this.removePolicyInternal('p', ptype, params, true).finally(() => this.lock.release()); + return this.removePolicyInternal('p', ptype, params, true, true).finally(() => this.lock.release()); } /** diff --git a/test/managementAPI.test.ts b/test/managementAPI.test.ts index 2afc92e..7def4cc 100644 --- a/test/managementAPI.test.ts +++ b/test/managementAPI.test.ts @@ -377,3 +377,232 @@ test('updateNamedGroupingPolicy', async () => { groupingPolicy = await e.getGroupingPolicy(); testArray2DEquals(groupingPolicy, [['alice', 'update_test']]); }); + +test('addPolicyLocally', async () => { + const p = ['eve', 'data3', 'read']; + const added = await e.addPolicyLocally(...p); + expect(added).toBe(true); + expect(await e.hasPolicy(...p)).toBe(true); +}); + +test('addPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const rules = [ + ['jack', 'data4', 'read'], + ['katy', 'data4', 'write'], + ['leyo', 'data4', 'read'], + ['ham', 'data4', 'write'], + ]; + const added = await e.addPoliciesLocally(rules); + expect(added).toBe(true); + for (const rule of rules) { + expect(await e.hasPolicy(...rule)).toBe(true); + } +}); + +test('addNamedPolicyLocally', async () => { + const p = ['eve', 'data3', 'read']; + const added = await e.addNamedPolicyLocally('p', ...p); + expect(added).toBe(true); + expect(await e.hasPolicy(...p)).toBe(true); +}); + +test('addNamedPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const rules = [ + ['jack', 'data4', 'read'], + ['katy', 'data4', 'write'], + ['leyo', 'data4', 'read'], + ['ham', 'data4', 'write'], + ]; + const added = await e.addNamedPoliciesLocally('p', rules); + expect(added).toBe(true); + for (const rule of rules) { + expect(await e.hasPolicy(...rule)).toBe(true); + } +}); + +test('updatePolicyLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const p = ['alice', 'data1', 'read']; + const q = ['alice', 'data2', 'read']; + const updated = await e.updatePolicyLocally(p, q); + expect(updated).toBe(true); + expect(await e.hasPolicy(...p)).toBe(false); + expect(await e.hasPolicy(...q)).toBe(true); +}); + +test('updateNamedPolicyLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const p = ['alice', 'data1', 'read']; + const q = ['alice', 'data2', 'read']; + const updated = await e.updateNamedPolicyLocally('p', p, q); + expect(updated).toBe(true); + expect(await e.hasPolicy(...p)).toBe(false); + expect(await e.hasPolicy(...q)).toBe(true); +}); + +test('removePolicyLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const p = ['alice', 'data1', 'read']; + const removed = await e.removePolicyLocally(...p); + expect(removed).toBe(true); + expect(await e.hasPolicy(...p)).toBe(false); +}); + +test('removePoliciesLocally', async () => { + const rules = [ + ['jack', 'data4', 'read'], + ['katy', 'data4', 'write'], + ['leyo', 'data4', 'read'], + ['ham', 'data4', 'write'], + ]; + const added = await e.addPoliciesLocally(rules); + expect(added).toBe(true); + const removed = await e.removePoliciesLocally(rules); + expect(removed).toBe(true); + for (const rule of rules) { + expect(await e.hasPolicy(...rule)).toBe(false); + } +}); + +test('removeFilteredPolicyLocally', async () => { + const p = ['alice', 'data1', 'read']; + const removed = await e.removeFilteredPolicyLocally(0, ...p); + expect(removed).toBe(true); + expect(await e.hasPolicy(...p)).toBe(false); +}); + +test('removeNamedPolicyLocally', async () => { + const p = ['alice', 'data1', 'read']; + const removed = await e.removeNamedPolicyLocally('p', ...p); + expect(removed).toBe(true); + expect(await e.hasPolicy(...p)).toBe(false); +}); + +test('removeNamedPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const rules = [ + ['jack', 'data4', 'read'], + ['katy', 'data4', 'write'], + ['leyo', 'data4', 'read'], + ['ham', 'data4', 'write'], + ]; + const added = await e.addPoliciesLocally(rules); + expect(added).toBe(true); + const removed = await e.removeNamedPoliciesLocally('p', rules); + expect(removed).toBe(true); + for (const rule of rules) { + expect(await e.hasPolicy(...rule)).toBe(false); + } +}); + +test('removeFilteredNamedPolicyLocally', async () => { + const p = ['alice', 'data1', 'read']; + const removed = await e.removeFilteredNamedPolicyLocally('p', 0, ...p); + expect(removed).toBe(true); + expect(await e.hasPolicy(...p)).toBe(false); +}); + +test('addGroupingPolicyLocally', async () => { + const added = await e.addGroupingPolicyLocally('group1', 'data2_admin'); + expect(added).toBe(true); +}); + +test('addGroupingPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const groupingRules = [ + ['ham', 'data4_admin'], + ['jack', 'data5_admin'], + ]; + const added = await e.addGroupingPoliciesLocally(groupingRules); + expect(added).toBe(true); +}); + +test('addNamedGroupingPolicyLocally', async () => { + const added = await e.addNamedGroupingPolicyLocally('g', 'group1', 'data2_admin'); + expect(added).toBe(true); +}); + +test('addNamedGroupingPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const groupingRules = [ + ['ham', 'data4_admin'], + ['jack', 'data5_admin'], + ]; + const added = await e.addNamedGroupingPoliciesLocally('g', groupingRules); + expect(added).toBe(true); +}); + +test('removeGroupingPolicyLocally', async () => { + const removed = await e.removeGroupingPolicyLocally('alice', 'data2_admin'); + expect(removed).toBe(true); +}); + +test('removeGroupingPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const groupingRules = [ + ['ham', 'data4_admin'], + ['jack', 'data5_admin'], + ]; + const added = await e.addGroupingPoliciesLocally(groupingRules); + expect(added).toBe(true); + const removed = await e.removeGroupingPoliciesLocally(groupingRules); + expect(removed).toBe(true); +}); + +test('removeFilteredGroupingPolicyLocally', async () => { + const removed = await e.removeFilteredGroupingPolicyLocally(0, 'alice'); + expect(removed).toBe(true); +}); + +test('removeFilteredNamedGroupingPolicyLocally', async () => { + const removed = await e.removeFilteredNamedGroupingPolicyLocally('g', 0, 'alice'); + expect(removed).toBe(true); +}); + +test('removeNamedGroupingPoliciesLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + const groupingRules = [ + ['ham', 'data4_admin'], + ['jack', 'data5_admin'], + ]; + const added = await e.addGroupingPoliciesLocally(groupingRules); + expect(added).toBe(true); + const removed = await e.removeNamedGroupingPoliciesLocally('g', groupingRules); + expect(removed).toBe(true); +}); + +test('updateGroupingPolicyLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + + let groupingPolicy = await e.getGroupingPolicy(); + testArray2DEquals(groupingPolicy, [['alice', 'data2_admin']]); + + const updated = e.updateGroupingPolicyLocally(['alice', 'data2_admin'], ['alice', 'update_test']); + groupingPolicy = await e.getGroupingPolicy(); + testArray2DEquals(groupingPolicy, [['alice', 'update_test']]); +}); + +test('updateNamedGroupingPolicyLocally', async () => { + const a = new FileAdapter('examples/rbac_policy.csv'); + e.setAdapter(a); + + let groupingPolicy = await e.getGroupingPolicy(); + testArray2DEquals(groupingPolicy, [['alice', 'data2_admin']]); + + const updated = e.updateNamedGroupingPolicyLocally('g', ['alice', 'data2_admin'], ['alice', 'update_test']); + groupingPolicy = await e.getGroupingPolicy(); + testArray2DEquals(groupingPolicy, [['alice', 'update_test']]); +});