From 593c1d85d32bc462e38dd64e1e6e9f19ee70f736 Mon Sep 17 00:00:00 2001 From: mathieu-chouchou Date: Tue, 29 Oct 2019 23:46:38 +0100 Subject: [PATCH 1/6] WIP: simple permission middleware integration --- routes/ads.js | 9 +++++---- src/permissions.js | 12 +++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/routes/ads.js b/routes/ads.js index bfba03e..e935bb9 100644 --- a/routes/ads.js +++ b/routes/ads.js @@ -1,13 +1,14 @@ const express = require('express'); const router = new express.Router(); +const checkPermissions = require('../src/permissions'); const adModel = require('../models/ad'); /* GET to get to get to the ad creation form */ -router.get('/create', function(req, res, next) { +router.get('/create', checkPermissions('agent'), function(req, res, next) { res.render('ad_create'); }) - .post('/create', function(req, res, next) { + .post('/create', checkPermissions('agent'), function(req, res, next) { // TODO : gérer l'upload de fichier // (avec le middleware multiparty par exemple) const body = req.body; @@ -61,7 +62,7 @@ router.get('/create', function(req, res, next) { }); }); }) - .get('/update/:id', function(req, res, next) { + .get('/update/:id', checkPermissions('agent'), function(req, res, next) { const id = req.params.id; adModel.Ad.findOne({_id: id}, function(err, ad) { @@ -76,7 +77,7 @@ router.get('/create', function(req, res, next) { res.render('ad_create', {ad: ad, errors_update: errors}); }); }) - .delete('/delete/:id', function(req, res, next) { + .delete('/delete/:id', checkPermissions('agent'), function(req, res, next) { const id = req.params.id; adModel.Ad.deleteOne({_id: id}).exec() diff --git a/src/permissions.js b/src/permissions.js index 2a07a8e..5c24c00 100644 --- a/src/permissions.js +++ b/src/permissions.js @@ -7,8 +7,13 @@ const USER_PERMISSIONS = require('../models/user').USER_PERMISSIONS; * En cas d'autorisations insuffisantes l'utilisateur est redirigé vers la page * d'accueil avec un message d'erreur. * Ce middleware est à utiliser avant la véritable fonction de route. + * + * @param {string} requiredPermissionLevel + * le niveau de permission requis pour accéder à la ressource + * @return {Function} + * une fonction Express-friendly pour garder la chaîne intacte */ -function check_permissions(requiredPermissionLevel) { +function checkPermissions(requiredPermissionLevel) { return function(req, res, next) { const requestEmitterPermissionLevel = USER_PERMISSIONS[(req.user && req.user.role) || 'NOBODY']; @@ -17,7 +22,8 @@ function check_permissions(requiredPermissionLevel) { if (requestEmitterPermissionLevel < requiredPermissionLevel) { req.flash( 'info', - 'Vous n\'avez pas les autorisations requises pour accéder à cette ressource', + 'Vous n\'avez pas les autorisations requises' + + ' pour accéder à cette ressource', ); res.redirect('/'); } else { @@ -27,5 +33,5 @@ function check_permissions(requiredPermissionLevel) { } module.exports = { - check_permissions, + checkPermissions, }; -- GitLab From 95435fca2340161c2b0a7000f16fd33389fde7bd Mon Sep 17 00:00:00 2001 From: florian-boubou Date: Wed, 30 Oct 2019 19:58:56 +0100 Subject: [PATCH 2/6] Logged user availability middleware Middleware that passes the session's user to all templates with the name `_user` --- app.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app.js b/app.js index b6ecdad..2b70a42 100644 --- a/app.js +++ b/app.js @@ -77,6 +77,11 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use(flash()); app.use(passport.initialize()); app.use(passport.session()); +// Pass data for all renders +app.use(function(req, res, next) { + res.locals._user = req.user; + next(); +}); app.use('/', authRouter); app.use('/users', usersRouter); -- GitLab From 7c680890cb26c17650ee3ff6ba12057b3690086b Mon Sep 17 00:00:00 2001 From: florian-boubou Date: Wed, 30 Oct 2019 19:59:22 +0100 Subject: [PATCH 3/6] Fix ads checkbox input --- routes/ads.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/ads.js b/routes/ads.js index e935bb9..cc25d58 100644 --- a/routes/ads.js +++ b/routes/ads.js @@ -1,6 +1,6 @@ const express = require('express'); const router = new express.Router(); -const checkPermissions = require('../src/permissions'); +const checkPermissions = require('../src/permissions').checkPermissions; const adModel = require('../models/ad'); @@ -19,7 +19,7 @@ router.get('/create', checkPermissions('agent'), function(req, res, next) { type: body.type, transactionStatus: body.transactionStatus, price: body.price.replace(',', '.'), - published: body.published && true, + published: body.published === 'on', description: body.description, availabilityDate: body.availabilityDate === '' ? null : body.availabilityDate, -- GitLab From 9b28df746076fbf7ac8e0e8924c917f554c61a8e Mon Sep 17 00:00:00 2001 From: florian-boubou Date: Wed, 30 Oct 2019 20:01:52 +0100 Subject: [PATCH 4/6] Permissions enhancement Reinforce middleware, and add a function which authorizes for a given user and required level. --- src/permissions.js | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/permissions.js b/src/permissions.js index 5c24c00..266724e 100644 --- a/src/permissions.js +++ b/src/permissions.js @@ -8,13 +8,22 @@ const USER_PERMISSIONS = require('../models/user').USER_PERMISSIONS; * d'accueil avec un message d'erreur. * Ce middleware est à utiliser avant la véritable fonction de route. * - * @param {string} requiredPermissionLevel + * @param {string} level * le niveau de permission requis pour accéder à la ressource * @return {Function} * une fonction Express-friendly pour garder la chaîne intacte */ -function checkPermissions(requiredPermissionLevel) { +function checkPermissions(level) { + const requiredPermissionLevel = USER_PERMISSIONS[level]; + return function(req, res, next) { + if (!requiredPermissionLevel) { + console.error(`checkPermissions: Le rôle ${level} n'existe pas !`); + req.flash('info', 'Erreur dev : Rôle non défini (' + level + ')'); + res.redirect('/'); + return; + } + const requestEmitterPermissionLevel = USER_PERMISSIONS[(req.user && req.user.role) || 'NOBODY']; @@ -32,6 +41,30 @@ function checkPermissions(requiredPermissionLevel) { }; } +/** + * Vérifie les droits d'un utilisateur donné. + * + * @param {*} user + * l'utilisateur dont on vérifie les droits. + * @param {string} level + * le niveau d'autorisation requis pour qu'il soit autorisé. + * @return {boolean} + * vrai si l'utilisateur est autorisé. + */ +function checkUserPermissions(user, level) { + const requiredPermissionLevel = USER_PERMISSIONS[level]; + const requestEmitterPermissionLevel = + USER_PERMISSIONS[(user && user.role) || 'NOBODY']; + + if (!requiredPermissionLevel) { + console.error(`checkUserPermissions: Le rôle ${level} n'existe pas !`); + return false; + } + + return requestEmitterPermissionLevel >= requiredPermissionLevel; +} + module.exports = { checkPermissions, + checkUserPermissions, }; -- GitLab From 2e8549114193f28ce6c9df4aeeac76ab58a9c8ba Mon Sep 17 00:00:00 2001 From: florian-boubou Date: Wed, 30 Oct 2019 20:03:28 +0100 Subject: [PATCH 5/6] Permissions helper on templates Only render a page section if the logged user is authorized to --- src/helpers.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/helpers.js b/src/helpers.js index 0b457ba..f50386a 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -5,6 +5,15 @@ const addHelpers = function() { return (arg1 === arg2) ? options.fn(this) : options.inverse(this); }); + hbs.registerHelper('authorize', function(role, options) { + const check = require('./permissions').checkUserPermissions; + const user = options.data.root._user; + + if (check(user, role)) { + return options.fn(this); + } + }); + hbs.registerHelper('getEnumValue', function(enumName, key, options) { const adModule = require('../models/ad'); -- GitLab From 239bcb5868d30183afcb4b7ad052a0f277759daf Mon Sep 17 00:00:00 2001 From: florian-boubou Date: Wed, 30 Oct 2019 20:03:40 +0100 Subject: [PATCH 6/6] Authorize added to ad_view page --- views/ad_view.hbs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/views/ad_view.hbs b/views/ad_view.hbs index 8a90b55..8ac9e12 100644 --- a/views/ad_view.hbs +++ b/views/ad_view.hbs @@ -17,8 +17,10 @@ {{/if}} - Mettre à jour - + {{#authorize "agent"}} + Mettre à jour + + {{/authorize}} {{/each}} -- GitLab