2016-03-16 14:13:37 +00:00
|
|
|
|
###
|
|
|
|
|
* Federated Wiki : Security Plugin : Social
|
|
|
|
|
*
|
|
|
|
|
* Copyright Ward Cunningham and other contributors
|
|
|
|
|
* Licensed under the MIT license.
|
|
|
|
|
* https://github.com/fedwiki/wiki-security-social/blob/master/LICENSE.txt
|
|
|
|
|
###
|
|
|
|
|
|
|
|
|
|
#### Requires ####
|
|
|
|
|
fs = require 'fs'
|
|
|
|
|
path = require 'path'
|
|
|
|
|
|
|
|
|
|
https = require 'https'
|
|
|
|
|
qs = require 'qs'
|
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
url = require 'url'
|
|
|
|
|
|
|
|
|
|
_ = require('lodash')
|
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
passport = require 'passport'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Export a function that generates security handler
|
|
|
|
|
# when called with options object.
|
|
|
|
|
module.exports = exports = (log, loga, argv) ->
|
|
|
|
|
security = {}
|
|
|
|
|
|
|
|
|
|
#### Private stuff ####
|
|
|
|
|
|
|
|
|
|
owner = ''
|
2016-03-31 04:47:41 +00:00
|
|
|
|
ownerName = ''
|
2016-04-07 10:00:09 +00:00
|
|
|
|
user = {}
|
|
|
|
|
wikiName = argv.url
|
2016-04-29 20:29:58 +00:00
|
|
|
|
wikiHost = argv.wiki_domain
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
admin = argv.admin
|
|
|
|
|
|
2016-03-31 04:47:41 +00:00
|
|
|
|
statusDir = argv.status
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-06-24 10:33:17 +00:00
|
|
|
|
idFile = argv.id
|
2016-03-31 04:47:41 +00:00
|
|
|
|
usingPersona = false
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
if argv.security_useHttps
|
|
|
|
|
useHttps = true
|
|
|
|
|
callbackProtocol = "https:"
|
|
|
|
|
else
|
|
|
|
|
useHttps = false
|
|
|
|
|
callbackProtocol = url.parse(argv.url).protocol
|
|
|
|
|
|
|
|
|
|
if wikiHost
|
|
|
|
|
callbackHost = wikiHost
|
2016-05-28 08:51:15 +00:00
|
|
|
|
if url.parse(argv.url).port
|
|
|
|
|
callbackHost = callbackHost + ":" + url.parse(argv.url).port
|
2016-04-29 20:29:58 +00:00
|
|
|
|
else
|
|
|
|
|
callbackHost = url.parse(argv.url).host
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
ids = []
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-03-31 04:47:41 +00:00
|
|
|
|
# Mozilla Persona service closes on
|
|
|
|
|
personaEnd = new Date('2016-11-30')
|
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
#### Public stuff ####
|
|
|
|
|
|
|
|
|
|
# Attempt to figure out if the wiki is claimed or not,
|
|
|
|
|
# if it is return the owner.
|
|
|
|
|
|
|
|
|
|
security.retrieveOwner = (cb) ->
|
2016-06-24 10:33:17 +00:00
|
|
|
|
fs.exists idFile, (exists) ->
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if exists
|
2016-06-24 10:33:17 +00:00
|
|
|
|
fs.readFile(idFile, (err, data) ->
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if err then return cb err
|
2016-06-24 10:33:17 +00:00
|
|
|
|
owner = JSON.parse(data)
|
|
|
|
|
if _.has(owner, 'persona')
|
|
|
|
|
usingPersona = true
|
2016-03-16 14:13:37 +00:00
|
|
|
|
cb())
|
|
|
|
|
else
|
2016-06-24 10:33:17 +00:00
|
|
|
|
owner = ''
|
|
|
|
|
cb()
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
security.getOwner = getOwner = ->
|
2016-06-24 10:33:17 +00:00
|
|
|
|
if !owner.name?
|
|
|
|
|
ownerName = ''
|
2016-03-16 14:13:37 +00:00
|
|
|
|
else
|
2016-06-24 10:33:17 +00:00
|
|
|
|
ownerName = owner.name
|
2016-03-16 14:13:37 +00:00
|
|
|
|
ownerName
|
|
|
|
|
|
|
|
|
|
security.setOwner = setOwner = (id, cb) ->
|
2016-04-07 10:00:09 +00:00
|
|
|
|
fs.exists idFile, (exists) ->
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if !exists
|
2016-04-12 16:13:46 +00:00
|
|
|
|
fs.writeFile(idFile, JSON.stringify(id), (err) ->
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if err then return cb err
|
2016-04-07 10:00:09 +00:00
|
|
|
|
console.log "Claiming wiki #{wikiName} for #{id}"
|
2016-03-31 04:47:41 +00:00
|
|
|
|
owner = id
|
2016-04-12 16:13:46 +00:00
|
|
|
|
ownerName = owner.name
|
2016-03-16 14:13:37 +00:00
|
|
|
|
cb())
|
|
|
|
|
else
|
2016-04-07 10:00:09 +00:00
|
|
|
|
cb('Already Claimed')
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
security.getUser = (req) ->
|
2016-03-31 04:47:41 +00:00
|
|
|
|
if req.session.passport
|
|
|
|
|
if req.session.passport.user
|
|
|
|
|
return req.session.passport.user
|
|
|
|
|
else
|
|
|
|
|
return ''
|
2016-03-16 14:13:37 +00:00
|
|
|
|
else
|
|
|
|
|
return ''
|
|
|
|
|
|
2016-03-31 04:47:41 +00:00
|
|
|
|
security.isAuthorized = isAuthorized = (req) ->
|
2016-06-24 10:33:17 +00:00
|
|
|
|
if owner is ''
|
|
|
|
|
console.log 'isAuthorized: site not claimed'
|
2016-03-16 14:13:37 +00:00
|
|
|
|
return true
|
|
|
|
|
else
|
2016-04-07 10:00:09 +00:00
|
|
|
|
try
|
2016-07-04 10:57:16 +00:00
|
|
|
|
idProvider = req.session.passport.user.provider
|
2016-07-07 09:50:14 +00:00
|
|
|
|
switch idProvider
|
|
|
|
|
when 'github', 'google', 'twitter'
|
|
|
|
|
if _.isEqual(owner[idProvider].id, req.session.passport.user.id)
|
|
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
when 'persona'
|
|
|
|
|
if _.isEqual(owner[idProvider].email, req.session.passport.user.email)
|
|
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
else
|
|
|
|
|
return false
|
2016-06-24 10:33:17 +00:00
|
|
|
|
catch error
|
|
|
|
|
return false
|
2016-04-07 10:00:09 +00:00
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
security.isAdmin = (req) ->
|
2016-06-24 10:33:17 +00:00
|
|
|
|
try
|
|
|
|
|
if admin
|
2016-07-04 10:57:16 +00:00
|
|
|
|
idProvider = req.session.passport.user.provider
|
2016-07-07 09:50:14 +00:00
|
|
|
|
switch idProvider
|
|
|
|
|
when 'github', 'google', 'twitter'
|
|
|
|
|
if _.isEqual(admin[idProvider].id, req.session.passport.user.id)
|
|
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
when 'persona'
|
|
|
|
|
if _.isEqual(admin[idProvider].email, req.session.passport.user.email)
|
|
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
else
|
|
|
|
|
return false
|
2016-06-24 10:33:17 +00:00
|
|
|
|
catch error
|
2016-04-29 20:29:58 +00:00
|
|
|
|
return false
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-06-24 10:33:17 +00:00
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
security.login = (updateOwner) ->
|
2016-03-31 04:47:41 +00:00
|
|
|
|
console.log "Login...."
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
security.logout = () ->
|
|
|
|
|
(req, res) ->
|
|
|
|
|
console.log "Logout...."
|
|
|
|
|
|
|
|
|
|
security.defineRoutes = (app, cors, updateOwner) ->
|
|
|
|
|
|
|
|
|
|
passport.serializeUser = (user, req, done) ->
|
|
|
|
|
done(null, user)
|
|
|
|
|
|
|
|
|
|
passport.deserializeUser = (obj, req, done) ->
|
|
|
|
|
done(null, obj)
|
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
# Github Strategy
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if argv.github_clientID? and argv.github_clientSecret?
|
2016-04-29 20:29:58 +00:00
|
|
|
|
ids.push('github')
|
2016-03-16 14:13:37 +00:00
|
|
|
|
GithubStrategy = require('passport-github').Strategy
|
|
|
|
|
|
|
|
|
|
passport.use(new GithubStrategy({
|
2016-04-29 20:29:58 +00:00
|
|
|
|
clientID: argv.github_clientID
|
|
|
|
|
clientSecret: argv.github_clientSecret
|
|
|
|
|
scope: 'user:emails'
|
|
|
|
|
# callbackURL is optional, and if it exists must match that given in
|
|
|
|
|
# the OAuth application settings - so we don't specify it.
|
2016-03-16 14:13:37 +00:00
|
|
|
|
}, (accessToken, refreshToken, profile, cb) ->
|
2016-04-29 20:29:58 +00:00
|
|
|
|
user = {
|
2016-07-07 09:50:14 +00:00
|
|
|
|
provider: 'github'
|
2016-04-29 20:29:58 +00:00
|
|
|
|
id: profile.id
|
|
|
|
|
username: profile.username
|
|
|
|
|
displayName: profile.displayName
|
2016-07-07 09:50:14 +00:00
|
|
|
|
emails: profile.emails
|
2016-04-29 20:29:58 +00:00
|
|
|
|
}
|
|
|
|
|
cb(null, user)))
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
# Twitter Strategy
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if argv.twitter_consumerKey? and argv.twitter_consumerSecret?
|
2016-04-29 20:29:58 +00:00
|
|
|
|
ids.push('twitter')
|
2016-03-16 14:13:37 +00:00
|
|
|
|
TwitterStrategy = require('passport-twitter').Strategy
|
|
|
|
|
|
|
|
|
|
passport.use(new TwitterStrategy({
|
2016-04-29 20:29:58 +00:00
|
|
|
|
consumerKey: argv.twitter_consumerKey
|
|
|
|
|
consumerSecret: argv.twitter_consumerSecret
|
|
|
|
|
callbackURL: callbackProtocol + '//' + callbackHost + '/auth/twitter/callback'
|
2016-03-16 14:13:37 +00:00
|
|
|
|
}, (accessToken, refreshToken, profile, cb) ->
|
2016-03-31 04:47:41 +00:00
|
|
|
|
user = {
|
2016-04-29 20:29:58 +00:00
|
|
|
|
provider: 'twitter',
|
|
|
|
|
id: profile.id,
|
|
|
|
|
username: profile.username,
|
|
|
|
|
displayName: profile.displayName
|
2016-03-31 04:47:41 +00:00
|
|
|
|
}
|
|
|
|
|
cb(null, user)))
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
# Google Strategy
|
2016-03-16 14:13:37 +00:00
|
|
|
|
if argv.google_clientID? and argv.google_clientSecret?
|
2016-04-29 20:29:58 +00:00
|
|
|
|
ids.push('google')
|
2016-03-16 14:13:37 +00:00
|
|
|
|
GoogleStrategy = require('passport-google-oauth20').Strategy
|
|
|
|
|
|
|
|
|
|
passport.use(new GoogleStrategy({
|
2016-04-29 20:29:58 +00:00
|
|
|
|
clientID: argv.google_clientID
|
|
|
|
|
clientSecret: argv.google_clientSecret
|
|
|
|
|
callbackURL: callbackProtocol + '//' + callbackHost + '/auth/google/callback'
|
2016-03-16 14:13:37 +00:00
|
|
|
|
}, (accessToken, refreshToken, profile, cb) ->
|
2016-04-29 20:29:58 +00:00
|
|
|
|
user = {
|
|
|
|
|
provider: "google"
|
|
|
|
|
id: profile.id
|
|
|
|
|
displayName: profile.displayName
|
|
|
|
|
emails: profile.emails
|
|
|
|
|
}
|
2016-03-16 14:13:37 +00:00
|
|
|
|
cb(null, profile)))
|
2016-04-29 20:29:58 +00:00
|
|
|
|
|
2016-05-25 07:36:55 +00:00
|
|
|
|
# Persona Strategy
|
|
|
|
|
PersonaStrategy = require('persona-pass').Strategy
|
|
|
|
|
|
2016-07-07 09:50:14 +00:00
|
|
|
|
personaAudience = callbackProtocol + '//' + callbackHost
|
|
|
|
|
console.log 'Persona Audience: ', personaAudience
|
|
|
|
|
|
2016-05-25 07:36:55 +00:00
|
|
|
|
passport.use(new PersonaStrategy({
|
2016-07-07 09:50:14 +00:00
|
|
|
|
audience: personaAudience
|
2016-05-25 07:36:55 +00:00
|
|
|
|
}, (email, cb) ->
|
|
|
|
|
user = {
|
2016-07-07 09:50:14 +00:00
|
|
|
|
provider: "persona"
|
|
|
|
|
email: email
|
2016-05-25 07:36:55 +00:00
|
|
|
|
}
|
|
|
|
|
cb(null, user)))
|
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
app.use(passport.initialize())
|
|
|
|
|
app.use(passport.session())
|
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
# Github
|
|
|
|
|
app.get('/auth/github', passport.authenticate('github', {scope: 'user:email'}), (req, res) -> )
|
2016-03-16 14:13:37 +00:00
|
|
|
|
app.get('/auth/github/callback',
|
2016-04-29 20:29:58 +00:00
|
|
|
|
passport.authenticate('github', { successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
# Twitter
|
|
|
|
|
app.get('/auth/twitter', passport.authenticate('twitter'), (req, res) -> )
|
|
|
|
|
app.get('/auth/twitter/callback',
|
2016-03-31 04:47:41 +00:00
|
|
|
|
passport.authenticate('twitter', { successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
|
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
# Google
|
2016-03-16 14:13:37 +00:00
|
|
|
|
app.get('/auth/google', passport.authenticate('google', { scope: [
|
|
|
|
|
'https://www.googleapis.com/auth/plus.profile.emails.read'
|
|
|
|
|
]}))
|
|
|
|
|
app.get('/auth/google/callback',
|
2016-04-29 20:29:58 +00:00
|
|
|
|
passport.authenticate('google', { successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
|
|
|
|
|
|
2016-05-25 07:36:55 +00:00
|
|
|
|
# Persona
|
|
|
|
|
app.post('/auth/browserid',
|
|
|
|
|
passport.authenticate('persona', { successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
|
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
|
|
|
|
|
app.get '/auth/client-settings.json', (req, res) ->
|
|
|
|
|
# the client needs some information to configure itself
|
|
|
|
|
settings = {
|
|
|
|
|
useHttps: useHttps
|
2016-05-25 07:36:55 +00:00
|
|
|
|
usingPersona: usingPersona
|
2016-04-29 20:29:58 +00:00
|
|
|
|
}
|
|
|
|
|
if wikiHost
|
|
|
|
|
settings.wikiHost = wikiHost
|
|
|
|
|
res.json settings
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
|
|
|
|
app.get '/auth/loginDialog', (req, res) ->
|
2016-04-29 20:29:58 +00:00
|
|
|
|
referer = req.headers.referer
|
|
|
|
|
console.log "logging into: ", url.parse(referer).hostname
|
2016-03-16 14:13:37 +00:00
|
|
|
|
|
2016-04-29 20:29:58 +00:00
|
|
|
|
schemeButtons = []
|
|
|
|
|
_(ids).forEach (scheme) ->
|
|
|
|
|
switch scheme
|
|
|
|
|
when "twitter" then schemeButtons.push({button: "<a href='/auth/twitter' class='scheme-button twitter-button'><span>Twitter</span></a>"})
|
|
|
|
|
when "github" then schemeButtons.push({button: "<a href='/auth/github' class='scheme-button github-button'><span>Github</span></a>"})
|
|
|
|
|
when "google" then schemeButtons.push({button: "<a href='/auth/google' class='scheme-button google-button'><span>Google</span></a>"})
|
2016-04-12 16:46:51 +00:00
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
info = {
|
2016-05-28 08:51:15 +00:00
|
|
|
|
wikiName: if useHttps
|
|
|
|
|
url.parse(referer).hostname
|
|
|
|
|
else
|
|
|
|
|
url.parse(referer).host
|
2016-04-29 20:29:58 +00:00
|
|
|
|
wikiHostName: if wikiHost
|
|
|
|
|
"part of " + req.hostname + " wiki farm"
|
2016-04-12 16:46:51 +00:00
|
|
|
|
else
|
2016-04-29 20:29:58 +00:00
|
|
|
|
"a federated wiki site"
|
|
|
|
|
title: "Federated Wiki: Site Owner Sign-on"
|
|
|
|
|
loginText: "Sign in to"
|
|
|
|
|
schemes: schemeButtons
|
2016-03-16 14:13:37 +00:00
|
|
|
|
}
|
|
|
|
|
res.render(path.join(__dirname, '..', 'views', 'securityDialog.html'), info)
|
|
|
|
|
|
2016-05-25 07:36:55 +00:00
|
|
|
|
app.get '/auth/personaLogin', (req, res) ->
|
|
|
|
|
referer = req.headers.referer
|
|
|
|
|
console.log "logging into: ", url.parse(referer).hostname
|
|
|
|
|
|
|
|
|
|
schemeButtons = []
|
|
|
|
|
if Date.now() < personaEnd
|
|
|
|
|
schemeButtons.push({
|
|
|
|
|
button: "<a href='#' id='browserid' class='scheme-button persona-button'><span>Persona</span></a>
|
|
|
|
|
<script>
|
|
|
|
|
$('#browserid').click(function(){
|
|
|
|
|
navigator.id.get(function(assertion) {
|
|
|
|
|
if (assertion) {
|
|
|
|
|
$('input').val(assertion);
|
|
|
|
|
$('form').submit();
|
|
|
|
|
} else {
|
|
|
|
|
location.reload();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
</script>"})
|
|
|
|
|
info = {
|
2016-05-28 08:51:15 +00:00
|
|
|
|
wikiName: if useHttps
|
|
|
|
|
url.parse(referer).hostname
|
|
|
|
|
else
|
|
|
|
|
url.parse(referer).host
|
2016-05-25 07:36:55 +00:00
|
|
|
|
wikiHostName: if wikiHost
|
|
|
|
|
"part of " + req.hostname + " wiki farm"
|
|
|
|
|
else
|
|
|
|
|
"a federated wiki site"
|
|
|
|
|
title: "Federated Wiki: Site Owner Sign-on"
|
|
|
|
|
loginText: "Sign in to"
|
|
|
|
|
message: "Mozilla Persona closes on 30th November 2016. Wiki owners should add an alternative identity as soon as they are able."
|
|
|
|
|
schemes: schemeButtons
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
info = {
|
2016-05-28 08:51:15 +00:00
|
|
|
|
wikiName: if useHttps
|
|
|
|
|
url.parse(referer).hostname
|
|
|
|
|
else
|
|
|
|
|
url.parse(referer).host
|
2016-05-25 07:36:55 +00:00
|
|
|
|
wikiHostName: if wikiHost
|
|
|
|
|
"part of " + req.hostname + " wiki farm"
|
|
|
|
|
else
|
|
|
|
|
"a federated wiki site"
|
|
|
|
|
title: "Federated Wiki: Site Owner Sign-on"
|
|
|
|
|
message: "Mozilla Persona has now closed. Wiki owners will need to contact the Wiki Farm owner to re-claim their wiki."
|
|
|
|
|
}
|
|
|
|
|
res.render(path.join(__dirname, '..', 'views', 'personaDialog.html'), info)
|
|
|
|
|
|
2016-04-07 10:00:09 +00:00
|
|
|
|
app.get '/auth/loginDone', (req, res) ->
|
2016-07-26 11:17:22 +00:00
|
|
|
|
referer = req.headers.referer
|
2016-03-31 04:47:41 +00:00
|
|
|
|
info = {
|
2016-07-26 11:17:22 +00:00
|
|
|
|
wikiName: if useHttps
|
|
|
|
|
url.parse(referer).hostname
|
|
|
|
|
else
|
|
|
|
|
url.parse(referer).host
|
|
|
|
|
wikiHostName: if wikiHost
|
|
|
|
|
"part of " + req.hostname + " wiki farm"
|
|
|
|
|
else
|
|
|
|
|
"a federated wiki site"
|
2016-03-31 04:47:41 +00:00
|
|
|
|
title: if owner
|
|
|
|
|
"Wiki Site Owner Sign-on"
|
|
|
|
|
else
|
|
|
|
|
"Sign-on to claim Wiki site"
|
|
|
|
|
owner: getOwner
|
2016-07-26 11:17:22 +00:00
|
|
|
|
authMessage: "You are now logged in<br>If this window hasn't closed, you can close it."
|
2016-03-31 04:47:41 +00:00
|
|
|
|
}
|
|
|
|
|
res.render(path.join(__dirname, '..', 'views', 'done.html'), info)
|
|
|
|
|
|
2016-07-26 11:17:22 +00:00
|
|
|
|
app.get '/auth/addAuthDialog', (req, res) ->
|
|
|
|
|
|
|
|
|
|
|
2016-04-07 10:00:09 +00:00
|
|
|
|
app.get '/auth/claim-wiki', (req, res) ->
|
|
|
|
|
if owner
|
|
|
|
|
console.log 'Claim Request Ignored: Wiki already has owner'
|
|
|
|
|
res.sendStatus(403)
|
|
|
|
|
else
|
|
|
|
|
user = req.session.passport.user
|
|
|
|
|
id = switch user.provider
|
|
|
|
|
when "twitter" then {
|
|
|
|
|
name: user.displayName
|
|
|
|
|
twitter: {
|
|
|
|
|
id: user.id
|
|
|
|
|
username: user.username
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-04-29 20:29:58 +00:00
|
|
|
|
when "github" then {
|
|
|
|
|
name: user.displayName
|
|
|
|
|
github: {
|
|
|
|
|
id: user.id
|
|
|
|
|
username: user.username
|
2016-07-07 09:50:14 +00:00
|
|
|
|
email: user.emails
|
2016-04-29 20:29:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
when "google" then {
|
|
|
|
|
name: user.displayName
|
|
|
|
|
google: {
|
|
|
|
|
id: user.id
|
|
|
|
|
emails: user.emails
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-04-12 16:13:46 +00:00
|
|
|
|
|
|
|
|
|
setOwner id, (err) ->
|
2016-04-07 10:00:09 +00:00
|
|
|
|
if err
|
2016-04-29 20:29:58 +00:00
|
|
|
|
console.log 'Failed to claim wiki ', req.hostname, ' for ', JSON.stringify(id)
|
2016-04-07 10:00:09 +00:00
|
|
|
|
res.sendStatus(500)
|
2016-04-12 16:13:46 +00:00
|
|
|
|
updateOwner getOwner()
|
2016-04-07 10:00:09 +00:00
|
|
|
|
res.json({
|
|
|
|
|
ownerName: id.name
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-03-31 04:47:41 +00:00
|
|
|
|
app.get '/logout', (req, res) ->
|
|
|
|
|
console.log 'Logout...'
|
|
|
|
|
req.logout()
|
|
|
|
|
res.send("OK")
|
|
|
|
|
|
2016-03-16 14:13:37 +00:00
|
|
|
|
security
|