You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sm...@apache.org on 2018/08/31 11:08:28 UTC
[ambari] branch branch-2.7 updated: AMBARI-24546. Only
authenticated users with proper AMBARI/CLUSTER authorization roles can
query Ambari Request related information (#2219)
This is an automated email from the ASF dual-hosted git repository.
smolnar pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-2.7 by this push:
new 0c3812b AMBARI-24546. Only authenticated users with proper AMBARI/CLUSTER authorization roles can query Ambari Request related information (#2219)
0c3812b is described below
commit 0c3812bbb563b1d05d916e7af46ac9bc6cab31ea
Author: Sandor Molnar <sm...@apache.org>
AuthorDate: Fri Aug 31 13:08:26 2018 +0200
AMBARI-24546. Only authenticated users with proper AMBARI/CLUSTER authorization roles can query Ambari Request related information (#2219)
---
.../internal/RequestResourceProvider.java | 26 +++++++++++-
.../security/authorization/RoleAuthorization.java | 1 +
.../ambari/server/upgrade/UpgradeCatalog272.java | 7 ++++
.../internal/RequestResourceProviderTest.java | 47 ++++++++++++++++++++++
.../server/upgrade/UpgradeCatalog272Test.java | 10 ++++-
5 files changed, 88 insertions(+), 3 deletions(-)
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 0b9bce0..d5222d2 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
@@ -21,6 +21,10 @@ import static org.apache.ambari.server.controller.internal.HostComponentResource
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.COMPONENT_NAME;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_NAME;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.SERVICE_NAME;
+import static org.apache.ambari.server.security.authorization.RoleAuthorization.AMBARI_VIEW_STATUS_INFO;
+import static org.apache.ambari.server.security.authorization.RoleAuthorization.CLUSTER_VIEW_STATUS_INFO;
+import static org.apache.ambari.server.security.authorization.RoleAuthorization.HOST_VIEW_STATUS_INFO;
+import static org.apache.ambari.server.security.authorization.RoleAuthorization.SERVICE_VIEW_STATUS_INFO;
import java.util.ArrayList;
import java.util.Collection;
@@ -295,9 +299,9 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
Boolean ascOrder = (ascOrderRaw == null ? null : Boolean.parseBoolean(ascOrderRaw));
if (null == predicate) {
+ authorizeGetResources(null);
// the no-arg call to /requests is here
- resources.addAll(
- getRequestResources(null, null, null, maxResults, ascOrder, requestedIds));
+ resources.addAll(getRequestResources(null, null, null, maxResults, ascOrder, requestedIds));
} else {
// process /requests with a predicate
// process /clusters/[cluster]/requests
@@ -316,6 +320,7 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
requestStatus = (String) properties.get(REQUEST_STATUS_PROPERTY_ID);
}
+ authorizeGetResources(clusterName);
resources.addAll(getRequestResources(clusterName, requestId, requestStatus, maxResults,
ascOrder, requestedIds));
}
@@ -324,6 +329,23 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
return resources;
}
+ private void authorizeGetResources(String clusterName) throws NoSuchParentResourceException, AuthorizationException {
+ final boolean ambariLevelRequest = StringUtils.isBlank(clusterName);
+ final ResourceType resourceType = ambariLevelRequest ? ResourceType.AMBARI : ResourceType.CLUSTER;
+ Long resourceId;
+ try {
+ resourceId = ambariLevelRequest ? null : getClusterResourceId(clusterName);
+ } catch (AmbariException e) {
+ throw new NoSuchParentResourceException("Error while fetching cluster resource ID", e);
+ }
+ final Set<RoleAuthorization> requiredAuthorizations = ambariLevelRequest ? Sets.newHashSet(AMBARI_VIEW_STATUS_INFO)
+ : Sets.newHashSet(CLUSTER_VIEW_STATUS_INFO, HOST_VIEW_STATUS_INFO, SERVICE_VIEW_STATUS_INFO);
+
+ if (!AuthorizationHelper.isAuthorized(resourceType, resourceId, requiredAuthorizations)) {
+ throw new AuthorizationException(String.format("The authenticated user is not authorized to fetch request related information."));
+ }
+ }
+
@Override
public RequestStatus updateResources(Request requestInfo, Predicate predicate)
throws SystemException, UnsupportedPropertyException,
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
index 3c50628..a079db1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
@@ -40,6 +40,7 @@ public enum RoleAuthorization {
AMBARI_RENAME_CLUSTER("AMBARI.RENAME_CLUSTER"),
AMBARI_RUN_CUSTOM_COMMAND("AMBARI.RUN_CUSTOM_COMMAND"),
AMBARI_MANAGE_CONFIGURATION("AMBARI.MANAGE_CONFIGURATION"),
+ AMBARI_VIEW_STATUS_INFO("AMBARI.VIEW_STATUS_INFO"),
CLUSTER_MANAGE_CREDENTIALS("CLUSTER.MANAGE_CREDENTIALS"),
CLUSTER_MODIFY_CONFIGS("CLUSTER.MODIFY_CONFIGS"),
CLUSTER_MANAGE_CONFIG_GROUPS("CLUSTER.MANAGE_CONFIG_GROUPS"),
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java
index d76e40d..32b8043 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java
@@ -18,11 +18,13 @@
package org.apache.ambari.server.upgrade;
import static org.apache.ambari.server.configuration.AmbariServerConfigurationCategory.LDAP_CONFIGURATION;
+import static org.apache.ambari.server.security.authorization.RoleAuthorization.AMBARI_VIEW_STATUS_INFO;
import static org.apache.ambari.server.upgrade.UpgradeCatalog270.AMBARI_CONFIGURATION_CATEGORY_NAME_COLUMN;
import static org.apache.ambari.server.upgrade.UpgradeCatalog270.AMBARI_CONFIGURATION_PROPERTY_NAME_COLUMN;
import static org.apache.ambari.server.upgrade.UpgradeCatalog270.AMBARI_CONFIGURATION_TABLE;
import java.sql.SQLException;
+import java.util.Collections;
import org.apache.ambari.server.AmbariException;
import org.slf4j.Logger;
@@ -72,6 +74,7 @@ public class UpgradeCatalog272 extends AbstractUpgradeCatalog {
@Override
protected void executeDMLUpdates() throws AmbariException, SQLException {
renameLdapSynchCollisionBehaviorValue();
+ createRoleAuthorizations();
}
protected int renameLdapSynchCollisionBehaviorValue() throws SQLException {
@@ -86,4 +89,8 @@ public class UpgradeCatalog272 extends AbstractUpgradeCatalog {
return numberOfRecordsRenamed;
}
+ protected void createRoleAuthorizations() throws SQLException {
+ addRoleAuthorization(AMBARI_VIEW_STATUS_INFO.getId(), "View status information", Collections.singleton("AMBARI.ADMINISTRATOR:AMBARI"));
+ LOG.info("Added new role authorization {}", AMBARI_VIEW_STATUS_INFO.getId());
+ }
}
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 c014692..04dceea 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
@@ -20,6 +20,8 @@ package org.apache.ambari.server.controller.internal;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.STALE_CONFIGS;
+import static org.apache.ambari.server.security.TestAuthenticationFactory.createAdministrator;
+import static org.apache.ambari.server.security.TestAuthenticationFactory.createViewUser;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.eq;
@@ -212,6 +214,8 @@ public class RequestResourceProviderTest {
expect(requestDAO.findByPks(Collections.emptyList(), true)).andReturn(Collections.emptyList()).anyTimes();
+ prepareGetAuthorizationExpectations();
+
ActionManager actionManager = createNiceMock(ActionManager.class);
Cluster cluster = createNiceMock(Cluster.class);
@@ -267,6 +271,14 @@ public class RequestResourceProviderTest {
verify(requestDAO);
}
+ private void prepareGetAuthorizationExpectations() {
+ prepareGetAuthorizationExpectations(true);
+ }
+
+ private void prepareGetAuthorizationExpectations(boolean allowedToAuthorize) {
+ SecurityContextHolder.getContext().setAuthentication(allowedToAuthorize ? createAdministrator() : createViewUser(1L));
+ }
+
@Test
public void testGetResources() throws Exception {
Resource.Type type = Resource.Type.Request;
@@ -313,6 +325,8 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, requestDAO, hrcDAO, requestMock);
@@ -363,6 +377,8 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, requestDAO, hrcDAO, requestMock);
@@ -414,6 +430,8 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, requestMock, requestDAO, hrcDAO);
@@ -472,6 +490,7 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
// replay
replay(managementController, actionManager, clusters, cluster, requestMock, requestDAO, hrcDAO);
@@ -538,6 +557,8 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, requestMock, requestMock1, requestDAO, hrcDAO);
@@ -590,6 +611,8 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().completed(2));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, requestMock0, requestMock1, requestDAO, hrcDAO);
@@ -659,6 +682,8 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1).queued(1));
}}).once();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, requestMock0, requestMock1, requestDAO, hrcDAO);
@@ -737,6 +762,7 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().aborted(1).timedout(1));
}}).once();
+ prepareGetAuthorizationExpectations();
// replay
replay(managementController, actionManager, requestMock0, requestMock1, requestDAO, hrcDAO);
@@ -785,6 +811,20 @@ public class RequestResourceProviderTest {
verify(managementController, actionManager, requestMock0, requestMock1, requestDAO, hrcDAO);
}
+ @Test(expected = AuthorizationException.class)
+ public void shouldThrowAuthorizationErrorInCaseTheAuthenticatedUserDoesNotHaveTheAppropriatePermissions() throws Exception {
+ // Given
+ prepareGetAuthorizationExpectations(false);
+ final ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(Resource.Type.Request, createMock(AmbariManagementController.class));
+ final Request request = PropertyHelper.getUpdateRequest(new LinkedHashMap<>(), null);
+ final Predicate predicate = new PredicateBuilder().property(RequestResourceProvider.REQUEST_ID_PROPERTY_ID).equals("100").toPredicate();
+
+ // When
+ provider.getResources(request, predicate);
+
+ // Then: see expected exception
+ }
+
@Test
public void testUpdateResources_CancelRequest() throws Exception {
Resource.Type type = Resource.Type.Request;
@@ -818,6 +858,8 @@ public class RequestResourceProviderTest {
RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, hostRoleCommand, clusters, requestMock, response, stage);
@@ -1559,6 +1601,7 @@ public class RequestResourceProviderTest {
put(1L, HostRoleCommandStatusSummaryDTO.create().inProgress(1));
}}).anyTimes();
+ prepareGetAuthorizationExpectations();
// replay
replay(managementController, actionManager, clusters, requestMock, requestDAO, hrcDAO);
@@ -1612,6 +1655,8 @@ public class RequestResourceProviderTest {
expect(hrcDAO.findAggregateCounts((Long) anyObject())).andReturn(
Collections.emptyMap()).anyTimes();
+ prepareGetAuthorizationExpectations();
+
// replay
replay(managementController, actionManager, clusters, requestMock, requestDAO, hrcDAO);
@@ -1707,6 +1752,8 @@ public class RequestResourceProviderTest {
: Optional.<String>absent();
expect(logicalRequest.getFailureReason()).andReturn(failureReason).anyTimes();
+ prepareGetAuthorizationExpectations();
+
replayAll();
Resource.Type type = Resource.Type.Request;
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java
index d303861..0c7fb02 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java
@@ -21,6 +21,7 @@ import static org.apache.ambari.server.upgrade.UpgradeCatalog270.AMBARI_CONFIGUR
import static org.apache.ambari.server.upgrade.UpgradeCatalog272.RENAME_COLLISION_BEHAVIOR_PROPERTY_SQL;
import static org.easymock.EasyMock.createMockBuilder;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
@@ -49,11 +50,16 @@ public class UpgradeCatalog272Test {
@Test
public void testExecuteDMLUpdates() throws Exception {
final Method renameLdapSynchCollisionBehaviorValue = UpgradeCatalog272.class.getDeclaredMethod("renameLdapSynchCollisionBehaviorValue");
+ final Method createRoleAuthorizations = UpgradeCatalog272.class.getDeclaredMethod("createRoleAuthorizations");
- final UpgradeCatalog272 upgradeCatalog272 = createMockBuilder(UpgradeCatalog272.class).addMockedMethod(renameLdapSynchCollisionBehaviorValue).createMock();
+ final UpgradeCatalog272 upgradeCatalog272 = createMockBuilder(UpgradeCatalog272.class).addMockedMethod(renameLdapSynchCollisionBehaviorValue)
+ .addMockedMethod(createRoleAuthorizations).createMock();
expect(upgradeCatalog272.renameLdapSynchCollisionBehaviorValue()).andReturn(0).once();
+ upgradeCatalog272.createRoleAuthorizations();
+ expectLastCall().once();
+
replay(upgradeCatalog272);
upgradeCatalog272.executeDMLUpdates();
@@ -83,5 +89,7 @@ public class UpgradeCatalog272Test {
assertEquals(expectedResult, upgradeCatalog272.renameLdapSynchCollisionBehaviorValue());
verify(dbAccessor);
}
+
+
}