diff --git a/.eslintrc.json b/.eslintrc.json index 4d0a6d0..141e4bf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,10 @@ { "extends": "standard", "rules": { + "semi": [ + "error", + "always" + ], "camelcase": [ "error", { diff --git a/src/adapter.js b/src/adapter.js index 50d5f00..e98434a 100644 --- a/src/adapter.js +++ b/src/adapter.js @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -const { Helper, logPrint } = require('casbin') -const mongoose = require('mongoose') -const CasbinRule = require('./model') -const { AdapterError, InvalidAdapterTypeError } = require('./errors') +const { Helper, logPrint } = require('casbin'); +const mongoose = require('mongoose'); +const CasbinRule = require('./model'); +const { AdapterError, InvalidAdapterTypeError } = require('./errors'); /** * Implements a policy adapter for casbin with MongoDB support. @@ -37,15 +37,15 @@ class MongooseAdapter { */ constructor (uri, options = {}) { if (!uri || typeof uri !== 'string') { - throw new AdapterError('You must provide Mongo URI to connect to!') + throw new AdapterError('You must provide Mongo URI to connect to!'); } // by default, adapter is not filtered - this.isFiltered = false - this.isSynced = false - this.autoAbort = false - this.uri = uri - this.options = options + this.isFiltered = false; + this.isSynced = false; + this.autoAbort = false; + this.uri = uri; + this.options = options; } /** @@ -55,8 +55,8 @@ class MongooseAdapter { async _open () { await mongoose.connect(this.uri, this.options) .then(instance => { - this.mongoseInstance = instance - }) + this.mongoseInstance = instance; + }); } /** @@ -73,14 +73,14 @@ class MongooseAdapter { * const adapter = await MongooseAdapter.newAdapter('MONGO_URI', { mongoose_options: 'here' }); */ static async newAdapter (uri, options = {}, adapterOptions = {}) { - const adapter = new MongooseAdapter(uri, options) - await adapter._open() - const { filtered = false, synced = false, autoAbort = false, autoCommit = false } = adapterOptions - adapter.setFiltered(filtered) - adapter.setSynced(synced) - adapter.setAutoAbort(autoAbort) - adapter.setAutoCommit(autoCommit) - return adapter + const adapter = new MongooseAdapter(uri, options); + await adapter._open(); + const { filtered = false, synced = false, autoAbort = false, autoCommit = false } = adapterOptions; + adapter.setFiltered(filtered); + adapter.setSynced(synced); + adapter.setAutoAbort(autoAbort); + adapter.setAutoCommit(autoCommit); + return adapter; } /** @@ -96,10 +96,10 @@ class MongooseAdapter { * const adapter = await MongooseAdapter.newFilteredAdapter('MONGO_URI', { mongoose_options: 'here' }); */ static async newFilteredAdapter (uri, options = {}) { - const adapter = await MongooseAdapter.newAdapter(uri, options, { filtered: true }) - await adapter._open() + const adapter = await MongooseAdapter.newAdapter(uri, options, { filtered: true }); + await adapter._open(); - return adapter + return adapter; } /** @@ -117,8 +117,8 @@ class MongooseAdapter { * const adapter = await MongooseAdapter.newFilteredAdapter('MONGO_URI', { mongoose_options: 'here' }); */ static async newSyncedAdapter (uri, options = {}, autoAbort = true, autoCommit = true) { - const adapter = await MongooseAdapter.newAdapter(uri, options, { synced: true, autoAbort, autoCommit }) - return adapter + const adapter = await MongooseAdapter.newAdapter(uri, options, { synced: true, autoAbort, autoCommit }); + return adapter; } /** @@ -128,7 +128,7 @@ class MongooseAdapter { * @param {Boolean} [isFiltered=true] Flag that represents the current state of adapter (filtered or not) */ setFiltered (isFiltered = true) { - this.isFiltered = isFiltered + this.isFiltered = isFiltered; } /** @@ -138,7 +138,7 @@ class MongooseAdapter { * @param {Boolean} [synced=true] Flag that represents the current state of adapter (filtered or not) */ setSynced (synced = true) { - this.isSynced = synced + this.isSynced = synced; } /** @@ -148,7 +148,7 @@ class MongooseAdapter { * @param {Boolean} [abort=true] Flag that represents if automatic abort should be enabled or not */ setAutoAbort (abort = true) { - if (this.isSynced) this.autoAbort = abort + if (this.isSynced) this.autoAbort = abort; } /** @@ -158,7 +158,7 @@ class MongooseAdapter { * @param {Boolean} [commit=true] Flag that represents if automatic commit should be enabled or not */ setAutoCommit (commit = true) { - if (this.isSynced) this.autoCommit = commit + if (this.isSynced) this.autoCommit = commit; } /** @@ -167,8 +167,8 @@ class MongooseAdapter { */ async getSession () { if (this.isSynced) { - return this.session && !this.session.hasEnded() ? this.session : this.mongoseInstance.startSession() - } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter') + return this.session && !this.session.hasEnded() ? this.session : this.mongoseInstance.startSession(); + } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter'); } /** @@ -177,12 +177,12 @@ class MongooseAdapter { async setSession (session) { if (this.isSynced) { if (session && (session.hasEnded && session.hasEnded.constructor && session.hasEnded.call && session.hasEnded.apply) && !session.hasEnded()) { - this.session = session + this.session = session; } else { - throw new AdapterError('Tried to set an invalid session') + throw new AdapterError('Tried to set an invalid session'); } } else { - throw new InvalidAdapterTypeError('Sessions are only supported by SyncedAdapter. See newSyncedAdapter') + throw new InvalidAdapterTypeError('Sessions are only supported by SyncedAdapter. See newSyncedAdapter'); } } @@ -193,13 +193,13 @@ class MongooseAdapter { */ async getTransaction () { if (this.isSynced) { - const session = await this.getSession() + const session = await this.getSession(); if (!session.transaction.isActive) { - await session.startTransaction() - logPrint('Transaction started. To commit changes use adapter.commitTransaction() or to abort use adapter.abortTransaction()') + await session.startTransaction(); + logPrint('Transaction started. To commit changes use adapter.commitTransaction() or to abort use adapter.abortTransaction()'); } - return session - } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter') + return session; + } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter'); } /** @@ -209,9 +209,9 @@ class MongooseAdapter { */ async commitTransaction () { if (this.isSynced) { - const session = await this.getSession() - await session.commitTransaction() - } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter') + const session = await this.getSession(); + await session.commitTransaction(); + } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter'); } /** @@ -221,10 +221,10 @@ class MongooseAdapter { */ async abortTransaction () { if (this.isSynced) { - const session = await this.getSession() - await session.abortTransaction() - logPrint('Transaction aborted') - } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter') + const session = await this.getSession(); + await session.abortTransaction(); + logPrint('Transaction aborted'); + } else throw new InvalidAdapterTypeError('Transactions are only supported by SyncedAdapter. See newSyncedAdapter'); } /** @@ -235,33 +235,33 @@ class MongooseAdapter { * @param {Object} model Casbin model to which policy rule must be loaded */ loadPolicyLine (line, model) { - let lineText = line.p_type + let lineText = line.p_type; if (line.v0) { - lineText += ', ' + line.v0 + lineText += ', ' + line.v0; } if (line.v1) { - lineText += ', ' + line.v1 + lineText += ', ' + line.v1; } if (line.v2) { - lineText += ', ' + line.v2 + lineText += ', ' + line.v2; } if (line.v3) { - lineText += ', ' + line.v3 + lineText += ', ' + line.v3; } if (line.v4) { - lineText += ', ' + line.v4 + lineText += ', ' + line.v4; } if (line.v5) { - lineText += ', ' + line.v5 + lineText += ', ' + line.v5; } - Helper.loadPolicyLine(lineText, model) + Helper.loadPolicyLine(lineText, model); } /** @@ -272,7 +272,7 @@ class MongooseAdapter { * @returns {Promise} */ async loadPolicy (model) { - return this.loadFilteredPolicy(model) + return this.loadFilteredPolicy(model); } /** @@ -284,18 +284,18 @@ class MongooseAdapter { */ async loadFilteredPolicy (model, filter) { if (filter) { - this.setFiltered(true) + this.setFiltered(true); } else { - this.setFiltered(false) + this.setFiltered(false); } - const options = {} - if (this.isSynced) options.session = await this.getTransaction() + const options = {}; + if (this.isSynced) options.session = await this.getTransaction(); - const lines = await CasbinRule.find(filter || {}, null, options) + const lines = await CasbinRule.find(filter || {}, null, options); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); for (const line of lines) { - this.loadPolicyLine(line, model) + this.loadPolicyLine(line, model); } } @@ -309,33 +309,33 @@ class MongooseAdapter { * @returns {Object} Returns a created CasbinRule record for MongoDB */ savePolicyLine (ptype, rule) { - const model = new CasbinRule({ p_type: ptype }) + const model = new CasbinRule({ p_type: ptype }); if (rule.length > 0) { - model.v0 = rule[0] + model.v0 = rule[0]; } if (rule.length > 1) { - model.v1 = rule[1] + model.v1 = rule[1]; } if (rule.length > 2) { - model.v2 = rule[2] + model.v2 = rule[2]; } if (rule.length > 3) { - model.v3 = rule[3] + model.v3 = rule[3]; } if (rule.length > 4) { - model.v4 = rule[4] + model.v4 = rule[4]; } if (rule.length > 5) { - model.v5 = rule[5] + model.v5 = rule[5]; } - return model + return model; } /** @@ -349,36 +349,36 @@ class MongooseAdapter { * @returns {Promise} */ async savePolicy (model) { - const options = {} - if (this.isSynced) options.session = await this.getTransaction() + const options = {}; + if (this.isSynced) options.session = await this.getTransaction(); try { - const lines = [] - const policyRuleAST = model.model.get('p') instanceof Map ? model.model.get('p') : new Map() - const groupingPolicyAST = model.model.get('g') instanceof Map ? model.model.get('g') : new Map() + const lines = []; + const policyRuleAST = model.model.get('p') instanceof Map ? model.model.get('p') : new Map(); + const groupingPolicyAST = model.model.get('g') instanceof Map ? model.model.get('g') : new Map(); for (const [ptype, ast] of policyRuleAST) { for (const rule of ast.policy) { - lines.push(this.savePolicyLine(ptype, rule)) + lines.push(this.savePolicyLine(ptype, rule)); } } for (const [ptype, ast] of groupingPolicyAST) { for (const rule of ast.policy) { - lines.push(this.savePolicyLine(ptype, rule)) + lines.push(this.savePolicyLine(ptype, rule)); } } - await CasbinRule.collection.insertMany(lines, options) + await CasbinRule.collection.insertMany(lines, options); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); } catch (err) { - this.autoAbort && options.session && await options.session.abortTransaction() - console.error(err) - return false + this.autoAbort && options.session && await options.session.abortTransaction(); + console.error(err); + return false; } - return true + return true; } /** @@ -391,17 +391,17 @@ class MongooseAdapter { * @returns {Promise} */ async addPolicy (sec, ptype, rule) { - const options = {} + const options = {}; try { - if (this.isSynced) options.session = await this.getTransaction() + if (this.isSynced) options.session = await this.getTransaction(); - const line = this.savePolicyLine(ptype, rule) - await line.save(options) + const line = this.savePolicyLine(ptype, rule); + await line.save(options); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); } catch (err) { - this.autoAbort && options.session && await options.session.abortTransaction() - throw err + this.autoAbort && options.session && await options.session.abortTransaction(); + throw err; } } @@ -415,17 +415,17 @@ class MongooseAdapter { * @returns {Promise} */ async addPolicies (sec, ptype, rules) { - const options = {} - if (this.isSynced) options.session = await this.getTransaction() - else throw new InvalidAdapterTypeError('addPolicies is only supported by SyncedAdapter. See newSyncedAdapter') + const options = {}; + if (this.isSynced) options.session = await this.getTransaction(); + else throw new InvalidAdapterTypeError('addPolicies is only supported by SyncedAdapter. See newSyncedAdapter'); try { - const promises = rules.map(async rule => this.addPolicy(sec, ptype, rule)) - await Promise.all(promises) + const promises = rules.map(async rule => this.addPolicy(sec, ptype, rule)); + await Promise.all(promises); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); } catch (err) { - this.autoAbort && options.session && await options.session.abortTransaction() - throw err + this.autoAbort && options.session && await options.session.abortTransaction(); + throw err; } } @@ -439,18 +439,18 @@ class MongooseAdapter { * @returns {Promise} */ async removePolicy (sec, ptype, rule) { - const options = {} + const options = {}; try { - if (this.isSynced) options.session = await this.getTransaction() + if (this.isSynced) options.session = await this.getTransaction(); - const { p_type, v0, v1, v2, v3, v4, v5 } = this.savePolicyLine(ptype, rule) + const { p_type, v0, v1, v2, v3, v4, v5 } = this.savePolicyLine(ptype, rule); - await CasbinRule.deleteMany({ p_type, v0, v1, v2, v3, v4, v5 }, options) + await CasbinRule.deleteMany({ p_type, v0, v1, v2, v3, v4, v5 }, options); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); } catch (err) { - this.autoAbort && options.session && await options.session.abortTransaction() - throw err + this.autoAbort && options.session && await options.session.abortTransaction(); + throw err; } } @@ -464,18 +464,18 @@ class MongooseAdapter { * @returns {Promise} */ async removePolicies (sec, ptype, rules) { - const options = {} + const options = {}; try { - if (this.isSynced) options.session = await this.getTransaction() - else throw new InvalidAdapterTypeError('removePolicies is only supported by SyncedAdapter. See newSyncedAdapter') + if (this.isSynced) options.session = await this.getTransaction(); + else throw new InvalidAdapterTypeError('removePolicies is only supported by SyncedAdapter. See newSyncedAdapter'); - const promises = rules.map(async rule => this.removePolicy(sec, ptype, rule)) - await Promise.all(promises) + const promises = rules.map(async rule => this.removePolicy(sec, ptype, rule)); + await Promise.all(promises); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); } catch (err) { - this.autoAbort && options.session && await options.session.abortTransaction() - throw err + this.autoAbort && options.session && await options.session.abortTransaction(); + throw err; } } @@ -490,49 +490,49 @@ class MongooseAdapter { * @returns {Promise} */ async removeFilteredPolicy (sec, ptype, fieldIndex, ...fieldValues) { - const options = {} + const options = {}; try { - if (this.isSynced) options.session = await this.getTransaction() - const where = ptype ? { p_type: ptype } : {} + if (this.isSynced) options.session = await this.getTransaction(); + const where = ptype ? { p_type: ptype } : {}; if (fieldIndex <= 0 && fieldIndex + fieldValues.length > 0 && fieldValues[0 - fieldIndex]) { - where.v0 = fieldValues[0 - fieldIndex] + where.v0 = fieldValues[0 - fieldIndex]; } if (fieldIndex <= 1 && fieldIndex + fieldValues.length > 1 && fieldValues[1 - fieldIndex]) { - where.v1 = fieldValues[1 - fieldIndex] + where.v1 = fieldValues[1 - fieldIndex]; } if (fieldIndex <= 2 && fieldIndex + fieldValues.length > 2 && fieldValues[2 - fieldIndex]) { - where.v2 = fieldValues[2 - fieldIndex] + where.v2 = fieldValues[2 - fieldIndex]; } if (fieldIndex <= 3 && fieldIndex + fieldValues.length > 3 && fieldValues[3 - fieldIndex]) { - where.v3 = fieldValues[3 - fieldIndex] + where.v3 = fieldValues[3 - fieldIndex]; } if (fieldIndex <= 4 && fieldIndex + fieldValues.length > 4 && fieldValues[4 - fieldIndex]) { - where.v4 = fieldValues[4 - fieldIndex] + where.v4 = fieldValues[4 - fieldIndex]; } if (fieldIndex <= 5 && fieldIndex + fieldValues.length > 5 && fieldValues[5 - fieldIndex]) { - where.v5 = fieldValues[5 - fieldIndex] + where.v5 = fieldValues[5 - fieldIndex]; } - await CasbinRule.deleteMany(where, options) + await CasbinRule.deleteMany(where, options); - this.autoCommit && options.session && await options.session.commitTransaction() + this.autoCommit && options.session && await options.session.commitTransaction(); } catch (err) { - this.autoAbort && options.session && await options.session.abortTransaction() - throw err + this.autoAbort && options.session && await options.session.abortTransaction(); + throw err; } } async close () { if (this.mongoseInstance && this.mongoseInstance.connection) { - if (this.session) await this.session.endSession() - await this.mongoseInstance.connection.close() + if (this.session) await this.session.endSession(); + await this.mongoseInstance.connection.close(); } } } -module.exports = MongooseAdapter +module.exports = MongooseAdapter; diff --git a/src/errors.js b/src/errors.js index 4be6d59..bde3876 100644 --- a/src/errors.js +++ b/src/errors.js @@ -1,15 +1,15 @@ class AdapterError extends Error { constructor (message) { - super(message) - this.name = 'AdapterError' + super(message); + this.name = 'AdapterError'; } } class InvalidAdapterTypeError extends Error { constructor (message) { - super(message) - this.name = 'InvalidAdapterTypeError' + super(message); + this.name = 'InvalidAdapterTypeError'; } } -module.exports = { AdapterError, InvalidAdapterTypeError } +module.exports = { AdapterError, InvalidAdapterTypeError }; diff --git a/src/model.js b/src/model.js index 8021bc1..fd0654c 100644 --- a/src/model.js +++ b/src/model.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -const { Schema } = require('mongoose') -const mongoose = require('mongoose') +const { Schema } = require('mongoose'); +const mongoose = require('mongoose'); const schema = new Schema({ p_type: { @@ -45,6 +45,6 @@ const schema = new Schema({ type: Schema.Types.String, index: true } -}, { collection: 'casbin_rule', minimize: false, timestamps: false }) +}, { collection: 'casbin_rule', minimize: false, timestamps: false }); -module.exports = mongoose.model('CasbinRule', schema, 'casbin_rule') +module.exports = mongoose.model('CasbinRule', schema, 'casbin_rule'); diff --git a/test/helpers/helpers.js b/test/helpers/helpers.js index 2c5f44d..8a7a185 100644 --- a/test/helpers/helpers.js +++ b/test/helpers/helpers.js @@ -12,34 +12,34 @@ // See the License for the specific language governing permissions and // limitations under the License. -const path = require('path') -const { newEnforcer } = require('casbin') -const MongooseAdapter = require('../../src/adapter') -const basicModel = path.resolve(__dirname, '../fixtures/basic_model.conf') -const basicPolicy = path.resolve(__dirname, '../fixtures/basic_policy.csv') -const rbacModel = path.resolve(__dirname, '../fixtures/rbac_model.conf') -const rbacPolicy = path.resolve(__dirname, '../fixtures/rbac_policy.csv') -const rbacDenyDomainModel = path.resolve(__dirname, '../fixtures/rbac_with_domains_with_deny_model.conf') -const rbacDenyDomainPolicy = path.resolve(__dirname, '../fixtures/rbac_with_domains_with_deny_policy.csv') - -const MONGOOSE_OPTIONS = { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true } +const path = require('path'); +const { newEnforcer } = require('casbin'); +const MongooseAdapter = require('../../src/adapter'); +const basicModel = path.resolve(__dirname, '../fixtures/basic_model.conf'); +const basicPolicy = path.resolve(__dirname, '../fixtures/basic_policy.csv'); +const rbacModel = path.resolve(__dirname, '../fixtures/rbac_model.conf'); +const rbacPolicy = path.resolve(__dirname, '../fixtures/rbac_policy.csv'); +const rbacDenyDomainModel = path.resolve(__dirname, '../fixtures/rbac_with_domains_with_deny_model.conf'); +const rbacDenyDomainPolicy = path.resolve(__dirname, '../fixtures/rbac_with_domains_with_deny_policy.csv'); + +const MONGOOSE_OPTIONS = { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true }; async function createEnforcer () { - const adapter = await MongooseAdapter.newAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS) + const adapter = await MongooseAdapter.newAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS); - return newEnforcer(basicModel, adapter) + return newEnforcer(basicModel, adapter); }; async function createAdapter (useTransaction = false) { - return MongooseAdapter.newAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS, false, useTransaction) + return MongooseAdapter.newAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS, false, useTransaction); }; async function createSyncedAdapter () { - return MongooseAdapter.newSyncedAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS) + return MongooseAdapter.newSyncedAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS); }; async function createDisconnectedAdapter () { - return new MongooseAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS) + return new MongooseAdapter('mongodb://localhost:27017,localhost:27018/casbin?replicaSet=rs0', MONGOOSE_OPTIONS); }; module.exports = { @@ -53,4 +53,4 @@ module.exports = { rbacPolicy, rbacDenyDomainModel, rbacDenyDomainPolicy -} +}; diff --git a/test/integration/adapter.test.js b/test/integration/adapter.test.js index e17e078..9467fee 100644 --- a/test/integration/adapter.test.js +++ b/test/integration/adapter.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -const { assert } = require('chai') -const sinon = require('sinon') +const { assert } = require('chai'); +const sinon = require('sinon'); const { createEnforcer, createAdapter, @@ -25,81 +25,81 @@ const { rbacPolicy, rbacDenyDomainModel, rbacDenyDomainPolicy -} = require('../helpers/helpers') -const { newEnforcer, Model } = require('casbin') -const CasbinRule = require('../../src/model') -const { InvalidAdapterTypeError } = require('../../src/errors') +} = require('../helpers/helpers'); +const { newEnforcer, Model } = require('casbin'); +const CasbinRule = require('../../src/model'); +const { InvalidAdapterTypeError } = require('../../src/errors'); // These tests are just smoke tests for get/set policy rules // We do not need to cover other aspects of casbin, since casbin itself is covered with tests describe('MongooseAdapter', () => { beforeEach(async () => { - await createEnforcer() - await CasbinRule.deleteMany() - }) + await createEnforcer(); + await CasbinRule.deleteMany(); + }); it('Should properly load policy', async () => { - const enforcer = await createEnforcer() - assert.deepEqual(await enforcer.getPolicy(), []) + const enforcer = await createEnforcer(); + assert.deepEqual(await enforcer.getPolicy(), []); - const rules = await CasbinRule.find() - assert.deepEqual(rules, []) - }) + const rules = await CasbinRule.find(); + assert.deepEqual(rules, []); + }); it('Should properly store new policy rules', async () => { - const enforcer = await createEnforcer() + const enforcer = await createEnforcer(); - const rulesBefore = await CasbinRule.find() - assert.deepEqual(rulesBefore, []) - assert.isTrue(await enforcer.addPolicy('sub', 'obj', 'act')) - assert.deepEqual(await enforcer.getPolicy(), [['sub', 'obj', 'act']]) + const rulesBefore = await CasbinRule.find(); + assert.deepEqual(rulesBefore, []); + assert.isTrue(await enforcer.addPolicy('sub', 'obj', 'act')); + assert.deepEqual(await enforcer.getPolicy(), [['sub', 'obj', 'act']]); - const rulesAfter = await CasbinRule.find({ p_type: 'p', v0: 'sub', v1: 'obj', v2: 'act' }) - assert.equal(rulesAfter.length, 1) - }) + const rulesAfter = await CasbinRule.find({ p_type: 'p', v0: 'sub', v1: 'obj', v2: 'act' }); + assert.equal(rulesAfter.length, 1); + }); it('Should properly add and remove policies', async () => { - const a = await createSyncedAdapter() + const a = await createSyncedAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacModel, rbacPolicy) + let e = await newEnforcer(rbacModel, rbacPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(await e.getModel()) - const rulesAfter = await CasbinRule.find({}) + await a.savePolicy(await e.getModel()); + const rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], ['p', 'data2_admin', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) + ['g', 'alice', 'data2_admin', undefined]]); // Add a single policy to Database - await a.addPolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(rbacModel, a) + await a.addPolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], ['data2_admin', 'data2', 'write'], - ['role', 'res', 'action']]) + ['role', 'res', 'action']]); // Add a policyList to Database - await a.addPolicies('', 'p', [['role', 'res', 'GET'], ['role', 'res', 'POST']]) - e = await newEnforcer(rbacModel, a) + await a.addPolicies('', 'p', [['role', 'res', 'GET'], ['role', 'res', 'POST']]); + e = await newEnforcer(rbacModel, a); // Clear the current policy. - await e.clearPolicy() - assert.deepEqual(await e.getPolicy(), []) + await e.clearPolicy(); + assert.deepEqual(await e.getPolicy(), []); // Load the policy from Database. - await a.loadPolicy(e.getModel()) + await a.loadPolicy(e.getModel()); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], @@ -107,143 +107,143 @@ describe('MongooseAdapter', () => { ['data2_admin', 'data2', 'write'], ['role', 'res', 'action'], ['role', 'res', 'GET'], - ['role', 'res', 'POST']]) + ['role', 'res', 'POST']]); // Remove a single policy from Database - await a.removePolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(rbacModel, a) + await a.removePolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], ['data2_admin', 'data2', 'write'], ['role', 'res', 'GET'], - ['role', 'res', 'POST']]) + ['role', 'res', 'POST']]); // Remove a policylist from Database - await a.removePolicies('', 'p', [['role', 'res', 'GET'], ['role', 'res', 'POST']]) - e = await newEnforcer(rbacModel, a) + await a.removePolicies('', 'p', [['role', 'res', 'GET'], ['role', 'res', 'POST']]); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) - }) + ['data2_admin', 'data2', 'write']]); + }); it('Add Policies and Remove Policies should not work on normal adapter', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacModel, rbacPolicy) + let e = await newEnforcer(rbacModel, rbacPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(await e.getModel()) - const rulesAfter = await CasbinRule.find({}) + await a.savePolicy(await e.getModel()); + const rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], ['p', 'data2_admin', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) + ['g', 'alice', 'data2_admin', undefined]]); // Add a single policy to Database - await a.addPolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(rbacModel, a) + await a.addPolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], ['data2_admin', 'data2', 'write'], - ['role', 'res', 'action']]) + ['role', 'res', 'action']]); // Add policyList to Database try { - await a.addPolicies('', 'p', [['role', 'res', 'GET'], ['role', 'res', 'POST']]) + await a.addPolicies('', 'p', [['role', 'res', 'GET'], ['role', 'res', 'POST']]); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert.equal(error.message, 'addPolicies is only supported by SyncedAdapter. See newSyncedAdapter') + assert(error instanceof InvalidAdapterTypeError); + assert.equal(error.message, 'addPolicies is only supported by SyncedAdapter. See newSyncedAdapter'); } - e = await newEnforcer(rbacModel, a) + e = await newEnforcer(rbacModel, a); // Clear the current policy. - await e.clearPolicy() - assert.deepEqual(await e.getPolicy(), []) + await e.clearPolicy(); + assert.deepEqual(await e.getPolicy(), []); // Load the policy from Database. - await a.loadPolicy(e.getModel()) + await a.loadPolicy(e.getModel()); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], ['data2_admin', 'data2', 'write'], - ['role', 'res', 'action']]) + ['role', 'res', 'action']]); // Remove a single policy from Database - await a.removePolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(rbacModel, a) + await a.removePolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) + ['data2_admin', 'data2', 'write']]); // Remove a policylist from Database try { - await a.removePolicies('', 'p', [['data2_admin', 'datag1712', 'read'], ['data2_admin', 'data2', 'write']]) + await a.removePolicies('', 'p', [['data2_admin', 'datag1712', 'read'], ['data2_admin', 'data2', 'write']]); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert.equal(error.message, 'removePolicies is only supported by SyncedAdapter. See newSyncedAdapter') + assert(error instanceof InvalidAdapterTypeError); + assert.equal(error.message, 'removePolicies is only supported by SyncedAdapter. See newSyncedAdapter'); } - e = await newEnforcer(rbacModel, a) + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) - }) + ['data2_admin', 'data2', 'write']]); + }); it('Should properly store new policy rules from a file', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacModel, rbacPolicy) + let e = await newEnforcer(rbacModel, rbacPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(await e.getModel()) - const rulesAfter = await CasbinRule.find({}) + await a.savePolicy(await e.getModel()); + const rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], ['p', 'data2_admin', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) + ['g', 'alice', 'data2_admin', undefined]]); // Clear the current policy. - await e.clearPolicy() - assert.deepEqual(await e.getPolicy(), []) + await e.clearPolicy(); + assert.deepEqual(await e.getPolicy(), []); // Load the policy from DB. - await a.loadPolicy(e.getModel()) + await a.loadPolicy(e.getModel()); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) + ['data2_admin', 'data2', 'write']]); // Note: you don't need to look at the above code // if you already have a working DB with policy inside. @@ -251,61 +251,61 @@ describe('MongooseAdapter', () => { // Now the DB has policy, so we can provide a normal use case. // Create an adapter and an enforcer. // newEnforcer() will load the policy automatically. - e = await newEnforcer(rbacModel, a) + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) + ['data2_admin', 'data2', 'write']]); // Add policy to DB - await a.addPolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(rbacModel, a) + await a.addPolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], ['data2_admin', 'data2', 'write'], - ['role', 'res', 'action']]) + ['role', 'res', 'action']]); // Remove policy from DB - await a.removePolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(rbacModel, a) + await a.removePolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) - }) + ['data2_admin', 'data2', 'write']]); + }); it('Empty Role Definition should not raise an error', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(basicModel, basicPolicy) + let e = await newEnforcer(basicModel, basicPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(e.getModel()) - const rulesAfter = await CasbinRule.find({}) + await a.savePolicy(e.getModel()); + const rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'] - ]) + ]); // Clear the current policy. - e.clearPolicy() - assert.deepEqual(await e.getPolicy(), []) + e.clearPolicy(); + assert.deepEqual(await e.getPolicy(), []); // Load the policy from DB. - await a.loadPolicy(e.getModel()) + await a.loadPolicy(e.getModel()); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'] - ]) + ]); // Note: you don't need to look at the above code // if you already have a working DB with policy inside. @@ -313,256 +313,256 @@ describe('MongooseAdapter', () => { // Now the DB has policy, so we can provide a normal use case. // Create an adapter and an enforcer. // newEnforcer() will load the policy automatically. - e = await newEnforcer(basicModel, a) + e = await newEnforcer(basicModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'] - ]) + ]); // Add policy to DB - await a.addPolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(basicModel, a) + await a.addPolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(basicModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'], - ['role', 'res', 'action']]) + ['role', 'res', 'action']]); // Remove policy from DB - await a.removePolicy('', 'p', ['role', 'res', 'action']) - e = await newEnforcer(basicModel, a) + await a.removePolicy('', 'p', ['role', 'res', 'action']); + e = await newEnforcer(basicModel, a); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], ['bob', 'data2', 'write'] - ]) - }) + ]); + }); it('Empty Policy return false and log an error', async () => { - const a = await createAdapter() - console.error = sinon.stub() - assert.isNotOk(await a.savePolicy(new Model())) - assert(console.error.lastCall.firstArg.name, 'MongoError') - assert(console.error.callCount, 1) - if (console.error.restore) console.error.restore() - }) + const a = await createAdapter(); + console.error = sinon.stub(); + assert.isNotOk(await a.savePolicy(new Model())); + assert(console.error.lastCall.firstArg.name, 'MongoError'); + assert(console.error.callCount, 1); + if (console.error.restore) console.error.restore(); + }); it('Should not store new policy rules if one of them fails', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - const e = await newEnforcer(rbacModel, rbacPolicy) - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const e = await newEnforcer(rbacModel, rbacPolicy); + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - e.getModel().model.set('g', {}) + e.getModel().model.set('g', {}); try { - await a.savePolicy(e.getModel()) + await a.savePolicy(e.getModel()); } catch (err) { if (err instanceof TypeError) { - const rulesAfter = await CasbinRule.find({}) - assert.equal(rulesAfter.length, 0) + const rulesAfter = await CasbinRule.find({}); + assert.equal(rulesAfter.length, 0); } else { - throw err + throw err; } } - }) + }); it('Should properly fail when transaction is set to true', async () => { try { - await createAdapter(true) + await createAdapter(true); } catch (error) { - assert.equal(error, 'Error: Tried to enable transactions for non-replicaset connection') + assert.equal(error, 'Error: Tried to enable transactions for non-replicaset connection'); } - }) + }); it('Should properly delete existing policy rules', async () => { - const enforcer = await createEnforcer() + const enforcer = await createEnforcer(); - const rulesBefore = await CasbinRule.find() - assert.deepEqual(rulesBefore, []) - assert.isTrue(await enforcer.addPolicy('sub', 'obj', 'act')) - assert.deepEqual(await enforcer.getPolicy(), [['sub', 'obj', 'act']]) + const rulesBefore = await CasbinRule.find(); + assert.deepEqual(rulesBefore, []); + assert.isTrue(await enforcer.addPolicy('sub', 'obj', 'act')); + assert.deepEqual(await enforcer.getPolicy(), [['sub', 'obj', 'act']]); - const rulesAfter = await CasbinRule.find({ p_type: 'p', v0: 'sub', v1: 'obj', v2: 'act' }) - assert.equal(rulesAfter.length, 1) - assert.isTrue(await enforcer.removePolicy('sub', 'obj', 'act')) - assert.deepEqual(await enforcer.getPolicy(), []) + const rulesAfter = await CasbinRule.find({ p_type: 'p', v0: 'sub', v1: 'obj', v2: 'act' }); + assert.equal(rulesAfter.length, 1); + assert.isTrue(await enforcer.removePolicy('sub', 'obj', 'act')); + assert.deepEqual(await enforcer.getPolicy(), []); - const rulesAfterDelete = await CasbinRule.find({ p_type: 'p', v0: 'sub', v1: 'obj', v2: 'act' }) - assert.equal(rulesAfterDelete.length, 0) - }) + const rulesAfterDelete = await CasbinRule.find({ p_type: 'p', v0: 'sub', v1: 'obj', v2: 'act' }); + assert.equal(rulesAfterDelete.length, 0); + }); it('Should remove related policy rules via a filter', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacModel, rbacPolicy) + let e = await newEnforcer(rbacModel, rbacPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(e.getModel()) - let rulesAfter = await CasbinRule.find({}) + await a.savePolicy(e.getModel()); + let rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], ['p', 'data2_admin', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) + ['g', 'alice', 'data2_admin', undefined]]); // Remove 'data2_admin' related policy rules via a filter. // Two rules: {'data2_admin', 'data2', 'read'}, {'data2_admin', 'data2', 'write'} are deleted. - await a.removeFilteredPolicy(undefined, undefined, 0, 'data2_admin') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 0, 'data2_admin'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) - e = await newEnforcer(rbacModel, a) - assert.deepEqual(await e.getPolicy(), [['alice', 'data1', 'read'], ['bob', 'data2', 'write']]) + ['g', 'alice', 'data2_admin', undefined]]); + e = await newEnforcer(rbacModel, a); + assert.deepEqual(await e.getPolicy(), [['alice', 'data1', 'read'], ['bob', 'data2', 'write']]); // Remove 'data1' related policy rules via a filter. // One rule: {'alice', 'data1', 'read'} is deleted. - await a.removeFilteredPolicy(undefined, undefined, 1, 'data1') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 1, 'data1'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'bob', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) - e = await newEnforcer(rbacModel, a) - assert.deepEqual(await e.getPolicy(), [['bob', 'data2', 'write']]) + ['g', 'alice', 'data2_admin', undefined]]); + e = await newEnforcer(rbacModel, a); + assert.deepEqual(await e.getPolicy(), [['bob', 'data2', 'write']]); // Remove 'write' related policy rules via a filter. // One rule: {'bob', 'data2', 'write'} is deleted. - await a.removeFilteredPolicy(undefined, undefined, 2, 'write') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 2, 'write'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ - ['g', 'alice', 'data2_admin', undefined]]) - e = await newEnforcer(rbacModel, a) - assert.deepEqual(await e.getPolicy(), []) - }) + ['g', 'alice', 'data2_admin', undefined]]); + e = await newEnforcer(rbacModel, a); + assert.deepEqual(await e.getPolicy(), []); + }); it('Should remove user\'s policies and groups when using deleteUser', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacModel, rbacPolicy) + let e = await newEnforcer(rbacModel, rbacPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(e.getModel()) - let rulesAfter = await CasbinRule.find({}) + await a.savePolicy(e.getModel()); + let rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], ['p', 'data2_admin', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) + ['g', 'alice', 'data2_admin', undefined]]); - e = await newEnforcer(rbacModel, a) + e = await newEnforcer(rbacModel, a); // Remove 'alice' related policy rules via a RBAC deleteUser-function. // One policy: {'alice', 'data2', 'read'} and One Grouping Policy {'alice', 'data2_admin'} are deleted. - await e.deleteUser('alice') - rulesAfter = await CasbinRule.find({}) + await e.deleteUser('alice'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], - ['p', 'data2_admin', 'data2', 'write']]) - e = await newEnforcer(rbacModel, a) + ['p', 'data2_admin', 'data2', 'write']]); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['bob', 'data2', 'write'], ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) + ['data2_admin', 'data2', 'write']]); // Remove 'data1' related policy rules via a filter. // One rule: {'bob', 'data2', 'write'} is deleted. - await e.deleteUser('bob') - rulesAfter = await CasbinRule.find({}) + await e.deleteUser('bob'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'data2_admin', 'data2', 'read'], - ['p', 'data2_admin', 'data2', 'write']]) - e = await newEnforcer(rbacModel, a) + ['p', 'data2_admin', 'data2', 'write']]); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['data2_admin', 'data2', 'read'], - ['data2_admin', 'data2', 'write']]) - }) + ['data2_admin', 'data2', 'write']]); + }); it('Should remove user\'s policies and groups when using deleteRole', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacModel, rbacPolicy) + let e = await newEnforcer(rbacModel, rbacPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(e.getModel()) - let rulesAfter = await CasbinRule.find({}) + await a.savePolicy(e.getModel()); + let rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], ['p', 'bob', 'data2', 'write'], ['p', 'data2_admin', 'data2', 'read'], ['p', 'data2_admin', 'data2', 'write'], - ['g', 'alice', 'data2_admin', undefined]]) + ['g', 'alice', 'data2_admin', undefined]]); - e = await newEnforcer(rbacModel, a) + e = await newEnforcer(rbacModel, a); // Remove 'data2_admin' related policy rules via a RBAC deleteRole-function. // One policy: {'alice', 'data2', 'read'} and One Grouping Policy {'alice', 'data2_admin'} are deleted. - await e.deleteRole('data2_admin') - rulesAfter = await CasbinRule.find({}) + await e.deleteRole('data2_admin'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2]), [ ['p', 'alice', 'data1', 'read'], - ['p', 'bob', 'data2', 'write']]) + ['p', 'bob', 'data2', 'write']]); assert.deepEqual(await e.getPolicy(), [ ['alice', 'data1', 'read'], - ['bob', 'data2', 'write']]) - }) + ['bob', 'data2', 'write']]); + }); it('Should properly store new complex policy rules from a file', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy) + let e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(await e.getModel()) - const rulesAfter = await CasbinRule.find({}) + await a.savePolicy(await e.getModel()); + const rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ ['p', 'admin', 'domain1', 'data1', 'read', 'allow'], ['p', 'admin', 'domain1', 'data1', 'write', 'allow'], ['p', 'admin', 'domain2', 'data2', 'read', 'allow'], ['p', 'admin', 'domain2', 'data2', 'write', 'allow'], ['p', 'alice', 'domain2', 'data2', 'write', 'deny'], - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); // Clear the current policy. - await e.clearPolicy() - assert.deepEqual(await e.getPolicy(), []) + await e.clearPolicy(); + assert.deepEqual(await e.getPolicy(), []); // Load the policy from DB. - await a.loadPolicy(e.getModel()) + await a.loadPolicy(e.getModel()); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'read', 'allow'], ['admin', 'domain1', 'data1', 'write', 'allow'], ['admin', 'domain2', 'data2', 'read', 'allow'], ['admin', 'domain2', 'data2', 'write', 'allow'], - ['alice', 'domain2', 'data2', 'write', 'deny']]) + ['alice', 'domain2', 'data2', 'write', 'deny']]); // Note: you don't need to look at the above code // if you already have a working DB with policy inside. @@ -570,70 +570,70 @@ describe('MongooseAdapter', () => { // Now the DB has policy, so we can provide a normal use case. // Create an adapter and an enforcer. // newEnforcer() will load the policy automatically. - e = await newEnforcer(rbacDenyDomainModel, a) + e = await newEnforcer(rbacDenyDomainModel, a); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'read', 'allow'], ['admin', 'domain1', 'data1', 'write', 'allow'], ['admin', 'domain2', 'data2', 'read', 'allow'], ['admin', 'domain2', 'data2', 'write', 'allow'], - ['alice', 'domain2', 'data2', 'write', 'deny']]) + ['alice', 'domain2', 'data2', 'write', 'deny']]); // Add policy to DB - await a.addPolicy('', 'p', ['role', 'domain', 'res', 'action', 'allow']) - e = await newEnforcer(rbacDenyDomainModel, a) + await a.addPolicy('', 'p', ['role', 'domain', 'res', 'action', 'allow']); + e = await newEnforcer(rbacDenyDomainModel, a); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'read', 'allow'], ['admin', 'domain1', 'data1', 'write', 'allow'], ['admin', 'domain2', 'data2', 'read', 'allow'], ['admin', 'domain2', 'data2', 'write', 'allow'], ['alice', 'domain2', 'data2', 'write', 'deny'], - ['role', 'domain', 'res', 'action', 'allow']]) + ['role', 'domain', 'res', 'action', 'allow']]); // Remove policy from DB - await a.removePolicy('', 'p', ['role', 'domain', 'res', 'action', 'allow']) - e = await newEnforcer(rbacDenyDomainModel, a) + await a.removePolicy('', 'p', ['role', 'domain', 'res', 'action', 'allow']); + e = await newEnforcer(rbacDenyDomainModel, a); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'read', 'allow'], ['admin', 'domain1', 'data1', 'write', 'allow'], ['admin', 'domain2', 'data2', 'read', 'allow'], ['admin', 'domain2', 'data2', 'write', 'allow'], - ['alice', 'domain2', 'data2', 'write', 'deny']]) + ['alice', 'domain2', 'data2', 'write', 'deny']]); // Enforce a rule - assert.notOk(await e.enforce('alice', 'domain2', 'data2', 'write')) - assert.ok(await e.enforce('admin', 'domain2', 'data2', 'write')) - assert.ok(await e.enforce('admin', 'domain2', 'data2', 'write')) - assert.ok(await e.enforce('admin', 'domain2', 'data2', 'read')) - assert.ok(await e.enforce('alice', 'domain2', 'data2', 'read')) - assert.notOk(await e.enforce('alice', 'domain1', 'data1', 'read')) - assert.notOk(await e.enforce('alice', 'domain1', 'data1', 'write')) - }) + assert.notOk(await e.enforce('alice', 'domain2', 'data2', 'write')); + assert.ok(await e.enforce('admin', 'domain2', 'data2', 'write')); + assert.ok(await e.enforce('admin', 'domain2', 'data2', 'write')); + assert.ok(await e.enforce('admin', 'domain2', 'data2', 'read')); + assert.ok(await e.enforce('alice', 'domain2', 'data2', 'read')); + assert.notOk(await e.enforce('alice', 'domain1', 'data1', 'read')); + assert.notOk(await e.enforce('alice', 'domain1', 'data1', 'write')); + }); it('Should remove related complex policy rules via a filter', async () => { - const a = await createAdapter() + const a = await createAdapter(); // Because the DB is empty at first, // so we need to load the policy from the file adapter (.CSV) first. - let e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy) + let e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy); - const rulesBefore = await CasbinRule.find({}) - assert.equal(rulesBefore.length, 0) + const rulesBefore = await CasbinRule.find({}); + assert.equal(rulesBefore.length, 0); // This is a trick to save the current policy to the DB. // We can't call e.savePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Node-Casbin enforcer (aka in memory). - await a.savePolicy(e.getModel()) - let rulesAfter = await CasbinRule.find({}) + await a.savePolicy(e.getModel()); + let rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ ['p', 'admin', 'domain1', 'data1', 'read', 'allow'], ['p', 'admin', 'domain1', 'data1', 'write', 'allow'], ['p', 'admin', 'domain2', 'data2', 'read', 'allow'], ['p', 'admin', 'domain2', 'data2', 'write', 'allow'], ['p', 'alice', 'domain2', 'data2', 'write', 'deny'], - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) - e = await newEnforcer(rbacDenyDomainModel, a) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); + e = await newEnforcer(rbacDenyDomainModel, a); assert.deepEqual(await e.getPolicy(), [['admin', 'domain1', 'data1', 'read', 'allow'], ['admin', 'domain1', 'data1', 'write', 'allow'], ['admin', 'domain2', 'data2', 'read', 'allow'], ['admin', 'domain2', 'data2', 'write', 'allow'], - ['alice', 'domain2', 'data2', 'write', 'deny']]) + ['alice', 'domain2', 'data2', 'write', 'deny']]); // Remove 'data2_admin' related policy rules via a filter. // Four rules: @@ -642,166 +642,166 @@ describe('MongooseAdapter', () => { // {'admin', 'domain2', 'data2', 'read', 'allow'}, // {'admin', 'domain2', 'data2', 'write', 'allow'} // are deleted. - await a.removeFilteredPolicy(undefined, undefined, 0, 'admin') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 0, 'admin'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ ['p', 'alice', 'domain2', 'data2', 'write', 'deny'], - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) - e = await newEnforcer(rbacDenyDomainModel, a) - assert.deepEqual(await e.getPolicy(), [['alice', 'domain2', 'data2', 'write', 'deny']]) - await a.removeFilteredPolicy(undefined, 'g') - rulesAfter = await CasbinRule.find({}) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); + e = await newEnforcer(rbacDenyDomainModel, a); + assert.deepEqual(await e.getPolicy(), [['alice', 'domain2', 'data2', 'write', 'deny']]); + await a.removeFilteredPolicy(undefined, 'g'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ - ['p', 'alice', 'domain2', 'data2', 'write', 'deny']]) - await a.removeFilteredPolicy(undefined, 'p') - rulesAfter = await CasbinRule.find({}) - assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), []) + ['p', 'alice', 'domain2', 'data2', 'write', 'deny']]); + await a.removeFilteredPolicy(undefined, 'p'); + rulesAfter = await CasbinRule.find({}); + assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), []); // Reload the mode + policy - e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy) - await a.savePolicy(e.getModel()) + e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy); + await a.savePolicy(e.getModel()); // Remove 'domain2' related policy rules via a filter. // Three rules: // {'p', 'admin', 'domain2', 'data2', 'read', 'allow'}, // {'p', 'admin', 'domain2', 'data2', 'write', 'allow'}, // {'p', 'alice', 'domain2', 'data2', 'write', 'deny'} // are deleted. - await a.removeFilteredPolicy(undefined, undefined, 1, 'domain2') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 1, 'domain2'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ ['p', 'admin', 'domain1', 'data1', 'read', 'allow'], ['p', 'admin', 'domain1', 'data1', 'write', 'allow'], - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) - e = await newEnforcer(rbacModel, a) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); + e = await newEnforcer(rbacModel, a); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'read', 'allow'], - ['admin', 'domain1', 'data1', 'write', 'allow']]) + ['admin', 'domain1', 'data1', 'write', 'allow']]); // Remove 'data1' related policy rules via a filter. // Two rules: // {'admin', 'domain1', 'data1', 'read', 'allow'}, // {'admin', 'domain1', 'data1', 'write', 'allow'} // are deleted. - await a.removeFilteredPolicy(undefined, undefined, 2, 'data1') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 2, 'data1'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) - e = await newEnforcer(rbacDenyDomainModel, a) - assert.deepEqual(await e.getPolicy(), []) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); + e = await newEnforcer(rbacDenyDomainModel, a); + assert.deepEqual(await e.getPolicy(), []); - await a.removeFilteredPolicy(undefined, 'g') - await a.removeFilteredPolicy(undefined, 'p') - rulesAfter = await CasbinRule.find({}) - assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), []) + await a.removeFilteredPolicy(undefined, 'g'); + await a.removeFilteredPolicy(undefined, 'p'); + rulesAfter = await CasbinRule.find({}); + assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), []); - e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy) - await a.savePolicy(e.getModel()) + e = await newEnforcer(rbacDenyDomainModel, rbacDenyDomainPolicy); + await a.savePolicy(e.getModel()); // Remove 'read' related policy rules via a filter. // Two rules: // {'admin', 'domain1', 'data1', 'read', 'allow'}, // {'admin', 'domain2', 'data2', 'read', 'allow'} // are deleted. - await a.removeFilteredPolicy(undefined, undefined, 3, 'read') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 3, 'read'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ ['p', 'admin', 'domain1', 'data1', 'write', 'allow'], ['p', 'admin', 'domain2', 'data2', 'write', 'allow'], ['p', 'alice', 'domain2', 'data2', 'write', 'deny'], - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) - e = await newEnforcer(rbacDenyDomainModel, a) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); + e = await newEnforcer(rbacDenyDomainModel, a); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'write', 'allow'], ['admin', 'domain2', 'data2', 'write', 'allow'], - ['alice', 'domain2', 'data2', 'write', 'deny']]) + ['alice', 'domain2', 'data2', 'write', 'deny']]); // Remove 'read' related policy rules via a filter. // One rule: // {'alice', 'domain2', 'data2', 'write', 'deny'}, // is deleted. - await a.removeFilteredPolicy(undefined, undefined, 4, 'deny') - rulesAfter = await CasbinRule.find({}) + await a.removeFilteredPolicy(undefined, undefined, 4, 'deny'); + rulesAfter = await CasbinRule.find({}); assert.deepEqual(rulesAfter.map(rule => [rule.p_type, rule.v0, rule.v1, rule.v2, rule.v3, rule.v4]), [ ['p', 'admin', 'domain1', 'data1', 'write', 'allow'], ['p', 'admin', 'domain2', 'data2', 'write', 'allow'], - ['g', 'alice', 'admin', 'domain2', undefined, undefined]]) - e = await newEnforcer(rbacDenyDomainModel, a) + ['g', 'alice', 'admin', 'domain2', undefined, undefined]]); + e = await newEnforcer(rbacDenyDomainModel, a); assert.deepEqual(await e.getPolicy(), [ ['admin', 'domain1', 'data1', 'write', 'allow'], - ['admin', 'domain2', 'data2', 'write', 'allow']]) - }) + ['admin', 'domain2', 'data2', 'write', 'allow']]); + }); it('SetSynced should fail in non-replicaset connection', async () => { // Create SyncedMongoAdapter try { - const adapter = await createAdapter() - adapter.setSynced(true) + const adapter = await createAdapter(); + adapter.setSynced(true); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert.equal(error.message, 'Tried to enable transactions for non-replicaset connection') + assert(error instanceof InvalidAdapterTypeError); + assert.equal(error.message, 'Tried to enable transactions for non-replicaset connection'); } - }) + }); it('getSession should fail in non-replicaset connection', async () => { // Create SyncedMongoAdapter try { - const adapter = await createAdapter() - adapter.getSession() + const adapter = await createAdapter(); + adapter.getSession(); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert.equal(error.message, 'Tried to start a session for non-replicaset connection') + assert(error instanceof InvalidAdapterTypeError); + assert.equal(error.message, 'Tried to start a session for non-replicaset connection'); } - }) + }); it('getTransaction should fail in non-replicaset connection', async () => { // Create SyncedMongoAdapter try { - const adapter = await createAdapter() - adapter.getTransaction() + const adapter = await createAdapter(); + adapter.getTransaction(); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert.equal(error.message, 'Tried to start a session for non-replicaset connection') + assert(error instanceof InvalidAdapterTypeError); + assert.equal(error.message, 'Tried to start a session for non-replicaset connection'); } - }) + }); it('commitTransaction should fail in non-replicaset connection', async () => { // Create SyncedMongoAdapter try { - const adapter = await createAdapter() - adapter.commitTransaction() + const adapter = await createAdapter(); + adapter.commitTransaction(); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert.equal(error.message, 'Tried to start a session for non-replicaset connection') + assert(error instanceof InvalidAdapterTypeError); + assert.equal(error.message, 'Tried to start a session for non-replicaset connection'); } - }) + }); it('abortTransaction should fail in non-replicaset connection', async () => { // Create SyncedMongoAdapter try { - const adapter = await createAdapter() - adapter.abortTransaction() + const adapter = await createAdapter(); + adapter.abortTransaction(); } catch (error) { - assert(error instanceof InvalidAdapterTypeError) - assert(error.message, 'Tried to start a session for non-replicaset connection') + assert(error instanceof InvalidAdapterTypeError); + assert(error.message, 'Tried to start a session for non-replicaset connection'); } - }) + }); it('Should allow you to close the connection', async () => { // Create mongoAdapter - const enforcer = await createEnforcer() - const adapter = enforcer.getAdapter() - assert.equal(adapter.mongoseInstance.connection.readyState, 1, 'Connection should be open') + const enforcer = await createEnforcer(); + const adapter = enforcer.getAdapter(); + assert.equal(adapter.mongoseInstance.connection.readyState, 1, 'Connection should be open'); // Connection should close - await adapter.close() - assert.equal(adapter.mongoseInstance.connection.readyState, 0, 'Connection should be closed') - }) + await adapter.close(); + assert.equal(adapter.mongoseInstance.connection.readyState, 0, 'Connection should be closed'); + }); it('Closing a closed/undefined connection should not raise an error', async () => { // Create mongoAdapter - const adapter = await createDisconnectedAdapter() + const adapter = await createDisconnectedAdapter(); // Closing a closed connection should not raise an error - await adapter.close() - assert.equal(adapter.mongoseInstance, undefined, 'mongoseInstance should be undefined') - }) -}) + await adapter.close(); + assert.equal(adapter.mongoseInstance, undefined, 'mongoseInstance should be undefined'); + }); +}); diff --git a/test/unit/adapter.test.js b/test/unit/adapter.test.js index df1d0d4..2f95ad9 100644 --- a/test/unit/adapter.test.js +++ b/test/unit/adapter.test.js @@ -12,62 +12,62 @@ // See the License for the specific language governing permissions and // limitations under the License. -const { assert } = require('chai') -const MongooseAdapter = require('../..') +const { assert } = require('chai'); +const MongooseAdapter = require('../..'); -const MONGOOSE_OPTIONS = { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true } +const MONGOOSE_OPTIONS = { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true }; describe('MongooseAdapter', () => { it('Should properly throw error if Mongo URI is not provided', async () => { - assert.throws(() => new MongooseAdapter(), 'You must provide Mongo URI to connect to!') - }) + assert.throws(() => new MongooseAdapter(), 'You must provide Mongo URI to connect to!'); + }); it('Should properly instantiate adapter', async () => { - const adapter = new MongooseAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS) + const adapter = new MongooseAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS); - assert.instanceOf(adapter, MongooseAdapter) - assert.isFalse(adapter.isFiltered) - }) + assert.instanceOf(adapter, MongooseAdapter); + assert.isFalse(adapter.isFiltered); + }); it('Should properly create new instance via static newAdapter', async () => { - const adapter = await MongooseAdapter.newAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS) + const adapter = await MongooseAdapter.newAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS); - assert.instanceOf(adapter, MongooseAdapter) - assert.isFalse(adapter.isFiltered) - }) + assert.instanceOf(adapter, MongooseAdapter); + assert.isFalse(adapter.isFiltered); + }); it('Should properly create filtered instance via static newFilteredAdapter', async () => { - const adapter = await MongooseAdapter.newFilteredAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS) + const adapter = await MongooseAdapter.newFilteredAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS); - assert.instanceOf(adapter, MongooseAdapter) - assert.isTrue(adapter.isFiltered) - }) + assert.instanceOf(adapter, MongooseAdapter); + assert.isTrue(adapter.isFiltered); + }); it('Should have implemented interface for casbin', async () => { - const adapter = new MongooseAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS) + const adapter = new MongooseAdapter('mongodb://localhost:27017/casbin', MONGOOSE_OPTIONS); - assert.isFunction(MongooseAdapter.newAdapter) - assert.isFunction(MongooseAdapter.newFilteredAdapter) - assert.isFunction(MongooseAdapter.newSyncedAdapter) - assert.isFunction(adapter._open) - assert.isFunction(adapter.close) - assert.isFunction(adapter.getSession) - assert.isFunction(adapter.getTransaction) - assert.isFunction(adapter.commitTransaction) - assert.isFunction(adapter.abortTransaction) - assert.isFunction(adapter.abortTransaction) - assert.isFunction(adapter.loadPolicyLine) - assert.isFunction(adapter.loadPolicy) - assert.isFunction(adapter.loadFilteredPolicy) - assert.isFunction(adapter.setFiltered) - assert.isFunction(adapter.setSynced) - assert.isBoolean(adapter.isFiltered) - assert.isBoolean(adapter.isFiltered) - assert.isBoolean(adapter.isSynced) - assert.isFunction(adapter.savePolicyLine) - assert.isFunction(adapter.savePolicy) - assert.isFunction(adapter.addPolicy) - assert.isFunction(adapter.removePolicy) - assert.isFunction(adapter.removeFilteredPolicy) - }) -}) + assert.isFunction(MongooseAdapter.newAdapter); + assert.isFunction(MongooseAdapter.newFilteredAdapter); + assert.isFunction(MongooseAdapter.newSyncedAdapter); + assert.isFunction(adapter._open); + assert.isFunction(adapter.close); + assert.isFunction(adapter.getSession); + assert.isFunction(adapter.getTransaction); + assert.isFunction(adapter.commitTransaction); + assert.isFunction(adapter.abortTransaction); + assert.isFunction(adapter.abortTransaction); + assert.isFunction(adapter.loadPolicyLine); + assert.isFunction(adapter.loadPolicy); + assert.isFunction(adapter.loadFilteredPolicy); + assert.isFunction(adapter.setFiltered); + assert.isFunction(adapter.setSynced); + assert.isBoolean(adapter.isFiltered); + assert.isBoolean(adapter.isFiltered); + assert.isBoolean(adapter.isSynced); + assert.isFunction(adapter.savePolicyLine); + assert.isFunction(adapter.savePolicy); + assert.isFunction(adapter.addPolicy); + assert.isFunction(adapter.removePolicy); + assert.isFunction(adapter.removeFilteredPolicy); + }); +});