From 0e29b4d08c5e1ca26c91a2a459766b77a6ca5146 Mon Sep 17 00:00:00 2001 From: "j.femia" Date: Sun, 1 Apr 2018 15:02:51 +0100 Subject: [PATCH 1/2] refactor auth mechanism into plugin --- app.js | 2 + config/config.json | 1 + plugins/auth/db/db.js | 100 +++++++++++++++++++++++++++++++++++++++++ plugins/loader.js | 3 ++ routes/index.js | 101 +++--------------------------------------- 5 files changed, 113 insertions(+), 94 deletions(-) create mode 100644 plugins/auth/db/db.js create mode 100644 plugins/loader.js diff --git a/app.js b/app.js index ec191356..a1d995e6 100644 --- a/app.js +++ b/app.js @@ -256,6 +256,8 @@ app.use(function (req, res, next){ req.i18n = i18n; req.app_context = app_context; req.i18n.setLocaleFromCookie(); + req.common = common; + req.config = config; next(); }); diff --git a/config/config.json b/config/config.json index 7473dd9c..ad8795c0 100644 --- a/config/config.json +++ b/config/config.json @@ -15,6 +15,7 @@ "show_featured_in_article": false, "featured_articles_count": "4", "password_protect": false, + "auth_provider": "db", "show_kb_meta": true, "suggest_allowed": true, "show_author_email": true, diff --git a/plugins/auth/db/db.js b/plugins/auth/db/db.js new file mode 100644 index 00000000..ab8da8a2 --- /dev/null +++ b/plugins/auth/db/db.js @@ -0,0 +1,100 @@ +exports.route = function(router) { + // setup form is shown when there are no users setup in the DB + router.get('/setup', function (req, res){ + var db = req.app.db; + db.users.count({}, function (err, user_count){ + // dont allow the user to "re-setup" if a user exists. + // set needs_setup to false as a user exists + req.session.needs_setup = false; + if(user_count === 0){ + res.render('setup', { + title: 'Setup', + config: req.config, + message: req.common.clear_session_value(req.session, 'message'), + message_type: req.common.clear_session_value(req.session, 'message_type'), + show_footer: 'show_footer', + helpers: req.handlebars + }); + }else{ + res.redirect(req.app_context + '/login'); + } + }); + }); + + // login the user and check the password + router.post('/login_action', function (req, res){ + var db = req.app.db; + var bcrypt = req.bcrypt; + var url = require('url'); + + db.users.findOne({user_email: req.body.email}, function (err, user){ + // check if user exists with that email + if(user === undefined || user === null){ + req.session.message = req.i18n.__('A user with that email does not exist.'); + req.session.message_type = 'danger'; + res.redirect(req.app_context + '/login'); + }else{ + // we have a user under that email so we compare the password + if(bcrypt.compareSync(req.body.password, user.user_password) === true){ + req.session.user = req.body.email; + req.session.users_name = user.users_name; + req.session.user_id = user._id.toString(); + req.session.is_admin = user.is_admin; + if(req.body.frm_referring_url === undefined || req.body.frm_referring_url === ''){ + res.redirect(req.app_context + '/'); + }else{ + var url_parts = url.parse(req.body.frm_referring_url, true); + if(url_parts.pathname !== '/setup' && url_parts.pathname !== req.app_context + '/login'){ + res.redirect(req.body.frm_referring_url); + }else{ + res.redirect(req.app_context + '/'); + } + } + }else{ + // password is not correct + req.session.message = req.i18n.__('Access denied. Check password and try again.'); + req.session.message_type = 'danger'; + res.redirect(req.app_context + '/login'); + } + } + }); + }); +} + +exports.logout = function(req, res) { + res.redirect(req.app_context + '/'); +}; + +exports.login = function(req, res) { + var db = req.app.db; + // set the template + req.common.setTemplateDir('admin', req); + + db.users.count({}, function (err, user_count){ + // we check for a user. If one exists, redirect to login form otherwise setup + if(user_count > 0){ + // set needs_setup to false as a user exists + req.session.needs_setup = false; + + // set the referring url + var referringUrl = req.header('Referer'); + if(typeof req.session.refer_url !== 'undefined' && req.session.refer_url !== ''){ + referringUrl = req.session.refer_url; + } + + res.render('login', { + title: 'Login', + referring_url: referringUrl, + config: req.config, + message: req.common.clear_session_value(req.session, 'message'), + message_type: req.common.clear_session_value(req.session, 'message_type'), + show_footer: 'show_footer', + helpers: req.handlebars + }); + }else{ + // if there are no users set the "needs_setup" session + req.session.needs_setup = true; + res.redirect(req.app_context + '/setup'); + } + }); +} \ No newline at end of file diff --git a/plugins/loader.js b/plugins/loader.js new file mode 100644 index 00000000..47636560 --- /dev/null +++ b/plugins/loader.js @@ -0,0 +1,3 @@ +exports.load = function(pluginType, pluginName) { + return require('./' + pluginType + '/' + pluginName + '/' + pluginName); +}; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index 2bea5d26..04f38b23 100644 --- a/routes/index.js +++ b/routes/index.js @@ -9,6 +9,9 @@ var mime = require('mime-types'); var lunr = require('lunr'); var config = common.read_config(); +var authProvider = require('../plugins/loader').load('auth', config.settings.auth_provider); +authProvider.route(router); + var appDir = path.dirname(require('require-main-filename')()); // The homepage of the site @@ -705,7 +708,8 @@ router.get('/logout', function (req, res){ req.session.pw_validated = null; req.session.message = null; req.session.message_type = null; - res.redirect(req.app_context + '/'); + + authProvider.logout(req, res); }); // users @@ -958,60 +962,8 @@ router.post('/user_update', common.restrict, function (req, res){ }); // login form -router.get('/login', function (req, res){ - var db = req.app.db; - // set the template - common.setTemplateDir('admin', req); - - db.users.count({}, function (err, user_count){ - // we check for a user. If one exists, redirect to login form otherwise setup - if(user_count > 0){ - // set needs_setup to false as a user exists - req.session.needs_setup = false; - - // set the referring url - var referringUrl = req.header('Referer'); - if(typeof req.session.refer_url !== 'undefined' && req.session.refer_url !== ''){ - referringUrl = req.session.refer_url; - } - - res.render('login', { - title: 'Login', - referring_url: referringUrl, - config: config, - message: common.clear_session_value(req.session, 'message'), - message_type: common.clear_session_value(req.session, 'message_type'), - show_footer: 'show_footer', - helpers: req.handlebars - }); - }else{ - // if there are no users set the "needs_setup" session - req.session.needs_setup = true; - res.redirect(req.app_context + '/setup'); - } - }); -}); - -// setup form is shown when there are no users setup in the DB -router.get('/setup', function (req, res){ - var db = req.app.db; - db.users.count({}, function (err, user_count){ - // dont allow the user to "re-setup" if a user exists. - // set needs_setup to false as a user exists - req.session.needs_setup = false; - if(user_count === 0){ - res.render('setup', { - title: 'Setup', - config: config, - message: common.clear_session_value(req.session, 'message'), - message_type: common.clear_session_value(req.session, 'message_type'), - show_footer: 'show_footer', - helpers: req.handlebars - }); - }else{ - res.redirect(req.app_context + '/login'); - } - }); +router.get('/login', function (req, res) { + authProvider.login(req, res); }); // Loops files on the disk, checks for their existance in any KB articles and removes non used files. @@ -1049,45 +1001,6 @@ router.get('/file_cleanup', common.restrict, function (req, res){ }); }); -// login the user and check the password -router.post('/login_action', function (req, res){ - var db = req.app.db; - var bcrypt = req.bcrypt; - var url = require('url'); - - db.users.findOne({user_email: req.body.email}, function (err, user){ - // check if user exists with that email - if(user === undefined || user === null){ - req.session.message = req.i18n.__('A user with that email does not exist.'); - req.session.message_type = 'danger'; - res.redirect(req.app_context + '/login'); - }else{ - // we have a user under that email so we compare the password - if(bcrypt.compareSync(req.body.password, user.user_password) === true){ - req.session.user = req.body.email; - req.session.users_name = user.users_name; - req.session.user_id = user._id.toString(); - req.session.is_admin = user.is_admin; - if(req.body.frm_referring_url === undefined || req.body.frm_referring_url === ''){ - res.redirect(req.app_context + '/'); - }else{ - var url_parts = url.parse(req.body.frm_referring_url, true); - if(url_parts.pathname !== '/setup' && url_parts.pathname !== req.app_context + '/login'){ - res.redirect(req.body.frm_referring_url); - }else{ - res.redirect(req.app_context + '/'); - } - } - }else{ - // password is not correct - req.session.message = req.i18n.__('Access denied. Check password and try again.'); - req.session.message_type = 'danger'; - res.redirect(req.app_context + '/login'); - } - } - }); -}); - // delete user router.get('/user/delete/:id', common.restrict, function (req, res){ // only allow admin From aa20e865e1e951a966bae0663e000f5ce7bfcac6 Mon Sep 17 00:00:00 2001 From: jfemia Date: Tue, 3 Apr 2018 15:12:42 +0100 Subject: [PATCH 2/2] Fixes crash attempting to edit a user that doesn't exist --- routes/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routes/index.js b/routes/index.js index 04f38b23..1053373f 100644 --- a/routes/index.js +++ b/routes/index.js @@ -736,9 +736,11 @@ router.get('/users', common.restrict, function (req, res){ }); // users -router.get('/user/edit/:id', common.restrict, function (req, res){ +router.get('/user/edit/:id', common.restrict, function (req, res, next){ var db = req.app.db; db.users.findOne({_id: common.getId(req.params.id)}, function (err, user){ + if(!user) return next('router'); + // if the user we want to edit is not the current logged in user and the current user is not // an admin we render an access denied message if(user.user_email !== req.session.user && req.session.is_admin === 'false'){