diff --git a/src/adapter.ts b/src/adapter.ts index 638f2e4..71e1a76 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -14,7 +14,7 @@ import {Adapter, Helper, Model} from 'casbin'; import {CasbinRule} from './casbinRule'; -import {Connection, ConnectionOptions, createConnection, getRepository} from 'typeorm'; +import {Connection, ConnectionOptions, createConnection, getRepository, getConnection} from 'typeorm'; import {CasbinMongoRule} from './casbinMongoRule'; type GenericCasbinRule = CasbinRule | CasbinMongoRule; @@ -130,7 +130,21 @@ export default class TypeORMAdapter implements Adapter { lines.push(line); } } - await getRepository(this.getCasbinRuleConstructor(), this.option.name).save(lines); + + const queryRunner = this.typeorm.createQueryRunner(); + + await queryRunner.connect(); + await queryRunner.startTransaction(); + + try { + await queryRunner.manager.save(lines); + await queryRunner.commitTransaction(); + } catch (err) { + await queryRunner.rollbackTransaction(); + throw err; + } finally { + await queryRunner.release(); + } return true; } @@ -143,6 +157,32 @@ export default class TypeORMAdapter implements Adapter { await getRepository(this.getCasbinRuleConstructor(), this.option.name).save(line); } + /** + * addPolicies adds policy rules to the storage. + */ + public async addPolicies(sec: string, ptype: string, rules: string[][]) { + const lines: GenericCasbinRule[] = []; + for (const rule of rules) { + const line = this.savePolicyLine(ptype, rule); + lines.push(line); + } + + const queryRunner = this.typeorm.createQueryRunner(); + + await queryRunner.connect(); + await queryRunner.startTransaction(); + + try { + await queryRunner.manager.save(lines); + await queryRunner.commitTransaction(); + } catch (err) { + await queryRunner.rollbackTransaction(); + throw err; + } finally { + await queryRunner.release(); + } + } + /** * removePolicy removes a policy rule from the storage. */ @@ -151,6 +191,30 @@ export default class TypeORMAdapter implements Adapter { await getRepository(this.getCasbinRuleConstructor(), this.option.name).delete(line); } + /** + * removePolicies removes policy rules from the storage. + */ + public async removePolicies(sec: string, ptype: string, rules: string[][]) { + const queryRunner = this.typeorm.createQueryRunner(); + const type = TypeORMAdapter.getCasbinRuleType(this.option.type); + + await queryRunner.connect(); + await queryRunner.startTransaction(); + + try { + for (const rule of rules) { + const line = this.savePolicyLine(ptype, rule); + await queryRunner.manager.delete(type, line); + } + await queryRunner.commitTransaction(); + } catch (err) { + await queryRunner.rollbackTransaction(); + throw err; + } finally { + await queryRunner.release(); + } + } + /** * removeFilteredPolicy removes policy rules that match the filter from the storage. */ diff --git a/test/adapter.test.ts b/test/adapter.test.ts index 64ae76f..63d5ae2 100644 --- a/test/adapter.test.ts +++ b/test/adapter.test.ts @@ -76,9 +76,50 @@ test('TestAdapter', async () => { ['data2_admin', 'data2', 'write'], ['role', 'res', 'action']]); + await a.addPolicies('', 'p', [ + ['role1', 'res1', 'action1'], + ['role2', 'res2', 'action2'], + ['role3', 'res3', 'action3'], + ['role4', 'res4', 'action4'], + ['role5', 'res5', 'action5'] + ]); + e = await Enforcer.newEnforcer('examples/rbac_model.conf', a); + testGetPolicy(e, [ + ['alice', 'data1', 'read'], + ['bob', 'data2', 'write'], + ['data2_admin', 'data2', 'read'], + ['data2_admin', 'data2', 'write'], + ['role', 'res', 'action'], + ['role1', 'res1', 'action1'], + ['role2', 'res2', 'action2'], + ['role3', 'res3', 'action3'], + ['role4', 'res4', 'action4'], + ['role5', 'res5', 'action5'] + ]); + // Remove policy from DB await a.removePolicy('', 'p', ['role', 'res', 'action']); e = await Enforcer.newEnforcer('examples/rbac_model.conf', a); + testGetPolicy(e, [ + ['alice', 'data1', 'read'], + ['bob', 'data2', 'write'], + ['data2_admin', 'data2', 'read'], + ['data2_admin', 'data2', 'write'], + ['role1', 'res1', 'action1'], + ['role2', 'res2', 'action2'], + ['role3', 'res3', 'action3'], + ['role4', 'res4', 'action4'], + ['role5', 'res5', 'action5'] + ]); + + await a.removePolicies('', 'p', [ + ['role1', 'res1', 'action1'], + ['role2', 'res2', 'action2'], + ['role3', 'res3', 'action3'], + ['role4', 'res4', 'action4'], + ['role5', 'res5', 'action5'] + ]); + e = await Enforcer.newEnforcer('examples/rbac_model.conf', a); testGetPolicy(e, [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'],