From 6fe11be108815e7e6243d2862caa0cc490e3020d Mon Sep 17 00:00:00 2001 From: WubzyGD Date: Fri, 20 Jan 2023 22:56:07 -0500 Subject: [PATCH] authorization/perms checking --- api/ani/v1/routes/user.js | 12 ++++++++---- api/index.js | 6 ++++-- .../{baseAuthorize.js => auth/authenticate.js} | 0 api/util/auth/authorize.js | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+), 6 deletions(-) rename api/util/{baseAuthorize.js => auth/authenticate.js} (100%) create mode 100644 api/util/auth/authorize.js diff --git a/api/ani/v1/routes/user.js b/api/ani/v1/routes/user.js index 0e22ea6..8ed01ab 100644 --- a/api/ani/v1/routes/user.js +++ b/api/ani/v1/routes/user.js @@ -22,8 +22,8 @@ module.exports = (app, router) => { if (!req.body) {return res.status(400).send("Missing body!");} if ( !req.body.name || !req.body.discord || !req.body.permissions || !Array.isArray(req.body.permissions) - || !req.body.name.match(/^[\w_ ]+$/gm) || req.body.name.length > 20 - || !req.params.id.match(/^[\w_]+$/gm) || req.params.id.length > 15 + || !req.body.name.match(/^[\w_\- ]+$/gm) || req.body.name.length > 20 + || !req.params.id.match(/^[\w_\-]+$/gm) || req.params.id.length > 15 || !req.body.password || req.body.password.length > 30 ) {return res.status(400).send("Malformed body or missing body data. Make sure you have all the required parameters, and you don't have illegal characters present.");} @@ -80,7 +80,7 @@ module.exports = (app, router) => { }); }); - router.use('/user/:id/permissions', app.auth.tokenPass, async (req, res, next) => { + router.use('/user/:id/permissions', app.auth.tokenPass, app.auth.permsPass('edit-users'), async (req, res, next) => { if (!req.params.id) {return res.status(400).send("Missing ID!");} const user = await Users.findOne({id: req.params.id.toLowerCase()}); if (!user) {return res.status(404).send("That user doesn't exist!");} @@ -93,5 +93,9 @@ module.exports = (app, router) => { req.user.permissions = permissions; req.user.markModified('permissions'); await req.user.save(); - }, (req, res, next) => {if (!req.authenticatedUser) {return res.status(401).send("You must be authenticated before you do that!");} return next();})); + }, (req, res, next) => { + if (!req.authenticatedUser) {return res.status(401).send("You must be authenticated before you do that!");} + if (req.unauthorized) {return res.status(401).send("You are not authorized to edit users!");} + return next(); + })); }; \ No newline at end of file diff --git a/api/index.js b/api/index.js index 96adabe..b2b851e 100644 --- a/api/index.js +++ b/api/index.js @@ -34,8 +34,10 @@ server = app.listen(4062, async () => { require('../db/build')(app); //place all models in memory to prevent double-compiling - app.auth.token = require('./util/baseAuthorize')(app); //jwt token validation - app.auth.tokenPass = require('./util/baseAuthorize')(app, true); //"next()" will run even if auth is not passed + app.auth.token = require('./util/auth/authenticate')(app); //jwt token validation + app.auth.tokenPass = require('./util/auth/authenticate')(app, true); //"next()" will run even if auth is not passed + app.auth.perms = require('./util/auth/authorize')(app); //permissions checking + app.auth.permsPass = require('./util/auth/authorize')(app, true); app.util = {}; app.util.list = require('./util/list'); diff --git a/api/util/baseAuthorize.js b/api/util/auth/authenticate.js similarity index 100% rename from api/util/baseAuthorize.js rename to api/util/auth/authenticate.js diff --git a/api/util/auth/authorize.js b/api/util/auth/authorize.js new file mode 100644 index 0000000..5a37eec --- /dev/null +++ b/api/util/auth/authorize.js @@ -0,0 +1,18 @@ +module.exports = (app, passAuth) => { + return requiredPermissions => { + if (!Array.isArray(requiredPermissions)) {requiredPermissions = [requiredPermissions];} + return (req, res, next) => { + if (!req.authenticatedUser) {return next();} + if (req.authenticatedUser.permissions.includes("admin")) {return next();} + else { + let hasAllPerms = true; + for (let permission of requiredPermissions) { + if (!req.authenticatedUser.permissions.includes(permission)) {hasAllPerms = false;} + } + + if (!hasAllPerms) {req.unauthorized = true; return passAuth ? next() : res.status(401).send("You are not authorized to do that!");} + else {return next();} + } + }; + }; +}; \ No newline at end of file