Repository: ambari Updated Branches: refs/heads/trunk 13a981c1a -> 34761fcdc
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/34761fcd Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/34761fcd Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/34761fcd Branch: refs/heads/trunk Commit: 34761fcdcec142d1d6e1dcf76febb9ce526ae927 Parents: 13a981c Author: Robert Levas <[email protected]> Authored: Tue May 2 10:52:18 2017 -0400 Committer: Robert Levas <[email protected]> Committed: Tue May 2 10:52:18 2017 -0400 ---------------------------------------------------------------------- .../internal/RequestResourceProvider.java | 12 ++++++- .../internal/RequestResourceProviderTest.java | 35 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/34761fcd/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 57e7024..c405995 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,6 +69,7 @@ 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; @@ -741,7 +742,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/34761fcd/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 feedc74..6bc856d 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 @@ -83,6 +83,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; @@ -98,6 +99,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. @@ -142,6 +145,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(); } @@ -258,12 +265,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(); @@ -287,6 +320,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(); @@ -297,6 +331,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
