Skip to content

Instantly share code, notes, and snippets.

@pfrazee
Created May 22, 2013 18:01
Show Gist options
  • Save pfrazee/5629555 to your computer and use it in GitHub Desktop.
Save pfrazee/5629555 to your computer and use it in GitHub Desktop.
Old grimserver auth service
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