You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by tb...@apache.org on 2014/08/11 03:06:52 UTC
[2/2] git commit: AMBARI-6723 - Views: Support clean install scenario
AMBARI-6723 - Views: Support clean install scenario
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/da2ac577
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/da2ac577
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/da2ac577
Branch: refs/heads/trunk
Commit: da2ac57778b406f2ac6ce0ca1e4c7e6944552568
Parents: 778d62e
Author: tbeerbower <tb...@hortonworks.com>
Authored: Sun Aug 3 01:16:18 2014 -0400
Committer: tbeerbower <tb...@hortonworks.com>
Committed: Sun Aug 10 20:19:47 2014 -0400
----------------------------------------------------------------------
.../server/api/services/ClusterService.java | 181 ++++++++++++++++---
.../api/services/ViewInstanceService.java | 46 ++++-
.../ambari/server/controller/AmbariServer.java | 20 +-
.../server/controller/ControllerModule.java | 4 +-
.../internal/AbstractProviderModule.java | 23 ++-
.../ClusterPrivilegeResourceProvider.java | 22 +++
.../internal/ClusterResourceProvider.java | 102 +++++++----
.../internal/PrivilegeResourceProvider.java | 14 +-
.../internal/ViewInstanceResourceProvider.java | 59 +++++-
.../internal/ViewPrivilegeResourceProvider.java | 14 ++
.../ambari/server/orm/dao/PrivilegeDAO.java | 17 ++
.../server/orm/entities/PermissionEntity.java | 18 +-
.../server/orm/entities/ViewInstanceEntity.java | 43 +----
.../ambari/server/security/SecurityHelper.java | 43 +++++
.../server/security/SecurityHelperImpl.java | 87 +++++++++
.../AmbariAuthorizationFilter.java | 137 ++++++++++++++
.../authorization/AmbariGrantedAuthority.java | 85 +++++++++
.../AmbariLdapAuthoritiesPopulator.java | 28 ++-
.../AmbariLocalUserDetailsService.java | 31 +++-
.../authorization/AuthorizationHelper.java | 13 +-
.../InternalTokenAuthenticationFilter.java | 60 ------
.../org/apache/ambari/server/state/Cluster.java | 14 +-
.../apache/ambari/server/state/Clusters.java | 11 ++
.../server/state/cluster/ClusterImpl.java | 20 ++
.../server/state/cluster/ClustersImpl.java | 60 +++++-
.../apache/ambari/server/view/ViewRegistry.java | 152 +++++++++-------
.../webapp/WEB-INF/spring-security.xml | 5 +-
.../ambari/server/agent/AgentResourceTest.java | 3 +
.../server/api/services/ClusterServiceTest.java | 23 ++-
.../ClusterPrivilegeResourceProviderTest.java | 17 +-
.../internal/ClusterResourceProviderTest.java | 57 ++++--
.../ViewPrivilegeResourceProviderTest.java | 2 +
.../orm/entities/ViewInstanceEntityTest.java | 27 ++-
.../authorization/AuthorizationHelperTest.java | 68 +++++--
.../TestAmbariLdapAuthoritiesPopulator.java | 47 ++++-
.../ambari/server/view/ViewRegistryTest.java | 83 +++------
36 files changed, 1263 insertions(+), 373 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index e80a90b..8043b3f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -19,7 +19,9 @@
package org.apache.ambari.server.api.services;
import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.state.Clusters;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
@@ -33,12 +35,40 @@ import java.util.Collections;
public class ClusterService extends BaseService {
/**
+ * The clusters utilities.
+ */
+ private final Clusters clusters;
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a ClusterService.
+ */
+ public ClusterService() {
+ this.clusters = AmbariServer.getController().getClusters();
+ }
+
+ /**
+ * Construct a ClusterService.
+ *
+ * @param clusters the clusters utilities
+ */
+ protected ClusterService(Clusters clusters) {
+ this.clusters = clusters;
+ }
+
+
+ // ----- ClusterService ----------------------------------------------------
+
+ /**
* Handles: GET /clusters/{clusterID}
* Get a specific cluster.
*
- * @param headers http headers
- * @param ui uri info
- * @param clusterName cluster id
+ * @param headers http headers
+ * @param ui uri info
+ * @param clusterName cluster id
+ *
* @return cluster instance representation
*/
@GET
@@ -47,6 +77,7 @@ public class ClusterService extends BaseService {
public Response getCluster(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("clusterName") String clusterName) {
+ hasPermission(Request.Type.GET, clusterName);
return handleRequest(headers, body, ui, Request.Type.GET, createClusterResource(clusterName));
}
@@ -54,13 +85,16 @@ public class ClusterService extends BaseService {
* Handles: GET /clusters
* Get all clusters.
*
- * @param headers http headers
- * @param ui uri info
+ * @param headers http headers
+ * @param ui uri info
+ *
* @return cluster collection resource representation
*/
@GET
@Produces("text/plain")
public Response getClusters(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+
+ hasPermission(Request.Type.GET, null);
return handleRequest(headers, body, ui, Request.Type.GET, createClusterResource(null));
}
@@ -68,9 +102,10 @@ public class ClusterService extends BaseService {
* Handles: POST /clusters/{clusterID}
* Create a specific cluster.
*
- * @param headers http headers
- * @param ui uri info
- * @param clusterName cluster id
+ * @param headers http headers
+ * @param ui uri info
+ * @param clusterName cluster id
+ *
* @return information regarding the created cluster
*/
@POST
@@ -79,16 +114,18 @@ public class ClusterService extends BaseService {
public Response createCluster(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("clusterName") String clusterName) {
- return handleRequest(headers, body, ui, Request.Type.POST, createClusterResource(clusterName));
+ hasPermission(Request.Type.POST, clusterName);
+ return handleRequest(headers, body, ui, Request.Type.POST, createClusterResource(clusterName));
}
/**
* Handles: PUT /clusters/{clusterID}
* Update a specific cluster.
*
- * @param headers http headers
- * @param ui uri info
- * @param clusterName cluster id
+ * @param headers http headers
+ * @param ui uri info
+ * @param clusterName cluster id
+ *
* @return information regarding the updated cluster
*/
@PUT
@@ -97,6 +134,7 @@ public class ClusterService extends BaseService {
public Response updateCluster(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("clusterName") String clusterName) {
+ hasPermission(Request.Type.PUT, clusterName);
return handleRequest(headers, body, ui, Request.Type.PUT, createClusterResource(clusterName));
}
@@ -104,9 +142,10 @@ public class ClusterService extends BaseService {
* Handles: DELETE /clusters/{clusterID}
* Delete a specific cluster.
*
- * @param headers http headers
- * @param ui uri info
- * @param clusterName cluster id
+ * @param headers http headers
+ * @param ui uri info
+ * @param clusterName cluster id
+ *
* @return information regarding the deleted cluster
*/
@DELETE
@@ -115,47 +154,67 @@ public class ClusterService extends BaseService {
public Response deleteCluster(@Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("clusterName") String clusterName) {
+ hasPermission(Request.Type.DELETE, clusterName);
return handleRequest(headers, null, ui, Request.Type.DELETE, createClusterResource(clusterName));
}
/**
* Get the hosts sub-resource
*
- * @param clusterName cluster id
+ * @param request the request
+ * @param clusterName cluster id
+ *
* @return the hosts service
*/
@Path("{clusterName}/hosts")
- public HostService getHostHandler(@PathParam("clusterName") String clusterName) {
+ public HostService getHostHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new HostService(clusterName);
}
/**
* Get the services sub-resource
*
- * @param clusterName cluster id
+ * @param request the request
+ * @param clusterName cluster id
+ *
* @return the services service
*/
@Path("{clusterName}/services")
- public ServiceService getServiceHandler(@PathParam("clusterName") String clusterName) {
+ public ServiceService getServiceHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ServiceService(clusterName);
}
/**
* Gets the configurations sub-resource.
*
+ * @param request the request
* @param clusterName the cluster name
+ *
* @return the configuration service
*/
@Path("{clusterName}/configurations")
- public ConfigurationService getConfigurationHandler(@PathParam("clusterName") String clusterName) {
+ public ConfigurationService getConfigurationHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ConfigurationService(clusterName);
}
/**
* Gets the requests sub-resource.
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the requests service
*/
@Path("{clusterName}/requests")
- public RequestService getRequestHandler(@PathParam("clusterName") String clusterName) {
+ public RequestService getRequestHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new RequestService(clusterName);
}
@@ -163,11 +222,15 @@ public class ClusterService extends BaseService {
* Get the host component resource without specifying the parent host component.
* Allows accessing host component resources across hosts.
*
- * @param clusterName the cluster name
+ * @param request the request
+ * @param clusterName the cluster name
+ *
* @return the host component service with no parent set
*/
@Path("{clusterName}/host_components")
- public HostComponentService getHostComponentHandler(@PathParam("clusterName") String clusterName) {
+ public HostComponentService getHostComponentHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new HostComponentService(clusterName, null);
}
@@ -175,56 +238,98 @@ public class ClusterService extends BaseService {
* Get the component resource without specifying the parent service.
* Allows accessing component resources across services.
*
- * @param clusterName the cluster name
+ * @param request the request
+ * @param clusterName the cluster name
+ *
* @return the host component service with no parent set
*/
@Path("{clusterName}/components")
- public ComponentService getComponentHandler(@PathParam("clusterName") String clusterName) {
+ public ComponentService getComponentHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ComponentService(clusterName, null);
}
/**
* Gets the workflows sub-resource.
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the workflow service
*/
@Path("{clusterName}/workflows")
- public WorkflowService getWorkflowHandler(@PathParam("clusterName") String clusterName) {
+ public WorkflowService getWorkflowHandler(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new WorkflowService(clusterName);
}
/**
* Gets the config group service
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the config group service
*/
@Path("{clusterName}/config_groups")
- public ConfigGroupService getConfigGroupService(@PathParam("clusterName") String clusterName) {
+ public ConfigGroupService getConfigGroupService(@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ConfigGroupService(clusterName);
}
/**
* Gets the request schedule service
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the request schedule service
*/
@Path("{clusterName}/request_schedules")
public RequestScheduleService getRequestScheduleService
- (@PathParam ("clusterName") String clusterName) {
+ (@Context javax.ws.rs.core.Request request, @PathParam ("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new RequestScheduleService(clusterName);
}
/**
* Gets the alert definition service
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the alert definition service
*/
@Path("{clusterName}/alert_definitions")
public AlertDefinitionService getAlertDefinitionService(
- @PathParam("clusterName") String clusterName) {
+ @Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new AlertDefinitionService(clusterName);
}
/**
* Gets the privilege service
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the privileges service
*/
@Path("{clusterName}/privileges")
- public PrivilegeService getPrivilegeService(@PathParam ("clusterName") String clusterName) {
+ public PrivilegeService getPrivilegeService(@Context javax.ws.rs.core.Request request, @PathParam ("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ClusterPrivilegeService(clusterName);
}
+
+ // ----- helper methods ----------------------------------------------------
+
/**
* Create a cluster resource instance.
*
@@ -236,4 +341,20 @@ public class ClusterService extends BaseService {
return createResource(Resource.Type.Cluster,
Collections.singletonMap(Resource.Type.Cluster, clusterName));
}
+
+ /**
+ * Determine whether or not the access specified by the given request type
+ * is permitted for the current user on the cluster resource identified by
+ * the given cluster name.
+ *
+ * @param requestType the request method type
+ * @param clusterName the name of the cluster resource
+ *
+ * @throws WebApplicationException if access is forbidden
+ */
+ private void hasPermission(Request.Type requestType, String clusterName) throws WebApplicationException {
+ if (!clusters.checkPermission(clusterName, requestType == Request.Type.GET)) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
index e9556f8..05c5079 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
@@ -30,6 +30,7 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
@@ -51,6 +52,11 @@ public class ViewInstanceService extends BaseService {
*/
private final String version;
+ /**
+ * The view registry;
+ */
+ private final ViewRegistry viewRegistry;
+
// ----- Constructors ------------------------------------------------------
@@ -63,6 +69,8 @@ public class ViewInstanceService extends BaseService {
public ViewInstanceService(String viewName, String version) {
this.viewName = viewName;
this.version = version;
+
+ viewRegistry = ViewRegistry.getInstance();
}
@@ -84,6 +92,7 @@ public class ViewInstanceService extends BaseService {
public Response getService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("instanceName") String instanceName) {
+ hasPermission(Request.Type.GET, instanceName);
return handleRequest(headers, body, ui, Request.Type.GET,
createResource(viewName, version, instanceName));
}
@@ -100,6 +109,8 @@ public class ViewInstanceService extends BaseService {
@GET
@Produces("text/plain")
public Response getServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+
+ hasPermission(Request.Type.GET, null);
return handleRequest(headers, body, ui, Request.Type.GET,
createResource(viewName, version, null));
}
@@ -120,6 +131,7 @@ public class ViewInstanceService extends BaseService {
@Produces("text/plain")
public Response createService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("instanceName") String instanceName) {
+ hasPermission(Request.Type.POST, instanceName);
return handleRequest(headers, body, ui, Request.Type.POST,
createResource(viewName, version, instanceName));
}
@@ -138,6 +150,7 @@ public class ViewInstanceService extends BaseService {
@Produces("text/plain")
public Response createServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+ hasPermission(Request.Type.POST, null);
return handleRequest(headers, body, ui, Request.Type.POST,
createResource(viewName, version, null));
}
@@ -159,6 +172,7 @@ public class ViewInstanceService extends BaseService {
public Response updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("instanceName") String instanceName) {
+ hasPermission(Request.Type.PUT, instanceName);
return handleRequest(headers, body, ui, Request.Type.PUT, createResource(viewName, version, instanceName));
}
@@ -176,6 +190,7 @@ public class ViewInstanceService extends BaseService {
@Produces("text/plain")
public Response updateServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+ hasPermission(Request.Type.PUT, null);
return handleRequest(headers, body, ui, Request.Type.PUT, createResource(viewName, version, null));
}
@@ -195,6 +210,7 @@ public class ViewInstanceService extends BaseService {
public Response deleteService(@Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("instanceName") String instanceName) {
+ hasPermission(Request.Type.DELETE, instanceName);
return handleRequest(headers, null, ui, Request.Type.DELETE, createResource(viewName, version, instanceName));
}
@@ -206,8 +222,11 @@ public class ViewInstanceService extends BaseService {
* @return the service
*/
@Path("{instanceName}/{resources}")
- public Object getResourceHandler(@PathParam("instanceName") String instanceName,
- @PathParam("resources") String resources) {
+ public Object getResourceHandler(@Context javax.ws.rs.core.Request request,
+ @PathParam("instanceName") String instanceName,
+ @PathParam("resources") String resources) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), instanceName);
ViewInstanceEntity instanceDefinition =
ViewRegistry.getInstance().getInstanceDefinition(viewName, version, instanceName);
@@ -230,10 +249,15 @@ public class ViewInstanceService extends BaseService {
* Gets the admin privilege service
*/
@Path("{instanceName}/privileges")
- public PrivilegeService getPrivilegeService(@PathParam ("instanceName") String instanceName) {
+ public PrivilegeService getPrivilegeService(@Context javax.ws.rs.core.Request request,
+ @PathParam ("instanceName") String instanceName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), instanceName);
+
return new ViewPrivilegeService(viewName, version, instanceName);
}
+
// ----- helper methods ----------------------------------------------------
/**
@@ -251,4 +275,20 @@ public class ViewInstanceService extends BaseService {
mapIds.put(Resource.Type.ViewInstance, instanceName);
return createResource(Resource.Type.ViewInstance, mapIds);
}
+
+ /**
+ * Determine whether or not the access specified by the given request type
+ * is permitted for the current user on the view instance resource identified
+ * by the given instance name.
+ *
+ * @param requestType the request method type
+ * @param instanceName the name of the view instance resource
+ *
+ * @throws WebApplicationException if access is forbidden
+ */
+ private void hasPermission(Request.Type requestType, String instanceName) {
+ if (!viewRegistry.checkPermission(viewName, version, instanceName, requestType == Request.Type.GET)) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 0e9e108..723feba 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -68,7 +68,6 @@ import org.apache.ambari.server.orm.dao.PermissionDAO;
import org.apache.ambari.server.orm.dao.PrincipalDAO;
import org.apache.ambari.server.orm.dao.PrivilegeDAO;
import org.apache.ambari.server.orm.dao.ResourceDAO;
-import org.apache.ambari.server.orm.dao.ResourceTypeDAO;
import org.apache.ambari.server.orm.dao.UserDAO;
import org.apache.ambari.server.orm.dao.ViewDAO;
import org.apache.ambari.server.orm.dao.ViewInstanceDAO;
@@ -79,12 +78,13 @@ import org.apache.ambari.server.resources.api.rest.GetResource;
import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
import org.apache.ambari.server.security.CertificateManager;
import org.apache.ambari.server.security.SecurityFilter;
+import org.apache.ambari.server.security.SecurityHelper;
import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
import org.apache.ambari.server.security.authorization.AmbariLdapDataPopulator;
import org.apache.ambari.server.security.authorization.AmbariLocalUserDetailsService;
import org.apache.ambari.server.security.authorization.Users;
+import org.apache.ambari.server.security.authorization.AmbariAuthorizationFilter;
import org.apache.ambari.server.security.authorization.internal.AmbariInternalAuthenticationProvider;
-import org.apache.ambari.server.security.authorization.internal.InternalTokenAuthenticationFilter;
import org.apache.ambari.server.security.unsecured.rest.CertificateDownload;
import org.apache.ambari.server.security.unsecured.rest.CertificateSign;
import org.apache.ambari.server.security.unsecured.rest.ConnectionInfo;
@@ -127,7 +127,6 @@ public class AmbariServer {
private static Logger LOG = LoggerFactory.getLogger(AmbariServer.class);
private Server server = null;
- private Server serverForAgent = null;
public volatile boolean running = true; // true while controller runs
@@ -168,7 +167,7 @@ public class AmbariServer {
performStaticInjection();
initDB();
server = new Server();
- serverForAgent = new Server();
+ Server serverForAgent = new Server();
checkDBVersion();
@@ -188,8 +187,8 @@ public class AmbariServer {
injector.getInstance(AmbariLdapAuthenticationProvider.class));
factory.registerSingleton("ambariLdapDataPopulator",
injector.getInstance(AmbariLdapDataPopulator.class));
- factory.registerSingleton("internalTokenAuthenticationFilter",
- injector.getInstance(InternalTokenAuthenticationFilter.class));
+ factory.registerSingleton("ambariAuthorizationFilter",
+ injector.getInstance(AmbariAuthorizationFilter.class));
factory.registerSingleton("ambariInternalAuthenticationProvider",
injector.getInstance(AmbariInternalAuthenticationProvider.class));
@@ -284,7 +283,7 @@ public class AmbariServer {
sslConnectorOneWay.setPort(configs.getOneWayAuthPort());
sslConnectorOneWay.setAcceptors(2);
sslConnectorTwoWay.setAcceptors(2);
- serverForAgent.setConnectors(new Connector[]{ sslConnectorOneWay, sslConnectorTwoWay});
+ serverForAgent.setConnectors(new Connector[]{sslConnectorOneWay, sslConnectorTwoWay});
ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
@@ -543,9 +542,8 @@ public class AmbariServer {
injector.getInstance(PermissionDAO.class), injector.getInstance(ResourceDAO.class));
ClusterPrivilegeResourceProvider.init(injector.getInstance(ClusterDAO.class));
ViewRegistry.init(injector.getInstance(ViewDAO.class), injector.getInstance(ViewInstanceDAO.class),
- injector.getInstance(ResourceDAO.class), injector.getInstance(ResourceTypeDAO.class),
injector.getInstance(UserDAO.class), injector.getInstance(MemberDAO.class),
- injector.getInstance(PrivilegeDAO.class));
+ injector.getInstance(PrivilegeDAO.class), injector.getInstance(SecurityHelper.class));
}
/**
@@ -588,9 +586,7 @@ public class AmbariServer {
CertificateManager certMan = injector.getInstance(CertificateManager.class);
certMan.initRootCert();
ComponentSSLConfiguration.instance().init(server.configs);
- if (server != null) {
- server.run();
- }
+ server.run();
} catch (Throwable t) {
LOG.error("Failed to run the Ambari Server", t);
if (server != null) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 8f87bae..2513382 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -46,6 +46,8 @@ import org.apache.ambari.server.orm.DBAccessorImpl;
import org.apache.ambari.server.orm.PersistenceType;
import org.apache.ambari.server.scheduler.ExecutionScheduler;
import org.apache.ambari.server.scheduler.ExecutionSchedulerImpl;
+import org.apache.ambari.server.security.SecurityHelper;
+import org.apache.ambari.server.security.SecurityHelperImpl;
import org.apache.ambari.server.serveraction.ServerActionManager;
import org.apache.ambari.server.serveraction.ServerActionManagerImpl;
import org.apache.ambari.server.state.Cluster;
@@ -276,6 +278,6 @@ public class ControllerModule extends AbstractModule {
install(new FactoryModuleBuilder().build(RequestFactory.class));
bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
+ bind(SecurityHelper.class).toInstance(SecurityHelperImpl.getInstance());
}
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
index f7d2ed1..bf92238 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
@@ -528,7 +528,14 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
private void initProviderMaps() throws SystemException {
ResourceProvider provider = getResourceProvider(Resource.Type.Cluster);
- Request request = PropertyHelper.getReadRequest(CLUSTER_NAME_PROPERTY_ID);
+
+ Set<String> propertyIds = new HashSet<String>();
+ propertyIds.add(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID);
+
+ Map<String, String> requestInfoProperties = new HashMap<String, String>();
+ requestInfoProperties.put(ClusterResourceProvider.GET_IGNORE_PERMISSIONS_PROPERTY_ID, "true");
+
+ Request request = PropertyHelper.getReadRequest(propertyIds, requestInfoProperties, null);
try {
jmxPortMap.clear();
@@ -607,9 +614,17 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
Set<Resource> clusterResource = null;
try {
- clusterResource = clusterResourceProvider.getResources(
- PropertyHelper.getReadRequest(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID,
- ClusterResourceProvider.CLUSTER_DESIRED_CONFIGS_PROPERTY_ID), basePredicate);
+
+ Set<String> propertyIds = new HashSet<String>();
+ propertyIds.add(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID);
+ propertyIds.add(ClusterResourceProvider.CLUSTER_DESIRED_CONFIGS_PROPERTY_ID);
+
+ Map<String, String> requestInfoProperties = new HashMap<String, String>();
+ requestInfoProperties.put(ClusterResourceProvider.GET_IGNORE_PERMISSIONS_PROPERTY_ID, "true");
+
+ Request readRequest = PropertyHelper.getReadRequest(propertyIds, requestInfoProperties, null);
+
+ clusterResource = clusterResourceProvider.getResources(readRequest, basePredicate);
} catch (NoSuchResourceException e) {
LOG.error("Resource for the desired config not found. " + e);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterPrivilegeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterPrivilegeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterPrivilegeResourceProvider.java
index a29f3c8..46bfea0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterPrivilegeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterPrivilegeResourceProvider.java
@@ -17,12 +17,15 @@
*/
package org.apache.ambari.server.controller.internal;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.orm.dao.ClusterDAO;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.GroupEntity;
+import org.apache.ambari.server.orm.entities.PermissionEntity;
import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.UserEntity;
import java.util.Collections;
@@ -68,6 +71,16 @@ public class ClusterPrivilegeResourceProvider extends PrivilegeResourceProvider<
keyPropertyIds.put(Resource.Type.ClusterPrivilege, PRIVILEGE_ID_PROPERTY_ID);
}
+ /**
+ * The built-in VIEW.USE permission.
+ */
+ private final PermissionEntity clusterReadPermission;
+
+ /**
+ * The built-in VIEW.USE permission.
+ */
+ private final PermissionEntity clusterOperatePermission;
+
// ----- Constructors ------------------------------------------------------
@@ -76,6 +89,8 @@ public class ClusterPrivilegeResourceProvider extends PrivilegeResourceProvider<
*/
public ClusterPrivilegeResourceProvider() {
super(propertyIds, keyPropertyIds, Resource.Type.ClusterPrivilege);
+ clusterReadPermission = permissionDAO.findById(PermissionEntity.CLUSTER_READ_PERMISSION);
+ clusterOperatePermission = permissionDAO.findById(PermissionEntity.CLUSTER_OPERATE_PERMISSION);
}
@@ -137,5 +152,12 @@ public class ClusterPrivilegeResourceProvider extends PrivilegeResourceProvider<
}
return resource;
}
+
+ @Override
+ protected PermissionEntity getPermission(String permissionName, ResourceEntity resourceEntity) throws AmbariException {
+ return (permissionName.equals(PermissionEntity.CLUSTER_READ_PERMISSION_NAME)) ? clusterReadPermission :
+ permissionName.equals(PermissionEntity.CLUSTER_OPERATE_PERMISSION_NAME) ? clusterOperatePermission :
+ super.getPermission(permissionName, resourceEntity);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
index 5bddeb9..64cdb4d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
@@ -60,7 +60,7 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
// Clusters
protected static final String CLUSTER_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_id");
protected static final String CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_name");
- protected static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
+ protected static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
protected static final String CLUSTER_PROVISIONING_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "provisioning_state");
protected static final String CLUSTER_DESIRED_CONFIGS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_configs");
protected static final String CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_serviceconfigversions");
@@ -68,6 +68,14 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
protected static final String CLUSTER_HEALTH_REPORT_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "health_report");
protected static final String BLUEPRINT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "blueprint");
+ /**
+ * Request info property ID. Allow internal getResources call to bypass permissions check.
+ */
+ public static final String GET_IGNORE_PERMISSIONS_PROPERTY_ID = "get_resource/ignore_permissions";
+
+ /**
+ * The cluster primary key properties.
+ */
private static Set<String> pkPropertyIds =
new HashSet<String>(Arrays.asList(new String[]{CLUSTER_ID_PROPERTY_ID}));
@@ -99,19 +107,8 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
super(propertyIds, keyPropertyIds, managementController);
}
- /**
- * Inject the blueprint data access object which is used to obtain blueprint entities.
- *
- * @param dao blueprint data access object
- */
- public static void init(BlueprintDAO dao, AmbariMetaInfo metaInfo, ConfigHelper ch) {
- blueprintDAO = dao;
- stackInfo = metaInfo;
- configHelper = ch;
- }
-
-// ----- ResourceProvider ------------------------------------------------
+ // ----- ResourceProvider ------------------------------------------------
@Override
public RequestStatus createResources(Request request)
@@ -160,17 +157,25 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
LOG.debug("Found clusters matching getClusters request"
+ ", clusterResponseCount=" + responses.size());
}
-
+
+ // Allow internal call to bypass permissions check.
+ Map<String, String> requestInfoProperties = request.getRequestInfoProperties();
+ boolean ignorePermissions = requestInfoProperties == null ? false :
+ Boolean.valueOf(requestInfoProperties.get(GET_IGNORE_PERMISSIONS_PROPERTY_ID));
+
for (ClusterResponse response : responses) {
+
+ String clusterName = response.getClusterName();
+
Resource resource = new ResourceImpl(Resource.Type.Cluster);
setResourceProperty(resource, CLUSTER_ID_PROPERTY_ID, response.getClusterId(), requestedIds);
- setResourceProperty(resource, CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
+ setResourceProperty(resource, CLUSTER_NAME_PROPERTY_ID, clusterName, requestedIds);
setResourceProperty(resource, CLUSTER_PROVISIONING_STATE_PROPERTY_ID, response.getProvisioningState(), requestedIds);
setResourceProperty(resource, CLUSTER_DESIRED_CONFIGS_PROPERTY_ID, response.getDesiredConfigs(), requestedIds);
setResourceProperty(resource, CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID, response.getDesiredServiceConfigVersions(), requestedIds);
setResourceProperty(resource, CLUSTER_TOTAL_HOSTS_PROPERTY_ID, response.getTotalHosts(), requestedIds);
setResourceProperty(resource, CLUSTER_HEALTH_REPORT_PROPERTY_ID, response.getClusterHealthReport(), requestedIds);
-
+
resource.setProperty(CLUSTER_VERSION_PROPERTY_ID,
response.getDesiredStackVersion());
@@ -178,8 +183,9 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
LOG.debug("Adding ClusterResponse to resource"
+ ", clusterResponse=" + response.toString());
}
-
- resources.add(resource);
+ if (ignorePermissions || includeCluster(clusterName, true)) {
+ resources.add(resource);
+ }
}
return resources;
}
@@ -194,7 +200,10 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
for (Map<String, Object> requestPropertyMap : request.getProperties()) {
Set<Map<String, Object>> propertyMaps = getPropertyMaps(requestPropertyMap, predicate);
for (Map<String, Object> propertyMap : propertyMaps) {
- requests.add(getRequest(propertyMap));
+ ClusterRequest clusterRequest = getRequest(propertyMap);
+ if (includeCluster(clusterRequest.getClusterName(), false)) {
+ requests.add(clusterRequest);
+ }
}
}
response = modifyResources(new Command<RequestStatusResponse>() {
@@ -241,13 +250,15 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
final ClusterRequest clusterRequest = getRequest(propertyMap);
- modifyResources(new Command<Void>() {
- @Override
- public Void invoke() throws AmbariException {
- getManagementController().deleteCluster(clusterRequest);
- return null;
- }
- });
+ if (includeCluster(clusterRequest.getClusterName(), false)) {
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ getManagementController().deleteCluster(clusterRequest);
+ return null;
+ }
+ });
+ }
}
notifyDelete(Resource.Type.Cluster, predicate);
return getRequestStatus(null);
@@ -274,7 +285,22 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
return checkConfigPropertyIds(baseUnsupported, "Clusters");
}
- // ----- utility methods -------------------------------------------------
+
+ // ----- ClusterResourceProvider -------------------------------------------
+
+ /**
+ * Inject the blueprint data access object which is used to obtain blueprint entities.
+ *
+ * @param dao blueprint data access object
+ */
+ public static void init(BlueprintDAO dao, AmbariMetaInfo metaInfo, ConfigHelper ch) {
+ blueprintDAO = dao;
+ stackInfo = metaInfo;
+ configHelper = ch;
+ }
+
+
+ // ----- utility methods ---------------------------------------------------
/**
* Get a cluster request object from a map of property values.
@@ -814,14 +840,14 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
configurationProcessor.doUpdateForClusterCreate(blueprintHostGroups);
setMissingConfigurations();
}
-
+
/**
* Since global configs are deprecated since 1.7.0, but still supported.
* We should automatically map any globals used, to *-env dictionaries.
*
* @param blueprintConfigurations map of blueprint configurations keyed by type
*/
- private void handleGlobalsBackwardsCompability(Stack stack,
+ private void handleGlobalsBackwardsCompability(Stack stack,
Map<String, Map<String, String>> blueprintConfigurations) {
StackId stackId = new StackId(stack.getName(), stack.getVersion());
configHelper.moveDeprecatedGlobals(stackId, blueprintConfigurations);
@@ -884,7 +910,7 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
userProps.put("hcat_user", "hive-env");
userProps.put("hbase_user", "hbase-env");
userProps.put("falcon_user", "falcon-env");
-
+
String proxyUserHosts = "hadoop.proxyuser.%s.hosts";
String proxyUserGroups = "hadoop.proxyuser.%s.groups";
@@ -957,7 +983,7 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
private void registerConfigGroups(String clusterName, Map<String, HostGroupImpl> hostGroups, Stack stack) throws
ResourceAlreadyExistsException, SystemException,
UnsupportedPropertyException, NoSuchParentResourceException {
-
+
for (HostGroupImpl group : hostGroups.values()) {
HostGroupEntity entity = group.getEntity();
Map<String, Map<String, Config>> groupConfigs = new HashMap<String, Map<String, Config>>();
@@ -1015,5 +1041,19 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
flaggedHosts);
}
}
+
+ /**
+ * Determine whether or not the cluster resource identified
+ * by the given cluster name should be included based on the
+ * permissions granted to the current user.
+ *
+ * @param clusterName the cluster name
+ * @param readOnly indicate whether or not this is for a read only operation
+ *
+ * @return true if the cluster should be included based on the permissions of the current user
+ */
+ private boolean includeCluster(String clusterName, boolean readOnly) {
+ return getManagementController().getClusters().checkPermission(clusterName, readOnly);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java
index 559f415..42ab21d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PrivilegeResourceProvider.java
@@ -309,15 +309,14 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi
String permissionName = (String) properties.get(PERMISSION_NAME_PROPERTY_ID);
ResourceEntity resourceEntity = resourceDAO.findById(resourceId);
- entity.setResource(resourceEntity);
+ PermissionEntity permission = getPermission(permissionName, resourceEntity);
- PermissionEntity permission =
- permissionDAO.findPermissionByNameAndType(permissionName, resourceEntity.getResourceType());
if (permission == null) {
throw new AmbariException("Can't find a permission named " + permissionName +
- " for the resource type " + resourceEntity.getResourceType().getName() + ".");
+ " for the resource.");
}
entity.setPermission(permission);
+ entity.setResource(resourceEntity);
String principalName = (String) properties.get(PRINCIPAL_NAME_PROPERTY_ID);
String principalType = (String) properties.get(PRINCIPAL_TYPE_PROPERTY_ID);
@@ -336,6 +335,13 @@ public abstract class PrivilegeResourceProvider<T> extends AbstractResourceProvi
return entity;
}
+ // Get a permission with the given permission name for the given resource.
+ protected PermissionEntity getPermission(String permissionName, ResourceEntity resourceEntity)
+ throws AmbariException {
+
+ return permissionDAO.findPermissionByNameAndType(permissionName, resourceEntity.getResourceType());
+ }
+
// Create a create command with the given properties map.
private Command<Void> getCreateCommand(final Map<String, Object> properties) {
return new Command<Void>() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
index 5b48679..2ebd9f4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
@@ -145,8 +145,10 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
for (ViewInstanceEntity viewInstanceDefinition : viewRegistry.getInstanceDefinitions(viewDefinition)) {
if (instanceName == null || instanceName.equals(viewInstanceDefinition.getName())) {
if (viewVersion == null || viewVersion.equals(viewDefinition.getVersion())) {
- Resource resource = toResource(viewInstanceDefinition, requestedIds);
- resources.add(resource);
+ if (includeInstance(viewInstanceDefinition, true)) {
+ Resource resource = toResource(viewInstanceDefinition, requestedIds);
+ resources.add(resource);
+ }
}
}
}
@@ -220,8 +222,11 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
properties, requestedIds);
Map<String, String> applicationData = new HashMap<String, String>();
+ String currentUserName = viewInstanceEntity.getCurrentUserName();
for (ViewInstanceDataEntity viewInstanceDataEntity : viewInstanceEntity.getData()) {
- applicationData.put(viewInstanceDataEntity.getName(), viewInstanceDataEntity.getValue());
+ if (currentUserName.equals(viewInstanceDataEntity.getUser())) {
+ applicationData.put(viewInstanceDataEntity.getName(), viewInstanceDataEntity.getValue());
+ }
}
setResourceProperty(resource, DATA_PROPERTY_ID,
applicationData, requestedIds);
@@ -308,6 +313,7 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
viewInstanceDataEntity.setViewName(viewName);
viewInstanceDataEntity.setViewInstanceName(name);
viewInstanceDataEntity.setName(entry.getKey().substring(DATA_PREFIX.length()));
+ viewInstanceDataEntity.setUser(viewInstanceEntity.getCurrentUserName());
viewInstanceDataEntity.setValue((String) entry.getValue());
viewInstanceDataEntity.setViewInstanceEntity(viewInstanceEntity);
@@ -340,7 +346,13 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
return new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
- ViewRegistry.getInstance().updateViewInstance(toEntity(properties));
+
+ ViewInstanceEntity instance = toEntity(properties);
+ ViewEntity view = instance.getViewEntity();
+
+ if (includeInstance(view.getCommonName(), view.getVersion(), instance.getInstanceName(), false)) {
+ ViewRegistry.getInstance().updateViewInstance(instance);
+ }
return null;
}
};
@@ -360,7 +372,9 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
for (ViewInstanceEntity viewInstanceEntity : viewRegistry.getInstanceDefinitions(viewEntity)){
Resource resource = toResource(viewInstanceEntity, requestedIds);
if (predicate == null || predicate.evaluate(resource)) {
- viewInstanceEntities.add(viewInstanceEntity);
+ if (includeInstance(viewInstanceEntity, false)) {
+ viewInstanceEntities.add(viewInstanceEntity);
+ }
}
}
}
@@ -377,4 +391,39 @@ public class ViewInstanceResourceProvider extends AbstractResourceProvider {
return iconPath == null || iconPath.length() == 0 ? null :
contextPath + (iconPath.startsWith("/") ? "" : "/") + iconPath;
}
+
+ /**
+ * Determine whether or not the view instance resource identified
+ * by the given instance name should be included based on the permissions
+ * granted to the current user.
+ *
+ * @param viewName the view name
+ * @param version the view version
+ * @param instanceName the name of the view instance resource
+ * @param readOnly indicate whether or not this is for a read only operation
+ *
+ * @return true if the view instance should be included based on the permissions of the current user
+ */
+ private boolean includeInstance(String viewName, String version, String instanceName, boolean readOnly) {
+
+ ViewRegistry viewRegistry = ViewRegistry.getInstance();
+
+ return viewRegistry.checkPermission(viewName, version, instanceName, readOnly);
+ }
+
+ /**
+ * Determine whether or not the given view instance resource should be included
+ * based on the permissions granted to the current user.
+ *
+ * @param instanceEntity the view instance entity
+ * @param readOnly indicate whether or not this is for a read only operation
+ *
+ * @return true if the view instance should be included based on the permissions of the current user
+ */
+ private boolean includeInstance(ViewInstanceEntity instanceEntity, boolean readOnly) {
+
+ ViewRegistry viewRegistry = ViewRegistry.getInstance();
+
+ return viewRegistry.checkPermission(instanceEntity, readOnly);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java
index fa01bb6..6d10797 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProvider.java
@@ -20,7 +20,9 @@ package org.apache.ambari.server.controller.internal;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.orm.entities.GroupEntity;
+import org.apache.ambari.server.orm.entities.PermissionEntity;
import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
import org.apache.ambari.server.orm.entities.UserEntity;
import org.apache.ambari.server.orm.entities.ViewEntity;
@@ -70,6 +72,11 @@ public class ViewPrivilegeResourceProvider extends PrivilegeResourceProvider<Vie
keyPropertyIds.put(Resource.Type.ViewPrivilege, PRIVILEGE_ID_PROPERTY_ID);
}
+ /**
+ * The built-in VIEW.USE permission.
+ */
+ private final PermissionEntity viewUsePermission;
+
// ----- Constructors ------------------------------------------------------
@@ -78,6 +85,7 @@ public class ViewPrivilegeResourceProvider extends PrivilegeResourceProvider<Vie
*/
public ViewPrivilegeResourceProvider() {
super(propertyIds, keyPropertyIds, Resource.Type.ViewPrivilege);
+ viewUsePermission = permissionDAO.findById(PermissionEntity.VIEW_USE_PERMISSION);
}
@@ -157,5 +165,11 @@ public class ViewPrivilegeResourceProvider extends PrivilegeResourceProvider<Vie
}
return resource;
}
+
+ @Override
+ protected PermissionEntity getPermission(String permissionName, ResourceEntity resourceEntity) throws AmbariException {
+ return (permissionName.equals(PermissionEntity.VIEW_USE_PERMISSION_NAME)) ?
+ viewUsePermission : super.getPermission(permissionName, resourceEntity);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PrivilegeDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PrivilegeDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PrivilegeDAO.java
index 7fed17b..2ad14d2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PrivilegeDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PrivilegeDAO.java
@@ -29,6 +29,7 @@ import org.apache.ambari.server.orm.entities.ResourceEntity;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
+import java.util.Collections;
import java.util.List;
/**
@@ -99,6 +100,22 @@ public class PrivilegeDAO {
}
/**
+ * Find the privileges entities for the given list of principals
+ *
+ * @param principalList the list of principal entities
+ *
+ * @return the list of privileges matching the query
+ */
+ public List<PrivilegeEntity> findAllByPrincipal(List<PrincipalEntity> principalList) {
+ if (principalList == null || principalList.isEmpty()) {
+ return Collections.emptyList();
+ }
+ TypedQuery<PrivilegeEntity> query = entityManagerProvider.get().createQuery("SELECT privilege FROM PrivilegeEntity privilege WHERE privilege.principal IN :principalList", PrivilegeEntity.class);
+ query.setParameter("principalList", principalList);
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Make an instance managed and persistent.
*
* @param entity entity to persist
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PermissionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PermissionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PermissionEntity.java
index 8889bde..4702d05 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PermissionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PermissionEntity.java
@@ -27,8 +27,6 @@ import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
@@ -46,6 +44,22 @@ import javax.persistence.TableGenerator;
public class PermissionEntity {
/**
+ * Admin permission id constants.
+ */
+ public static final int AMBARI_ADMIN_PERMISSION = 1;
+ public static final int CLUSTER_READ_PERMISSION = 2;
+ public static final int CLUSTER_OPERATE_PERMISSION = 3;
+ public static final int VIEW_USE_PERMISSION = 4;
+
+ /**
+ * Admin permission name constants.
+ */
+ public static final String AMBARI_ADMIN_PERMISSION_NAME = "AMBARI.ADMIN";
+ public static final String CLUSTER_READ_PERMISSION_NAME = "CLUSTER.READ";
+ public static final String CLUSTER_OPERATE_PERMISSION_NAME = "CLUSTER.OPERATE";
+ public static final String VIEW_USE_PERMISSION_NAME = "VIEW.USE";
+
+ /**
* The permission id.
*/
@Id
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
index fa303c7..2878dd6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java
@@ -43,14 +43,12 @@ import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.security.SecurityHelper;
+import org.apache.ambari.server.security.SecurityHelperImpl;
import org.apache.ambari.server.view.configuration.InstanceConfig;
import org.apache.ambari.view.ResourceProvider;
import org.apache.ambari.view.ViewDefinition;
import org.apache.ambari.view.ViewInstanceDefinition;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
/**
* Represents an instance of a View.
@@ -179,8 +177,9 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
/**
* Helper class.
*/
+ // TODO : we should @Inject this.
@Transient
- private UserNameProvider userNameProvider = new UserNameProvider();
+ private SecurityHelper securityHelper = SecurityHelperImpl.getInstance();
// ----- Constructors ------------------------------------------------------
@@ -647,7 +646,7 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
* @return the current user name; empty String if user is not known
*/
public String getUsername() {
- return userNameProvider.getUsername();
+ return securityHelper.getCurrentUserName();
}
/**
@@ -698,7 +697,7 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
// ----- helper methods ----------------------------------------------------
// get the current user name
- private String getCurrentUserName() {
+ public String getCurrentUserName() {
String currentUserName = getUsername();
return currentUserName == null || currentUserName.length() == 0 ?
@@ -706,33 +705,11 @@ public class ViewInstanceEntity implements ViewInstanceDefinition {
}
/**
- * Set the user name provider helper.
+ * Set the security helper.
*
- * @param userNameProvider the helper
+ * @param securityHelper the helper
*/
- protected void setUserNameProvider(UserNameProvider userNameProvider) {
- this.userNameProvider = userNameProvider;
- }
-
-
- // ----- inner class : UserNameProvider ----------------------------------
-
- /**
- * User name provider helper class.
- */
- protected static class UserNameProvider {
- public String getUsername() {
- SecurityContext ctx = SecurityContextHolder.getContext();
- Authentication authentication = ctx == null ? null : ctx.getAuthentication();
- Object principal = authentication == null ? null : authentication.getPrincipal();
-
- String username;
- if (principal instanceof UserDetails) {
- username = ((UserDetails) principal).getUsername();
- } else {
- username = principal == null ? "" : principal.toString();
- }
- return username;
- }
+ protected void setSecurityHelper(SecurityHelper securityHelper) {
+ this.securityHelper = securityHelper;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelper.java
new file mode 100644
index 0000000..55ddf5d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelper.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.security;
+
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.Collection;
+
+/**
+ * Security related utilities.
+ */
+public interface SecurityHelper {
+
+ /**
+ * Get the current user.
+ *
+ * @return the current user.
+ */
+ public String getCurrentUserName();
+
+ /**
+ * Get the granted authorities for the current user.
+ *
+ * @return the granted authorities
+ */
+ public Collection<? extends GrantedAuthority> getCurrentAuthorities();
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelperImpl.java
new file mode 100644
index 0000000..519fd3a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/SecurityHelperImpl.java
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.security;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Security related utilities.
+ */
+// TODO : combine with AuthorizationHelper.
+public class SecurityHelperImpl implements SecurityHelper {
+
+ /**
+ * The singleton instance.
+ */
+ private static final SecurityHelper singleton = new SecurityHelperImpl();
+
+
+ // ----- Constructors --------------------------------------------------
+
+ /**
+ * Hidden constructor.
+ */
+ private SecurityHelperImpl() {
+ }
+
+
+ // ----- SecurityHelperImpl --------------------------------------------
+
+ public static SecurityHelper getInstance() {
+ return singleton;
+ }
+
+
+ // ----- SecurityHelper ------------------------------------------------
+
+ @Override
+ public String getCurrentUserName() {
+ SecurityContext ctx = SecurityContextHolder.getContext();
+ Authentication authentication = ctx == null ? null : ctx.getAuthentication();
+ Object principal = authentication == null ? null : authentication.getPrincipal();
+
+ String username;
+ if (principal instanceof UserDetails) {
+ username = ((UserDetails) principal).getUsername();
+ } else {
+ username = principal == null ? "" : principal.toString();
+ }
+ return username;
+ }
+
+ @Override
+ public Collection<? extends GrantedAuthority> getCurrentAuthorities()
+ {
+ SecurityContext context = SecurityContextHolder.getContext();
+
+ Authentication authentication = context.getAuthentication();
+
+ if (context.getAuthentication() != null && context.getAuthentication().isAuthenticated()) {
+ return authentication.getAuthorities();
+ }
+ return Collections.emptyList();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/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
new file mode 100644
index 0000000..4ba8c7f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.security.authorization;
+
+import org.apache.ambari.server.orm.entities.PermissionEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class AmbariAuthorizationFilter implements Filter {
+
+ private static final String REALM_PARAM = "realm";
+ private static final String DEFAULT_REALM = "AuthFilter";
+
+ private static final String INTERNAL_TOKEN_HEADER = "X-Internal-Token";
+
+ /**
+ * The realm to use for the basic http auth
+ */
+ private String realm;
+
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ realm = getParameterValue(filterConfig, REALM_PARAM, DEFAULT_REALM);
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+ SecurityContext context = SecurityContextHolder.getContext();
+
+ if (context.getAuthentication() == null || !context.getAuthentication().isAuthenticated()) {
+ String token = httpRequest.getHeader(INTERNAL_TOKEN_HEADER);
+ if (token != null) {
+ context.setAuthentication(new InternalAuthenticationToken(token));
+ }
+ } else {
+ boolean authorized = false;
+
+ Authentication authentication = context.getAuthentication();
+ for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
+ if (grantedAuthority instanceof AmbariGrantedAuthority) {
+
+ AmbariGrantedAuthority ambariGrantedAuthority = (AmbariGrantedAuthority) grantedAuthority;
+
+ PrivilegeEntity privilegeEntity = ambariGrantedAuthority.getPrivilegeEntity();
+ String requestURI = httpRequest.getRequestURI();
+ Integer permissionId = privilegeEntity.getPermission().getId();
+
+ // admin has full access
+ if (permissionId.equals(PermissionEntity.AMBARI_ADMIN_PERMISSION)) {
+ authorized = true;
+ break;
+ }
+
+ if (requestURI.matches("/api/v[0-9]+/clusters.*")) {
+ // clusters require permission
+ if (permissionId.equals(PermissionEntity.CLUSTER_READ_PERMISSION) ||
+ permissionId.equals(PermissionEntity.CLUSTER_OPERATE_PERMISSION)) {
+ authorized = true;
+ break;
+ }
+ } else if (requestURI.matches("/api/v[0-9]+/views.*")) {
+ // views require permission
+ if (permissionId.equals(PermissionEntity.VIEW_USE_PERMISSION)) {
+ authorized = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!authorized && !httpRequest.getMethod().equals("GET")) {
+
+ httpResponse.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
+ httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "You do not have permissions to access this resource.");
+ httpResponse.flushBuffer();
+ return;
+ }
+ }
+
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+ // do nothing
+ }
+
+
+ // ----- helper methods ----------------------------------------------------
+
+ /**
+ * Get the parameter value from the given servlet filter configuration.
+ *
+ * @param filterConfig the servlet configuration
+ * @param parameterName the parameter name
+ * @param defaultValue the default value
+ *
+ * @return the parameter value or the default value if not set
+ */
+ private static String getParameterValue(
+ FilterConfig filterConfig, String parameterName, String defaultValue) {
+
+ String value = filterConfig.getInitParameter(parameterName);
+ if (value == null || value.length() == 0) {
+ value = filterConfig.getServletContext().getInitParameter(parameterName);
+ }
+ return value == null || value.length() == 0 ? defaultValue : value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariGrantedAuthority.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariGrantedAuthority.java
new file mode 100644
index 0000000..e7bf086
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariGrantedAuthority.java
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.security.authorization;
+
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
+import org.springframework.security.core.GrantedAuthority;
+
+/**
+ * Authority granted for Ambari privileges.
+ */
+public class AmbariGrantedAuthority implements GrantedAuthority {
+ /**
+ * The Ambari privilege.
+ */
+ private final PrivilegeEntity privilegeEntity;
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ public AmbariGrantedAuthority(PrivilegeEntity privilegeEntity) {
+ this.privilegeEntity = privilegeEntity;
+ }
+
+
+ // ----- GrantedAuthority --------------------------------------------------
+
+ @Override
+ public String getAuthority() {
+
+ ResourceEntity resource = privilegeEntity.getResource();
+
+ Long resourceId = resource.getId();
+ String resourceTypeQualifier = resource.getResourceType().getName().toUpperCase() + ".";
+ String privilegeName = privilegeEntity.getPermission().getPermissionName() + "@" + resourceId;
+
+ return privilegeName.startsWith(resourceTypeQualifier) ? privilegeName : resourceTypeQualifier + privilegeName ;
+ }
+
+
+ // ----- AmbariGrantedAuthority --------------------------------------------
+
+ /**
+ * Get the associated privilege.
+ *
+ * @return the privilege
+ */
+ public PrivilegeEntity getPrivilegeEntity() {
+ return privilegeEntity;
+ }
+
+
+ // ----- Object overrides --------------------------------------------------
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AmbariGrantedAuthority that = (AmbariGrantedAuthority) o;
+
+ return !(privilegeEntity != null ? !privilegeEntity.equals(that.privilegeEntity) : that.privilegeEntity != null);
+ }
+
+ @Override
+ public int hashCode() {
+ return privilegeEntity != null ? privilegeEntity.hashCode() : 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java
index c609d04..0b65d05 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthoritiesPopulator.java
@@ -20,12 +20,16 @@ package org.apache.ambari.server.security.authorization;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.dao.MemberDAO;
import org.apache.ambari.server.orm.dao.PrincipalDAO;
import org.apache.ambari.server.orm.dao.PrincipalTypeDAO;
+import org.apache.ambari.server.orm.dao.PrivilegeDAO;
import org.apache.ambari.server.orm.dao.RoleDAO;
import org.apache.ambari.server.orm.dao.UserDAO;
+import org.apache.ambari.server.orm.entities.MemberEntity;
import org.apache.ambari.server.orm.entities.PrincipalEntity;
import org.apache.ambari.server.orm.entities.PrincipalTypeEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
import org.apache.ambari.server.orm.entities.RoleEntity;
import org.apache.ambari.server.orm.entities.UserEntity;
import org.slf4j.Logger;
@@ -35,6 +39,8 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
/**
* Provides authorities population for LDAP user from LDAP catalog
@@ -48,19 +54,24 @@ public class AmbariLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
RoleDAO roleDAO;
PrincipalDAO principalDAO;
PrincipalTypeDAO principalTypeDAO;
+ MemberDAO memberDAO;
+ PrivilegeDAO privilegeDAO;
private static final String AMBARI_ADMIN_LDAP_ATTRIBUTE_KEY = "ambari_admin";
@Inject
public AmbariLdapAuthoritiesPopulator(Configuration configuration, AuthorizationHelper authorizationHelper,
UserDAO userDAO, RoleDAO roleDAO,
- PrincipalDAO principalDAO, PrincipalTypeDAO principalTypeDAO) {
+ PrincipalDAO principalDAO, PrincipalTypeDAO principalTypeDAO,
+ MemberDAO memberDAO, PrivilegeDAO privilegeDAO) {
this.configuration = configuration;
this.authorizationHelper = authorizationHelper;
this.userDAO = userDAO;
this.roleDAO = roleDAO;
this.principalDAO = principalDAO;
this.principalTypeDAO = principalTypeDAO;
+ this.memberDAO = memberDAO;
+ this.privilegeDAO = privilegeDAO;
}
@Override
@@ -94,7 +105,20 @@ public class AmbariLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
}
}
- return authorizationHelper.convertRolesToAuthorities(user.getRoleEntities());
+ // get all of the privileges for the user
+ List<PrincipalEntity> principalEntities = new LinkedList<PrincipalEntity>();
+
+ principalEntities.add(user.getPrincipal());
+
+ List<MemberEntity> memberEntities = memberDAO.findAllMembersByUser(user);
+
+ for (MemberEntity memberEntity : memberEntities) {
+ principalEntities.add(memberEntity.getGroup().getPrincipal());
+ }
+
+ List<PrivilegeEntity> privilegeEntities = privilegeDAO.findAllByPrincipal(principalEntities);
+
+ return authorizationHelper.convertPrivilegesToAuthorities(privilegeEntities);
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserDetailsService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserDetailsService.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserDetailsService.java
index 34ebbd8..af663bf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserDetailsService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserDetailsService.java
@@ -20,8 +20,13 @@ package org.apache.ambari.server.security.authorization;
import com.google.inject.Inject;
import com.google.inject.Injector;
import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.dao.MemberDAO;
+import org.apache.ambari.server.orm.dao.PrivilegeDAO;
import org.apache.ambari.server.orm.dao.RoleDAO;
import org.apache.ambari.server.orm.dao.UserDAO;
+import org.apache.ambari.server.orm.entities.MemberEntity;
+import org.apache.ambari.server.orm.entities.PrincipalEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
import org.apache.ambari.server.orm.entities.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,6 +35,9 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import java.util.LinkedList;
+import java.util.List;
+
public class AmbariLocalUserDetailsService implements UserDetailsService {
private static final Logger log = LoggerFactory.getLogger(AmbariLocalUserDetailsService.class);
@@ -39,15 +47,20 @@ public class AmbariLocalUserDetailsService implements UserDetailsService {
private AuthorizationHelper authorizationHelper;
UserDAO userDAO;
RoleDAO roleDAO;
+ MemberDAO memberDAO;
+ PrivilegeDAO privilegeDAO;
@Inject
public AmbariLocalUserDetailsService(Injector injector, Configuration configuration,
- AuthorizationHelper authorizationHelper, UserDAO userDAO, RoleDAO roleDAO) {
+ AuthorizationHelper authorizationHelper, UserDAO userDAO,
+ RoleDAO roleDAO, MemberDAO memberDAO, PrivilegeDAO privilegeDAO) {
this.injector = injector;
this.configuration = configuration;
this.authorizationHelper = authorizationHelper;
this.userDAO = userDAO;
this.roleDAO = roleDAO;
+ this.memberDAO = memberDAO;
+ this.privilegeDAO = privilegeDAO;
}
/**
@@ -71,8 +84,20 @@ public class AmbariLocalUserDetailsService implements UserDetailsService {
throw new UsernameNotFoundException("Username " + username + " has no roles");
}
+ // get all of the privileges for the user
+ List<PrincipalEntity> principalEntities = new LinkedList<PrincipalEntity>();
+
+ principalEntities.add(user.getPrincipal());
+
+ List<MemberEntity> memberEntities = memberDAO.findAllMembersByUser(user);
+
+ for (MemberEntity memberEntity : memberEntities) {
+ principalEntities.add(memberEntity.getGroup().getPrincipal());
+ }
+
+ List<PrivilegeEntity> privilegeEntities = privilegeDAO.findAllByPrincipal(principalEntities);
+
return new User(user.getUserName(), user.getUserPassword(),
- authorizationHelper.convertRolesToAuthorities(user.getRoleEntities()));
+ authorizationHelper.convertPrivilegesToAuthorities(privilegeEntities));
}
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da2ac577/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AuthorizationHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AuthorizationHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AuthorizationHelper.java
index b67a843..9feaf93 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AuthorizationHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AuthorizationHelper.java
@@ -18,10 +18,9 @@
package org.apache.ambari.server.security.authorization;
import com.google.inject.Singleton;
-import org.apache.ambari.server.orm.entities.RoleEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -36,16 +35,16 @@ public class AuthorizationHelper {
/**
* Converts collection of RoleEntities to collection of GrantedAuthorities
*/
- public Collection<GrantedAuthority> convertRolesToAuthorities(Collection<RoleEntity> roleEntities) {
- Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(roleEntities.size());
+ public Collection<GrantedAuthority> convertPrivilegesToAuthorities(Collection<PrivilegeEntity> privilegeEntities) {
+ Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(privilegeEntities.size());
- for (RoleEntity roleEntity : roleEntities) {
- authorities.add(new SimpleGrantedAuthority(roleEntity.getRoleName().toUpperCase()));
+ for (PrivilegeEntity privilegeEntity : privilegeEntities) {
+ authorities.add(new AmbariGrantedAuthority(privilegeEntity));
}
return authorities;
}
-
+
/**
* Gets the name of the logged in user. Thread-safe due to use of thread-local.
* @return the name of the logged in user, or <code>null</code> if none set.