From 9f9c4089be2112bfd8a55dd2cb996c811afab898 Mon Sep 17 00:00:00 2001 From: Sheogorath Date: Thu, 31 Aug 2017 23:33:55 +0200 Subject: [PATCH] Add OpenID to CodiMD With OpenID every OpenID capable provider can provide authentication for users of a CodiMD instance. This means we have federated authentication. Signed-off-by: Sheogorath --- lib/config/default.js | 3 +- lib/config/environment.js | 3 +- lib/config/index.js | 1 + lib/response.js | 4 +- lib/web/auth/index.js | 1 + lib/web/auth/openid/index.js | 61 ++++++++++++++++++++++++++++ package.json | 1 + public/views/shared/signin-modal.ejs | 21 +++++++++- 8 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 lib/web/auth/openid/index.js diff --git a/lib/config/default.js b/lib/config/default.js index cf7d2fc5..acfc2157 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -145,5 +145,6 @@ module.exports = { email: true, allowEmailRegister: true, allowGravatar: true, - allowPDFExport: true + allowPDFExport: true, + openID: true } diff --git a/lib/config/environment.js b/lib/config/environment.js index 6c4ce92f..65bacb4e 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -123,5 +123,6 @@ module.exports = { email: toBooleanConfig(process.env.CMD_EMAIL), allowEmailRegister: toBooleanConfig(process.env.CMD_ALLOW_EMAIL_REGISTER), allowGravatar: toBooleanConfig(process.env.CMD_ALLOW_GRAVATAR), - allowPDFExport: toBooleanConfig(process.env.CMD_ALLOW_PDF_EXPORT) + allowPDFExport: toBooleanConfig(process.env.CMD_ALLOW_PDF_EXPORT), + openID: toBooleanConfig(process.env.CMD_OPENID) } diff --git a/lib/config/index.js b/lib/config/index.js index 7d059c5c..f8b68e30 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -96,6 +96,7 @@ config.isGoogleEnable = config.google.clientID && config.google.clientSecret config.isDropboxEnable = config.dropbox.clientID && config.dropbox.clientSecret config.isTwitterEnable = config.twitter.consumerKey && config.twitter.consumerSecret config.isEmailEnable = config.email +config.isOpenIDEnable = config.openID config.isGitHubEnable = config.github.clientID && config.github.clientSecret config.isGitLabEnable = config.gitlab.clientID && config.gitlab.clientSecret config.isMattermostEnable = config.mattermost.clientID && config.mattermost.clientSecret diff --git a/lib/response.js b/lib/response.js index d30f2a8d..9f1740c8 100644 --- a/lib/response.js +++ b/lib/response.js @@ -88,6 +88,7 @@ function showIndex (req, res, next) { email: config.isEmailEnable, allowEmailRegister: config.allowEmailRegister, allowPDFExport: config.allowPDFExport, + openID: config.isOpenIDEnable, signin: authStatus, infoMessage: req.flash('info'), errorMessage: req.flash('error'), @@ -142,7 +143,8 @@ function responseCodiMD (res, note) { oauth2: config.isOAuth2Enable, email: config.isEmailEnable, allowEmailRegister: config.allowEmailRegister, - allowPDFExport: config.allowPDFExport + allowPDFExport: config.allowPDFExport, + openID: config.isOpenIDEnable }) } diff --git a/lib/web/auth/index.js b/lib/web/auth/index.js index 61e7c3f9..86ab4b28 100644 --- a/lib/web/auth/index.js +++ b/lib/web/auth/index.js @@ -45,6 +45,7 @@ if (config.isLDAPEnable) authRouter.use(require('./ldap')) if (config.isSAMLEnable) authRouter.use(require('./saml')) if (config.isOAuth2Enable) authRouter.use(require('./oauth2')) if (config.isEmailEnable) authRouter.use(require('./email')) +if (config.isOpenIDEnable) authRouter.use(require('./openid')) // logout authRouter.get('/logout', function (req, res) { diff --git a/lib/web/auth/openid/index.js b/lib/web/auth/openid/index.js new file mode 100644 index 00000000..96f61807 --- /dev/null +++ b/lib/web/auth/openid/index.js @@ -0,0 +1,61 @@ +'use strict' + +const Router = require('express').Router +const passport = require('passport') +const OpenIDStrategy = require('@passport-next/passport-openid').Strategy +const config = require('../../../config') +const models = require('../../../models') +const logger = require('../../../logger') +const {urlencodedParser} = require('../../utils') +const {setReturnToFromReferer} = require('../utils') + +let openIDAuth = module.exports = Router() + +passport.use(new OpenIDStrategy({ + returnURL: config.serverURL + '/auth/openid/callback', + realm: config.serverURL, + profile: true +}, function (openid, profile, done) { + var stringifiedProfile = JSON.stringify(profile) + models.User.findOrCreate({ + where: { + profileid: openid + }, + defaults: { + profile: stringifiedProfile + } + }).spread(function (user, created) { + if (user) { + var needSave = false + if (user.profile !== stringifiedProfile) { + user.profile = stringifiedProfile + needSave = true + } + if (needSave) { + user.save().then(function () { + if (config.debug) { logger.info('user login: ' + user.id) } + return done(null, user) + }) + } else { + if (config.debug) { logger.info('user login: ' + user.id) } + return done(null, user) + } + } + }).catch(function (err) { + logger.error('auth callback failed: ' + err) + return done(err, null) + }) +})) + +openIDAuth.post('/auth/openid', urlencodedParser, function (req, res, next) { + setReturnToFromReferer(req) + passport.authenticate('openid')(req, res, next) +}) + +// openID auth callback +openIDAuth.get('/auth/openid/callback', + passport.authenticate('openid', { + successReturnToOrRedirect: config.serverurl + '/', + failureRedirect: config.serverurl + '/' + }) +) diff --git a/package.json b/package.json index 12172639..c260b65f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "doctoc": "doctoc --title='# Table of Contents' README.md" }, "dependencies": { + "@passport-next/passport-openid": "^1.0.0", "Idle.Js": "git+https://github.com/shawnmclean/Idle.js", "archiver": "^2.1.1", "async": "^2.1.4", diff --git a/public/views/shared/signin-modal.ejs b/public/views/shared/signin-modal.ejs index f0cffad9..b413511c 100644 --- a/public/views/shared/signin-modal.ejs +++ b/public/views/shared/signin-modal.ejs @@ -78,7 +78,26 @@ <% } %> - <% if((facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || oauth2) && email) { %> + <% if((facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || oauth2) && openID) { %> +
+ <% }%> + <% if(openID) { %> +

OpenID

+
+
+
+ + +
+
+
+
+ +
+
+
+ <% } %> + <% if((facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || oauth2 || openID) && email) { %>
<% }%> <% if(email) { %>