From 6fcca6f3681ac898095797a39cf41f00fa5e81ce Mon Sep 17 00:00:00 2001 From: Michael Standen Date: Mon, 15 May 2017 14:33:52 +1200 Subject: [PATCH 1/3] Add ability limit write access to a subset of users through an additional configuration file --- README.md | 6 ++++++ lib/app.js | 18 +++++++++++++++++- lib/config.js | 8 +++++++- routes/auth.js | 13 +++++++++++++ views/403.pug | 7 +++++++ 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 views/403.pug diff --git a/README.md b/README.md index 0ff9da8e..b988330b 100644 --- a/README.md +++ b/README.md @@ -395,6 +395,12 @@ Configuration options reference If the endpoint doesn't provide the email address for the user, allow empty emails to authenticate anyway. Note that GitHub authentication usually requires this to be `true` (unless all wiki users have public email addresses on their GitHub accounts). +#### authorization.moderatorsFile (string: "") + + Absolute path for your moderators YAML file. If used, this file must contain a list of `usernames` and `emails` for users who have write access to the wiki. A user who has a match in either the `usernames` or `emails` list will have right access. + + If this field is left blank, all logged in users will have write access to the wiki. + #### pages.index (string: "Home") Defines the page name for the index of the wiki diff --git a/lib/app.js b/lib/app.js index f60304b0..daad962b 100644 --- a/lib/app.js +++ b/lib/app.js @@ -201,7 +201,23 @@ module.exports.initialize = function (config) { } } - app.all('/pages/*', requireAuthentication) + function requireModerator (req, res, next) { + requireAuthentication(req, res, function(){ + if (!res.locals.user.moderator) { + res.locals.title = '403 - Permission denied' + res.statusCode = 403 + res.render('403.pug') + } else { + next() + } + }) + } + + if (app.locals.config.get('authorization').moderators) { + app.all('/pages/*', requireModerator) + } else { + app.all('/pages/*', requireAuthentication) + } if (!app.locals.config.get('authorization').anonRead) { app.all('/wiki', requireAuthentication) diff --git a/lib/config.js b/lib/config.js index 23a97061..e950bda9 100644 --- a/lib/config.js +++ b/lib/config.js @@ -36,6 +36,11 @@ module.exports = (function () { } } + // Load moderators from moderatorsFile + if (config.authorization.moderatorsFile){ + config.authorization.moderators = yaml.load(fs.readFileSync(config.authorization.moderatorsFile).toString()) + } + return true }, @@ -124,7 +129,8 @@ module.exports = (function () { anonRead: true, validMatches: '.+', // Breaking changes in Jingo 1.5 (when this parameter has been added): the default for new servers is to NOT allow empty emails to validate - emptyEmailMatches: false + emptyEmailMatches: false, + moderatorsFile: '' }, // Defaults for the pages key are compatible with Jingo < 1 (which means diff --git a/routes/auth.js b/routes/auth.js index c1f0834c..c9176fda 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -193,6 +193,19 @@ passport.deserializeUser(function (user, done) { user.email = 'jingouser' } + // Check moderator status + user.moderator = false + var moderators = app.locals.config.get('authorization').moderators + if (moderators){ + if (moderators.usernames.indexOf(user.displayName) > -1 || + moderators.emails.indexOf(user.email) > -1){ + user.moderator = true + } + } else { + // If no moderators file supplied everyone is a 'moderator' + user.moderator = true + } + user.asGitAuthor = user.displayName + ' <' + user.email + '>' done(undefined, user) }) diff --git a/views/403.pug b/views/403.pug new file mode 100644 index 00000000..03d19b7e --- /dev/null +++ b/views/403.pug @@ -0,0 +1,7 @@ +extends layout + +block content + #content + .jumbotron + h2 #{title} + p You do not have permission to perform this action From 961454c829cff823f7a89b7025dc0aecba912d27 Mon Sep 17 00:00:00 2001 From: Michael Standen Date: Fri, 19 May 2017 08:35:03 +1200 Subject: [PATCH 2/3] Add moderator support to LDAP roles --- routes/auth.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/routes/auth.js b/routes/auth.js index c9176fda..68f59d8f 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -200,6 +200,9 @@ passport.deserializeUser(function (user, done) { if (moderators.usernames.indexOf(user.displayName) > -1 || moderators.emails.indexOf(user.email) > -1){ user.moderator = true + } else if (moderators.ldap && auth.ldap.enabled && + user[moderators.ldap.attribute] == moderators.ldap.value){ + user.moderator = true; } } else { // If no moderators file supplied everyone is a 'moderator' From 8cda1108739a56b4fe1a5c3a5b3400ad127233fa Mon Sep 17 00:00:00 2001 From: Michael Standen Date: Fri, 19 May 2017 08:40:47 +1200 Subject: [PATCH 3/3] Update README with example moderators file --- README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b988330b..92479609 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,24 @@ Configuration options reference #### authorization.moderatorsFile (string: "") - Absolute path for your moderators YAML file. If used, this file must contain a list of `usernames` and `emails` for users who have write access to the wiki. A user who has a match in either the `usernames` or `emails` list will have right access. + Absolute path for your moderators YAML file. If used, this file must contain a list of `usernames` and `emails` for users who have write access to the wiki. A user who has a match in either the `usernames` or `emails` list will have right access. The moderators file may also include an attribute and value for managing moderators via LDAP roles. + + Example moderators YAML file: + + ``` +--- +# A list of moderators usernames and emails +usernames: + - 'admin1' + - 'admin2' +emails: + - 'admin@email.com' + - 'anotheradmin@email.com' +# LDAP moderator role +ldap: + attribute: 'businessCategory' + value: 'A' + ``` If this field is left blank, all logged in users will have write access to the wiki.