diff --git a/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java b/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java index 648d304e96..f2a282bd60 100644 --- a/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java +++ b/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java @@ -1358,7 +1358,7 @@ public void testSensitiveData() throws Exception { byte[] log = run(); assertLog(log, ".*" + Pattern.quote("sensitive: ******") + ".*"); assertLog(log, ".*" + Pattern.quote("log value: ******") + ".*"); - assertLog(log, ".*" + Pattern.quote("hack: B O O M") + ".*"); + assertLog(log, ".*" + Pattern.quote("hack: M A S K _ M E ") + ".*"); assertLog(log, ".*" + Pattern.quote("map: {nonSecretButMasked=******, secret=******}") + ".*"); assertLog(log, ".*" + Pattern.quote("map: {nonSecret=non secret value, secret=******}") + ".*"); @@ -1367,6 +1367,8 @@ public void testSensitiveData() throws Exception { assertLog(log, ".*" + Pattern.quote("secret from map: ******") + ".*"); + assertLog(log, ".*secret from task execute: .*" + Pattern.quote("keyWithSecretValue=******") + ".*"); + log = resume("ev1", ProcessConfiguration.builder().build()); assertLog(log, ".*" + Pattern.quote("mySecret after suspend: ******") + ".*"); } diff --git a/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/tasks/Tasks.java b/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/tasks/Tasks.java index ea962cff60..67e742271c 100644 --- a/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/tasks/Tasks.java +++ b/runtime/v2/runner-test/src/test/java/com/walmartlabs/concord/runtime/v2/runner/tasks/Tasks.java @@ -9,9 +9,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -305,6 +305,13 @@ public String get(Object key) { public Set> entrySet() { return null; } + + @SensitiveData(keys = "keyWithSecretValue") + @Override + public TaskResult execute(Variables input) { + return TaskResult.success() + .value("keyWithSecretValue", "topSecret!!!!"); + } } @Named("injectorTestBean") diff --git a/runtime/v2/runner-test/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/sensitiveData/concord.yaml b/runtime/v2/runner-test/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/sensitiveData/concord.yaml index 604f797b1c..c1b240001a 100644 --- a/runtime/v2/runner-test/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/sensitiveData/concord.yaml +++ b/runtime/v2/runner-test/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/sensitiveData/concord.yaml @@ -2,7 +2,7 @@ flows: default: - log: "sensitive: ${sensitiveTask.getSensitive('BOOM')}" - - expr: "${sensitiveTask.getSensitive('BOOM')}" + - expr: "${sensitiveTask.getSensitive('MASK_ME')}" out: mySecret - log: "log value: ${mySecret}" @@ -16,6 +16,10 @@ flows: - log: "secret from map: ${sensitiveTask.mySecretKey}" + - task: sensitiveTask + out: taskResult + - log: "secret from task execute: ${taskResult}" + - suspend: ev1 - log: "mySecret after suspend: ${mySecret}" diff --git a/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/LazyExpressionEvaluator.java b/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/LazyExpressionEvaluator.java index 71f6c13bfe..afdf75171a 100644 --- a/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/LazyExpressionEvaluator.java +++ b/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/LazyExpressionEvaluator.java @@ -114,8 +114,7 @@ T evalValue(LazyEvalContext ctx, Object value, Class expectedType) { } return expectedType.cast(src); - } else if (value instanceof String) { - String s = (String) value; + } else if (value instanceof String s) { if (hasExpression(s)) { return evalExpr(ctx, s, expectedType); } @@ -193,7 +192,7 @@ private ELResolver createResolver(LazyEvalContext evalContext, r.add(new ListELResolver()); r.add(new ArrayELResolver()); if (evalContext.context() != null) { - r.add(new TaskMethodResolver(taskMethodResolvers, evalContext.context())); + r.add(new TaskMethodResolver(taskMethodResolvers, customBeanELResolvers, evalContext.context())); } r.add(new BeanELResolver(customBeanELResolvers)); return r; diff --git a/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/resolvers/TaskMethodResolver.java b/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/resolvers/TaskMethodResolver.java index 18c93964b1..19815249f4 100644 --- a/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/resolvers/TaskMethodResolver.java +++ b/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/el/resolvers/TaskMethodResolver.java @@ -27,6 +27,7 @@ import com.walmartlabs.concord.runtime.v2.runner.tasks.TaskCallInterceptor; import com.walmartlabs.concord.runtime.v2.runner.tasks.TaskException; import com.walmartlabs.concord.runtime.v2.sdk.Context; +import com.walmartlabs.concord.runtime.v2.sdk.CustomBeanELResolver; import com.walmartlabs.concord.runtime.v2.sdk.CustomTaskMethodResolver; import com.walmartlabs.concord.runtime.v2.sdk.Task; @@ -42,10 +43,14 @@ public class TaskMethodResolver extends ELResolver { private final List customResolvers; + private final List customBeanELResolvers; private final Context context; - public TaskMethodResolver(List customResolvers, Context context) { + public TaskMethodResolver(List customResolvers, + List customBeanELResolvers, + Context context) { this.customResolvers = customResolvers; + this.customBeanELResolvers = customBeanELResolvers; this.context = context; } @@ -79,7 +84,7 @@ public Object invoke(ELContext elContext, Object base, Object method, Class[] try { return interceptor.invoke(callContext, Method.of(invocation.taskClass(), method.toString(), Arrays.asList(params)), () -> { - var result = invocation.invoke(new DefaultInvocationContext(elContext)); + var result = invocation.invoke(new DefaultInvocationContext(customBeanELResolvers, elContext)); elContext.setPropertyResolved(true); return result; }); @@ -155,9 +160,10 @@ private static class DefaultInvocationContext implements CustomTaskMethodResolve private final ELContext elContext; private final javax.el.BeanELResolver beanELResolver; - private DefaultInvocationContext(ELContext elContext) { + private DefaultInvocationContext(List customBeanELResolvers, + ELContext elContext) { this.elContext = elContext; - this.beanELResolver = new javax.el.BeanELResolver(); + this.beanELResolver = new BeanELResolver(customBeanELResolvers); } @Override diff --git a/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/vm/TaskCallCommand.java b/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/vm/TaskCallCommand.java index f10ac16e48..9e0125c504 100644 --- a/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/vm/TaskCallCommand.java +++ b/runtime/v2/runner/src/main/java/com/walmartlabs/concord/runtime/v2/runner/vm/TaskCallCommand.java @@ -20,8 +20,10 @@ * ===== */ +import com.sun.el.util.ReflectionUtil; import com.walmartlabs.concord.runtime.v2.model.TaskCall; import com.walmartlabs.concord.runtime.v2.model.TaskCallOptions; +import com.walmartlabs.concord.runtime.v2.runner.el.resolvers.SensitiveDataProcessor; import com.walmartlabs.concord.runtime.v2.runner.tasks.TaskCallInterceptor; import com.walmartlabs.concord.runtime.v2.runner.tasks.TaskException; import com.walmartlabs.concord.runtime.v2.runner.tasks.TaskProviders; @@ -83,6 +85,11 @@ protected void execute(Runtime runtime, State state, ThreadId threadId) { try { result = interceptor.invoke(callContext, Method.of(t.getClass(), "execute", Collections.singletonList(input)), () -> t.execute(input)); + + if (result instanceof TaskResult.SimpleResult simpleResult) { + var m = ReflectionUtil.findMethod(t.getClass(), "execute", new Class[]{Variables.class}, new Variables[]{input}); + SensitiveDataProcessor.process(simpleResult.values(), m); + } } catch (TaskException e) { result = TaskResult.fail(e.getCause()); } catch (RuntimeException e) {