Created
May 22, 2013 18:01
-
-
Save pfrazee/5629555 to your computer and use it in GitHub Desktop.
Old grimserver auth service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var auth = require('../../lib/auth'); | |
var utils = require('../../lib/utils'); | |
var qs = require('querystring'); | |
var main_server = require('../../globals').server; | |
function createServer(config) { | |
var express = require('express'); | |
var server = express(); | |
function end(req, res, next) { res.end(); } | |
function linkService(req, res, next) { | |
res.link('collection', '/auth/tokens', 'tokens'); | |
res.link('collection', '/auth/services', 'services'); | |
next(); | |
} | |
function linkTokensCollection(req, res, next) { | |
res.link('item', '/auth/tokens/{title}'); | |
next(); | |
} | |
function linkServicesCollection(req, res, next) { | |
res.link('item', '/auth/services/{title}'); | |
next(); | |
} | |
function linkServiceItem(req, res, next) { | |
res.link('collection', '/auth/services/'+req.param('serviceId')+'/tokens', 'tokens'); | |
next(); | |
} | |
function linkServiceTokensCollection(req, res, next) { | |
res.link('item', '/auth/services/'+req.param('serviceId')+'/tokens/{title}'); | |
next(); | |
} | |
function validateTokenRequest(req, res, next) { | |
if (!req.user) | |
return res.send(401, 'must authenticate using Basic auth'); | |
var params = (req.method == 'POST' ? req.body : req.query); | |
if (!params) | |
return res.send(422, 'request parameters (`response_type`, `client_id`, `scope`) required'); | |
if (params.response_type != 'token') | |
return res.send(422, 'unsupported `response_type` - must be "token"'); | |
if (!params.client_id) | |
return res.send(422, '`client_id` must be specified'); | |
var perms = auth.parseScope(params.scope || 'root:rw', req.param('serviceId')); | |
if (!perms) | |
return respondToTokenRequest({ error:'invalid_scope' }, req, res, next); | |
next(); | |
} | |
function renderTokenInterface(req, res, next) { | |
validateTokenRequest(req, res, function() { | |
var params = (req.method == 'POST' ? req.body : req.query); | |
params.scope = params.scope || 'root:rw'; | |
var perms = auth.parseScope(params.scope, req.param('serviceId')); | |
var html = utils.renderHtmlDoc( | |
'Grant access to '+params.client_id+' ?', | |
[ | |
'<form>', | |
'<h1>Grant access to '+params.client_id+' ?</h1>', | |
'<p>Requested permissions:</p>', | |
renderPermsHtml(perms), | |
'<p>', | |
'<button name="decision" value="allow">Allow</button>', | |
'<button name="decision" value="deny">Deny</button>', | |
'</p>', | |
'<input type="hidden" name="client_id" value="',params.client_id,'" />', | |
'<input type="hidden" name="redirect_uri" value="',params.redirect_uri || '','" />', | |
'<input type="hidden" name="scope" value="',params.scope,'" />', | |
'<input type="hidden" name="state" value="',params.state || '','" />', | |
'</form>' | |
] | |
); | |
res.type('html'); | |
res.send(html); | |
}); | |
} | |
function renderPermsHtml(perms) { | |
var html = []; | |
for (var module in perms) { | |
html.push('<li>'+module+': read'); | |
if (perms[module] == 'rw') | |
html.push(' and write'); | |
html.push('</li>'); | |
} | |
return '<ul>'+html.join('')+'</ul>'; | |
} | |
function getTokensCollection(req, res, next) { | |
if (req.accepts('html')) | |
renderTokenInterface(req, res, next); | |
else | |
res.send(406); | |
} | |
function addtoTokensCollection(req, res, next) { | |
var params = (req.method == 'POST' ? req.body : req.query); | |
params.scope = params.scope || 'root:rw'; | |
if (params.decision && params.decision != 'allow') | |
return respondToTokenRequest({ error:'access_denied' }, req, res, next); | |
var perms = auth.parseScope(params.scope, req.param('serviceId')); | |
auth.grantAccessToken(req.user.id, perms, params, function(err, token) { | |
if (err) respondToTokenRequest({ error:'server_error' }, req, res, next); | |
else { | |
var response = { | |
access_token: token, | |
token_type: 'bearer', | |
expires_in: main_server.config.auth.tokenTTL, | |
scope: params.scope, | |
state: params.state | |
}; | |
respondToTokenRequest(response, req, res, next); | |
} | |
}); | |
} | |
function respondToTokenRequest(data, req, res, next) { | |
var params = (req.method == 'POST' ? req.body : req.query); | |
if (params.redirect_uri) { | |
res.writeHead(302, { Location:params.redirect_uri+'#'+qs.stringify(data) }); | |
res.end(); | |
} else { | |
if (req.accepts('json')) | |
res.send(data); | |
else | |
res.send(qs.stringify(data)); | |
} | |
} | |
server.head('/', linkService, end); | |
server.get ('/', linkService, end); | |
server.head('/tokens', linkTokensCollection, end); | |
server.get ('/tokens', linkTokensCollection, getTokensCollection); | |
server.post('/tokens', linkTokensCollection, validateTokenRequest, addtoTokensCollection); | |
server.head('/services', linkServicesCollection, end); | |
server.get ('/services', linkServicesCollection, end); | |
server.head('/services/:serviceId', linkServiceItem, end); | |
server.get ('/services/:serviceId', linkServiceItem, end); | |
server.head('/services/:serviceId/tokens', linkServiceTokensCollection, end); | |
server.get ('/services/:serviceId/tokens', linkServiceTokensCollection, getTokensCollection); | |
server.post('/services/:serviceId/tokens', linkServiceTokensCollection, validateTokenRequest, addtoTokensCollection); | |
return server; | |
} | |
module.exports = { | |
createServer: createServer | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment