diff --git a/src/constants.js b/src/constants.js index dae3efb9..f9773787 100644 --- a/src/constants.js +++ b/src/constants.js @@ -14,7 +14,7 @@ const allowedFirstLevelKeys = [ module.exports = { DESIGN_DOC_NAME: 'app', DESIGN_DOC_ID: '_design/app', - DESIGN_DOC_VERSION: 15, + DESIGN_DOC_VERSION: 16, RIGHTS_DOC_ID: 'rights', DEFAULT_GROUPS_DOC_ID: 'defaultGroups', globalRightTypes, diff --git a/src/couch/entry.js b/src/couch/entry.js index 10ae64e3..88d105ad 100644 --- a/src/couch/entry.js +++ b/src/couch/entry.js @@ -142,7 +142,6 @@ const methods = { await this.open(); options = options || {}; - options.groups = options.groups || []; if (!entry.$content) throw new CouchError('entry has no content'); if (options.groups !== undefined && !Array.isArray(options.groups)) throw new CouchError('options.groups should be an array if defined', 'invalid argument'); @@ -187,7 +186,9 @@ const methods = { } const res = await createNew(this, entry, user); action = 'created'; - await util.addGroups(res, this, user, options.groups); + if (options.groups) { + await this.addOwnersToDoc(res.id, user, options.groups, 'entry'); + } result = res; } @@ -204,7 +205,9 @@ function onNotFound(ctx, entry, user, options) { } const res = await createNew(ctx, entry, user); - await util.addGroups(res, ctx, user, options.groups); + if (options.groups) { + await ctx.addOwnersToDoc(res.id, user, options.groups, 'entry'); + } return res; } else { throw error; @@ -257,7 +260,9 @@ async function updateEntry(ctx, oldDoc, newDoc, user, options) { // Doc validation will fail $kind changed oldDoc.$kind = newDoc.$kind; const res = await nanoMethods.saveEntry(ctx._db, oldDoc, user); - await util.addGroups(res, ctx, user, options.groups); + if (options.groups) { + await ctx.addOwnersToDoc(res.id, user, options.groups, 'entry'); + } return res; } diff --git a/src/couch/group.js b/src/couch/group.js index aa7205f5..38fdf2b7 100644 --- a/src/couch/group.js +++ b/src/couch/group.js @@ -49,11 +49,6 @@ const methods = { return this.editDefaultGroup(group, type, 'remove'); }, - addGroupToEntry(uuid, user, group) { - debug(`addGroupToEntry (${uuid}, ${user}, ${group})`); - return this._doUpdateOnEntry(uuid, user, 'addGroupToEntry', {group}); - }, - removeGroupFromEntry(uuid, user, group) { debug(`removeGroupFromEntry (${uuid}, ${user}, ${group})`); return this._doUpdateOnEntry(uuid, user, 'removeGroupFromEntry', {group}); diff --git a/src/couch/util.js b/src/couch/util.js index ed04a622..c35b736c 100644 --- a/src/couch/util.js +++ b/src/couch/util.js @@ -35,12 +35,6 @@ function isAllowedFirstLevelKey(key) { return includes(constants.allowedFirstLevelKeys, key); } -async function addGroups(doc, ctx, user, groups) { - for (let i = 0; i < groups.length; i++) { - await ctx.addGroupToEntry(doc.id, user, groups[i]); - } -} - function isManagedDocumentType(type) { return type === 'entry' || type === 'group'; } @@ -53,6 +47,5 @@ module.exports = { isValidGlobalRightUser, isValidGlobalRightType, isAllowedFirstLevelKey, - addGroups, isManagedDocumentType }; diff --git a/src/design/updates.js b/src/design/updates.js index 7a259c93..0cef2355 100644 --- a/src/design/updates.js +++ b/src/design/updates.js @@ -2,51 +2,6 @@ const updates = module.exports; -updates.addGroupToEntry = function (doc, req) { - var group = JSON.parse(req.body).group || req.query.group; - var resp = { - headers: { - 'Content-Type': 'application/json' - } - }; - - if (!doc) { - resp.code = 404; - resp.body = '{"error": "not found"}'; - return [null, resp]; - } - if (doc.$type !== 'entry') { - resp.code = 400; - resp.body = '{"error": "not an entry"}'; - return [null, resp]; - } - if (!group) { - resp.code = 400; - resp.body = '{"error": "no group in query"}'; - return [null, resp]; - } - - if (!Array.isArray(group)) { - group = [group]; - } - - for (var i = 0; i < group.length; i++) { - if (typeof group[i] !== 'string') { - resp.code = 400; - resp.body = '{"error": "group must be a string or array"}'; - return [null, resp]; - } - var idx = doc.$owners.indexOf(group[i]); - if (idx === -1) { - doc.$owners.push(group[i]); - } - } - - resp.code = 200; - resp.body = '{"ok": true}'; - return [doc, resp]; -}; - updates.removeGroupFromEntry = function (doc, req) { var group = JSON.parse(req.body).group || req.query.group; var resp = { diff --git a/src/server/middleware/couch.js b/src/server/middleware/couch.js index 946617af..9d7efa45 100644 --- a/src/server/middleware/couch.js +++ b/src/server/middleware/couch.js @@ -170,7 +170,7 @@ exports.getOwners = composeWithError(function*() { }); exports.addOwner = composeWithError(function*() { - yield this.state.couch.addGroupToEntry(this.params.uuid, this.state.userEmail, this.params.owner); + yield this.state.couch.addOwnersToDoc(this.params.uuid, this.state.userEmail, this.params.owner, 'entry'); this.body = OK; }); @@ -261,6 +261,7 @@ function onGetError(ctx, e, secure) { case 'forbidden': ctx.status = 403; ctx.body = e.message || statusMessages[403]; + break; default: if (!handleCouchError(ctx, e, secure)) { ctx.status = 500; diff --git a/test/entry.js b/test/entry.js index 067c98bd..d01f29fd 100644 --- a/test/entry.js +++ b/test/entry.js @@ -155,7 +155,7 @@ describe('entry creation and editions', function () { }); it('should add group to entry', function () { - return couch.addGroupToEntry('A', 'b@b.com', 'groupD') + return couch.addOwnersToDoc('A', 'b@b.com', 'groupD', 'entry') .then(() => couch.getEntry('A', 'b@b.com')) .then(doc => { doc.$owners.indexOf('groupD').should.be.above(0); @@ -163,8 +163,8 @@ describe('entry creation and editions', function () { }); it('Add existing group to entry', function () { - return couch.addGroupToEntry('A', 'b@b.com', 'groupD') - .then(() => couch.addGroupToEntry('A', 'b@b.com', 'groupD')) + return couch.addOwnersToDoc('A', 'b@b.com', 'groupD', 'entry') + .then(() => couch.addOwnersToDoc('A', 'b@b.com', 'groupD', 'entry')) .then(() => couch.getEntry('A', 'b@b.com')) .then(entry => { let count = 0; @@ -176,8 +176,8 @@ describe('entry creation and editions', function () { }); it('Add existing group to entry (2)', function () { - return couch.addGroupToEntry('A', 'b@b.com', 'anonymousRead') - .then(() => couch.addGroupToEntry('A', 'b@b.com', 'anonymousRead')) + return couch.addOwnersToDoc('A', 'b@b.com', 'anonymousRead', 'entry') + .then(() => couch.addOwnersToDoc('A', 'b@b.com', 'anonymousRead', 'entry')) .then(() => couch.getEntry('A', 'b@b.com')) .then(entry => { let count = 0; @@ -189,7 +189,8 @@ describe('entry creation and editions', function () { }); it('should fail to add group to entry', function () { - return couch.addGroupToEntry('A', 'a@a.com', 'groupC').should.be.rejectedWith(/unauthorized/); + return couch.addOwnersToDoc('A', 'a@a.com', 'groupC', 'entry') + .should.be.rejectedWith(/user has no access/); }); it('should remove group from entry', function () { diff --git a/test/rest-api/owners.js b/test/rest-api/owners.js index 13a465d4..b4d6f8e9 100644 --- a/test/rest-api/owners.js +++ b/test/rest-api/owners.js @@ -5,11 +5,9 @@ const data = require('../data/data'); const authenticateAs = require('./authenticate'); describe('rest api - manage owners', function () { - var id; + const id = 'A'; before(function () { - return data().then(() => authenticateAs(request, 'b@b.com', '123')).then(() => { - return couch.getEntryById('A', 'b@b.com').then(entry => id = entry._id); - }); + return data().then(() => authenticateAs(request, 'b@b.com', '123')); }); it('get owners', function () { return request.get(`/db/test/entry/${id}/_owner`) @@ -27,7 +25,7 @@ describe('rest api - manage owners', function () { }); }); it('remove owner', function () { - return couch.addGroupToEntry(id, 'b@b.com', 'testRemove') + return couch.addOwnersToDoc(id, 'b@b.com', 'testRemove', 'entry') .then(() => { return request.del(`/db/test/entry/${id}/_owner/testRemove`) .expect(200)