From 03e3ebe0214348ff2190acba986d00f45b1dc702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20J=C3=A1nos=20Kov=C3=A1cs?= Date: Mon, 19 Sep 2016 14:56:16 +0200 Subject: [PATCH] Make Javascript implementation configurable Currently the only Javascript implentation supported by the std.javascript action is PyV8, a project that has been abandoned for about two years and can only be compiled with an outdated version of V8, one affected by several security vulnerabilities. This change adds support for v8eval, a more recent interface to V8 that is still being maintained. Change-Id: Id9cb89ffb05b37ef525a6085d49229de63420bbf --- mistral/config.py | 13 +++++++++++-- mistral/utils/javascript.py | 24 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/mistral/config.py b/mistral/config.py index 3045cfb7..2884575c 100644 --- a/mistral/config.py +++ b/mistral/config.py @@ -80,6 +80,14 @@ api_opts = [ ) ] +js_impl_opt = cfg.StrOpt( + 'js_implementation', + default='pyv8', + choices=['pyv8', 'v8eval'], + help='The JavaScript implementation to be used by the std.javascript ' + 'action to evaluate scripts.' +) + rpc_impl_opt = cfg.StrOpt( 'rpc_implementation', default='oslo', @@ -275,6 +283,7 @@ CONF.register_opts(event_engine_opts, group=EVENT_ENGINE_GROUP) CONF.register_opts(pecan_opts, group=PECAN_GROUP) CONF.register_opts(coordination_opts, group=COORDINATION_GROUP) CONF.register_opts(profiler_opts, group=PROFILER_GROUP) +CONF.register_opt(js_impl_opt) CONF.register_opt(rpc_impl_opt) CONF.register_opt(rpc_response_timeout_opt) CONF.register_opts(keycloak_oidc_opts, group=KEYCLOAK_OIDC_GROUP) @@ -288,8 +297,8 @@ CLI_OPTS = [ default_group_opts = itertools.chain( CLI_OPTS, - [wf_trace_log_name_opt, auth_type_opt, rpc_impl_opt, os_endpoint_type, - rpc_response_timeout_opt, expiration_token_duration] + [wf_trace_log_name_opt, auth_type_opt, js_impl_opt, rpc_impl_opt, + os_endpoint_type, rpc_response_timeout_opt, expiration_token_duration] ) CONF.register_cli_opts(CLI_OPTS) diff --git a/mistral/utils/javascript.py b/mistral/utils/javascript.py index 6245ff2d..a05f79b6 100644 --- a/mistral/utils/javascript.py +++ b/mistral/utils/javascript.py @@ -15,12 +15,14 @@ import abc import json +from oslo_config import cfg from oslo_utils import importutils from mistral import exceptions as exc - +CONF = cfg.CONF _PYV8 = importutils.try_import('PyV8') +_V8EVAL = importutils.try_import('v8eval') class JSEvaluator(object): @@ -31,7 +33,7 @@ class JSEvaluator(object): pass -class V8Evaluator(JSEvaluator): +class PyV8Evaluator(JSEvaluator): @classmethod def evaluate(cls, script, context): if not _PYV8: @@ -46,8 +48,22 @@ class V8Evaluator(JSEvaluator): result = ctx.eval(script) return _PYV8.convert(result) -# TODO(nmakhotkin) Make it configurable. -EVALUATOR = V8Evaluator + +class V8EvalEvaluator(JSEvaluator): + @classmethod + def evaluate(cls, script, context): + if not _V8EVAL: + raise exc.MistralException( + "v8eval module is not available. Please install v8eval." + ) + + v8 = _V8EVAL.V8() + return v8.eval(('$ = %s; %s' % (json.dumps(context), script)).encode( + encoding='UTF-8')) + + +EVALUATOR = (V8EvalEvaluator if CONF.js_implementation == 'v8eval' + else PyV8Evaluator) def evaluate(script, context):