Compare commits
31 Commits
47bcf9c4ac
...
67d0315917
Author | SHA1 | Date |
---|---|---|
3wc | 67d0315917 | |
3wc | 9c8d8c89ca | |
Paul Rodwell | a38a1be4b7 | |
Paul Rodwell | ec5359de48 | |
Paul Rodwell | b3ffdd0890 | |
Robert Best | 7449fdab44 | |
Paul Rodwell | 70cebf5ab2 | |
Paul Rodwell | 1e443f2934 | |
Paul Rodwell | 95e2c76b5f | |
Robert Best | cae4118bc9 | |
Paul Rodwell | d43cbe7ff6 | |
Paul Rodwell | ebcfe9cc42 | |
Paul Rodwell | 5137dd86ac | |
Paul Rodwell | 3305674597 | |
Paul Rodwell | ec05842d31 | |
Paul Rodwell | cec8c04417 | |
Paul Rodwell | 88c15c0cef | |
Paul Rodwell | 53f8da4d4b | |
Paul Rodwell | 8f304374cf | |
Paul Rodwell | ff69116fbf | |
Paul Rodwell | 30a339f49a | |
Paul Rodwell | f7da864fdb | |
Paul Rodwell | b2927e47c9 | |
Paul Rodwell | 7e4e1e940d | |
Paul Rodwell | a0ef92ec8e | |
Paul Rodwell | 1d4c5d51df | |
Paul Rodwell | f6dcb5425e | |
Paul Rodwell | e648bf64a7 | |
Paul Rodwell | 32ef602460 | |
Paul Rodwell | 40afd20e4f | |
Robert Best | f914667efe |
|
@ -5,3 +5,4 @@ Ward Cunningham <ward@c2.com>
|
|||
Marc-Antoine Parent <maparent@acm.org>
|
||||
Ian Goodacre <Ian.Goodacre@entrain.nz>
|
||||
3wc <3wc.github@doesthisthing.work>
|
||||
Robert Best <chessscholar@gmail.com>
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
/*! modernizr 3.3.1 (Custom Build) | MIT *
|
||||
* https://modernizr.com/download/?-fetch-promises-setclasses !*/
|
||||
!function(e,n,s){function o(e,n){return typeof e===n}function i(){var e,n,s,i,a,f,l;for(var c in r)if(r.hasOwnProperty(c)){if(e=[],n=r[c],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(s=0;s<n.options.aliases.length;s++)e.push(n.options.aliases[s].toLowerCase());for(i=o(n.fn,"function")?n.fn():n.fn,a=0;a<e.length;a++)f=e[a],l=f.split("."),1===l.length?Modernizr[l[0]]=i:(!Modernizr[l[0]]||Modernizr[l[0]]instanceof Boolean||(Modernizr[l[0]]=new Boolean(Modernizr[l[0]])),Modernizr[l[0]][l[1]]=i),t.push((i?"":"no-")+l.join("-"))}}function a(e){var n=l.className,s=Modernizr._config.classPrefix||"";if(c&&(n=n.baseVal),Modernizr._config.enableJSClass){var o=new RegExp("(^|\\s)"+s+"no-js(\\s|$)");n=n.replace(o,"$1"+s+"js$2")}Modernizr._config.enableClasses&&(n+=" "+s+e.join(" "+s),c?l.className.baseVal=n:l.className=n)}var t=[],r=[],f={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var s=this;setTimeout(function(){n(s[e])},0)},addTest:function(e,n,s){r.push({name:e,fn:n,options:s})},addAsyncTest:function(e){r.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=f,Modernizr=new Modernizr,Modernizr.addTest("promises",function(){return"Promise"in e&&"resolve"in e.Promise&&"reject"in e.Promise&&"all"in e.Promise&&"race"in e.Promise&&function(){var n;return new e.Promise(function(e){n=e}),"function"==typeof n}()});var l=n.documentElement,c="svg"===l.nodeName.toLowerCase();Modernizr.addTest("fetch","fetch"in e),i(),a(t),delete f.addTest,delete f.addAsyncTest;for(var u=0;u<Modernizr._q.length;u++)Modernizr._q[u]();e.Modernizr=Modernizr}(window,document);
|
|
@ -15,9 +15,6 @@
|
|||
|
||||
settings = {}
|
||||
|
||||
# Mozilla Persona service closes on
|
||||
personaEnd = new Date('2016-11-30')
|
||||
|
||||
claim_wiki = () ->
|
||||
# we want to initiate a claim on a wiki
|
||||
#
|
||||
|
@ -34,10 +31,13 @@ claim_wiki = () ->
|
|||
.then (response) ->
|
||||
if response.ok
|
||||
response.json().then (json) ->
|
||||
ownerName = json.ownerName
|
||||
window.isClaimed = true
|
||||
window.isOwner = true
|
||||
update_footer ownerName, true
|
||||
if wiki.lineup.bestTitle() is 'Login Required'
|
||||
location.reload()
|
||||
else
|
||||
ownerName = json.ownerName
|
||||
window.isClaimed = true
|
||||
window.isOwner = true
|
||||
update_footer ownerName, true
|
||||
else
|
||||
console.log 'Attempt to claim site failed', response
|
||||
|
||||
|
@ -59,7 +59,7 @@ update_footer = (ownerName, isAuthenticated) ->
|
|||
logoutTitle = "Not Owner : Sign-out"
|
||||
logoutIconClass = 'fa fa-lock fa-lg fa-fw notOwner'
|
||||
$('footer > #security').append "<a href='#' id='logout' class='footer-item' title='#{logoutTitle}'><i class='#{logoutIconClass}'></i></a>"
|
||||
$('footer > #security > #logout').click (e) ->
|
||||
$('footer > #security > #logout').on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
myInit = {
|
||||
method: 'GET'
|
||||
|
@ -79,63 +79,16 @@ update_footer = (ownerName, isAuthenticated) ->
|
|||
# These probably should move into a menu, but this is far easier to begin with
|
||||
if !isClaimed
|
||||
$('footer > #security').append "<a href='#' id='claim' class='foot-item' title='Claim this Wiki'><i class='fa fa-key fa-lg fa-fw'></i></a>"
|
||||
$('footer > #security > #claim').click (e) ->
|
||||
$('footer > #security > #claim').on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
claim_wiki()
|
||||
else
|
||||
# only offer to add alternative id if using persona - at least initially.
|
||||
if settings.usingPersona
|
||||
$('footer > #security').append "<a href='#' id='addAltAuth' class='foot-item' title='Add Alternative Credentials'><i class='fa fa-user-plus fa-lg fa-fw'></i></a>"
|
||||
$('footer > #security > #addAltAuth').click (e) ->
|
||||
e.preventDefault
|
||||
|
||||
document.cookie = "wikiName=#{window.location.host}" + ";domain=.#{settings.cookieDomain}; path=/; max-age=300; sameSite=Strict;"
|
||||
|
||||
w = WinChan.open({
|
||||
url: settings.dialogAddAltURL
|
||||
relay_url: settings.relayURL
|
||||
window_features: "menubar=0, location=0, resizable=0, scrollbars=1, status=0, dialog=1, width=700, height=375"
|
||||
params: {}
|
||||
}, (err, r) ->
|
||||
if err
|
||||
console.log err
|
||||
else
|
||||
# add call to add alternative to owner here
|
||||
console.log 'send request to add owner identity'
|
||||
myInit = {
|
||||
method: 'GET'
|
||||
cache: 'no-cache'
|
||||
mode: 'same-origin'
|
||||
credentials: 'include'
|
||||
}
|
||||
fetch '/auth/addAltAuth', myInit
|
||||
.then (response) ->
|
||||
if response.ok
|
||||
console.log 'Alternative Identity added', response
|
||||
settings.usingPersona = false
|
||||
if settings.wikiHost
|
||||
dialogHost = settings.wikiHost
|
||||
else
|
||||
dialogHost = window.location.hostname
|
||||
settings.cookieDomain = dialogHost
|
||||
if settings.useHttps
|
||||
dialogProtocol = 'https:'
|
||||
else
|
||||
dialogProtocol = window.location.protocol
|
||||
if window.location.port
|
||||
dialogHost = dialogHost + ':' + window.location.port
|
||||
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'
|
||||
update_footer ownerName, isAuthenticated
|
||||
else
|
||||
console.log 'Attempt to claim site failed', response
|
||||
)
|
||||
else
|
||||
if !isClaimed
|
||||
signonTitle = 'Claim this Wiki'
|
||||
else
|
||||
signonTitle = 'Wiki Owner Sign-on'
|
||||
$('footer > #security').append "<a href='#' id='show-security-dialog' class='footer-item' title='#{signonTitle}'><i class='fa fa-lock fa-lg fa-fw'></i></a>"
|
||||
$('footer > #security > #show-security-dialog').click (e) ->
|
||||
$('footer > #security > #show-security-dialog').on 'click', (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
document.cookie = "wikiName=#{window.location.host}" + ";domain=.#{settings.cookieDomain}; path=/; max-age=300; sameSite=Strict;"
|
||||
|
@ -153,7 +106,10 @@ update_footer = (ownerName, isAuthenticated) ->
|
|||
if !isClaimed
|
||||
claim_wiki()
|
||||
else
|
||||
update_footer ownerName, true)
|
||||
if wiki.lineup.bestTitle() is 'Login Required'
|
||||
location.reload()
|
||||
else
|
||||
update_footer ownerName, true)
|
||||
|
||||
|
||||
|
||||
|
@ -187,49 +143,36 @@ setup = (user) ->
|
|||
lastCookie = currentCookie
|
||||
, 100
|
||||
|
||||
wiki.getScript '/security/modernizr-custom.js', () ->
|
||||
console.log 'modernizr loaded'
|
||||
unless Modernizr.promises
|
||||
require('es6-promise').polyfill()
|
||||
|
||||
unless Modernizr.fetch
|
||||
require('whatwg-fetch')
|
||||
|
||||
wiki.getScript '/security/winchan.js'
|
||||
if (!$("link[href='/security/style.css']").length)
|
||||
$('<link rel="stylesheet" href="/security/style.css">').appendTo("head")
|
||||
myInit = {
|
||||
method: 'GET'
|
||||
cache: 'no-cache'
|
||||
mode: 'same-origin'
|
||||
}
|
||||
fetch '/auth/client-settings.json', myInit
|
||||
.then (response) ->
|
||||
if response.ok
|
||||
response.json().then (json) ->
|
||||
window.isOwner = json.isOwner
|
||||
settings = json
|
||||
if settings.wikiHost
|
||||
dialogHost = settings.wikiHost
|
||||
else
|
||||
dialogHost = window.location.hostname
|
||||
settings.cookieDomain = dialogHost
|
||||
if settings.useHttps
|
||||
dialogProtocol = 'https:'
|
||||
else
|
||||
dialogProtocol = window.location.protocol
|
||||
if window.location.port
|
||||
dialogHost = dialogHost + ':' + window.location.port
|
||||
if settings.usingPersona
|
||||
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/personaLogin'
|
||||
else
|
||||
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'
|
||||
settings.relayURL = dialogProtocol + '//' + dialogHost + '/auth/relay.html'
|
||||
settings.dialogAddAltURL = dialogProtocol + '//' + dialogHost + '/auth/addAuthDialog'
|
||||
|
||||
|
||||
update_footer ownerName, isAuthenticated
|
||||
else
|
||||
console.log 'Unable to fetch client settings: ', response
|
||||
wiki.getScript '/security/winchan.js'
|
||||
if (!$("link[href='/security/style.css']").length)
|
||||
$('<link rel="stylesheet" href="/security/style.css">').appendTo("head")
|
||||
myInit = {
|
||||
method: 'GET'
|
||||
cache: 'no-cache'
|
||||
mode: 'same-origin'
|
||||
}
|
||||
fetch '/auth/client-settings.json', myInit
|
||||
.then (response) ->
|
||||
if response.ok
|
||||
response.json().then (json) ->
|
||||
window.isOwner = json.isOwner
|
||||
settings = json
|
||||
if settings.wikiHost
|
||||
dialogHost = settings.wikiHost
|
||||
else
|
||||
dialogHost = window.location.hostname
|
||||
settings.cookieDomain = dialogHost
|
||||
if settings.useHttps
|
||||
dialogProtocol = 'https:'
|
||||
else
|
||||
dialogProtocol = window.location.protocol
|
||||
if window.location.port
|
||||
dialogHost = dialogHost + ':' + window.location.port
|
||||
settings.dialogURL = dialogProtocol + '//' + dialogHost + '/auth/loginDialog'
|
||||
settings.relayURL = dialogProtocol + '//' + dialogHost + '/auth/relay.html'
|
||||
settings.dialogAddAltURL = dialogProtocol + '//' + dialogHost + '/auth/addAuthDialog'
|
||||
update_footer ownerName, isAuthenticated
|
||||
else
|
||||
console.log 'Unable to fetch client settings: ', response
|
||||
|
||||
window.plugins.security = {setup, claim_wiki, update_footer}
|
||||
|
|
|
@ -35,6 +35,7 @@ Sometimes, you'll be able to look up the URLs by visiting your provider's
|
|||
```JSON
|
||||
{
|
||||
"farm": true,
|
||||
"admin": {"oauth2": "ID VALUE FROM OWNER.JSON FILE OF ADMIN"},
|
||||
"security_type": "passportjs",
|
||||
"oauth2_clientID": "CLIENT ID",
|
||||
"oauth2_clientSecret": "CLIENT SECRET",
|
||||
|
@ -48,6 +49,7 @@ Sometimes, you'll be able to look up the URLs by visiting your provider's
|
|||
```JSON
|
||||
{
|
||||
"farm": true,
|
||||
"admin": {"oauth2": "ID VALUE FROM OWNER.JSON FILE OF ADMIN"},
|
||||
"security_type": "passportjs",
|
||||
"oauth2_clientID": "CLIENT ID",
|
||||
"oauth2_clientSecret": "CLIENT SECRET",
|
||||
|
|
|
@ -9,7 +9,7 @@ Configuration of Passport security plug-ins is a two stage process:
|
|||
|
||||
The legacy Mozilla Persona Passport plug-in does not require any configuration.
|
||||
|
||||
This plug-in comes with support for using GitHub, Google, and Twitter. Although the configuration process is broadly the same for each of these, there are some slight differences.
|
||||
This plug-in comes with support for using GitHub, Google, Twitter, and generic OAuth. Although the configuration process is broadly the same for each of these, there are some slight differences.
|
||||
|
||||
As a wiki server owner you need to pick one, or more, of these that you want to use.
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
|
@ -1,21 +1,17 @@
|
|||
{
|
||||
"name": "wiki-security-passportjs",
|
||||
"version": "0.6.1",
|
||||
"version": "0.8.2",
|
||||
"description": "Security plugin for Federated Wiki, using passport.js",
|
||||
"author": "Paul Rodwell <paul.rodwell@btinternet.com> (http://rodwell.me)",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@passport-js/passport-twitter": "^1.0.8",
|
||||
"coffeescript": "^2.4.1",
|
||||
"es6-promise": "^4.2.8",
|
||||
"lodash": "^4.17.19",
|
||||
"passport": "^0.3.2",
|
||||
"passport-github2": "^0.1.12",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"passport-oauth2": "^1.6.1",
|
||||
"passport-twitter": "github:paul90/passport-twitter#48b52556f48e4e8f7c55288baaf3ba3076eeba16",
|
||||
"persona-pass": "^0.2.1",
|
||||
"qs": "^6.7.0",
|
||||
"whatwg-fetch": "^3.2.0"
|
||||
"passport-oauth2": "^1.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coffeeify": "^3.0.1",
|
||||
|
|
|
@ -11,7 +11,6 @@ fs = require 'fs'
|
|||
path = require 'path'
|
||||
|
||||
https = require 'https'
|
||||
qs = require 'qs'
|
||||
|
||||
url = require 'url'
|
||||
|
||||
|
@ -38,7 +37,6 @@ module.exports = exports = (log, loga, argv) ->
|
|||
statusDir = argv.status
|
||||
|
||||
idFile = argv.id
|
||||
usingPersona = false
|
||||
|
||||
if argv.security_useHttps
|
||||
useHttps = true
|
||||
|
@ -53,29 +51,13 @@ module.exports = exports = (log, loga, argv) ->
|
|||
callbackHost = callbackHost + ":" + url.parse(argv.url).port
|
||||
else
|
||||
callbackHost = url.parse(argv.url).host
|
||||
if argv.oauth2_CallbackPort?
|
||||
callbackHost = callbackHost + ":" + argv.oauth2_CallbackPort
|
||||
|
||||
console.log "callbackHost", callbackHost
|
||||
|
||||
ids = []
|
||||
|
||||
# Mozilla Persona service closes on
|
||||
personaEnd = new Date('2016-11-30')
|
||||
|
||||
watchForOwnerChange = ->
|
||||
# we watch for owner changes, so we can update the information held here
|
||||
fs.watch(idFile, (eventType, filename) ->
|
||||
# re-read the owner file
|
||||
fs.readFile(idFile, (err, data) ->
|
||||
if err
|
||||
console.log 'Error reading ', idFile, err
|
||||
return
|
||||
owner = JSON.parse(data)
|
||||
usingPersona = false
|
||||
if _.isEmpty(_.intersection(_.keys(owner), ids))
|
||||
if _.has(owner, 'persona')
|
||||
usingPersona = true
|
||||
ownerName = owner.name
|
||||
)
|
||||
)
|
||||
|
||||
#### Public stuff ####
|
||||
|
||||
# Attempt to figure out if the wiki is claimed or not,
|
||||
|
@ -87,11 +69,6 @@ module.exports = exports = (log, loga, argv) ->
|
|||
fs.readFile(idFile, (err, data) ->
|
||||
if err then return cb err
|
||||
owner = JSON.parse(data)
|
||||
# we only enable persona if it is the only owner information.
|
||||
if _.isEmpty(_.intersection(_.keys(owner), ids))
|
||||
if _.has(owner, 'persona')
|
||||
usingPersona = true
|
||||
watchForOwnerChange()
|
||||
cb())
|
||||
else
|
||||
owner = ''
|
||||
|
@ -109,10 +86,9 @@ module.exports = exports = (log, loga, argv) ->
|
|||
if !exists
|
||||
fs.writeFile(idFile, JSON.stringify(id), (err) ->
|
||||
if err then return cb err
|
||||
console.log "Claiming wiki #{wikiName} for #{id}"
|
||||
console.log "Claiming wiki #{wikiName} for #{id.name}"
|
||||
owner = id
|
||||
ownerName = owner.name
|
||||
watchForOwnerChange()
|
||||
cb())
|
||||
else
|
||||
cb('Already Claimed')
|
||||
|
@ -140,11 +116,6 @@ module.exports = exports = (log, loga, argv) ->
|
|||
return true
|
||||
else
|
||||
return false
|
||||
when 'persona'
|
||||
if _.isEqual(owner[idProvider].email, req.session.passport.user[idProvider].email)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
else
|
||||
return false
|
||||
catch error
|
||||
|
@ -165,16 +136,11 @@ module.exports = exports = (log, loga, argv) ->
|
|||
return false
|
||||
|
||||
switch idProvider
|
||||
when "github", "google", "twitter", 'oauth2'
|
||||
when "github", "google", "twitter", "oauth2"
|
||||
if _.isEqual(admin[idProvider], req.session.passport.user[idProvider].id)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
when "persona"
|
||||
if _.isEqual(admin[idProvider], req.session.passport.user[idProvider].email)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
else
|
||||
return false
|
||||
|
||||
|
@ -200,12 +166,13 @@ module.exports = exports = (log, loga, argv) ->
|
|||
OAuth2Strategy = require('passport-oauth2').Strategy
|
||||
|
||||
oauth2StrategyName = callbackHost + 'OAuth'
|
||||
console.log "callbackHost", callbackHost
|
||||
|
||||
if argv.oauth2_UserInfoURL?
|
||||
OAuth2Strategy::userProfile = (accesstoken, done) ->
|
||||
console.log "hello"
|
||||
console.log accesstoken
|
||||
@_oauth2._request "GET", argv.oauth2_UserInfoURL, null, null, accesstoken, (err, data) ->
|
||||
console.log "data", data
|
||||
console.log "err", err
|
||||
if err
|
||||
return done err
|
||||
try
|
||||
|
@ -288,7 +255,7 @@ module.exports = exports = (log, loga, argv) ->
|
|||
# Twitter Strategy
|
||||
if argv.twitter_consumerKey? and argv.twitter_consumerSecret?
|
||||
ids.push('twitter')
|
||||
TwitterStrategy = require('passport-twitter').Strategy
|
||||
TwitterStrategy = require('@passport-js/passport-twitter').Strategy
|
||||
|
||||
twitterStrategyName = callbackHost + 'Twitter'
|
||||
|
||||
|
@ -323,24 +290,6 @@ module.exports = exports = (log, loga, argv) ->
|
|||
}
|
||||
cb(null, user)))
|
||||
|
||||
# Persona Strategy
|
||||
PersonaStrategy = require('persona-pass').Strategy
|
||||
|
||||
personaAudience = callbackProtocol + '//' + callbackHost
|
||||
|
||||
personaStrategyName = callbackHost + 'Persona'
|
||||
|
||||
passport.use(personaStrategyName, new PersonaStrategy({
|
||||
audience: personaAudience
|
||||
}, (email, cb) ->
|
||||
user = {
|
||||
persona: {
|
||||
email: email
|
||||
}
|
||||
}
|
||||
cb(null, user)))
|
||||
|
||||
|
||||
app.use(passport.initialize())
|
||||
app.use(passport.session())
|
||||
|
||||
|
@ -367,16 +316,11 @@ module.exports = exports = (log, loga, argv) ->
|
|||
app.get('/auth/google/callback',
|
||||
passport.authenticate(googleStrategyName, { prompt: 'select_account', successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
|
||||
|
||||
# Persona
|
||||
app.post('/auth/browserid',
|
||||
passport.authenticate(personaStrategyName, { successRedirect: '/auth/loginDone', failureRedirect: '/auth/loginDialog'}))
|
||||
|
||||
|
||||
app.get '/auth/client-settings.json', (req, res) ->
|
||||
# the client needs some information to configure itself
|
||||
settings = {
|
||||
useHttps: useHttps
|
||||
usingPersona: usingPersona
|
||||
}
|
||||
if wikiHost
|
||||
settings.wikiHost = wikiHost
|
||||
|
@ -417,47 +361,6 @@ module.exports = exports = (log, loga, argv) ->
|
|||
}
|
||||
res.render(path.join(__dirname, '..', 'views', 'securityDialog.html'), info)
|
||||
|
||||
app.get '/auth/personaLogin', (req, res) ->
|
||||
cookies = req.cookies
|
||||
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 = {
|
||||
wikiName: cookies['wikiName']
|
||||
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 = {
|
||||
wikiName: cookies['wikiName']
|
||||
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)
|
||||
|
||||
app.get '/auth/loginDone', (req, res) ->
|
||||
cookies = req.cookies
|
||||
|
||||
|
@ -502,15 +405,17 @@ module.exports = exports = (log, loga, argv) ->
|
|||
false
|
||||
|
||||
app.all '*', (req, res, next) ->
|
||||
# todo: think about assets??
|
||||
# don't protect site flag,
|
||||
return next() if req.url is '/favicon.png'
|
||||
return next() unless /\.(json|html)$/.test req.url
|
||||
|
||||
# prepare to examine remote server's forwarded session
|
||||
res.header 'Access-Control-Allow-Origin', req.get('Origin')||'*'
|
||||
res.header 'Access-Control-Allow-Credentials', 'true'
|
||||
return next() if isAuthorized(req) || allowedToView(req)
|
||||
# protect unclaimed by adding "add owner isnt ''" - maybe via parameter
|
||||
return next() if (isAuthorized(req) and (owner isnt '')) or allowedToView(req)
|
||||
return res.redirect("/view/#{m[1]}") if m = req.url.match /\/(.*)\.html/
|
||||
return res.json([]) if req.url == '/system/sitemap.json'
|
||||
return res.json(['Login Required']) if req.url == '/system/sitemap.json'
|
||||
|
||||
# not happy, explain why these pages can't be viewed
|
||||
problem = "This is a restricted wiki requires users to login to view pages. You do not have to be the site owner but you do need to login with a participating email address."
|
||||
|
@ -569,94 +474,12 @@ module.exports = exports = (log, loga, argv) ->
|
|||
console.log 'rejecting - not authorized', req.path
|
||||
res.sendStatus(403)
|
||||
|
||||
app.get '/auth/addAltAuth', authorized, (req, res) ->
|
||||
# add alternative authorentication scheme - only makes sense if user owns this site
|
||||
res.status(202).end()
|
||||
|
||||
user = req.session.passport.user
|
||||
|
||||
idProviders = _.keys(user)
|
||||
userIds = {}
|
||||
idProviders.forEach (idProvider) ->
|
||||
id = switch idProvider
|
||||
when "oauth2" then {
|
||||
name: user.oauth2.displayName
|
||||
oauth2: {
|
||||
id: user.oauth2.id
|
||||
username: user.oauth2.username
|
||||
}
|
||||
}
|
||||
when "twitter" then {
|
||||
name: user.twitter.displayName
|
||||
twitter: {
|
||||
id: user.twitter.id
|
||||
username: user.twitter.username
|
||||
}
|
||||
}
|
||||
when "github" then {
|
||||
name: user.github.displayName
|
||||
github: {
|
||||
id: user.github.id
|
||||
username: user.github.username
|
||||
email: user.github.emails
|
||||
}
|
||||
}
|
||||
when "google" then {
|
||||
name: user.google.displayName
|
||||
google: {
|
||||
id: user.google.id
|
||||
emails: user.google.emails
|
||||
}
|
||||
}
|
||||
# only needed until persona closes
|
||||
when "persona" then {
|
||||
name: user.persona.email
|
||||
.substr(0, user.persona.email.indexOf('@'))
|
||||
.split('.')
|
||||
.join(' ')
|
||||
.toLowerCase()
|
||||
.replace(/(^| )(\w)/g, (x) ->
|
||||
return x.toUpperCase())
|
||||
persona: {
|
||||
email: user.persona.email
|
||||
}
|
||||
}
|
||||
userIds = _.merge(userIds, id)
|
||||
|
||||
wikiDir = path.resolve(argv.data, '..')
|
||||
statusDir = argv.status.split(path.sep).slice(-1)[0]
|
||||
idFileName = path.parse(idFile).base
|
||||
|
||||
pattern = '*/' + statusDir + '/' + idFileName
|
||||
|
||||
glob(pattern, {cwd: wikiDir}, (err, files) ->
|
||||
_.forEach files, (file) ->
|
||||
# are we the owner?
|
||||
fs.readFile(path.join(wikiDir, file), 'utf8', (err, data) ->
|
||||
if err
|
||||
console.log 'Error reading ', file, err
|
||||
return
|
||||
siteOwner = JSON.parse(data)
|
||||
|
||||
if _.intersectionWith(_.entries(siteOwner), _.entries(user), _.isEqual).length > 0
|
||||
updateOwner = _.merge(user, siteOwner)
|
||||
fs.writeFile(path.join(wikiDir, file), JSON.stringify(userIds), (err) ->
|
||||
if err
|
||||
console.log 'Error writing ', file, err
|
||||
# if the write works the change will be picked up by fs.watch() in watchForOwnerChange
|
||||
# so there is nothing more to do here.
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
app.get '/auth/claim-wiki', (req, res) ->
|
||||
if owner
|
||||
console.log 'Claim Request Ignored: Wiki already has owner - ', wikiName
|
||||
res.sendStatus(403)
|
||||
else
|
||||
user = req.session.passport.user
|
||||
# there can be more than one id provider - initially only if we logged in with persona
|
||||
idProviders = _.keys(user)
|
||||
|
||||
id = {}
|
||||
|
@ -691,19 +514,6 @@ module.exports = exports = (log, loga, argv) ->
|
|||
emails: user.google.emails
|
||||
}
|
||||
}
|
||||
# only needed until persona closes
|
||||
when "persona" then {
|
||||
name: user.persona.email
|
||||
.substr(0, user.persona.email.indexOf('@'))
|
||||
.split('.')
|
||||
.join(' ')
|
||||
.toLowerCase()
|
||||
.replace(/(^| )(\w)/g, (x) ->
|
||||
return x.toUpperCase())
|
||||
persona: {
|
||||
email: user.persona.email
|
||||
}
|
||||
}
|
||||
|
||||
if _.isEmpty(id)
|
||||
console.log 'Unable to claim wiki', req.hostname, ' no valid id provided'
|
||||
|
|
Loading…
Reference in New Issue