Mark sensitive information in Rest Server

Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/c627ed72
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/c627ed72
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/c627ed72

Branch: refs/heads/master
Commit: c627ed7272a0a5bca1686daafb13f2195021b2b3
Parents: 7b8b1ce
Author: Valentin Aitken <bos...@gmail.com>
Authored: Tue Jun 7 18:12:55 2016 +0300
Committer: Valentin Aitken <bos...@gmail.com>
Committed: Wed Jun 8 14:43:02 2016 +0300

----------------------------------------------------------------------
 .../brooklyn/api/effector/ParameterType.java    |  2 +
 .../core/effector/BasicParameterType.java       |  2 +-
 .../mgmt/internal/TestEntityWithEffectors.java  |  9 ++-
 .../internal/TestEntityWithEffectorsImpl.java   | 15 ++--
 .../brooklyn/rest/domain/EffectorSummary.java   |  9 ++-
 .../rest/transform/EffectorTransformer.java     |  4 +-
 .../rest/resources/EffectorUtilsRestTest.java   | 72 +++++++++++++++++---
 7 files changed, 94 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java 
b/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java
index 7f0736d..07e86bd 100644
--- a/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java
+++ b/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java
@@ -27,6 +27,8 @@ import javax.management.MBeanParameterInfo;
  *
  * @see Effector
  */
+// TODO rename this to ParameterInfo rather than type. A ParameterType object 
is used for each parameter not for each type of parameter.
+// check MethodEffector.AnnotationsOnMethod.toParameterType
 public interface ParameterType<T> extends Serializable {
     
     public String getName();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java 
b/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
index eb0417f..5dd6211 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
@@ -75,7 +75,7 @@ public class BasicParameterType<T> implements 
ParameterType<T> {
 
     @Override
     public Class<T> getParameterClass() { return type; }
-    
+
     @Override
     public String getParameterClassName() { return type.getCanonicalName(); }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectors.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectors.java
 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectors.java
index 15a2ac1..f986674 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectors.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectors.java
@@ -25,6 +25,11 @@ import org.apache.brooklyn.core.test.entity.TestEntity;
 
 @ImplementedBy(TestEntityWithEffectorsImpl.class)
 public interface TestEntityWithEffectors extends TestEntity {
-    @Effector(description = "Reset User pass effetor")
-    Void resetUserPassword(@EffectorParam(name = "newPassword") String param1);
+    @Effector(description = "Reset password")
+    Void resetPassword(@EffectorParam(name = "newPassword") String param1, 
@EffectorParam(name = "secretPin") Integer secretPin);
+
+    @Effector(description = "Reset User and password effector")
+    Void invokeUserAndPassword(@EffectorParam(name = "user") String user,
+                               @EffectorParam(name = "newPassword", 
defaultValue = "Test") String newPassword,
+                               @EffectorParam(name = "paramDefault", 
defaultValue = "DefaultValue") String paramDefault);
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectorsImpl.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectorsImpl.java
 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectorsImpl.java
index b090152..8566d59 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectorsImpl.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/TestEntityWithEffectorsImpl.java
@@ -18,17 +18,24 @@
  */
 package org.apache.brooklyn.core.mgmt.internal;
 
-import org.apache.brooklyn.core.annotation.EffectorParam;
 import org.apache.brooklyn.core.test.entity.TestEntityImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class TestEntityWithEffectorsImpl extends TestEntityImpl implements 
TestEntityWithEffectors {
-    private static final Logger log = 
LoggerFactory.getLogger(EffectorUtils.class);
+    private static final Logger log = 
LoggerFactory.getLogger(TestEntityWithEffectorsImpl.class);
 
     @Override
-    public Void resetUserPassword(@EffectorParam(name = "newPassword") String 
newPassword) {
-        log.info("Invoking Test effector {}", this);
+    public Void resetPassword(String newPassword, Integer secretPin) {
+        log.info("Invoked effector from resetPassword with params {} {}", new 
Object[] {newPassword, secretPin});
+        assert newPassword != null;
+        return null;
+    }
+
+    @Override
+    public Void invokeUserAndPassword(String user,String newPassword, String 
paramDefault) {
+        log.info("Invoked effector from invokeUserAndPassword with params {} 
{} {}", new Object[] {user, newPassword, paramDefault});
+        assert user != null;
         assert newPassword != null;
         return null;
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EffectorSummary.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EffectorSummary.java
 
b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EffectorSummary.java
index 8ad7812..daa0e3b 100644
--- 
a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EffectorSummary.java
+++ 
b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EffectorSummary.java
@@ -40,16 +40,19 @@ public class EffectorSummary implements HasName, 
Serializable {
         @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
         private final String description;
         private final T defaultValue;
+        private final boolean shouldSanitize;
 
         public ParameterSummary (
                 @JsonProperty("name") String name,
                 @JsonProperty("type") String type,
                 @JsonProperty("description") String description,
-                @JsonProperty("defaultValue") T defaultValue) {
+                @JsonProperty("defaultValue") T defaultValue,
+                @JsonProperty("shouldSanitize") boolean shouldSanitize) {
             this.name = name;
             this.type = type;
             this.description = description;
             this.defaultValue = defaultValue;
+            this.shouldSanitize = shouldSanitize;
         }
 
         @Override
@@ -61,6 +64,10 @@ public class EffectorSummary implements HasName, 
Serializable {
             return type;
         }
 
+        public boolean shouldSanitize() {
+            return shouldSanitize;
+        }
+
         public String getDescription() {
             return description;
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EffectorTransformer.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EffectorTransformer.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EffectorTransformer.java
index b374bb3..9304008 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EffectorTransformer.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EffectorTransformer.java
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.effector.ParameterType;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.rest.domain.EffectorSummary;
 import org.apache.brooklyn.rest.domain.EffectorSummary.ParameterSummary;
 import org.apache.brooklyn.rest.util.WebResourceUtils;
@@ -83,7 +84,8 @@ public class EffectorTransformer {
                 
.context(entity).timeout(ValueResolver.REAL_QUICK_WAIT).getMaybe();
             return new ParameterSummary(parameterType.getName(), 
parameterType.getParameterClassName(), 
                 parameterType.getDescription(), 
-                WebResourceUtils.getValueForDisplay(defaultValue.orNull(), 
true, false));
+                WebResourceUtils.getValueForDisplay(defaultValue.orNull(), 
true, false),
+                Sanitizer.IS_SECRET_PREDICATE.apply(parameterType.getName()));
         } catch (Exception e) {
             throw Exceptions.propagate(e);
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c627ed72/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EffectorUtilsRestTest.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EffectorUtilsRestTest.java
 
b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EffectorUtilsRestTest.java
index 98df14a..5fe729d 100644
--- 
a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EffectorUtilsRestTest.java
+++ 
b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EffectorUtilsRestTest.java
@@ -18,33 +18,46 @@
  */
 package org.apache.brooklyn.rest.resources;
 
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
 import org.apache.brooklyn.core.mgmt.internal.TestEntityWithEffectors;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.rest.domain.EffectorSummary;
+import org.apache.brooklyn.rest.domain.SummaryComparators;
 import org.apache.brooklyn.rest.domain.TaskSummary;
+import org.apache.brooklyn.rest.transform.EffectorTransformer;
 import org.apache.brooklyn.rest.transform.TaskTransformer;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import javax.annotation.Nullable;
 import javax.ws.rs.core.UriBuilder;
 import java.net.URI;
-import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
 public class EffectorUtilsRestTest extends BrooklynAppUnitTestSupport {
     private static final Logger log = 
LoggerFactory.getLogger(EffectorUtils.class);
 
     private TestEntityWithEffectors entity;
+    private UriBuilder uriBuilder = new 
org.apache.cxf.jaxrs.impl.UriBuilderImpl(URI.create("http://localhost";));
 
     @BeforeMethod(alwaysRun=true)
     @Override
@@ -53,19 +66,18 @@ public class EffectorUtilsRestTest extends 
BrooklynAppUnitTestSupport {
         entity = 
app.createAndManageChild(EntitySpec.create(TestEntityWithEffectors.class));
     }
 
-
     /**
      * Invoking an effector with sensitive parameters.
      * Invocation imitates {@link EffectorResource#invoke(String, String, 
String, String, Map)}
      */
     @Test
     public void testInvokingEffector() {
-        Maybe<Effector<?>> effector = 
EffectorUtils.findEffectorDeclared(entity, "resetUserPassword");
+        Maybe<Effector<?>> effector = 
EffectorUtils.findEffectorDeclared(entity, "resetPassword");
 
-        final String sensitiveField = "newPassword";
-        Task<?> t = entity.invoke(effector.get(), 
ImmutableMap.of(sensitiveField, "#$%'332985$23$#\"sd'"));
+        final String sensitiveField1 = "newPassword";
+        final String sensitiveField2 = "secretPin";
+        Task<?> t = entity.invoke(effector.get(), 
ImmutableMap.of(sensitiveField1, "#$%'332985$23$#\"sd'", "secretPin", 1234));
 
-        UriBuilder uriBuilder = new 
org.apache.cxf.jaxrs.impl.UriBuilderImpl(URI.create("http://localhost";));
         TaskSummary summary = TaskTransformer.taskSummary(t, uriBuilder);
 
         try {
@@ -73,10 +85,50 @@ public class EffectorUtilsRestTest extends 
BrooklynAppUnitTestSupport {
         } catch (InterruptedException|ExecutionException e) {
             throw Exceptions.propagate(e);
         }
-        Assert.assertEquals(
+        assertEquals(
                 summary.getDescription(),
-                "Invoking effector resetUserPassword on 
"+TestEntityWithEffectors.class.getSimpleName()+":"+entity.getId().substring(0,4)
-                    +" with parameters {"+sensitiveField+"=xxxxxxxx}",
+                "Invoking effector resetPassword on 
"+TestEntityWithEffectors.class.getSimpleName()+":"+entity.getId().substring(0,4)
+                    +" with parameters {"+sensitiveField1+"=xxxxxxxx, 
"+sensitiveField2+"=xxxxxxxx}",
                 "Task summary must hide sensitive parameters");
     }
+
+    /**
+     * Invoking an effector with sensitive parameters.
+     * Invocation imitates {@link EffectorResource#list}
+     */
+    @Test
+    public void testListingEffectorsParameterSummary() {
+        List<EffectorSummary> effectorSummaries = FluentIterable
+                .from(entity.getEntityType().getEffectors())
+                .filter(new Predicate<Effector<?>>() {
+                    @Override
+                    public boolean apply(@Nullable Effector<?> input) {
+                        return ImmutableList.of("resetPassword", 
"invokeUserAndPassword").contains(input.getName());
+                    }
+                })
+                .transform(new Function<Effector<?>, EffectorSummary>() {
+                    @Override
+                    public EffectorSummary apply(Effector<?> effector) {
+                        return EffectorTransformer.effectorSummary(entity, 
effector, uriBuilder);
+                    }
+                })
+                .toSortedList(SummaryComparators.nameComparator());
+        EffectorSummary.ParameterSummary<?> passwordFieldInSimpleEffector = 
findEffectorSummary(effectorSummaries, 
"resetPassword").getParameters().iterator().next();
+        assertTrue(passwordFieldInSimpleEffector.shouldSanitize());
+
+        EffectorSummary longEffector = findEffectorSummary(effectorSummaries, 
"invokeUserAndPassword");
+        EffectorSummary.ParameterSummary<?> resetUsersPassword_user = 
Iterables.getFirst(longEffector.getParameters(), null);
+        assertFalse(resetUsersPassword_user.shouldSanitize());
+        EffectorSummary.ParameterSummary<?> resetUsersPassword_password = 
longEffector.getParameters().toArray(new 
EffectorSummary.ParameterSummary<?>[0])[1];
+        assertTrue(resetUsersPassword_password.shouldSanitize());
+    }
+
+    private EffectorSummary findEffectorSummary(List<EffectorSummary> 
effectorSummaries, final String effectorName) {
+        return Iterables.find(effectorSummaries, new 
Predicate<EffectorSummary>() {
+            @Override
+            public boolean apply(@Nullable EffectorSummary input) {
+                return input.getName().equals(effectorName);
+            }
+        });
+    }
 }

Reply via email to