diff --git a/app.js b/app.js index b6ecdad82f70599c45b6f38aa753ab666f67eb3d..2b70a4261882a375c742388e5a95ab9d26069696 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); diff --git a/routes/ads.js b/routes/ads.js index 3755db61db58f7e3799654e9f04f2f62d8d6f8c8..38e4ca4f26361b4c4489b0f7801b0cfeccaaa319 100644 --- a/routes/ads.js +++ b/routes/ads.js @@ -1,6 +1,7 @@ const express = require('express'); const multer = require('multer'); const router = new express.Router(); +const checkPermissions = require('../src/permissions').checkPermissions; const adModel = require('../models/ad'); @@ -9,12 +10,11 @@ const upload = multer({ }); /* 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', upload.array('pictures', 3), function(req, res, next) { - // TODO : gérer l'upload de fichier - // (avec le middleware multiparty par exemple) + .post('/create', checkPermissions('agent'), + upload.array('pictures', 3), function(req, res, next) { const body = req.body; const id = body.id; @@ -23,7 +23,7 @@ router.get('/create', 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, @@ -72,7 +72,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) { @@ -87,7 +87,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/helpers.js b/src/helpers.js index 0b457ba031993da8e5ea966ac5fbe0c60039a6f8..f50386aec6d40a6a08475c1662f75c2cd120ce64 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'); diff --git a/src/permissions.js b/src/permissions.js index 2a07a8e971fef44ae37b079ae8b5c95e9309aa2e..266724e7f4d6a854200262ba7964bac262e45b78 100644 --- a/src/permissions.js +++ b/src/permissions.js @@ -7,9 +7,23 @@ 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} level + * 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(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']; @@ -17,7 +31,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 { @@ -26,6 +41,30 @@ function check_permissions(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 = { - check_permissions, + checkPermissions, + checkUserPermissions, }; diff --git a/views/ad_view.hbs b/views/ad_view.hbs index 8a90b55ef86edeaabf4ccc2517c31c30f2ac048a..8ac9e129d0fa048a51bc7f08b6c990b42320a7a6 100644 --- a/views/ad_view.hbs +++ b/views/ad_view.hbs @@ -17,8 +17,10 @@ {{/if}} - Mettre à jour - + {{#authorize "agent"}} + Mettre à jour + + {{/authorize}} {{/each}}