[NEW] Add permission to enable personal access token to specific roles (#12309)

* Add permission to enable personal access token to specific roles

* Update v136.js

* Update v136.js
pull/12692/head
Marcos Spessatto Defendi 7 years ago committed by Rodrigo Nascimento
parent dc70e803b4
commit 206e2553a3
  1. 4
      imports/personal-access-tokens/client/personalAccessTokens.js
  2. 4
      imports/personal-access-tokens/server/api/methods/generateToken.js
  3. 4
      imports/personal-access-tokens/server/api/methods/regenerateToken.js
  4. 4
      imports/personal-access-tokens/server/api/methods/removeToken.js
  5. 1
      imports/personal-access-tokens/server/index.js
  6. 2
      imports/personal-access-tokens/server/publications/personalAccessTokens.js
  7. 5
      imports/personal-access-tokens/server/settings.js
  8. 4
      packages/rocketchat-api/server/v1/users.js
  9. 1
      packages/rocketchat-authorization/server/startup.js
  10. 2
      packages/rocketchat-i18n/i18n/en.i18n.json
  11. 2
      packages/rocketchat-ui-account/client/accountFlex.js
  12. 15
      server/startup/migrations/v136.js
  13. 36
      tests/end-to-end/api/01-users.js

@ -12,7 +12,7 @@ const PersonalAccessTokens = new Mongo.Collection('personal_access_tokens');
Template.accountTokens.helpers({
isAllowed() {
return RocketChat.settings.get('API_Enable_Personal_Access_Tokens');
return RocketChat.authz.hasAllPermission(['create-personal-access-tokens']);
},
tokens() {
return (PersonalAccessTokens.find({}).fetch()[0] && PersonalAccessTokens.find({}).fetch()[0].tokens) || [];
@ -46,7 +46,7 @@ Template.accountTokens.events({
return toastr.error(t(error.error));
}
showSuccessModal(token);
instance.find('#input-token-name').value = '';
instance.find('#tokenName').value = '';
});
},
'click .remove-personal-access-token'() {

@ -7,8 +7,8 @@ Meteor.methods({
if (!Meteor.userId()) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'personalAccessTokens:generateToken' });
}
if (!RocketChat.settings.get('API_Enable_Personal_Access_Tokens')) {
throw new Meteor.Error('error-personal-access-tokens-are-current-disabled', 'Personal Access Tokens are currently disabled', { method: 'personalAccessTokens:generateToken' });
if (!RocketChat.authz.hasPermission(Meteor.userId(), 'create-personal-access-tokens')) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'personalAccessTokens:generateToken' });
}
const token = Random.secret();

@ -5,8 +5,8 @@ Meteor.methods({
if (!Meteor.userId()) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'personalAccessTokens:regenerateToken' });
}
if (!RocketChat.settings.get('API_Enable_Personal_Access_Tokens')) {
throw new Meteor.Error('error-personal-access-tokens-are-current-disabled', 'Personal Access Tokens are currently disabled', { method: 'personalAccessTokens:regenerateToken' });
if (!RocketChat.authz.hasPermission(Meteor.userId(), 'create-personal-access-tokens')) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'personalAccessTokens:regenerateToken' });
}
const tokenExist = RocketChat.models.Users.findPersonalAccessTokenByTokenNameAndUserId({

@ -5,8 +5,8 @@ Meteor.methods({
if (!Meteor.userId()) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'personalAccessTokens:removeToken' });
}
if (!RocketChat.settings.get('API_Enable_Personal_Access_Tokens')) {
throw new Meteor.Error('error-personal-access-tokens-are-current-disabled', 'Personal Access Tokens are currently disabled', { method: 'personalAccessTokens:removeToken' });
if (!RocketChat.authz.hasPermission(Meteor.userId(), 'create-personal-access-tokens')) {
throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'personalAccessTokens:removeToken' });
}
const tokenExist = RocketChat.models.Users.findPersonalAccessTokenByTokenNameAndUserId({
userId: Meteor.userId(),

@ -1,5 +1,4 @@
import './api/methods';
import './settings';
import './models';
import './publications';

@ -4,7 +4,7 @@ Meteor.publish('personalAccessTokens', function() {
if (!this.userId) {
return this.ready();
}
if (!RocketChat.settings.get('API_Enable_Personal_Access_Tokens')) {
if (!RocketChat.authz.hasPermission(this.userId, 'create-personal-access-tokens')) {
return this.ready();
}
const self = this;

@ -1,5 +0,0 @@
RocketChat.settings.addGroup('General', function() {
this.section('REST API', function() {
this.add('API_Enable_Personal_Access_Tokens', false, { type: 'boolean', public: true });
});
});

@ -498,8 +498,8 @@ RocketChat.API.v1.addRoute('users.regeneratePersonalAccessToken', { authRequired
RocketChat.API.v1.addRoute('users.getPersonalAccessTokens', { authRequired: true }, {
get() {
if (!RocketChat.settings.get('API_Enable_Personal_Access_Tokens')) {
throw new Meteor.Error('error-personal-access-tokens-are-current-disabled', 'Personal Access Tokens are currently disabled');
if (!RocketChat.authz.hasPermission(this.userId, 'create-personal-access-tokens')) {
throw new Meteor.Error('not-authorized', 'Not Authorized');
}
const loginTokens = RocketChat.models.Users.getLoginTokensByUserId(this.userId).fetch()[0];
const getPersonalAccessTokens = () => loginTokens.services.resume.loginTokens

@ -21,6 +21,7 @@ Meteor.startup(function() {
{ _id: 'create-c', roles : ['admin', 'user', 'bot'] },
{ _id: 'create-d', roles : ['admin', 'user', 'bot'] },
{ _id: 'create-p', roles : ['admin', 'user', 'bot'] },
{ _id: 'create-personal-access-tokens', roles : ['admin', 'user'] },
{ _id: 'create-user', roles : ['admin'] },
{ _id: 'clean-channel-history', roles : ['admin'] },
{ _id: 'delete-c', roles : ['admin', 'owner'] },

@ -278,8 +278,6 @@
"API_Enable_CORS": "Enable CORS",
"API_Enable_Direct_Message_History_EndPoint": "Enable Direct Message History Endpoint",
"API_Enable_Direct_Message_History_EndPoint_Description": "This enables the `/api/v1/im.history.others` which allows the viewing of direct messages sent by other users that the caller is not part of.",
"API_Enable_Personal_Access_Tokens": "Enable Personal Access Tokens to REST API",
"API_Enable_Personal_Access_Tokens_Description": "Enable personal access tokens for use with the REST API",
"API_Enable_Shields": "Enable Shields",
"API_Enable_Shields_Description": "Enable shields available at `/api/v1/shield.svg`",
"API_GitHub_Enterprise_URL": "Server URL",

@ -15,7 +15,7 @@ Template.accountFlex.helpers({
return RocketChat.settings.get('Accounts_AllowUserProfileChange');
},
accessTokensEnabled() {
return RocketChat.settings.get('API_Enable_Personal_Access_Tokens');
return RocketChat.authz.hasAllPermission(['create-personal-access-tokens']);
},
encryptionEnabled() {
return RocketChat.settings.get('E2E_Enable');

@ -0,0 +1,15 @@
RocketChat.Migrations.add({
version: 136,
up() {
const personalTokensEnabled = RocketChat.settings.get('API_Enable_Personal_Access_Tokens');
const roles = RocketChat.models.Roles.find({ scope: 'Users' }).fetch().map((role) => role._id);
if (personalTokensEnabled) {
RocketChat.models.Permissions.upsert({ _id: 'create-personal-access-tokens' }, { $set: { roles } });
}
RocketChat.models.Settings.remove({
_id: 'API_Enable_Personal_Access_Tokens',
});
},
});

@ -1247,17 +1247,7 @@ describe('[Users]', function() {
describe('Personal Access Tokens', () => {
const tokenName = `${ Date.now() }token`;
describe('successful cases', () => {
it('Enable "API_Enable_Personal_Access_Tokens" setting...', (done) => {
request.post('/api/v1/settings/API_Enable_Personal_Access_Tokens')
.set(credentials)
.send({ value: true })
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
})
.end(done);
});
it('Grant necessary permission "create-personal-accss-tokens" to user', (done) => updatePermission('create-personal-access-tokens', ['admin']).then(done));
describe('[/users.generatePersonalAccessToken]', () => {
it('should return a personal access token to user', (done) => {
request.post(api('users.generatePersonalAccessToken'))
@ -1359,18 +1349,8 @@ describe('[Users]', function() {
});
});
describe('unsuccessful cases', () => {
it('disable "API_Enable_Personal_Access_Tokens" setting...', (done) => {
request.post('/api/v1/settings/API_Enable_Personal_Access_Tokens')
.set(credentials)
.send({ value: false })
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
})
.end(done);
});
describe('should return an error when setting "API_Enable_Personal_Access_Tokens" is disabled for the following routes', () => {
it('Remove necessary permission "create-personal-accss-tokens" to user', (done) => updatePermission('create-personal-access-tokens', []).then(done));
describe('should return an error when the user dont have the necessary permission "create-personal-access-tokens"', () => {
it('/users.generatePersonalAccessToken', (done) => {
request.post(api('users.generatePersonalAccessToken'))
.set(credentials)
@ -1381,7 +1361,7 @@ describe('[Users]', function() {
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-personal-access-tokens-are-current-disabled');
expect(res.body.errorType).to.be.equal('not-authorized');
})
.end(done);
});
@ -1395,7 +1375,7 @@ describe('[Users]', function() {
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-personal-access-tokens-are-current-disabled');
expect(res.body.errorType).to.be.equal('not-authorized');
})
.end(done);
});
@ -1406,7 +1386,7 @@ describe('[Users]', function() {
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-personal-access-tokens-are-current-disabled');
expect(res.body.errorType).to.be.equal('not-authorized');
})
.end(done);
});
@ -1420,7 +1400,7 @@ describe('[Users]', function() {
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-personal-access-tokens-are-current-disabled');
expect(res.body.errorType).to.be.equal('not-authorized');
})
.end(done);
});
@ -1434,7 +1414,7 @@ describe('[Users]', function() {
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body.errorType).to.be.equal('error-personal-access-tokens-are-current-disabled');
expect(res.body.errorType).to.be.equal('not-authorized');
})
.end(done);
});

Loading…
Cancel
Save