Merge pull request #949 from coralproject/fix-moderator-rest-permission

Allow Moderator to have read access on assets and settings
This commit is contained in:
Wyatt Johnson
2017-09-14 08:47:28 -06:00
committed by GitHub
5 changed files with 95 additions and 62 deletions
+5 -4
View File
@@ -1,5 +1,6 @@
const express = require('express');
const router = express.Router();
const authorization = require('../../../middleware/authorization');
const errors = require('../../../errors');
const AssetsService = require('../../../services/assets');
@@ -33,7 +34,7 @@ const FilterOpenAssets = (query, filter) => {
};
// List assets.
router.get('/', async (req, res, next) => {
router.get('/', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
const {
limit = 20,
@@ -72,7 +73,7 @@ router.get('/', async (req, res, next) => {
});
// Get an asset by id.
router.get('/:asset_id', async (req, res, next) => {
router.get('/:asset_id', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
try {
// Send back the asset.
@@ -87,7 +88,7 @@ router.get('/:asset_id', async (req, res, next) => {
}
});
router.put('/:asset_id/settings', async (req, res, next) => {
router.put('/:asset_id/settings', authorization.needed('ADMIN'), async (req, res, next) => {
try {
await AssetsService.overrideSettings(req.params.asset_id, req.body);
res.status(204).end();
@@ -96,7 +97,7 @@ router.put('/:asset_id/settings', async (req, res, next) => {
}
});
router.put('/:asset_id/status', async (req, res, next) => {
router.put('/:asset_id/status', authorization.needed('ADMIN'), async (req, res, next) => {
const {
closedAt,
closedMessage
+2 -3
View File
@@ -1,5 +1,4 @@
const express = require('express');
const authorization = require('../../middleware/authorization');
const pkg = require('../../package.json');
const router = express.Router();
@@ -8,8 +7,8 @@ router.get('/', (req, res) => {
res.json({version: pkg.version});
});
router.use('/assets', authorization.needed('ADMIN'), require('./assets'));
router.use('/settings', authorization.needed('ADMIN'), require('./settings'));
router.use('/assets', require('./assets'));
router.use('/settings', require('./settings'));
router.use('/auth', require('./auth'));
router.use('/users', require('./users'));
router.use('/account', require('./account'));
+3 -2
View File
@@ -1,9 +1,10 @@
const express = require('express');
const SettingsService = require('../../../services/settings');
const authorization = require('../../../middleware/authorization');
const router = express.Router();
router.get('/', async (req, res, next) => {
router.get('/', authorization.needed('ADMIN', 'MODERATOR'), async (req, res, next) => {
try {
let settings = await SettingsService.retrieve();
res.json(settings);
@@ -12,7 +13,7 @@ router.get('/', async (req, res, next) => {
}
});
router.put('/', async (req, res, next) => {
router.put('/', authorization.needed('ADMIN'), async (req, res, next) => {
try {
await SettingsService.update(req.body);
res.status(204).end();
+66 -42
View File
@@ -37,78 +37,88 @@ describe('/api/v1/assets', () => {
describe('#get', () => {
it('should return all assets without a search query', async () => {
const res = await chai.request(app)
.get('/api/v1/assets')
.set(passport.inject({roles: ['ADMIN']}));
for (const role of ['ADMIN', 'MODERATOR']) {
const res = await chai.request(app)
.get('/api/v1/assets')
.set(passport.inject({roles: [role]}));
const body = res.body;
const body = res.body;
expect(body).to.have.property('count', 2);
expect(body).to.have.property('result');
expect(body).to.have.property('count', 2);
expect(body).to.have.property('result');
const assets = body.result;
const assets = body.result;
expect(assets).to.have.length(2);
expect(assets).to.have.length(2);
}
});
it('should return assets that we search for', async () => {
const res = await chai.request(app)
.get('/api/v1/assets?search=term2')
.set(passport.inject({roles: ['ADMIN']}));
for (const role of ['ADMIN', 'MODERATOR']) {
const res = await chai.request(app)
.get('/api/v1/assets?search=term2')
.set(passport.inject({roles: [role]}));
const body = res.body;
const body = res.body;
expect(body).to.have.property('count', 1);
expect(body).to.have.property('result');
expect(body).to.have.property('count', 1);
expect(body).to.have.property('result');
const assets = body.result;
const assets = body.result;
expect(assets).to.have.length(1);
expect(assets).to.have.length(1);
const asset = assets[0];
const asset = assets[0];
expect(asset).to.have.property('url', 'https://coralproject.net/news/asset2');
expect(asset).to.have.property('title', 'Asset 2');
expect(asset).to.have.property('url', 'https://coralproject.net/news/asset2');
expect(asset).to.have.property('title', 'Asset 2');
}
});
it('should not return assets that we do not search for', async () => {
const res = await chai.request(app)
.get('/api/v1/assets?search=term3')
.set(passport.inject({roles: ['ADMIN']}));
const body = res.body;
for (const role of ['ADMIN', 'MODERATOR']) {
const res = await chai.request(app)
.get('/api/v1/assets?search=term3')
.set(passport.inject({roles: [role]}));
const body = res.body;
expect(body).to.have.property('count', 0);
expect(body).to.have.property('result');
expect(body).to.have.property('count', 0);
expect(body).to.have.property('result');
expect(body.result).to.be.empty;
expect(body.result).to.be.empty;
}
});
it('should return only closed assets', async () => {
const res = await chai.request(app)
.get('/api/v1/assets?filter=closed')
.set(passport.inject({roles: ['ADMIN']}));
const body = res.body;
for (const role of ['ADMIN', 'MODERATOR']) {
const res = await chai.request(app)
.get('/api/v1/assets?filter=closed')
.set(passport.inject({roles: [role]}));
const body = res.body;
expect(body).to.have.property('count', 1);
expect(body).to.have.property('result');
expect(body).to.have.property('count', 1);
expect(body).to.have.property('result');
const assets = body.result;
const assets = body.result;
expect(assets[0]).to.have.property('title', 'Asset 1');
expect(assets[0]).to.have.property('title', 'Asset 1');
}
});
it('should return only opened assets', async () => {
const res = await chai.request(app)
.get('/api/v1/assets?filter=open')
.set(passport.inject({roles: ['ADMIN']}));
const body = res.body;
for (const role of ['ADMIN', 'MODERATOR']) {
const res = await chai.request(app)
.get('/api/v1/assets?filter=open')
.set(passport.inject({roles: [role]}));
const body = res.body;
expect(body).to.have.property('count', 1);
expect(body).to.have.property('result');
expect(body).to.have.property('count', 1);
expect(body).to.have.property('result');
const assets = body.result;
const assets = body.result;
expect(assets[0]).to.have.property('title', 'Asset 2');
expect(assets[0]).to.have.property('title', 'Asset 2');
}
});
});
@@ -133,6 +143,20 @@ describe('/api/v1/assets', () => {
expect(closedAsset).to.have.property('isClosed', true);
expect(closedAsset).to.have.property('closedAt').and.to.not.equal(null);
});
it('should require ADMIN role', async () => {
const today = Date.now();
const asset = await AssetsService.findOrCreateByUrl('http://test.com');
expect(asset).to.have.property('isClosed', false);
expect(asset).to.have.property('closedAt', null);
const promise = chai.request(app)
.put(`/api/v1/assets/${asset.id}/status`)
.set(passport.inject({roles: ['MODERATOR']}))
.send({closedAt: today});
await expect(promise).to.eventually.be.rejected;
});
});
});
+19 -11
View File
@@ -16,17 +16,17 @@ describe('/api/v1/settings', () => {
describe('#get', () => {
it('should return a settings object', () => {
return chai.request(app)
.get('/api/v1/settings')
.set(passport.inject({
roles: ['ADMIN']
}))
.then((res) => {
expect(res).to.have.status(200);
expect(res).to.be.json;
expect(res.body).to.have.property('moderation', 'PRE');
});
it('should return a settings object', async () => {
for (let role of ['ADMIN', 'MODERATOR']) {
const res = await chai.request(app)
.get('/api/v1/settings')
.set(passport.inject({
roles: [role]
}));
expect(res).to.have.status(200);
expect(res).to.be.json;
expect(res.body).to.have.property('moderation', 'PRE');
}
});
});
@@ -46,6 +46,14 @@ describe('/api/v1/settings', () => {
expect(settings).to.have.property('moderation', 'POST');
});
});
it('should require ADMIN role', () => {
const promise = chai.request(app)
.put('/api/v1/settings')
.set(passport.inject({roles: ['MODERATOR']}))
.send({moderation: 'POST'});
return expect(promise).to.eventually.be.rejected;
});
});
});