From 7aa680c26d330d25c45542169f382b78f07f2488 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Sat, 28 Apr 2018 10:18:27 +0200 Subject: [PATCH] Implemented user admin API Renamed repository methods for consistency --- lib/api/admin.js | 128 +++++++++++++++++++++++++++++++++++---- lib/api/token.js | 2 +- lib/api/upload.js | 6 +- lib/repository/code.js | 10 +-- lib/repository/upload.js | 6 +- lib/repository/user.js | 103 +++++++++++++++++++++++++++++-- 6 files changed, 228 insertions(+), 27 deletions(-) diff --git a/lib/api/admin.js b/lib/api/admin.js index 687fd2f..127e114 100644 --- a/lib/api/admin.js +++ b/lib/api/admin.js @@ -46,7 +46,7 @@ async function checkAuthorization(req, res, repository, onVerified) if (decoded.userId) { - var user = await repository.users.getUser(decoded.userId); + var user = await repository.users.get(decoded.userId); if (user === null || !user.active) { res.sendStatus(403); @@ -111,7 +111,7 @@ module.exports = (repository) => { await checkAuthorization(req, res, repository, async (user) => { - var codes = await repository.codes.getCodes(user.hasAuth(AuthTokens.ViewAllCodes) ? null : user.id); + var codes = await repository.codes.list(user.hasAuth(AuthTokens.ViewAllCodes) ? null : user.id); var usernames = await repository.users.getNames(); codes.forEach((item) => @@ -124,18 +124,18 @@ module.exports = (repository) => })); - router.get('/codes/:code', asyncHandler(async (req, res) => + router.get('/codes/:id', asyncHandler(async (req, res) => { await checkAuthorization(req, res, repository, async (user) => { - var code = await repository.codes.getCode(req.params.code); + var code = await repository.codes.get(req.params.id); if (code === null || (code.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllCodes))) { res.sendStatus(404); return; } - var user = await repository.users.getUser(code.userId); + var user = await repository.users.get(code.userId); if (user !== null) code.username = user.name; @@ -152,14 +152,14 @@ module.exports = (repository) => if (postedCode.id) { - var code = await repository.codes.getCode(postedCode.id); + var code = await repository.codes.get(postedCode.id); if (code === null || (code.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllCodes))) { res.sendStatus(404); return; } - await repository.codes.updateCode({ + await repository.codes.update({ id: postedCode.id, expiration: postedCode.expiration, description: postedCode.description, @@ -170,7 +170,7 @@ module.exports = (repository) => } else { - var codeId = await repository.codes.addCode({ + var codeId = await repository.codes.insert({ userId: user.id, expiration: postedCode.expiration, description: postedCode.description, @@ -187,7 +187,7 @@ module.exports = (repository) => { await checkAuthorization(req, res, repository, async (user) => { - var code = await repository.codes.getCode(req.params.id); + var code = await repository.codes.get(req.params.id); if (code == null || (code.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllCodes))) { res.sendStatus(404); @@ -206,7 +206,7 @@ module.exports = (repository) => { await checkAuthorization(req, res, repository, async (user) => { - var files = await repository.uploads.getUploads(user.hasAuth(AuthTokens.ViewAllUploads) ? null : user.id); + var files = await repository.uploads.list(user.hasAuth(AuthTokens.ViewAllUploads) ? null : user.id); var usernames = await repository.users.getNames(); var codedescriptions = await repository.codes.getDescriptions(); @@ -225,7 +225,7 @@ module.exports = (repository) => { await checkAuthorization(req, res, repository, async (user) => { - var upload = await repository.uploads.getUpload(req.params.id); + var upload = await repository.uploads.get(req.params.id); if (upload == null || (upload.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllUploads))) { res.sendStatus(404); @@ -269,5 +269,111 @@ module.exports = (repository) => })); + /* + Users + */ + router.get('/users', asyncHandler(async (req, res) => + { + await checkAuthorization(req, res, repository, async (user) => + { + if (!user.hasAuth(AuthTokens.ManageUsers)) + { + res.sendStatus(403); + return; + } + + var users = await repository.users.list(); + res.send(users); + }); + })); + + + router.get('/users/:id', asyncHandler(async (req, res) => + { + await checkAuthorization(req, res, repository, async (user) => + { + if (req.params.id !== user.id && !user.hasAuth(AuthTokens.ManageUsers)) + { + res.sendStatus(404); + return; + } + + var user = await repository.users.get(req.params.id); + if (user === null) + { + res.sendStatus(404); + return; + } + + res.send(user); + }); + })); + + + router.post('/users', asyncHandler(async (req, res) => + { + await checkAuthorization(req, res, repository, async (user) => + { + var postedUser = req.body; + + if (postedUser.id) + { + if (postedUser.id !== user.id && !user.hasAuth(AuthTokens.ManageUsers)) + { + res.sendStatus(403); + return; + } + + await repository.users.update({ + id: postedUser.id, + username: postedUser.username, + name: postedUser.name, + password: postedUser.password, + email: postedUser.email, + auth: postedUser.auth, + active: postedUser.active + }); + + res.sendStatus(200); + } + else + { + if (!user.hasAuth(AuthTokens.ManageUsers)) + { + res.sendStatus(403); + return; + } + + var userId = await repository.users.insert({ + username: postedUser.username, + name: postedUser.name, + password: postedUser.password, + email: postedUser.email, + auth: postedUser.auth, + active: postedUser.active, + createdByUserId: postedUser.createdByUserId + }); + } + + res.send(userId); + }); + })); + + + router.delete('/users/:id', asyncHandler(async (req, res) => + { + await checkAuthorization(req, res, repository, async (user) => + { + if (!user.hasAuth(AuthTokens.ManageUsers)) + { + res.sendStatus(403); + return; + } + + repository.users.delete(req.params.id); + res.sendStatus(200); + }); + })); + return router; } \ No newline at end of file diff --git a/lib/api/token.js b/lib/api/token.js index 0c13a7d..c2f8927 100644 --- a/lib/api/token.js +++ b/lib/api/token.js @@ -16,7 +16,7 @@ module.exports = (repository) => return; } - var userId = await repository.codes.findCodeUserId(req.body.code); + var userId = await repository.codes.getUserId(req.body.code); if (userId !== null) { jwt.sign({ diff --git a/lib/api/upload.js b/lib/api/upload.js index 0614445..99409bf 100644 --- a/lib/api/upload.js +++ b/lib/api/upload.js @@ -48,7 +48,7 @@ module.exports = (repository, tusServer) => // Upload API router.get('/message/:code', asyncHandler(async (req, res) => { - var code = await repository.codes.getCode(req.params.code); + var code = await repository.codes.get(req.params.code); if (code === null) { res.sendStatus(404); @@ -61,7 +61,7 @@ module.exports = (repository, tusServer) => return; } - var user = await repository.users.getUser(code.userId); + var user = await repository.users.get(code.userId); var name = user !== null ? user.name : null; res.send({ @@ -105,7 +105,7 @@ module.exports = (repository, tusServer) => return; } - var uploadId = await repository.uploads.addUpload(decoded.codeUserId, decoded.code, req.body.files, expiration); + var uploadId = await repository.uploads.insert(decoded.codeUserId, decoded.code, req.body.files, expiration); res.send({ id: uploadId }); }); }); diff --git a/lib/repository/code.js b/lib/repository/code.js index 22be78e..52c8885 100644 --- a/lib/repository/code.js +++ b/lib/repository/code.js @@ -42,7 +42,7 @@ class CodeRepository } - findCodeUserId(code) + getUserId(code) { var self = this; @@ -62,7 +62,7 @@ class CodeRepository } - async addCode(code) + async insert(code) { var self = this; @@ -92,7 +92,7 @@ class CodeRepository } - updateCode(code) + update(code) { var self = this; @@ -123,7 +123,7 @@ class CodeRepository } - getCodes(userId) + list(userId) { var self = this; @@ -170,7 +170,7 @@ class CodeRepository } - getCode(codeId) + get(codeId) { var self = this; diff --git a/lib/repository/upload.js b/lib/repository/upload.js index 24dc9fe..5717fe8 100644 --- a/lib/repository/upload.js +++ b/lib/repository/upload.js @@ -50,7 +50,7 @@ class UploadRepository } - addUpload(userId, code, files, expiration) + insert(userId, code, files, expiration) { var self = this; @@ -87,7 +87,7 @@ class UploadRepository } - getUploads(userId) + list(userId) { var self = this; @@ -110,7 +110,7 @@ class UploadRepository } - getUpload(uploadId) + get(uploadId) { var self = this; diff --git a/lib/repository/user.js b/lib/repository/user.js index bf49de6..63a4f5c 100644 --- a/lib/repository/user.js +++ b/lib/repository/user.js @@ -106,8 +106,27 @@ class UserRepository }); } + list() + { + var self = this; - getUser(userId) + return new Promise((resolve, reject) => + { + self.store.find({}, (err, docs) => + { + if (err) + { + reject(err); + return; + } + + resolve(_.map(docs, (doc) => new User(doc))); + }); + }); + } + + + get(userId) { var self = this; @@ -127,7 +146,7 @@ class UserRepository } - addUser(user) + insert(user) { var self = this; @@ -146,10 +165,10 @@ class UserRepository name: user.name, email: user.email, hashedPassword: hash, - created: user.created, + created: user.created || new Date(), createdByUserId: user.createdByUserId, active: user.active, - auth: user.auth + auth: user.auth || [] }, (err, dbUser) => { if (err) @@ -165,6 +184,82 @@ class UserRepository } + update(user) + { + var self = this; + + return new Promise((resolve, reject) => + { + let doUpdate = (newPassword) => + { + let updateObject = { + username: user.username, + name: user.name, + email: user.email, + active: user.active, + auth: user.auth + }; + + if (newPassword !== null) + updateObject.hashedPassword = newPassword; + + self.store.update({ _id: user.id }, { $set: updateObject }, + (err, numAffected) => + { + if (err) + { + reject(err); + return; + } + + if (numAffected == 0) + { + reject(); + } + + resolve(); + }); + }; + + if (user.password) + { + bcrypt.hash(user.password, 10, function(err, hash) + { + if (err) + { + reject(err); + return; + } + + doUpdate(hash); + }); + } + else + doUpdate(null); + }); + } + + + delete(userId) + { + var self = this; + + return new Promise((resolve, reject) => + { + self.store.remove({ _id: userId }, (err, numRemoved) => + { + if (err) + { + reject(err); + return; + } + + resolve(); + }); + }); + } + + getNames() { var self = this;