You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2015/12/04 01:51:51 UTC

ambari git commit: AMBARI-14114. Enforce granular role-based access control for stack version functions (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/trunk 12f70d99c -> fe65472ac


AMBARI-14114. Enforce granular role-based access control for stack version functions (rlevas)


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

Branch: refs/heads/trunk
Commit: fe65472acbd4c76e9be7e3d29e24e1f747438a8d
Parents: 12f70d9
Author: Robert Levas <rl...@hortonworks.com>
Authored: Thu Dec 3 19:51:39 2015 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Thu Dec 3 19:51:39 2015 -0500

----------------------------------------------------------------------
 .../RepositoryVersionResourceProvider.java      | 35 ++++++++++--
 .../AmbariAuthorizationFilter.java              |  2 +
 ...leRepositoryVersionResourceProviderTest.java |  6 ++
 .../RepositoryVersionResourceProviderTest.java  | 58 ++++++++++++++++++--
 4 files changed, 91 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/fe65472a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
index 7cc2aa3..3782a9f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.controller.internal;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -52,6 +53,10 @@ import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.OperatingSystemInfo;
@@ -70,7 +75,7 @@ import com.google.inject.Inject;
 /**
  * Resource provider for repository versions resources.
  */
-public class RepositoryVersionResourceProvider extends AbstractResourceProvider {
+public class RepositoryVersionResourceProvider extends AbstractAuthorizedResourceProvider {
 
   // ----- Property ID constants ---------------------------------------------
 
@@ -140,10 +145,19 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
    */
   public RepositoryVersionResourceProvider() {
     super(propertyIds, keyPropertyIds);
+    setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS));
+    setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS));
+    setRequiredUpdateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS, RoleAuthorization.AMBARI_EDIT_STACK_REPOS));
+
+    setRequiredGetAuthorizations(EnumSet.of(
+        RoleAuthorization.AMBARI_MANAGE_STACK_VERSIONS,
+        RoleAuthorization.AMBARI_EDIT_STACK_REPOS,
+        RoleAuthorization.CLUSTER_VIEW_STACK_DETAILS,
+        RoleAuthorization.CLUSTER_UPGRADE_DOWNGRADE_STACK));
   }
 
   @Override
-  public RequestStatus createResources(final Request request)
+  protected RequestStatus createResourcesAuthorized(final Request request)
       throws SystemException,
       UnsupportedPropertyException,
       ResourceAlreadyExistsException,
@@ -186,7 +200,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   }
 
   @Override
-  public Set<Resource> getResources(Request request, Predicate predicate)
+  protected Set<Resource> getResourcesAuthorized(Request request, Predicate predicate)
       throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     final Set<Resource> resources = new HashSet<Resource>();
     final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
@@ -230,13 +244,13 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
 
   @Override
   @Transactional
-  public RequestStatus updateResources(Request request, Predicate predicate)
+  protected RequestStatus updateResourcesAuthorized(Request request, Predicate predicate)
     throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     final Set<Map<String, Object>> propertyMaps = request.getProperties();
 
     modifyResources(new Command<Void>() {
       @Override
-      public Void invoke() throws AmbariException {
+      public Void invoke() throws AmbariException, AuthorizationException {
         for (Map<String, Object> propertyMap : propertyMaps) {
           final Long id;
           try {
@@ -267,6 +281,10 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
           List<OperatingSystemEntity> operatingSystemEntities = null;
 
           if (StringUtils.isNotBlank(ObjectUtils.toString(propertyMap.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID)))) {
+            if(!AuthorizationHelper.isAuthorized(ResourceType.AMBARI,null, RoleAuthorization.AMBARI_EDIT_STACK_REPOS)) {
+              throw new AuthorizationException("The authenticated user does not have authorization to modify stack repositories");
+            }
+
             final Object operatingSystems = propertyMap.get(SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID);
             final String operatingSystemsJson = gson.toJson(operatingSystems);
             try {
@@ -306,7 +324,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   }
 
   @Override
-  public RequestStatus deleteResources(Predicate predicate)
+  protected RequestStatus deleteResourcesAuthorized(Predicate predicate)
       throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
 
@@ -487,4 +505,9 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
     return null;
   }
 
+  @Override
+  protected ResourceType getResourceType(Request request, Predicate predicate) {
+    // This information is not associated with any particular resource
+    return null;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/fe65472a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
index 2bc749f..c87c338 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
@@ -71,6 +71,7 @@ public class AmbariAuthorizationFilter implements Filter {
   private static final String API_LDAP_SYNC_EVENTS_ALL_PATTERN = API_VERSION_PREFIX + "/ldap_sync_events.*";
   private static final String API_CREDENTIALS_ALL_PATTERN = API_VERSION_PREFIX + "/clusters/.*?/credentials.*";
   private static final String API_CREDENTIALS_AMBARI_PATTERN = API_VERSION_PREFIX + "/clusters/.*?/credentials/ambari\\..*";
+  private static final String API_STACK_VERSIONS_PATTERN = API_VERSION_PREFIX + "/stacks/.*?/versions/.*";
 
   protected static final String LOGIN_REDIRECT_BASE = "/#/login?targetURI=";
 
@@ -254,6 +255,7 @@ public class AmbariAuthorizationFilter implements Filter {
         requestURI.matches(API_GROUPS_ALL_PATTERN) ||
         requestURI.matches(API_CREDENTIALS_ALL_PATTERN) ||
         requestURI.matches(API_CLUSTERS_PATTERN) ||
+        requestURI.matches(API_STACK_VERSIONS_PATTERN) ||
         requestURI.matches(API_PRIVILEGES_ALL_PATTERN);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/fe65472a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
index 4e4386e..dd8efa6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompatibleRepositoryVersionResourceProviderTest.java
@@ -37,6 +37,7 @@ import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.security.TestAuthenticationFactory;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.stack.UpgradePack;
@@ -47,6 +48,7 @@ import static org.easymock.EasyMock.replay;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.springframework.security.core.context.SecurityContextHolder;
 
 import java.util.*;
 
@@ -223,10 +225,14 @@ public class CompatibleRepositoryVersionResourceProviderTest {
   public void after() {
     injector.getInstance(PersistService.class).stop();
     injector = null;
+
+    SecurityContextHolder.getContext().setAuthentication(null);
   }
 
   @Test
   public void testGetResources() throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createClusterAdministrator("admin"));
+
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
 
     Request getRequest = PropertyHelper.getReadRequest(

http://git-wip-us.apache.org/repos/asf/ambari/blob/fe65472a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
index dfaef98..c99f631 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
@@ -46,6 +46,8 @@ import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.security.TestAuthenticationFactory;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
@@ -68,6 +70,8 @@ import com.google.gson.Gson;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 
 /**
  * RepositoryVersionResourceProvider tests.
@@ -228,7 +232,18 @@ public class RepositoryVersionResourceProviderTest {
   }
 
   @Test
-  public void testCreateResources() throws Exception {
+  public void testCreateResourcesAsAdministrator() throws Exception {
+    testCreateResources(TestAuthenticationFactory.createAdministrator("admin"));
+  }
+
+  @Test(expected = AuthorizationException.class)
+  public void testCreateResourcesAsClusterAdministrator() throws Exception {
+    testCreateResources(TestAuthenticationFactory.createClusterAdministrator("User1"));
+  }
+
+  private void testCreateResources(Authentication authentication) throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(authentication);
+
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
 
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
@@ -252,7 +267,18 @@ public class RepositoryVersionResourceProviderTest {
   }
 
   @Test
-  public void testGetResources() throws Exception {
+  public void testGetResourcesAsAdministrator() throws Exception {
+    testGetResources(TestAuthenticationFactory.createAdministrator("admin"));
+  }
+
+  @Test
+  public void testGetResourcesAsClusterAdministrator() throws Exception {
+    testGetResources(TestAuthenticationFactory.createClusterAdministrator("User1"));
+  }
+
+  private void testGetResources(Authentication authentication) throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(authentication);
+
     StackDAO stackDAO = injector.getInstance(StackDAO.class);
     StackEntity stackEntity = stackDAO.find("HDP", "1.1");
     Assert.assertNotNull(stackEntity);
@@ -349,7 +375,18 @@ public class RepositoryVersionResourceProviderTest {
   }
 
   @Test
-  public void testDeleteResources() throws Exception {
+  public void testDeleteResourcesAsAdministrator() throws Exception {
+    testDeleteResources(TestAuthenticationFactory.createAdministrator("admin"));
+  }
+
+  @Test(expected = AuthorizationException.class)
+  public void testDeleteResourcesAsClusterAdministrator() throws Exception {
+    testDeleteResources(TestAuthenticationFactory.createClusterAdministrator("User1"));
+  }
+
+  private void testDeleteResources(Authentication authentication) throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(authentication);
+
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
 
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
@@ -378,7 +415,18 @@ public class RepositoryVersionResourceProviderTest {
   }
 
   @Test
-  public void testUpdateResources() throws Exception {
+  public void testUpdateResourcesAsAdministrator() throws Exception {
+    testUpdateResources(TestAuthenticationFactory.createAdministrator("admin"));
+  }
+
+  @Test(expected = AuthorizationException.class)
+  public void testUpdateResourcesAsClusterAdministrator() throws Exception {
+    testUpdateResources(TestAuthenticationFactory.createClusterAdministrator("User1"));
+  }
+
+  private void testUpdateResources(Authentication authentication) throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(authentication);
+
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionResourceProvider();
 
     Mockito.when(clusterVersionDAO.findByStackAndVersion(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenAnswer(
@@ -478,5 +526,7 @@ public class RepositoryVersionResourceProviderTest {
   public void after() {
     injector.getInstance(PersistService.class).stop();
     injector = null;
+
+    SecurityContextHolder.getContext().setAuthentication(null);
   }
 }