Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ The _authorization_ section of the config file has three keys: `anonRead`, `vali

If `anonRead` is true, then anyone who can access the wiki can read anything. If `anonRead` is false you need to authenticate also for reading and then the email of the user _must_ match at least one of the regular expressions provided via validMatches, which is a comma separated list. There is no "anonWrite", though. To edit a page the user must be authenticated.

`emptyEmailMatches` allows access when remote authentication providers do not provide an email address as part of user data. It defaults to `false`, but will usually need to be set to `true` for GitHub authentication (GitHub only returns email addresses that have been made public on users' GitHub accounts).
`emptyEmailMatches` allows access when remote authentication providers do not provide an email address as part of user data. It defaults to `false`, but will usually need to be set to `true` for GitHub authentication (GitHub only returns email addresses that have been made public on users' GitHub accounts). It must be set to `true` for Mastodon authentication.

The authentication is mandatory to edit pages from the web interface, but jingo works on a git repository; that means that you could skip the authentication altogether and edit pages with your editor and push to the remote that jingo is serving.

Expand Down Expand Up @@ -290,7 +290,24 @@ Configuration options reference

Values required for GitHub OAuth2 authentication. Refer to a previous section of this document on how to set them up.

#### authentication.google.redirectUrl (string: /auth/github/callback)
#### authentication.github.redirectUrl (string: /auth/github/callback)

Specifies a custom redirect URL for OAuth2 authentication instead of the default

#### authentication.mastodon.enabled (boolean: false)

Enable or disable authentication via Mastodon logins

#### authentication.mastodon.clientId
#### authentication.mastodon.clientSecret

Values required for Mastodon OAuth2 authentication. Refer to a previous section of this document on how to set them up.

#### authentication.mastodon.domain

Instance of Mastodon used to authenticate logins

#### authentication.mastodon.redirectUrl (string: /auth/mastodon/callback)

Specifies a custom redirect URL for OAuth2 authentication instead of the default

Expand Down
13 changes: 13 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ module.exports = (function () {
clientSecret: 'replace me with the real value',
redirectURL: ''
},
mastodon: {
enabled: false,
clientId: 'replace me with the real value',
clientSecret: 'replace me with the real value',
domain: 'your.mastodon.instance',
redirectURL: ''
},
ldap: {
enabled: false,
url: 'ldap://example.org:389',
Expand Down Expand Up @@ -165,6 +172,7 @@ module.exports = (function () {

if (!config.authentication.google.enabled &&
!config.authentication.github.enabled &&
!config.authentication.mastodon.enabled &&
!config.authentication.ldap.enabled &&
!config.authentication.alone.enabled &&
!config.authentication.local.enabled
Expand All @@ -183,6 +191,11 @@ module.exports = (function () {
return false
}

if (config.authentication.mastodon.enabled && (!config.authentication.mastodon.clientId || !config.authentication.mastodon.clientSecret || !config.authentication.mastodon.domain)) {
error = 'Invalid or missing authentication credentials for Mastodon (clientId and/or clientSecret and/or domain).'
return false
}

if (config.authentication.ldap.enabled && (!config.authentication.ldap.url || !config.authentication.ldap.searchBase || !config.authentication.ldap.searchFilter)) {
error = 'Invalid or missing config for LDAP (url and/or searchBase and/or searchFilter).'
return false
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"passport-github": "^0.1.5",
"passport-google-oauth": "^0.1.5",
"passport-local": "^1.0.0",
"passport-mastodon": "^0.1.3",
"pug": "^2.0.0-rc.4",
"semver": "^5.3.0",
"serve-favicon": "^2.1.7",
Expand Down
68 changes: 45 additions & 23 deletions routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var _ = require('lodash')
var passportLocal = require('passport-local')
var passportGoogle = require('passport-google-oauth')
var passportGithub = require('passport-github').Strategy
var passportMastodon = require('passport-mastodon').Strategy
var tools = require('../lib/tools')

var auth = app.locals.config.get('authentication')
Expand All @@ -16,7 +17,6 @@ if (auth.ldap.enabled) {

var passport = app.locals.passport
var proxyPath = app.locals.config.getProxyPath()
var redirectURL

router.get('/login', _getLogin)
router.get('/logout', _getLogout)
Expand All @@ -27,31 +27,17 @@ router.post('/login', passport.authenticate('local', {
}))
router.get('/auth/done', _getAuthDone)

router.get('/auth/google', passport.authenticate('google', {
scope: ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile']
}))

router.get('/oauth2callback', passport.authenticate('google', {
successRedirect: proxyPath + '/auth/done',
failureRedirect: proxyPath + '/login'
}))

router.get('/auth/github', passport.authenticate('github'))
router.get('/auth/github/callback', passport.authenticate('github', {
successRedirect: proxyPath + '/auth/done',
failureRedirect: proxyPath + '/login'
}))
if (auth.google.enabled) {
router.get('/auth/google', passport.authenticate('google', {
scope: ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile']
}))

if (auth.ldap.enabled) {
router.post('/auth/ldap', passport.authenticate('ldapauth', {
router.get('/oauth2callback', passport.authenticate('google', {
successRedirect: proxyPath + '/auth/done',
failureRedirect: proxyPath + '/login',
failureFlash: true
failureRedirect: proxyPath + '/login'
}))
}

if (auth.google.enabled) {
redirectURL = auth.google.redirectURL || app.locals.baseUrl + '/oauth2callback'
var redirectURL = auth.google.redirectURL || app.locals.baseUrl + '/oauth2callback'
passport.use(new passportGoogle.OAuth2Strategy({
clientID: auth.google.clientId,
clientSecret: auth.google.clientSecret,
Expand All @@ -68,7 +54,13 @@ if (auth.google.enabled) {
}

if (auth.github.enabled) {
redirectURL = auth.github.redirectURL || app.locals.baseUrl + '/auth/github/callback'
router.get('/auth/github', passport.authenticate('github'))
router.get('/auth/github/callback', passport.authenticate('github', {
successRedirect: proxyPath + '/auth/done',
failureRedirect: proxyPath + '/login'
}))

var redirectURL = auth.github.redirectURL || app.locals.baseUrl + '/auth/github/callback'

// Register a new Application with Github https://github.com/settings/applications/new
// Authorization callback URL /auth/github/callback
Expand All @@ -84,7 +76,37 @@ if (auth.github.enabled) {
))
}

if (auth.mastodon.enabled) {
router.get('/auth/mastodon', passport.authenticate('mastodon'))
router.get('/auth/mastodon/callback', passport.authenticate('mastodon', {
successRedirect: proxyPath + '/auth/done',
failureRedirect: proxyPath + '/login'
}))

var redirectURL = auth.mastodon.redirectURL || app.locals.baseUrl + '/auth/mastodon/callback'
// Register a new Application with Mastodon
// https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#apps
// Authorization callback URL /auth/mastodon/callback
passport.use(new passportMastodon({ // eslint-disable-line new-cap
clientID: auth.mastodon.clientId,
clientSecret: auth.mastodon.clientSecret,
domain: auth.mastodon.domain,
callbackURL: redirectURL
},
function (accessToken, refreshToken, profile, done) {
usedAuthentication('mastodon')
done(null, profile)
}
))
}

if (auth.ldap.enabled) {
router.post('/auth/ldap', passport.authenticate('ldapauth', {
successRedirect: proxyPath + '/auth/done',
failureRedirect: proxyPath + '/login',
failureFlash: true
}))

passport.use(new passportLDAP(function(req, callback) {
process.nextTick(function() {
var bindDn = auth.ldap.bindDn.replace(/{{username}}/g, req.body.username)
Expand Down
6 changes: 5 additions & 1 deletion views/login.pug
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ block content
p
+anchor('/auth/github', 'Github login').btn-auth.btn-auth-github

if (auth.google.enabled || auth.github.enabled)
if (auth.mastodon.enabled)
p
+anchor('/auth/mastodon', 'Mastodon login').btn-default

if (auth.google.enabled || auth.github.enabled || auth.mastodon.enabled)
p
+anchor("/", 'Cancel')

Expand Down