Repository: ambari
Updated Branches:
  refs/heads/branch-2.4 ed2369d10 -> 3da6ab38d


AMBARI-20874. Mask passwords in Request resource responses (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3da6ab38
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3da6ab38
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3da6ab38

Branch: refs/heads/branch-2.4
Commit: 3da6ab38d3b57d289dc895931a1875658b90a23f
Parents: ed2369d
Author: Robert Levas <[email protected]>
Authored: Tue May 2 10:53:48 2017 -0400
Committer: Robert Levas <[email protected]>
Committed: Tue May 2 10:53:48 2017 -0400

----------------------------------------------------------------------
 .../internal/RequestResourceProvider.java       | 14 ++++++--
 .../internal/RequestResourceProviderTest.java   | 35 ++++++++++++++++++++
 2 files changed, 47 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/3da6ab38/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
index 8c1bc57..7f06347 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
@@ -69,10 +69,11 @@ import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.topology.LogicalRequest;
 import org.apache.ambari.server.topology.TopologyManager;
+import org.apache.ambari.server.utils.SecretReference;
+import org.apache.commons.lang.StringUtils;
 
 import com.google.common.collect.Sets;
 import com.google.inject.Inject;
-import org.apache.commons.lang.StringUtils;
 
 /**
  * Resource provider for request resources.
@@ -709,7 +710,16 @@ public class RequestResourceProvider extends 
AbstractControllerResourceProvider
     setResourceProperty(resource, REQUEST_ID_PROPERTY_ID, 
entity.getRequestId(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_CONTEXT_ID, 
entity.getRequestContext(), requestedPropertyIds);
     setResourceProperty(resource, REQUEST_TYPE_ID, entity.getRequestType(), 
requestedPropertyIds);
-    setResourceProperty(resource, REQUEST_INPUTS_ID, entity.getInputs(), 
requestedPropertyIds);
+
+    // Mask any sensitive data fields in the inputs data structure
+    if (isPropertyRequested(REQUEST_INPUTS_ID, requestedPropertyIds)) {
+      String value = entity.getInputs();
+      if (!StringUtils.isBlank(value)) {
+        value = SecretReference.maskPasswordInPropertyMap(value);
+      }
+      resource.setProperty(REQUEST_INPUTS_ID, value);
+    }
+
     setResourceProperty(resource, REQUEST_RESOURCE_FILTER_ID,
         
org.apache.ambari.server.actionmanager.Request.filtersFromEntity(entity),
         requestedPropertyIds);

http://git-wip-us.apache.org/repos/asf/ambari/blob/3da6ab38/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
index 5dfc74d..4200622 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
@@ -82,6 +82,7 @@ import org.apache.ambari.server.topology.HostGroupInfo;
 import org.apache.ambari.server.topology.LogicalRequest;
 import org.apache.ambari.server.topology.TopologyManager;
 import org.apache.ambari.server.topology.TopologyRequest;
+import org.apache.ambari.server.utils.SecretReference;
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.junit.After;
@@ -97,6 +98,8 @@ import 
org.springframework.security.core.context.SecurityContextHolder;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 
 /**
  * RequestResourceProvider tests.
@@ -141,6 +144,10 @@ public class RequestResourceProviderTest {
     field.setAccessible(true);
     field.set(null, topologyManager);
 
+    field = SecretReference.class.getDeclaredField("gson");
+    field.setAccessible(true);
+    field.set(null, new Gson());
+
     AuthorizationHelperInitializer.viewInstanceDAOReturningNull();
   }
 
@@ -257,12 +264,38 @@ public class RequestResourceProviderTest {
   public void testGetResources() throws Exception {
     Resource.Type type = Resource.Type.Request;
 
+    String storedInputs = "{" +
+        " \"hosts\": \"host1\"," +
+        " \"check_execute_list\": 
\"last_agent_env_check,installed_packages,existing_repos,transparentHugePage\","
 +
+        " \"jdk_location\": \"http://ambari_server.home:8080/resources/\","; +
+        " \"threshold\": \"20\"," +
+        " \"password\": \"for your eyes only\"," +
+        " \"foo_password\": \"for your eyes only\"," +
+        " \"passwd\": \"for your eyes only\"," +
+        " \"foo_passwd\": \"for your eyes only\"" +
+        " }";
+    String cleanedInputs = 
SecretReference.maskPasswordInPropertyMap(storedInputs);
+
+    // Make sure SecretReference.maskPasswordInPropertyMap properly masked the 
password fields in cleanedInputs...
+    Gson gson = new Gson();
+    Map<String, String> map = gson.fromJson(cleanedInputs, new 
TypeToken<Map<String, String>>() {}.getType());
+    for (Map.Entry<String, String> entry : map.entrySet()) {
+      String name = entry.getKey();
+      if (name.contains("password") || name.contains("passwd")) {
+        Assert.assertEquals("SECRET", entry.getValue());
+      }
+      else {
+        Assert.assertFalse("SECRET".equals(entry.getValue()));
+      }
+    }
+
     AmbariManagementController managementController = 
createMock(AmbariManagementController.class);
     ActionManager actionManager = createNiceMock(ActionManager.class);
     RequestEntity requestMock = createNiceMock(RequestEntity.class);
 
     expect(requestMock.getRequestContext()).andReturn("this is a 
context").anyTimes();
     expect(requestMock.getRequestId()).andReturn(100L).anyTimes();
+    expect(requestMock.getInputs()).andReturn(storedInputs).anyTimes();
 
     Capture<Collection<Long>> requestIdsCapture = newCapture();
 
@@ -286,6 +319,7 @@ public class RequestResourceProviderTest {
 
     propertyIds.add(RequestResourceProvider.REQUEST_ID_PROPERTY_ID);
     propertyIds.add(RequestResourceProvider.REQUEST_STATUS_PROPERTY_ID);
+    propertyIds.add(RequestResourceProvider.REQUEST_INPUTS_ID);
 
     Predicate predicate = new 
PredicateBuilder().property(RequestResourceProvider.REQUEST_ID_PROPERTY_ID).equals("100").
       toPredicate();
@@ -296,6 +330,7 @@ public class RequestResourceProviderTest {
     for (Resource resource : resources) {
       Assert.assertEquals(100L, (long) (Long) 
resource.getPropertyValue(RequestResourceProvider.REQUEST_ID_PROPERTY_ID));
       Assert.assertEquals("IN_PROGRESS", 
resource.getPropertyValue(RequestResourceProvider.REQUEST_STATUS_PROPERTY_ID));
+      Assert.assertEquals(cleanedInputs, 
resource.getPropertyValue(RequestResourceProvider.REQUEST_INPUTS_ID));
     }
 
     // verify

Reply via email to