From 374eb2e900bd24a841d8d52e7a1a786f3c17cfea Mon Sep 17 00:00:00 2001 From: kostyan Date: Sat, 6 May 2017 22:46:34 +0300 Subject: [PATCH 1/2] Add default options for 'owner' rule --- README.md | 12 ++++++++--- src/index.js | 2 +- src/rule-checker/rules/owner.js | 5 +++-- test/integration/rules.test.js | 2 +- test/unit/owner.test.js | 38 ++++++++++++++++++++++++++++++++- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 66f2336..a5559e9 100644 --- a/README.md +++ b/README.md @@ -80,11 +80,17 @@ app.configure(acl(config, { mongooseConnection: db })); Then in config declare: ``` -allow: { owner: { where: { _id: '{params.id}', model: 'posts', ownerField: 'author' } } } +allow: { + owner: { + where: { _id: '{params.id}' }, + model: 'posts', + ownerField: 'author' + } +} ``` -`where` - how to find needed document. Set in {} path to needed values in `req` object. -`model` - mongoose model. +`where` - how to find needed document. Set in {} path to needed values in `req` object. Default is `{ _id: '{params.id}' }`. +`model` - mongoose model. By default can be got from route url. For example `posts` on `/posts`. `ownerField` - where you store user id? It gets user's id from `req.payload.userId`. diff --git a/src/index.js b/src/index.js index c0410ca..37c346d 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,8 @@ const denyNotAllowed = require('./deny-not-allowed'); module.exports = (configs, options = {}) => function () { const app = this; - const check = ruleChecker(options); + if (options.jwt) app.use(jwtDecode(options.jwt)); _.forEach(configs, ({ url, method, allow }) => { diff --git a/src/rule-checker/rules/owner.js b/src/rule-checker/rules/owner.js index 1f04fbb..81b8ba9 100644 --- a/src/rule-checker/rules/owner.js +++ b/src/rule-checker/rules/owner.js @@ -8,8 +8,9 @@ module.exports = (mongooseConnection) => (payload, allow, req) => { if (!mongooseConnection) return reject(httpError(500, 'No mongoose connection.')); const userId = _.get(payload, 'userId'); - const model = _.get(allow, 'owner.model'); - const where = buildWhere(_.get(allow, 'owner.where'), req); + const model = _.get(allow, 'owner.model') || _(req.url).split('/').get('[1]'); + const whereTemplate = _.get(allow, 'owner.where') || { _id: '{params.id}' }; + const where = buildWhere(whereTemplate, req); const ownerField = _.get(allow, 'owner.ownerField'); if (!userId) return reject(httpError(403, 'No user id.')); diff --git a/test/integration/rules.test.js b/test/integration/rules.test.js index 8678904..ed69574 100644 --- a/test/integration/rules.test.js +++ b/test/integration/rules.test.js @@ -6,7 +6,7 @@ const config = [{ }, { url: '/posts/:id', method: 'GET', allow: { - owner: { where: { _id: '{params.id}' }, model: 'posts', ownerField: 'userId' }, + owner: { where: { _id: '{params.id}' }, ownerField: 'userId' }, roles: ['admin'] } }]; diff --git a/test/unit/owner.test.js b/test/unit/owner.test.js index 332ff3d..8226ce5 100644 --- a/test/unit/owner.test.js +++ b/test/unit/owner.test.js @@ -10,7 +10,7 @@ const schema = new mongoose.Schema({ userId: Number, usersIds: [Number] }); const Post = db.model('posts', schema); const fn = ownerRule(db); -test('should be resolved for owner', async (t) => { +test('should be resolved for owner with all options', async (t) => { const userId = 1; const post = await Post.create({ userId }); const payload = { userId }; @@ -21,6 +21,28 @@ test('should be resolved for owner', async (t) => { t.truthy(res); }); +test('should be resolved for owner with model from url', async (t) => { + const userId = 1; + const post = await Post.create({ userId }); + const payload = { userId }; + const req = { params: { id: post._id }, url: '/posts' }; + const allow = { owner: { where: { _id: '{params.id}' }, ownerField: 'userId' } }; + + const res = await fn(payload, allow, req); + t.truthy(res); +}); + +test('should be resolved for owner with default where', async (t) => { + const userId = 1; + const post = await Post.create({ userId }); + const payload = { userId }; + const req = { params: { id: post._id } }; + const allow = { owner: { ownerField: 'userId', model: 'posts' } }; + + const res = await fn(payload, allow, req); + t.truthy(res); +}); + test('should be resolved for one of many owners', async (t) => { const userId = 1; const post = await Post.create({ usersIds: [userId, 2, 3] }); @@ -94,6 +116,20 @@ test('should be 500 for wrong where', async (t) => { } }); +test('should be error for wrong model', async (t) => { + const post = await Post.create({ userId: 1 }); + const req = { params: { id: post._id } }; + const payload = { userId: 2 }; + const allow = { owner: { where: { _id: '{params.id}' }, ownerField: 'userId' } }; + + try { + const res = await fn(payload, allow, req); + t.falsy(res); + } catch (err) { + t.truthy(err); + } +}); + test('should be 500 if no mongoose connection', async (t) => { const userId = 1; const post = await Post.create({ usersIds: [userId, 2, 3] }); From eb82143daa5ee45d795a107e005429766f512a5c Mon Sep 17 00:00:00 2001 From: kostyan Date: Sat, 6 May 2017 22:50:02 +0300 Subject: [PATCH 2/2] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0fee963..e276d91 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "feathers-acl", - "version": "0.6.0", + "version": "0.7.0", "description": "Declarative ACL for FeathersJS and Express apps", "main": "dist/index.js", "scripts": {