From 2383c0939781b222639139e6e5ee42b3b8271d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 1 Dec 2017 12:11:21 +0100 Subject: [PATCH] feat(api): allow to specify rights for user token (#81) * feat(api): allow to specify rights for user token * fix: add "delete" to global right types --- src/constants.js | 1 + src/couch/token.js | 3 ++- src/couch/validate.js | 9 +++++---- src/server/middleware/couch.js | 3 ++- test/token.js | 5 +++++ 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/constants.js b/src/constants.js index 2a804e7b..5376fcf1 100644 --- a/src/constants.js +++ b/src/constants.js @@ -2,6 +2,7 @@ // super administrators have all these rights const globalRightTypes = [ + 'delete', 'read', 'write', 'create', diff --git a/src/couch/token.js b/src/couch/token.js index 89bb8611..2042f428 100644 --- a/src/couch/token.js +++ b/src/couch/token.js @@ -3,7 +3,7 @@ const CouchError = require('../util/CouchError'); const debug = require('../util/debug')('main:token'); const token = require('../util/token'); -const {isValidUsername} = require('./util'); +const {isValidUsername, ensureRightsArray} = require('./util'); const methods = { async createEntryToken(user, uuid) { @@ -22,6 +22,7 @@ const methods = { if (!isValidUsername(user)) { throw new CouchError('only a user can create a token', 'unauthorized'); } + ensureRightsArray(rights); await this.open(); return token.createUserToken(this._db, user, rights); }, diff --git a/src/couch/validate.js b/src/couch/validate.js index 6b1602df..5cd1034c 100644 --- a/src/couch/validate.js +++ b/src/couch/validate.js @@ -87,20 +87,21 @@ async function validateTokenOrRights(ctx, uuid, owners, rights, user, token, typ if (token && token.$kind === type && token.uuid === uuid) { for (var i = 0; i < rights.length; i++) { - if (token.rights.includes(rights[i])) { - return true; + if (!token.rights.includes(rights[i])) { + return false; } } + return true; } const ok = await validateRights(ctx, owners, user, rights, type); return ok[0]; } function areRightsInToken(rights, token) { - const tokenRights = new Set(token.rights); - if (rights.length !== tokenRights.size) { + if (rights.length > token.rights.length) { return false; } + const tokenRights = new Set(token.rights); for (const right of rights) { if (!tokenRights.has(right)) { return false; diff --git a/src/server/middleware/couch.js b/src/server/middleware/couch.js index c330740d..8255e00f 100644 --- a/src/server/middleware/couch.js +++ b/src/server/middleware/couch.js @@ -298,7 +298,8 @@ exports.createEntryToken = composeWithError(async (ctx) => { }); exports.createUserToken = composeWithError(async (ctx) => { - const token = await ctx.state.couch.createUserToken(ctx.state.userEmail); + const rights = ctx.query.rights ? ctx.query.rights.split(',') : undefined; + const token = await ctx.state.couch.createUserToken(ctx.state.userEmail, rights); ctx.status = 201; ctx.body = token; }); diff --git a/test/token.js b/test/token.js index 35d51c3a..f487e2b3 100644 --- a/test/token.js +++ b/test/token.js @@ -67,4 +67,9 @@ describe('token methods', function () { await couch.createEntryToken('anonymous', 'A').should.be.rejectedWith('only a user can create a token'); await couch.createUserToken('anonymous').should.be.rejectedWith('only a user can create a token'); }); + + it('token should not accept invalid right', async () => { + await couch.createUserToken('a@a.com', 'test1').should.be.rejectedWith('invalid right: test1'); + await couch.createUserToken('a@a.com', ['read', 'test2']).should.be.rejectedWith('invalid right: test2'); + }); });