diff --git a/packages/rocketchat-api/server/v1/permissions.js b/packages/rocketchat-api/server/v1/permissions.js index 68ccb81c01e78..eb3f606ad0b4d 100644 --- a/packages/rocketchat-api/server/v1/permissions.js +++ b/packages/rocketchat-api/server/v1/permissions.js @@ -7,8 +7,74 @@ */ RocketChat.API.v1.addRoute('permissions', { authRequired: true }, { get() { + const warningMessage = 'The endpoint "permissions" is deprecated and will be removed after version v0.69'; + console.warn(warningMessage); + const result = Meteor.runAsUser(this.userId, () => Meteor.call('permissions/get')); return RocketChat.API.v1.success(result); } }); + +RocketChat.API.v1.addRoute('permissions.list', { authRequired: true }, { + get() { + const result = Meteor.runAsUser(this.userId, () => Meteor.call('permissions/get')); + + return RocketChat.API.v1.success({ + permissions: result + }); + } +}); + +RocketChat.API.v1.addRoute('permissions.update', { authRequired: true }, { + post() { + if (!RocketChat.authz.hasPermission(this.userId, 'access-permissions')) { + return RocketChat.API.v1.failure('Editing permissions is not allowed', 'error-edit-permissions-not-allowed'); + } + + check(this.bodyParams, { + permissions: [ + Match.ObjectIncluding({ + _id: String, + roles: [String] + }) + ] + }); + + let permissionNotFound = false; + let roleNotFound = false; + Object.keys(this.bodyParams.permissions).forEach((key) => { + const element = this.bodyParams.permissions[key]; + + if (!RocketChat.models.Permissions.findOneById(element._id)) { + permissionNotFound = true; + } + + Object.keys(element.roles).forEach((key) => { + const subelement = element.roles[key]; + + if (!RocketChat.models.Roles.findOneById(subelement)) { + roleNotFound = true; + } + }); + }); + + if (permissionNotFound) { + return RocketChat.API.v1.failure('Invalid permission', 'error-invalid-permission'); + } else if (roleNotFound) { + return RocketChat.API.v1.failure('Invalid role', 'error-invalid-role'); + } + + Object.keys(this.bodyParams.permissions).forEach((key) => { + const element = this.bodyParams.permissions[key]; + + RocketChat.models.Permissions.createOrUpdate(element._id, element.roles); + }); + + const result = Meteor.runAsUser(this.userId, () => Meteor.call('permissions/get')); + + return RocketChat.API.v1.success({ + permissions: result + }); + } +}); diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 1ec26f7da23da..e963eccd885d8 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -740,6 +740,7 @@ "error-department-not-found": "Department not found", "error-direct-message-file-upload-not-allowed": "File sharing not allowed in direct messages", "error-duplicate-channel-name": "A channel with name '__channel_name__' exists", + "error-edit-permissions-not-allowed": "Editing permissions is not allowed", "error-email-domain-blacklisted": "The email domain is blacklisted", "error-email-send-failed": "Error trying to send email: __message__", "error-field-unavailable": "__field__ is already in use :(", @@ -767,6 +768,7 @@ "error-invalid-method": "Invalid method", "error-invalid-name": "Invalid name", "error-invalid-password": "Invalid password", + "error-invalid-permission": "Invalid permission", "error-invalid-redirectUri": "Invalid redirectUri", "error-invalid-role": "Invalid role", "error-invalid-room": "Invalid room", diff --git a/tests/end-to-end/api/11-permissions.js b/tests/end-to-end/api/11-permissions.js index 86b702342c011..c7bb2e890355e 100644 --- a/tests/end-to-end/api/11-permissions.js +++ b/tests/end-to-end/api/11-permissions.js @@ -8,6 +8,8 @@ describe('[Permissions]', function() { before(done => getCredentials(done)); + //DEPRECATED + // TODO: Remove this after three versions have been released. That means at 0.69 this should be gone. describe('[/permissions]', () => { it('should return all permissions that exists on the server, with respective roles', (done) => { request.get(api('permissions')) @@ -30,4 +32,105 @@ describe('[Permissions]', function() { .end(done); }); }); + + describe('[/permissions.list]', () => { + it('should return all permissions that exists on the server, with respective roles', (done) => { + request.get(api('permissions.list')) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('permissions'); + + const firstElement = res.body.permissions[0]; + expect(firstElement).to.have.property('_id'); + expect(firstElement).to.have.property('roles').and.to.be.a('array'); + expect(firstElement).to.have.property('_updatedAt'); + expect(firstElement).to.have.property('meta'); + expect(firstElement.meta).to.have.property('revision'); + expect(firstElement.meta).to.have.property('created'); + expect(firstElement.meta).to.have.property('version'); + expect(firstElement).to.have.property('$loki'); + }) + .end(done); + }); + }); + + describe('[/permissions.update]', () => { + it('should change the permissions on the server', (done) => { + const permissions = [ + { + '_id': 'add-oauth-service', + 'roles': ['admin', 'user'] + } + ]; + request.post(api('permissions.update')) + .set(credentials) + .send({ permissions }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('permissions'); + + const firstElement = res.body.permissions[0]; + expect(firstElement).to.have.property('_id'); + expect(firstElement).to.have.property('roles').and.to.be.a('array'); + expect(firstElement).to.have.property('_updatedAt'); + expect(firstElement).to.have.property('meta'); + expect(firstElement.meta).to.have.property('revision'); + expect(firstElement.meta).to.have.property('created'); + expect(firstElement.meta).to.have.property('version'); + expect(firstElement).to.have.property('$loki'); + }) + .end(done); + }); + it('should 400 when trying to set an unknown permission', (done) => { + const permissions = [ + { + '_id': 'this-permission-does-not-exist', + 'roles': ['admin'] + } + ]; + request.post(api('permissions.update')) + .set(credentials) + .send({ permissions }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + it('should 400 when trying to assign a permission to an unknown role', (done) => { + const permissions = [ + { + '_id': 'add-oauth-service', + 'roles': ['this-role-does-not-exist'] + } + ]; + request.post(api('permissions.update')) + .set(credentials) + .send({ permissions }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + it('should 400 when trying to set permissions to a string', (done) => { + const permissions = ''; + request.post(api('permissions.update')) + .set(credentials) + .send({ permissions }) + .expect('Content-Type', 'application/json') + .expect(400) + .expect((res) => { + expect(res.body).to.have.property('success', false); + }) + .end(done); + }); + }); });