UNPKG

auth0-rules-testharness

Version:

deploy, execute, and test the output of Auth0 Rules using a webtask sandbox environment.

149 lines (121 loc) 4.41 kB
var assert = require('assert'); var cb = require('cb'); var ejs = require('ejs'); var request = require('request'); var winston = require('winston'); var sandbox_function_template = (function () { ; /* require('auth0-authz-rules-api').extend(global); return function (ctx, cb) { var console = _wrap_console(); var configuration = <%- JSON.stringify(model.configuration) %>; var webtask = ctx; var resultAggregate = function(error, user, context) { if (error) { return cb(error); } return cb(error, { user: user, context: context}); }; ( function (usr, ctx, cb) { var manipulator = function(error, user, context) { if(error) { return cb(error); } return cb(error, { user: usr, context: ctx }); }; (<%- model.script %>)(usr, ctx, manipulator); } )(<%- model.args %>, _wrap_callback(cb, console)); } */ }).toString().match(/[^]*\/\*([^]*)\*\/\s*\}$/)[1]; function runInSandbox(script, args, configuration, params) { var callback = args.slice(-1)[0]; var argList = args .slice(0, -1) .map(function (arg) { return JSON.stringify(arg || ''); }).join(', '); var code = ejs.render(sandbox_function_template, { model: { configuration: configuration || {}, args: argList, script: script } }); run(); function run() { var options = { method: 'POST', url: params.url + '/api/run/' + params.tenant + '?webtask_share_token', headers: { Authorization: 'Bearer ' + (params.token || params.key) }, timeout: params.timeout * 1000, ca: params.ca.length > 0 ? params.ca : undefined, body: code, }; request(options, function (err, res, body) { if (err) { if (typeof err === 'object' && (err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT')) { return callback(new Error(params.timeout)); } return callback(err); } if (res.statusCode === 429) { var backoff = (+res.headers['retry-after'] || 5) * 1000; backoff += Math.floor(Math.random() * backoff); winston.debug('scheduling retry of auth0-sandbox request', { backoff: backoff }); setTimeout(run_once, backoff); return; } if (res.statusCode !== 200 && res.statusCode !== 500) { var errorMessage = 'Invalid response code from the auth0-sandbox: HTTP ' + res.statusCode + '.'; var parsedBody = toJSON(body); if (parsedBody && parsedBody.error) { // Special error case: Script Error like a syntax error. The response has a status code of 500. errorMessage += ' ' + parsedBody.error; console.log('ADJUSTED ERROR MESSAGE', errorMessage); if (parsedBody.details) { errorMessage += ' ' + parsedBody.details; } return callback(new Error(errorMessage), undefined, parsedBody.stdout); } else { return callback(new Error(errorMessage), undefined, [body], null); } } var json = toJSON(body); if (!json || typeof json !== 'object') { return callback(new Error('Invalid response content from the auth0-sandbox: ' + body), undefined, [body], null); } if (json.message === 'Blocked event loop.') { var timeout_error = new Error(params.timeout, undefined, json.stdout, null); timeout_error.stack = json.stack; return callback(timeout_error, undefined, json.stdout, null); } if (json.error === 'Script generated an unhandled synchronous exception.') { var unhandledError = new Error(json.message); unhandledError.stack = json.stack; return callback(unhandledError, undefined, json.stdout, null); } if (json.error) { // callback is called with an error var parsed_error = typeof json.error === 'string' ? new Error(json.message || json.error) : json.error; parsed_error.fromSandbox = true; parsed_error.stack = json.stack; return callback(parsed_error, undefined, json.stdout, null); } return callback(null, json.result, json.stdout, null); }); } } function toJSON(obj) { var json; try { json = JSON.parse(obj); } catch (e) { json = null; } return json; } module.exports = runInSandbox;