wiki-security-passportjs/server/social.coffee

301 lines
8.0 KiB
CoffeeScript
Raw Normal View History

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'
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-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-03-31 04:47:41 +00:00
console.log "statusDir: ", statusDir
2016-04-07 10:00:09 +00:00
idFile = path.join(statusDir, "owner.json")
2016-03-31 04:47:41 +00:00
personaIDFile = argv.id
usingPersona = false
2016-03-16 14:13:37 +00:00
ids = {}
schemes = {}
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-03-31 04:47:41 +00:00
fs.exists personaIDFile, (exists) ->
2016-03-16 14:13:37 +00:00
if exists
2016-03-31 04:47:41 +00:00
fs.readFile(personaIDFile, (err, data) ->
2016-03-16 14:13:37 +00:00
if err then return cb err
owner += data
2016-03-31 04:47:41 +00:00
usingPersona = true
2016-03-16 14:13:37 +00:00
cb())
else
2016-04-07 10:00:09 +00:00
fs.exists idFile, (exists) ->
2016-03-31 04:47:41 +00:00
if exists
2016-04-07 10:00:09 +00:00
fs.readFile(idFile, (err, data) ->
2016-03-31 04:47:41 +00:00
if err then return cb err
2016-04-07 10:00:09 +00:00
owner = JSON.parse(data)
2016-03-31 04:47:41 +00:00
cb())
else
owner = ''
cb()
2016-03-16 14:13:37 +00:00
security.getOwner = getOwner = ->
2016-03-31 04:47:41 +00:00
if usingPersona
if ~owner.indexOf '@'
ownerName = owner.substr(0, owner.indexOf('@'))
else
ownerName = owner
ownerName = ownerName.split('.').join(' ')
2016-03-16 14:13:37 +00:00
else
2016-04-07 10:00:09 +00:00
if !owner.name?
2016-03-31 04:47:41 +00:00
ownerName = ''
else
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
fs.writeFile(idFile, id, (err) ->
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-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-04-07 10:00:09 +00:00
if usingPersona
# not added legacy support yet, so...
return false
else if owner is ''
# site not claimed?
2016-03-16 14:13:37 +00:00
return true
else
2016-04-07 10:00:09 +00:00
authorized = false
try
authorized = switch req.session.passport.user.provider
when "twitter"
if owner.twitter.id is req.session.passport.user.id
true
return authorized
2016-03-16 14:13:37 +00:00
security.isAdmin = (req) ->
2016-04-07 10:00:09 +00:00
if usingPersona
# not added legacy support yet, so...
2016-03-16 14:13:37 +00:00
return false
else
2016-04-07 10:00:09 +00:00
admin = false
try
admin = switch req.session.passport.user.provider
when "twitter"
if admin is req.session.passport.user.id
true
return admin
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)
###
if argv.github_clientID? and argv.github_clientSecret?
github = {}
github['clientID'] = argv.github_clientID
github['clientSecret'] = argv.github_clientSecret
ids['github'] = github
GithubStrategy = require('passport-github').Strategy
passport.use(new GithubStrategy({
clientID: ids['github'].clientID
clientSecret: ids['github'].clientSecret
# this is not going to work - callback must equal that specified won github
# when the application was setup - it can't be dynamic....
callbackURL: 'http://localhost:3000/auth/github/callback'
}, (accessToken, refreshToken, profile, cb) ->
User.findOrCreate({githubID: profile.id}, (err, user) ->
return cb(err, user))))
###
if argv.twitter_consumerKey? and argv.twitter_consumerSecret?
schemes['twitter'] = true
twitter = {}
twitter['consumerKey'] = argv.twitter_consumerKey
twitter['consumerSecret'] = argv.twitter_consumerSecret
ids['twitter'] = twitter
TwitterStrategy = require('passport-twitter').Strategy
passport.use(new TwitterStrategy({
consumerKey: ids['twitter'].consumerKey
consumerSecret: ids['twitter'].consumerSecret
callbackURL: '/auth/twitter/callback'
}, (accessToken, refreshToken, profile, cb) ->
2016-03-31 04:47:41 +00:00
user = {
"provider": 'twitter',
"id": profile.id,
"username": profile.username,
"displayName": profile.displayName
}
cb(null, user)))
2016-03-16 14:13:37 +00:00
###
if argv.google_clientID? and argv.google_clientSecret?
google = {}
google['clientID'] = argv.google_clientID
google['clientSecret'] = argv.google_clientSecret
ids['google'] = google
GoogleStrategy = require('passport-google-oauth20').Strategy
passport.use(new GoogleStrategy({
clientID: ids['google'].clientID
clientSecret: ids['google'].clientSecret
callbackURL: 'http://localhost:3000/auth/google/callback'
}, (accessToken, refreshToken, profile, cb) ->
cb(null, profile)))
###
app.use(passport.initialize())
app.use(passport.session())
### Github
app.get('/auth/github', passport.authenticate('github'), (req, res) -> )
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/'}), (req, res) ->
# do what ever happens on login
)
###
# 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-03-16 14:13:37 +00:00
### Google
app.get('/auth/google', passport.authenticate('google', { scope: [
'https://www.googleapis.com/auth/plus.profile.emails.read'
]}))
app.get('/auth/google/callback',
passport.authenticate('google', {failureRedirect: '/'}), (req, res) ->
console.log 'google logged in!!!!'
res.redirect('/view/welcome-visitors'))
###
app.get '/auth/loginDialog', (req, res) ->
info = {
2016-04-07 10:00:09 +00:00
wikiName: req.hostname
wikiHostName: "a federated wiki site"
2016-03-16 14:13:37 +00:00
title: if owner
"Wiki Site Owner Sign-on"
else
"Sign-on to claim Wiki site"
schemes: "<a href='/auth/twitter' class='scheme-button twitter-button'><span>Twitter</span></a>"
2016-03-16 14:13:37 +00:00
}
res.render(path.join(__dirname, '..', 'views', 'securityDialog.html'), info)
2016-04-07 10:00:09 +00:00
app.get '/auth/loginDone', (req, res) ->
2016-03-31 04:47:41 +00:00
info = {
title: if owner
"Wiki Site Owner Sign-on"
else
"Sign-on to claim Wiki site"
owner: getOwner
authMessage: "You are now logged in..."
}
res.render(path.join(__dirname, '..', 'views', 'done.html'), info)
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
}
}
console.log 'id: ', id
setOwner JSON.stringify(id), (err) ->
if err
console.log 'Failed to claim wiki ', req.hostname, ' for ', id
res.sendStatus(500)
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