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

ambari git commit: AMBARI-12476. Widget response differs when using ambarisessionid and basic auth.

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 2acaf832d -> 5cbfb2a63


AMBARI-12476. Widget response differs when using ambarisessionid and basic auth.


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

Branch: refs/heads/branch-2.1
Commit: 5cbfb2a6318d96dd1facb4ec081c9a35134a260e
Parents: 2acaf83
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Tue Sep 1 17:03:44 2015 -0700
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Tue Sep 1 17:04:19 2015 -0700

----------------------------------------------------------------------
 .../api/services/WidgetLayoutService.java       | 31 +++--------
 .../server/api/services/WidgetService.java      | 30 ++++-------
 .../internal/WidgetResourceProvider.java        | 10 +++-
 .../apache/ambari/server/orm/dao/WidgetDAO.java | 10 ++++
 .../server/orm/entities/WidgetEntity.java       |  4 ++
 .../internal/WidgetResourceProviderTest.java    | 57 +++++++++++++++++---
 6 files changed, 90 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5cbfb2a6/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetLayoutService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetLayoutService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetLayoutService.java
index fad83cb..7571396 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetLayoutService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetLayoutService.java
@@ -49,7 +49,7 @@ public class WidgetLayoutService extends BaseService {
                              @PathParam("widgetLayoutId") String widgetLayoutId) {
 
     return handleRequest(headers, body, ui, Request.Type.GET,
-            createResource(getUserName(headers), widgetLayoutId));
+            createResource(widgetLayoutId));
   }
 
   /**
@@ -64,9 +64,8 @@ public class WidgetLayoutService extends BaseService {
   @GET
   @Produces("text/plain")
   public Response getServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
-
     return handleRequest(headers, body, ui, Request.Type.GET,
-            createResource(getUserName(headers), null));
+            createResource(null));
   }
 
   @POST
@@ -75,7 +74,7 @@ public class WidgetLayoutService extends BaseService {
   public Response createService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
                                 @PathParam("widgetLayoutId") String widgetLayoutId) {
     return handleRequest(headers, body, ui, Request.Type.POST,
-            createResource(getUserName(headers), widgetLayoutId));
+            createResource(widgetLayoutId));
   }
 
   @POST
@@ -83,7 +82,7 @@ public class WidgetLayoutService extends BaseService {
   public Response createServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
 
     return handleRequest(headers, body, ui, Request.Type.POST,
-            createResource(getUserName(headers), null));
+            createResource(null));
   }
 
   @PUT
@@ -92,14 +91,14 @@ public class WidgetLayoutService extends BaseService {
   public Response updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
                                 @PathParam("widgetLayoutId") String widgetLayoutId) {
 
-    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(getUserName(headers), widgetLayoutId));
+    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(widgetLayoutId));
   }
 
   @PUT
   @Produces("text/plain")
   public Response updateServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
 
-    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(getUserName(headers), null));
+    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(null));
   }
 
   @DELETE
@@ -108,27 +107,13 @@ public class WidgetLayoutService extends BaseService {
   public Response deleteService(@Context HttpHeaders headers, @Context UriInfo ui,
                                 @PathParam("widgetLayoutId") String widgetLayoutId) {
 
-    return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(getUserName(headers), widgetLayoutId));
+    return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(widgetLayoutId));
   }
 
-  private ResourceInstance createResource(String userName, String widgetLayoutId) {
+  private ResourceInstance createResource(String widgetLayoutId) {
     Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
-    mapIds.put(Resource.Type.User, userName);
     mapIds.put(Resource.Type.WidgetLayout, widgetLayoutId);
     mapIds.put(Resource.Type.Cluster, clusterName);
     return createResource(Resource.Type.WidgetLayout, mapIds);
   }
-
-  private String getUserName(HttpHeaders headers) {
-    List<String> authorizationHeaders = headers.getRequestHeaders().get("Authorization");
-    if (authorizationHeaders != null && !authorizationHeaders.isEmpty()){
-      String authorizationString = authorizationHeaders.get(0);
-      if (authorizationString != null && authorizationString.startsWith("Basic")) {
-        String base64Credentials = authorizationString.substring("Basic".length()).trim();
-        String clearCredentials = new String(Base64.decode(base64Credentials),Charset.forName("UTF-8"));
-        return clearCredentials.split(":", 2)[0];
-      }
-    }
-    return null;
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/5cbfb2a6/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java
index 07dae40..e6907db 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/WidgetService.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.api.services;
 import com.sun.jersey.core.util.Base64;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
@@ -49,7 +50,7 @@ public class WidgetService extends BaseService {
                              @PathParam("widgetId") String widgetId) {
 
     return handleRequest(headers, body, ui, Request.Type.GET,
-            createResource(getUserName(headers), widgetId));
+            createResource(widgetId));
   }
 
   /**
@@ -66,7 +67,7 @@ public class WidgetService extends BaseService {
   public Response getServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
 
     return handleRequest(headers, body, ui, Request.Type.GET,
-            createResource(getUserName(headers), null));
+            createResource(null));
   }
 
   @POST
@@ -75,7 +76,7 @@ public class WidgetService extends BaseService {
   public Response createService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
                                 @PathParam("widgetId") String widgetId) {
     return handleRequest(headers, body, ui, Request.Type.POST,
-            createResource(getUserName(headers), widgetId));
+            createResource(widgetId));
   }
 
   @POST
@@ -83,7 +84,7 @@ public class WidgetService extends BaseService {
   public Response createServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
 
     return handleRequest(headers, body, ui, Request.Type.POST,
-            createResource(getUserName(headers), null));
+            createResource(null));
   }
 
   @PUT
@@ -92,14 +93,14 @@ public class WidgetService extends BaseService {
   public Response updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
                                 @PathParam("widgetId") String widgetId) {
 
-    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(getUserName(headers), widgetId));
+    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(widgetId));
   }
 
   @PUT
   @Produces("text/plain")
   public Response updateServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
 
-    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(getUserName(headers), null));
+    return handleRequest(headers, body, ui, Request.Type.PUT, createResource(null));
   }
 
   @DELETE
@@ -108,27 +109,14 @@ public class WidgetService extends BaseService {
   public Response deleteService(@Context HttpHeaders headers, @Context UriInfo ui,
                                 @PathParam("widgetId") String widgetId) {
 
-    return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(getUserName(headers), widgetId));
+    return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(widgetId));
   }
 
-  private ResourceInstance createResource(String userName, String widgetId) {
+  private ResourceInstance createResource(String widgetId) {
     Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
     mapIds.put(Resource.Type.Cluster, clusterName);
     mapIds.put(Resource.Type.Widget, widgetId);
-    mapIds.put(Resource.Type.User, userName);
     return createResource(Resource.Type.Widget, mapIds);
   }
 
-  private String getUserName(HttpHeaders headers) {
-    List<String> authorizationHeaders = headers.getRequestHeaders().get("Authorization");
-    if (authorizationHeaders != null && !authorizationHeaders.isEmpty()) {
-      String authorizationString = authorizationHeaders.get(0);
-      if (authorizationString != null && authorizationString.startsWith("Basic")) {
-        String base64Credentials = authorizationString.substring("Basic".length()).trim();
-        String clearCredentials = new String(Base64.decode(base64Credentials), Charset.forName("UTF-8"));
-        return clearCredentials.split(":", 2)[0];
-      }
-    }
-    return null;
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/5cbfb2a6/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java
index 897d7e8..5fc20fb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/WidgetResourceProvider.java
@@ -39,8 +39,10 @@ import org.apache.ambari.server.orm.entities.PermissionEntity;
 import org.apache.ambari.server.orm.entities.WidgetEntity;
 import org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity;
 import org.apache.ambari.server.security.authorization.AmbariGrantedAuthority;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
+import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -153,7 +155,7 @@ public class WidgetResourceProvider extends AbstractControllerResourceProvider {
           String scope = properties.get(WIDGET_SCOPE_PROPERTY_ID).toString();
 
           if (!isScopeAllowedForUser(scope)) {
-            throw new AmbariException("Only cluster operator can create widgets with cluster scope");
+            throw new AccessDeniedException("Only cluster operator can create widgets with cluster scope");
           }
 
           entity.setWidgetName(properties.get(WIDGET_WIDGET_NAME_PROPERTY_ID).toString());
@@ -206,6 +208,7 @@ public class WidgetResourceProvider extends AbstractControllerResourceProvider {
     final Set<Resource> resources = new HashSet<Resource>();
     final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
     final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+    String author = AuthorizationHelper.getAuthenticatedName();
 
     List<WidgetEntity> requestedEntities = new ArrayList<WidgetEntity>();
 
@@ -221,9 +224,12 @@ public class WidgetResourceProvider extends AbstractControllerResourceProvider {
         if (entity == null) {
           throw new NoSuchResourceException("WidgetLayout with id " + id + " does not exists");
         }
+        if (!(entity.getAuthor().equals(author) || entity.getScope().equals(SCOPE.CLUSTER.name()))) {
+          throw new AccessDeniedException("User must be author of the widget or widget must have cluster scope");
+        }
         requestedEntities.add(entity);
       } else {
-        requestedEntities.addAll(widgetDAO.findAll());
+        requestedEntities.addAll(widgetDAO.findByScopeOrAuthor(author, SCOPE.CLUSTER.name()));
       }
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/5cbfb2a6/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/WidgetDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/WidgetDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/WidgetDAO.java
index 93fd7c2..7c38316 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/WidgetDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/WidgetDAO.java
@@ -75,6 +75,16 @@ public class WidgetDAO {
   }
 
   @RequiresSession
+  public List<WidgetEntity> findByScopeOrAuthor(String author, String scope) {
+    TypedQuery<WidgetEntity> query = entityManagerProvider.get()
+            .createNamedQuery("WidgetEntity.findByScopeOrAuthor", WidgetEntity.class);
+    query.setParameter("author", author);
+    query.setParameter("scope", scope);
+
+    return daoUtils.selectList(query);
+  }
+
+  @RequiresSession
   public List<WidgetEntity> findAll() {
     TypedQuery<WidgetEntity> query = entityManagerProvider.get()
             .createNamedQuery("WidgetEntity.findAll", WidgetEntity.class);

http://git-wip-us.apache.org/repos/asf/ambari/blob/5cbfb2a6/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java
index 8710e5d..40eb7e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/WidgetEntity.java
@@ -46,6 +46,10 @@ import java.util.List;
 )
 @NamedQueries({
     @NamedQuery(name = "WidgetEntity.findAll", query = "SELECT widget FROM WidgetEntity widget"),
+    @NamedQuery(name = "WidgetEntity.findByScopeOrAuthor", query =
+            "SELECT widget FROM WidgetEntity widget " +
+                    "WHERE widget.author = :author " +
+                    "OR widget.scope = :scope"),
     @NamedQuery(name = "WidgetEntity.findByCluster", query = "SELECT widget FROM WidgetEntity widget WHERE widget.clusterId = :clusterId"),
     @NamedQuery(name = "WidgetEntity.findByName", query =
             "SELECT widget FROM WidgetEntity widget " +

http://git-wip-us.apache.org/repos/asf/ambari/blob/5cbfb2a6/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java
index 244049c..dff0a62 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/WidgetResourceProviderTest.java
@@ -27,7 +27,6 @@ import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
@@ -45,6 +44,7 @@ import org.powermock.api.easymock.PowerMock;
 import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
+import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 import java.util.Arrays;
@@ -129,7 +129,7 @@ public class WidgetResourceProviderTest {
           .and().property(WidgetResourceProvider.WIDGET_ID_PROPERTY_ID).equals("1")
             .and().property(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID).equals("username").toPredicate();
 
-    expect(dao.findById(1L)).andReturn(getMockEntities().get(0));
+    expect(dao.findById(1L)).andReturn(getMockEntities("CLUSTER").get(0));
 
     replay(amc, clusters, cluster, dao);
 
@@ -140,7 +140,7 @@ public class WidgetResourceProviderTest {
 
     Resource r = results.iterator().next();
     Assert.assertEquals("GAUGE", r.getPropertyValue(WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID));
-    Assert.assertEquals("USER", r.getPropertyValue(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID));
+    Assert.assertEquals("CLUSTER", r.getPropertyValue(WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID));
     Assert.assertEquals("username", r.getPropertyValue(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID));
     Assert.assertEquals("widget name", r.getPropertyValue(WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID));
     Object metrics = r.getPropertyValue(WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID);
@@ -160,6 +160,51 @@ public class WidgetResourceProviderTest {
     Assert.assertEquals("{\"name\":\"value\"}", r.getPropertyValue(WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID));
   }
 
+  /**
+   * @throws Exception
+   */
+  @Test
+  public void testGetResourceOfOtherUser() throws Exception {
+    Request request = PropertyHelper.getReadRequest(
+            WidgetResourceProvider.WIDGET_ID_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_WIDGET_NAME_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_WIDGET_TYPE_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_TIME_CREATED_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_DESCRIPTION_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_SCOPE_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_METRICS_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_VALUES_PROPERTY_ID,
+            WidgetResourceProvider.WIDGET_PROPERTIES_PROPERTY_ID);
+
+    AmbariManagementController amc = createMock(AmbariManagementController.class);
+    Clusters clusters = createMock(Clusters.class);
+    Cluster cluster = createMock(Cluster.class);
+    expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
+    expect(clusters.getClusterById(1L)).andReturn(cluster).atLeastOnce();
+    expect(cluster.getClusterName()).andReturn("c1").anyTimes();
+
+    Predicate predicate = new PredicateBuilder().property(
+            WidgetResourceProvider.WIDGET_CLUSTER_NAME_PROPERTY_ID).equals("c1")
+            .and().property(WidgetResourceProvider.WIDGET_ID_PROPERTY_ID).equals("1")
+            .and().property(WidgetResourceProvider.WIDGET_AUTHOR_PROPERTY_ID).equals("username").toPredicate();
+
+    expect(dao.findById(1L)).andReturn(getMockEntities("USER").get(0));
+
+    replay(amc, clusters, cluster, dao);
+
+    WidgetResourceProvider provider = createProvider(amc);
+
+    try {
+      Set<Resource> results = provider.getResources(request, predicate);
+    } catch (AccessDeniedException ex) {
+      //Expected exception
+      Assert.assertEquals("User must be author of the widget or widget must have cluster scope", ex.getMessage());
+    }
+
+  }
+
 
   /**
    * @throws Exception
@@ -408,7 +453,7 @@ public class WidgetResourceProviderTest {
 
     try {
       widgetResourceProvider.createResources(request);
-    } catch (SystemException ex) {
+    } catch (AccessDeniedException ex) {
       //Expected exception
     }
 
@@ -425,14 +470,14 @@ public class WidgetResourceProviderTest {
   /**
    * @return
    */
-  private List<WidgetEntity> getMockEntities() throws Exception {
+  private List<WidgetEntity> getMockEntities(String scope) throws Exception {
 
     WidgetEntity widgetEntity = new WidgetEntity();
     widgetEntity.setClusterId(Long.valueOf(1L));
     widgetEntity.setWidgetName("widget name");
     widgetEntity.setWidgetType("GAUGE");
     widgetEntity.setAuthor("username");
-    widgetEntity.setScope("USER");
+    widgetEntity.setScope(scope);
     widgetEntity.setDefaultSectionName("default_section_name");
     widgetEntity.setDescription("Description");
     widgetEntity.setMetrics("[{\"widget_id\":\"metrics/jvm/HeapMemoryUsed\"," +