diff --git a/app/routes/api/users.js b/app/routes/api/users.js index 0ba70f3..36fcc76 100644 --- a/app/routes/api/users.js +++ b/app/routes/api/users.js @@ -1,33 +1,59 @@ -var express = require('express'); -var router = express.Router(); +const express = require('express'); +const router = express.Router(); -var User = require('../../models/User.js'); +const ModelPath = '../../models/'; +const User = require(ModelPath + 'User.js'); -var requireScope = function (perm) { - return function(req, res, next) { - User.findOne({username: req.session.passport.user}, function(err, user) { - if (err) throw err; - if (user.scope.indexOf(perm) === -1) - res.status(400).json({'message': 'No permission.'}); - else - next(); - }); - } -}; +const wrap = require('../../util/wrap'); +const bodyVerifier = require('../../util/verifyBody').bodyVerifier; +const requireAuth = require('../../util/auth').requireAuth; -router.get('/get', requireScope('users.view'), function (req, res, next) { - var query = {}; +const getParams = [ + {name: 'username', type: 'string', optional: true}, + {name: 'displayname', type: 'string', optional: true}]; +router.get('/get', requireAuth('user.get'), bodyVerifier(getParams), wrap(async (req, res) => { + let query = {}; if (req.body.username) query.username = req.body.username; - User.find(query, function (err, users) { - if (err) { - next(err) - } else { - res.status(200).json(users); - } - }) -}); + if (req.body.displayname) + query.displayname = req.body.displayname; + + //const users = User.find(query, 'username displayname scope uploadCount uploadSize date banned'); + const users = await User.find(query); + + res.status(200).json(users); +})); + +const banParams = [{name: 'username', type: 'string'}]; +router.post('/ban', requireAuth('user.ban'), bodyVerifier(banParams), wrap(async (req, res) => { + const user = await User.findOne({username: req.body.username}); + if (!user) + return res.status(422).json({message: 'User not found.'}); + + if (user.banned) + return res.status(422).json({message: 'User already banned.'}); + + user.banned = true; + await user.save(); + + res.status(200).json({message: 'User banned.'}); +})); + +const unbanParams = [{name: 'username', type: 'string'}]; +router.post('/unban', requireAuth('user.unban'), bodyVerifier(unbanParams), wrap(async (req, res) => { + const user = await User.findOne({username: req.body.username}); + if (!user) + return res.status(422).json({message: 'User not found.'}); + + if (!user.banned) + return res.status(422).json({message: 'User not banned.'}); + + user.banned = false; + await user.save(); + + res.status(200).json({message: 'User unbanned.'}); +})); module.exports = router; \ No newline at end of file diff --git a/test/api.js b/test/api.js index 109cfa7..e435868 100644 --- a/test/api.js +++ b/test/api.js @@ -776,4 +776,95 @@ describe('Keys', () => { }); }); +describe('Users', () => { + describe('/GET get', () => { + beforeEach(() => Promise.all([ + Promise.all([ + util.insertInvite({code: 'test1', scope: ['file.upload'], issuer: 'Mocha'}), + util.insertInvite({code: 'test2', scope: ['file.upload'], issuer: 'Mocha'}) + ]), + Promise.all([ + util.registerUser({displayname: 'user1', password: 'pass', invite: 'test1'}, agent), + util.registerUser({displayname: 'user2', password: 'pass', invite: 'test2'}, agent) + ]) + ])); + + async function verifyGetUsers(res, users) { + res.should.have.status(200); + res.body.should.be.a('Array'); + res.body.map(user => user.username).sort().should.deep.equal(users.sort()); + } + + describe('0 Valid Request', () => { + it('must get all users with an empty query', async () => { + await util.createSession(agent, ['user.get'], 'admin'); + const res = await util.getUsers({}, agent); + return verifyGetUsers(res, ['user1', 'user2', 'admin']); + }); + + it('must filter users by username', async () => { + await util.createSession(agent, ['user.get'], 'admin'); + const res = await util.getUsers({username: 'user1'}, agent); + return verifyGetUsers(res, ['user1']); + }); + + it('must filter users by displayname', async () => { + await util.createSession(agent, ['user.get'], 'admin'); + const res = await util.getUsers({displayname: 'user1'}, agent); + return verifyGetUsers(res, ['user1']); + }); + + it('must return an empty array when no users were found', async () => { + await util.createSession(agent, ['user.get'], 'admin'); + const res = await util.getUsers({username: 'abc'}, agent); + return verifyGetUsers(res, []); + }); + }); + }); + + describe('/POST ban/unban', () => { + beforeEach(async () => { + await util.insertInvite({code: 'test1', scope: ['file.upload'], issuer: 'Mocha'}); + await util.registerUser({displayname: 'user', password: 'pass', invite: 'test1'}, agent); + }); + + async function verifyBanned(res, statusCode, message, username, banStatus) { + util.verifyResponse(res, statusCode, message); + const user = await User.findOne({username: username}); + user.should.exist; + user.should.have.property('banned').equal(banStatus, 'The user should have banned status ' + banStatus); + } + + describe('0 Valid Request', () => { + it('must ban a not banned user', async () => { + await util.createSession(agent, ['user.ban'], 'admin'); + const res = await util.ban('user', agent); + return verifyBanned(res, 200, 'User banned.', 'user', true); + }); + + it('must unban a banned user', async () => { + await util.setBanned('user', true); + await util.createSession(agent, ['user.unban'], 'admin'); + const res = await util.unban('user', agent); + return verifyBanned(res, 200, 'User unbanned.', 'user', false); + }); + }); + + describe('1 Already Requested Ban Status', () => { + it('must not ban an already banned user', async () => { + await util.setBanned('user', true); + await util.createSession(agent, ['user.ban'], 'admin'); + const res = await util.ban('user', agent); + return verifyBanned(res, 422, 'User already banned.', 'user', true); + }); + + it('must not unban a not banned user', async () => { + await util.createSession(agent, ['user.unban'], 'admin'); + const res = await util.unban('user', agent); + return verifyBanned(res, 422, 'User not banned.', 'user', false); + }); + }); + }); +}); + after(() => server.close(() => process.exit(0))); diff --git a/test/testUtil.js b/test/testUtil.js index 161440a..cc47090 100644 --- a/test/testUtil.js +++ b/test/testUtil.js @@ -186,4 +186,18 @@ exports.binaryFileParser = (res, cb) => { exports.view = (id, agent) => agent.get('/v/' + id) - .buffer(); \ No newline at end of file + .buffer(); + +//---------------- Users ----------------// + +exports.getUsers = (query, agent) => + agent.get('/api/users/get') + .send(query); + +exports.ban = (username, agent) => + agent.post('/api/users/ban') + .send({username: username}); + +exports.unban = (username, agent) => + agent.post('/api/users/unban') + .send({username: username}); \ No newline at end of file