UNPKG

identity

Version:

Identity client

214 lines (158 loc) 6.41 kB
var restify = require('restify'); var URL = require('url'); var http = require('http'); module.exports = function(api, config){ //restify config var identity_server = restify.createJsonClient({ url: config.site, userAgent: api.config.general.serverName }); //helper function var startRequest = function(application, path, method, options, callback){ path = '/api/' + path; //add the access_token if(path.indexOf('?') !== -1){ path += '&access_token=' + application.access_token; }else{ path += '?access_token=' + application.access_token; } var headers; if(method === 'del'){ headers = { 'content-length': 0 }; } //create restify instance var app = restify.createJsonClient({ url: application.url, userAgent: api.config.general.serverName, headers: headers }); api.logger.info('Request "' + path + '" of application "' + application.name + '" (' + application.url + ')'); //replace callback with a simpler version if(typeof callback === 'function'){ var original = callback; callback = function(err, req, res, resp){ original(err, resp, req, res); } } //start request if(options === null){ app[method](path, callback); }else{ app[method](path, options, callback); } }; return function application(name, access_token){ var key = '__identity_application_' + name + (access_token || ''); return { action: function(path, method, options, callback){ //get the current access_token for the application this.getAccessToken(function(application){ if(application){ if(access_token && name === 'identity'){ //if there is a given access_token - use it inseatd application.access_token = access_token; } startRequest(application, path, method, options, callback); }else{ api.logger.error('did not get an access_token for application ' + name); callback('did not get an access_token for application ' + name); } }); }, get: function(path, options, callback){ //put params into the url... restify wont do it for us :( path = URL.format({pathname: path, query:options}); this.action(path, 'get', null, callback); }, post: function(path, options, callback){ this.action(path, 'post', options, callback); }, put: function(path, options, callback){ this.action(path, 'put', options, callback); }, del: function(path, callback){ this.action(path, 'del', null, callback); }, proxy: function(path, connection, next){ var req = connection.rawConnection.req; var res = connection.rawConnection.res; this.getAccessToken(function(application){ if(access_token && name === 'identity'){ //if there is a given access_token - use it inseatd application.access_token = access_token; } path = '/api/' + path; //add the access_token if(path.indexOf('?') !== -1){ path += '&access_token=' + application.access_token; }else{ path += '?access_token=' + application.access_token; } api.logger.info('Request "' + path + '" of application "' + application.name + '" (' + application.url + ')'); var options = {}; var uri = URL.parse(application.url); options.hostname = uri.hostname; options.path = path; options.port = uri.port; options.method = req.method; var json = null; if(req.method === 'POST'){ json = JSON.stringify(connection.rawConnection.params.body); var len = Buffer.byteLength(json, 'utf8'); options.headers = {'content-type': req.headers['content-type'], 'content-length': len}; } var newReq = http.request(options, function(newRes) { var headers = newRes.headers; delete headers['set-cookie']; res.writeHead(newRes.statusCode, headers); newRes.pipe(res).on('finish', function(){ next(connection, false); }); }).on('error', function(err) { res.statusCode = 500; res.end(); }); if(json){ newReq.write(json); } newReq.end(); }); }, getAccessToken: function(callback){ //load the current access_token from our cache api.cache.load(key, function(error, application){ if(application && application.access_token && application.expires_at > new Date().getTime()){ //return it callback(application) }else{ var url = '/api/application/access_token'; var params = {client_id: config.id, secret: config.secret, application_name: name}; if(name !== 'identity' && access_token){ url = '/api/user/access_token'; params = {access_token: access_token, application_name: name}; } //ask identity server for a new token identity_server.post(url, params , function(err, req, res, resp){ if(err || resp === null){ return callback(null); } var application = resp.application; if(application && application.access_token){ var ttl = (application.ttl - 10) * 1000 application.expires_at = new Date().getTime() + ttl; api.cache.save(key, application, ttl, function(error){ //TODO: error handling... callback(application); }); }else{ callback(null); } }); } }); } } } };