You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ga...@apache.org on 2016/04/15 08:03:07 UTC

incubator-ranger git commit: RANGER-913 : Improvements on Reports page in Ranger Admin

Repository: incubator-ranger
Updated Branches:
  refs/heads/master bc1cf982e -> dbd0bba9e


RANGER-913 : Improvements on Reports page in Ranger Admin

Signed-off-by: Gautam Borad <ga...@apache.org>


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

Branch: refs/heads/master
Commit: dbd0bba9e4450c0e2022826f922879907f8495df
Parents: bc1cf98
Author: Mehul Parikh <me...@freestoneinfotech.com>
Authored: Thu Apr 14 12:55:46 2016 +0530
Committer: Gautam Borad <ga...@apache.org>
Committed: Fri Apr 15 11:31:36 2016 +0530

----------------------------------------------------------------------
 .../apache/ranger/plugin/util/SearchFilter.java |   4 +
 pom.xml                                         |   1 +
 security-admin/pom.xml                          |  10 +
 .../org/apache/ranger/biz/ServiceDBStore.java   | 235 ++++++++++++-
 .../org/apache/ranger/rest/ServiceREST.java     |  38 +++
 .../ranger/service/RangerPolicyServiceBase.java |  41 ++-
 .../src/main/webapp/scripts/utils/XAUtils.js    |   8 +
 .../scripts/views/reports/UserAccessLayout.js   | 327 +++++++++++++++----
 security-admin/src/main/webapp/styles/xa.css    |   4 +
 .../reports/UserAccessLayout_tmpl.html          |  37 ++-
 10 files changed, 624 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
index 61e8b09..cba3275 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
@@ -118,6 +118,10 @@ public class SearchFilter {
 
 		params.put(name, value);
 	}
+	public void removeParam(String name) {
+
+		params.remove(name);
+	}
 
 	public Map<String, String> getParamsWithPrefix(String prefix, boolean stripPrefix) {
 		Map<String, String> ret = null;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index c6f8ed7..ff16abd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -213,6 +213,7 @@
         <jackson.version>1.9.13</jackson.version>
         <sun-jersey-bundle.version>1.19</sun-jersey-bundle.version>
         <atlas.version>0.6-incubating-SNAPSHOT</atlas.version>
+        <poi.version>3.12</poi.version>
         <distMgmtStagingId>apache.staging.https</distMgmtStagingId>
         <distMgmtStagingName>Apache Release Distribution Repository</distMgmtStagingName>
         <distMgmtStagingUrl>https://repository.apache.org/service/local/staging/deploy/maven2</distMgmtStagingUrl>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/pom.xml
----------------------------------------------------------------------
diff --git a/security-admin/pom.xml b/security-admin/pom.xml
index 5e03564..2af0cf4 100644
--- a/security-admin/pom.xml
+++ b/security-admin/pom.xml
@@ -68,6 +68,16 @@
             <version>${commons.cli.version}</version>
         </dependency>
         <dependency>
+         <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
             <version>${commons.codec.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 9d2e4c6..21ed686 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -21,9 +21,13 @@ package org.apache.ranger.biz;
 
 import java.util.*;
 import java.util.Map.Entry;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
 
 import javax.annotation.PostConstruct;
-
+import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -80,7 +84,13 @@ import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.support.TransactionCallback;
 import org.springframework.transaction.support.TransactionTemplate;
-
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
 
 @Component
 public class ServiceDBStore extends AbstractServiceStore {
@@ -1792,20 +1802,80 @@ public class ServiceDBStore extends AbstractServiceStore {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceDBStore.getPolicies()");
 		}
-
 		RangerPolicyList policyList = policyService.searchRangerPolicies(filter);
-
-		predicateUtil.applyFilter(policyList.getPolicies(), filter);
-
 		List<RangerPolicy> ret = policyList.getPolicies();
-
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("<== ServiceDBStore.getPolicies()");
 		}
+		return ret;
+	}
+
+	public List<RangerPolicy> getPoliciesForReports(SearchFilter filter) throws Exception {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceDBStore.getPoliciesForReports()");
+		}
+		List<RangerPolicy> ret = new ArrayList<RangerPolicy>();
+		List<RangerPolicy> retTemp = new ArrayList<RangerPolicy>();
+		Map<Long, RangerPolicy> orderedPolicies = new TreeMap<Long, RangerPolicy>();
+		String serviceTypeNames = filter.getParam("serviceType");
+		if (serviceTypeNames != null) {
+			List<String> serviceTypeList = new ArrayList<String>(Arrays.asList(serviceTypeNames.split("_")));
+			if (!CollectionUtils.isEmpty(serviceTypeList)) {
+				for (String serviceType : serviceTypeList) {
+					filter.setParam("serviceType", serviceType);
+					RangerPolicyList policyList = policyService.searchRangerPolicies(filter);
+					if (policyList!=null){
+						retTemp = policyList.getPolicies();
+						if(!CollectionUtils.isEmpty(retTemp)) {
+							ret.addAll(retTemp);
+						}
+					}
+				}
+				if (!CollectionUtils.isEmpty(ret)){
+					for (RangerPolicy policy : ret) {
+						if(policy!=null){
+							orderedPolicies.put(policy.getId(), policy);
+						}
+					}
+					if (orderedPolicies.size()>0) {
+						ret.clear();
+						ret.addAll(orderedPolicies.values());
+					}
+				}
+			}
+		} else {
+			RangerPolicyList policyList = policyService.searchRangerPolicies(filter);
+			ret = policyList.getPolicies();
+			if (!CollectionUtils.isEmpty(ret)) {
+				for (RangerPolicy policy : ret) {
+					if (policy != null) {
+						orderedPolicies.put(policy.getId(), policy);
+					}
+				}
+				if (orderedPolicies.size() > 0) {
+					ret.clear();
+					ret.addAll(orderedPolicies.values());
+				}
+			}
+			if (policyList != null) {
+				ret = policyList.getPolicies();
+			}
+		}
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceDBStore.getPoliciesForReports()");
+		}
 
 		return ret;
 	}
 
+	public void getPoliciesInExcel(List<RangerPolicy> policies, HttpServletResponse response) throws Exception {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceDBStore.getPoliciesInExcel()");
+		}
+		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+		String excelFileName = "Ranger_Policies_"+timeStamp+".xls";
+		writeExcel(policies, excelFileName, response);
+	}
 
 	public PList<RangerPolicy> getPaginatedPolicies(SearchFilter filter) throws Exception {
 		if (LOG.isDebugEnabled()) {
@@ -2707,4 +2777,155 @@ public class ServiceDBStore extends AbstractServiceStore {
 
 		return false;
 	}
+	private void writeExcel(List<RangerPolicy> policies, String excelFileName, HttpServletResponse response)
+			throws IOException {
+		Workbook workbook=null;
+		OutputStream outStream =null;
+		try{
+			workbook = new HSSFWorkbook();
+			Sheet sheet = workbook.createSheet();
+			createHeaderRow(sheet);
+			int rowCount = 0;
+			if (!CollectionUtils.isEmpty(policies)){
+				for (RangerPolicy policy : policies) {
+					Row row = sheet.createRow(++rowCount);
+					writeBook(policy, row);
+				}
+			}
+			ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
+			workbook.write(outByteStream);
+			byte[] outArray = outByteStream.toByteArray();
+			response.setContentType("application/ms-excel");
+			response.setContentLength(outArray.length);
+			response.setHeader("Expires:", "0");
+			response.setHeader("Content-Disposition", "attachment; filename=" + excelFileName);
+			outStream=response.getOutputStream();
+			outStream.write(outArray);
+			outStream.flush();
+		}catch(IOException ex){
+			LOG.error("Failed to create report file " + excelFileName, ex);
+		}catch(Exception ex){
+			LOG.error("Error while generating report file " + excelFileName, ex);
+		}finally{
+			if(outStream!=null){
+				outStream.close();
+			}
+			if(workbook!=null){
+				workbook.close();
+			}
+		}
+	}
+
+	private void writeBook(RangerPolicy policy, Row row) {
+		String policyStatus = "";
+		Cell cell = row.createCell(0);
+		cell.setCellValue(policy.getId());
+		cell = row.createCell(1);
+		cell.setCellValue(policy.getName());
+		cell = row.createCell(2);
+		if (policy.getIsEnabled()) {
+			policyStatus = "Enabled";
+		} else {
+			policyStatus = "Disabled";
+		}
+		cell.setCellValue(policyStatus);
+		cell = row.createCell(3);
+		List<RangerPolicyItem> policyItems = policy.getPolicyItems();
+		List<String> groups = new ArrayList<String>();
+		List<String> users = new ArrayList<String>();
+		String groupNames = "";
+		String userNames = "";
+		String accessType = "";
+		if (!CollectionUtils.isEmpty(policyItems)) {
+			for (RangerPolicyItem policyItem : policyItems) {
+				groups = policyItem.getGroups();
+				List<RangerPolicyItemAccess> accesses = policyItem.getAccesses();
+				accessType = accessType + "[";
+				for (RangerPolicyItemAccess access : accesses) {
+					accessType = accessType + access.getType() + " ";
+				}
+				accessType = accessType + "] ";
+				if (!groups.isEmpty()) {
+					groupNames = groupNames + groups.toString();
+				}
+				users = policyItem.getUsers();
+				if (!users.isEmpty()) {
+					userNames = userNames + users.toString();
+				}
+			}
+		}
+		cell.setCellValue(groupNames);
+		cell = row.createCell(4);
+		cell.setCellValue(userNames);
+		cell = row.createCell(5);
+		XXService xxservice = daoMgr.getXXService().findByName(policy.getService());
+		String ServiceType = "";
+		if (xxservice != null) {
+			Long ServiceId = xxservice.getType();
+			XXServiceDef xxservDef = daoMgr.getXXServiceDef().getById(ServiceId);
+			if (xxservDef != null) {
+				ServiceType = xxservDef.getName();
+			}
+		}
+		cell.setCellValue(ServiceType);
+		cell = row.createCell(6);
+		cell.setCellValue(accessType.trim());
+		cell = row.createCell(7);
+		String resValue = "";
+		String resourceKeyVal = "";
+		String resKey = "";
+		Map<String, RangerPolicyResource> resources = policy.getResources();
+		if (resources!=null) {
+			for (Entry<String, RangerPolicyResource> resource : resources.entrySet()) {
+				resKey = resource.getKey();
+				RangerPolicyResource policyResource = resource.getValue();
+				List<String> resvalueList = policyResource.getValues();
+				resValue = resvalueList.toString();
+				resourceKeyVal = resourceKeyVal + " " + resKey + "=" + resValue;
+			}
+		}
+		cell.setCellValue(resourceKeyVal);
+	}
+
+	private void createHeaderRow(Sheet sheet) {
+		CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
+		Font font = sheet.getWorkbook().createFont();
+		font.setBold(true);
+		font.setFontHeightInPoints((short) 12);
+		cellStyle.setFont(font);
+
+		Row row = sheet.createRow(0);
+
+		Cell cellID = row.createCell(0);
+		cellID.setCellStyle(cellStyle);
+		cellID.setCellValue("ID");
+
+		Cell cellNAME = row.createCell(1);
+		cellNAME.setCellStyle(cellStyle);
+		cellNAME.setCellValue("Name");
+
+		Cell cellStatus = row.createCell(2);
+		cellStatus.setCellStyle(cellStyle);
+		cellStatus.setCellValue("Status");
+
+		Cell cellGroups = row.createCell(3);
+		cellGroups.setCellStyle(cellStyle);
+		cellGroups.setCellValue("Groups");
+
+		Cell cellUsers = row.createCell(4);
+		cellUsers.setCellStyle(cellStyle);
+		cellUsers.setCellValue("Users");
+
+		Cell cellServiceType = row.createCell(5);
+		cellServiceType.setCellStyle(cellStyle);
+		cellServiceType.setCellValue("Service Type");
+
+		Cell cellAccesses = row.createCell(6);
+		cellAccesses.setCellStyle(cellStyle);
+		cellAccesses.setCellValue("Accesses");
+
+		Cell cellResources = row.createCell(7);
+		cellResources.setCellStyle(cellStyle);
+		cellResources.setCellValue("Resources");
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 8f01bfc..ad25817 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -1290,6 +1290,44 @@ public class ServiceREST {
 		return ret;
 	}
 
+	@GET
+	@Path("/policies/downloadExcel")
+	@Produces("application/ms-excel")
+	public void getPoliciesInExcel(@Context HttpServletRequest request,
+			@Context HttpServletResponse response) {
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceREST.getPoliciesInExcel()");
+		}
+		RangerPerfTracer perf = null;
+
+		SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);
+
+		try {
+			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPoliciesInExcel()");
+			}
+			List<RangerPolicy> policies=new ArrayList<RangerPolicy>();
+			if (filter != null) {
+				filter.setStartIndex(0);
+				filter.setMaxRows(Integer.MAX_VALUE);
+				policies = svcStore.getPoliciesForReports(filter);
+			}
+			svcStore.getPoliciesInExcel(policies, response);
+
+		} catch (WebApplicationException excp) {
+			throw excp;
+		} catch (Throwable excp) {
+			LOG.error("Error while downloading policy report", excp);
+
+			throw restErrorUtil.createRESTException(excp.getMessage());
+		} finally {
+			RangerPerfTracer.log(perf);
+		}
+
+	}
+
+
 	public List<RangerPolicy> getPolicies(SearchFilter filter) {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceREST.getPolicies(filter)");

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyServiceBase.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyServiceBase.java
index 4929cf6..87f3463 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyServiceBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyServiceBase.java
@@ -18,9 +18,13 @@
 package org.apache.ranger.service;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.authorization.utils.StringUtil;
 import org.apache.ranger.common.GUIDUtil;
 import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.SearchField;
@@ -28,13 +32,16 @@ import org.apache.ranger.common.SortField;
 import org.apache.ranger.common.SearchField.DATA_TYPE;
 import org.apache.ranger.common.SearchField.SEARCH_TYPE;
 import org.apache.ranger.common.SortField.SORT_ORDER;
+import org.apache.ranger.entity.XXGroup;
 import org.apache.ranger.entity.XXPolicy;
 import org.apache.ranger.entity.XXPolicyBase;
 import org.apache.ranger.entity.XXService;
+import org.apache.ranger.entity.XXUser;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.view.RangerPolicyList;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
 
 public abstract class RangerPolicyServiceBase<T extends XXPolicyBase, V extends RangerPolicy> extends
 		RangerBaseModelService<T, V> {
@@ -121,12 +128,40 @@ public abstract class RangerPolicyServiceBase<T extends XXPolicyBase, V extends
 		List<RangerPolicy> policyList = new ArrayList<RangerPolicy>();
 		RangerPolicyList retList = new RangerPolicyList();
 
+		Comparator<RangerPolicy> comparator = new Comparator<RangerPolicy>() {
+			public int compare(RangerPolicy c1, RangerPolicy c2) {
+				return (int) ((c1.getId()).compareTo(c2.getId()));
+			}
+		};
+
 		List<XXPolicy> xPolList = (List<XXPolicy>) searchResources(searchFilter, searchFields, sortFields, retList);
-		for (XXPolicy xPol : xPolList) {
-			policyList.add(populateViewBean((T) xPol));
+		String userName = searchFilter.getParam("user");
+		if (!StringUtil.isEmpty(userName)) {
+			searchFilter.removeParam("user");
+			Set<String> groupNames = daoMgr.getXXGroupUser().findGroupNamesByUserName(userName);
+			if (!CollectionUtils.isEmpty(groupNames)) {
+				List<XXPolicy> xPolList2 = null;
+				for (String groupName : groupNames) {
+					xPolList2 = new ArrayList<XXPolicy>();
+					searchFilter.setParam("group", groupName);
+					xPolList2 = (List<XXPolicy>) searchResources(searchFilter, searchFields, sortFields, retList);
+					if (!CollectionUtils.isEmpty(xPolList2)) {
+						for (XXPolicy xPol2 : xPolList2) {
+							if(xPol2!=null){
+								policyList.add(populateViewBean((T) xPol2));
+							}
+						}
+					}
+				}
+			}
+		}
+		if (!CollectionUtils.isEmpty(xPolList)) {
+			for (XXPolicy xPol : xPolList) {
+				policyList.add(populateViewBean((T) xPol));
+			}
+			Collections.sort(policyList, comparator);
 		}
 		retList.setPolicies(policyList);
-
 		return retList;
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/webapp/scripts/utils/XAUtils.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/utils/XAUtils.js b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
index 6611fa6..f258a95 100644
--- a/security-admin/src/main/webapp/scripts/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/scripts/utils/XAUtils.js
@@ -1177,6 +1177,14 @@ define(function(require) {
 		}
 		return singleValue;
 	};
+	XAUtils.getBaseUrl = function (){
+		if(!window.location.origin){
+			window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
+		}
+		return window.location.origin
+		+ window.location.pathname.substring(window.location.pathname
+				.indexOf('/', 2) + 1, 0);
+	};
 	
 	XAUtils.isMaskingPolicy = function(type){
 		return type == XAEnums.RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value ? true : false;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js b/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js
index 47177f4..ff835fd 100644
--- a/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js
@@ -27,6 +27,7 @@ define(function(require) {'use strict';
 	var XABackgrid			= require('views/common/XABackgrid');
 	var XATableLayout		= require('views/common/XATableLayout');
 	var localization		= require('utils/XALangSupport');
+	var XAGlobals			= require('utils/XAGlobals');
 	
 	var RangerService		= require('models/RangerService');
 	var RangerServiceDefList= require('collections/RangerServiceDefList');
@@ -72,7 +73,9 @@ define(function(require) {'use strict';
 			btnShowMore 		: '[data-id="showMore"]',
 			btnShowLess 		: '[data-id="showLess"]',
 			btnShowMoreUsers 	: '[data-id="showMoreUsers"]',
-			btnShowLessUsers 	: '[data-id="showLessUsers"]'
+			btnShowLessUsers 	: '[data-id="showLessUsers"]',
+			componentType       : '[data-id="component"]',
+			downloadReport      : '[data-id="downloadReport"]'
 		},
 
 		/** ui events hash */
@@ -85,6 +88,7 @@ define(function(require) {'use strict';
 			events['click ' + this.ui.btnShowLess]  = 'onShowLess';
 			events['click ' + this.ui.btnShowMoreUsers]  = 'onShowMoreUsers';
 			events['click ' + this.ui.btnShowLessUsers]  = 'onShowLessUsers';
+			events['click ' + this.ui.downloadReport] = 'onDownload';
 			return events;
 		},
 
@@ -96,6 +100,9 @@ define(function(require) {'use strict';
 			console.log("initialized a UserAccessLayout Layout");
 			_.extend(this, _.pick(options, 'groupList','userList'));
 			this.bindEvents();
+			this.previousSearchUrl = '';
+			this.searchedFlag = true;
+			this.allowDownload = false;
 		},
 		initializeRequiredData : function() {
 			this.policyCollList = [];
@@ -126,16 +133,25 @@ define(function(require) {'use strict';
 		onRender : function() {
 			this.initializePlugins();
 			this.setupGroupAutoComplete();
+			this.onComponentSelect();
 			//Show policies listing for each service and GET policies for each service
 			_.each(this.policyCollList, function(obj,i){
 				this.renderTable(obj.collName, obj.serviceDefName);
 				this.getResourceLists(obj.collName,obj.serviceDefName);
 			},this);
+			this.modifyTableForSubcolumns();
 			this.$el.find('[data-js="policyName"]').focus()
+			var url_string = XAUtil.getBaseUrl();
+			if(url_string.slice(-1) == "/") {
+				url_string = url_string.slice(0,-1);
+			}
+			this.previousSearchUrl = url_string+"/service/plugins/policies/downloadExcel?";
 		},
 		
 		getResourceLists: function(collName, serviceDefName){
+
 			var that = this, coll = this[collName];
+			that.allowDownload = false;
 			coll.queryParams.serviceType = serviceDefName;
 			coll.fetch({
 				cache : false,
@@ -144,13 +160,15 @@ define(function(require) {'use strict';
 			}).done(function(){
 				coll.trigger('sync')
 				XAUtil.blockUI('unblock');
+				if(coll.length >= 1 && !that.allowDownload)
+					that.allowDownload = true;
 				
 			});
 		},
-		renderTable : function(collName){
+		renderTable : function(collName,serviceDefName){
 			var that = this, tableRegion  = this[collName+'Table'];
 			tableRegion.show(new XATableLayout({
-				columns: this.getColumns(this[collName]),
+				columns: this.getColumns(this[collName],collName,serviceDefName),
 				collection: this[collName],
 				includeFilter : false,
 				scrollToTop : false,
@@ -162,7 +180,7 @@ define(function(require) {'use strict';
 			}));
 		
 		},
-		getColumns : function(coll){
+		getColumns : function(coll,collName,serviceDefName){
 			var that = this;
 			var cols = {
 				id : {
@@ -199,53 +217,186 @@ define(function(require) {'use strict';
 					drag : false,
 					sortable : false
 				},
-				isAuditEnabled:{
-					label:localization.tt('lbl.auditLogging'),
-					cell :"html",
-					editable:false,
-					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-						fromRaw: function (rawValue) {
-							return rawValue ? '<label class="label label-success">Enabled</label>' : '<label class="label label-important">Disabled</label>';
+			permissions: {
+				label: 'Permissions',
+				cell : Backgrid.HtmlCell.extend({className: 'cellWidth-1', className: 'html-cell' }),
+					formatter: _.extend({}, Backgrid.CellFormatter.prototype,{
+						fromRaw: function(rawValue,model){
+							if(model.get("policyItems").length != 0) {
+							    var htmlStr = '';
+								var accessStr = '';
+								var grpStr = '';
+								var userStr = '';
+								_.each(model.get("policyItems"),function(policyItem){
+									if(_.isEmpty(policyItem.groups)){
+										grpStr = '--';
+										_.map(policyItem.users,function(el){
+											userStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+el+'</span>';
+											});
+										accessStr = '';
+										_.each(policyItem.accesses,function(obj2){
+											accessStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+obj2.type+'</span>';
+									});
+									}
+									else if(_.isEmpty(policyItem.users)) {
+										userStr = '--';
+										_.map(policyItem.groups,function(el){
+											grpStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+el+'</span>';
+											});
+										accessStr = '';
+										_.each(policyItem.accesses,function(obj2){
+											accessStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+obj2.type+'</span>';
+											});
+									}
+									else{
+										_.map(policyItem.users,function(el){
+											userStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+el+'</span>';
+										});
+										_.map(policyItem.groups,function(el){
+											grpStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+el+'</span>';
+										});
+										accessStr = '';
+										_.each(policyItem.accesses,function(obj2){
+											accessStr+='<span class="label label-info cellWidth-1 float-left-margin-2" style="">'+obj2.type+'</span>';
+										});
+									}
+									htmlStr+='<tr style="height:60px"><td style ="width:80px">'+grpStr+'</td>\
+									<td style="width:80px">'+(userStr)+'</td>\
+									<td style="width:150px">'+accessStr+'</td></tr>';
+									accessStr = '';
+									grpStr = '';
+									userStr = '';
+									});
+								return htmlStr;
+								}
+							else {
+								return '---';
+							}
 						}
 					}),
-					click : false,
-					drag : false,
-					sortable : false
+				editable: false,
+				sortable: false,
+				click: false
 				},
-				policyItems : {
-					reName : 'groupName',
-					cell	: Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
-					label : localization.tt("lbl.group"),
+				resources:
+				{
+					label: 'Resources',
+					cell: 'Html',
 					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-						fromRaw: function (rawValue, model) {
-							if(!_.isUndefined(rawValue))
-								return XAUtil.showGroupsOrUsersForPolicy(rawValue, model);
-							else 
-								return '--';
-						}
+						fromRaw: function (rawValue,model) {
+							var strVal = '';
+							var res = model.get('resources');
+							_.each(res,function(res_obj,key){
+								strVal += "<b>"+key+":</b>";
+								_.map(res_obj.values,function(ob){
+									strVal +="<span title='"+ob+"'>"+ ob+"</span>" + ",";
+								});
+								strVal = strVal.slice(0,-1);
+								strVal = strVal+ "<br />";
+							});
+							return strVal;
+							}
 					}),
-					editable : false,
-					sortable : false
-				},
-				//Hack for backgrid plugin doesn't allow to have same column name 
-				guid : {
-					reName : 'userName',
-					cell	: Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
-					label : localization.tt("lbl.users"),
-					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-						fromRaw: function (rawValue, model) {
-							if(!_.isUndefined(rawValue))
-								return XAUtil.showGroupsOrUsersForPolicy(model.get('policyItems'), model, false);
-							else 
-								return '--';
-						}
-					}),
-					editable : false,
-					sortable : false
-				},
+			editable: false,
+			sortable: false,
+			click: false
+					}
 			};
+
 			return coll.constructor.getTableCols(cols, coll);
 		},
+		/* components */
+	onComponentSelect: function(){
+		var that = this;
+		var options = this.serviceDefList.map(function(m){ return { 'id' : m.get('name'), 'text' : m.get('name')}; });
+		this.ui.componentType.select2({
+			multiple: true,
+			closeOnSelect: true,
+			placeholder: 'Select Component',
+		    //maximumSelectionSize : 1,
+		    width: '220px',
+		    allowClear: true,
+		    data: options
+		});
+	},
+	modifyTableForSubcolumns : function(){
+		this.$el.find(".permissions").html('<tr><th colspan="3">Permissions</th></tr>\
+							<tr><th style="width:80px">Groups</th><th style="width:80px">Users</th>\
+							<th style="width:150px">Accesses</th></tr>');
+	},
+	onDownload: function(e){
+		if(!this.allowDownload){
+			XAUtil.alertPopup({
+				msg :"No policies found to download!",
+			});
+			return;
+		}
+		var rangerPolicyList = new RangerPolicyList();
+		var that = this;
+		var url = '';
+		var groups = (this.ui.userGroup.is(':visible')) ? this.ui.userGroup.select2('val'):undefined;
+		if(groups == "") {
+			groups = undefined;
+		}
+		var users = (this.ui.userName.is(':visible')) ? this.ui.userName.select2('val'):undefined;
+		var rxName = this.ui.resourceName.val() || undefined;
+		var policyName = this.ui.policyName.val() || undefined;
+		var params = {group : groups, user : users, polResource : rxName, policyNamePartial : policyName};
+		var component = (this.ui.componentType.val() != "") ? this.ui.componentType.select2('val'):undefined;
+		_.each(that.policyCollList, function(obj,i){
+			var coll = that[obj.collName];
+		},this);
+		var btn = $(e.currentTarget);
+		if(!this.searchedFlag) {
+			var url_string = XAUtil.getBaseUrl();
+			if(url_string.slice(-1) == "/") {
+				url_string = url_string.slice(0,-1);
+			}
+			url = url_string + that.getDownloadExcelUrl(this,component,params);
+			this.previousSearchUrl = url;
+		 }
+		else {
+			url =  this.previousSearchUrl;
+		}
+		$('<a href="'+url+'" download hidden>').appendTo('body').get(0).click();
+
+	},
+	getDownloadExcelUrl: function(that,component,params){
+		var queryParams = {};
+		var data = {};
+		var comp_str = '';
+		if(!_.isUndefined(component)) {
+			_.each(component,function(comp){
+				comp_str = comp_str + comp + '_';
+				});
+		}
+		if (comp_str != '') {
+			comp_str = comp_str.slice(0,-1);
+		}
+		queryParams = that['hdfsPolicyList'].queryParams;
+		_.map(params, function(value, key) {
+			if (!_.isUndefined(value)) {
+				data[key] = value;
+			}
+		});
+		if(!_.isUndefined(queryParams.group)) {
+			data.group = queryParams.group;
+		}
+		if(!_.isUndefined(queryParams.user)) {
+			data.user = queryParams.user;
+		}
+		if(!_.isUndefined(queryParams.polResource)) {
+			data.polResource = queryParams.polResource;
+		}
+		if(!_.isUndefined(queryParams.policyNamePartial)) {
+			data.policyNamePartial = queryParams.policyNamePartial;
+		}
+		var policyList;
+		var url = '/service/plugins/policies/downloadExcel?';
+		var str = jQuery.param( data );
+		url = url + str + "&serviceType="+comp_str;
+		return url;
+	},
 		/** on render callback */
 		setupGroupAutoComplete : function(){
 			this.groupArr = this.groupList.map(function(m){
@@ -360,7 +511,7 @@ define(function(require) {'use strict';
 				var wrap = $(this).next();
 				// If next element is a wrap and hasn't .non-collapsible class
 				if (wrap.hasClass('wrap') && ! wrap.hasClass('non-collapsible'))
-					$(this).append('<a href="#" class="wrap-collapse pull-right">hide&nbsp;&nbsp;<i class="icon-caret-up"></i></a>').append('<a href="#" class="wrap-expand pull-right" style="display: none">show&nbsp;&nbsp;<i class="icon-caret-down"></i></a>');
+					$(this).prepend('<a href="#" class="wrap-collapse btn-right">hide&nbsp;&nbsp;<i class="icon-caret-up"></i></a>').prepend('<a href="#" class="wrap-expand btn-right" style="display: none">show&nbsp;&nbsp;<i class="icon-caret-down"></i></a>');
 			});
 			
 			// Collapse wrap
@@ -395,20 +546,80 @@ define(function(require) {'use strict';
 			var rxName = this.ui.resourceName.val() || undefined;
 			var policyName = this.ui.policyName.val() || undefined;
 			var params = {group : groups, user : users, polResource : rxName, policyNamePartial : policyName};
-			
-			_.each(this.policyCollList, function(obj,i){
-				var coll = this[obj.collName];
-				//clear previous query params
-				_.each(params, function(val, attr){
-					delete coll.queryParams[attr];
-				});
-				//Set default page state
-				coll.state = this.defaultPageState;
-				coll.queryParams = $.extend(coll.queryParams, params)
-            	this.getResourceLists(obj.collName, obj.serviceDefName);
-            },this);
-			
-		},
+			var component = (this.ui.componentType.val() != "") ? this.ui.componentType.select2('val'):undefined;
+			var compFlag = false;
+			var showTabs = false;
+			if(_.isUndefined(users) && _.isUndefined(rxName) && _.isUndefined(policyName) && (groups==""))	{
+				showTabs = false;
+			}
+			else {
+				showTabs = true;
+			}
+			if(!_.isUndefined(component)) {
+				compFlag = true;
+			}
+			else {
+				compFlag = false;
+			}
+			that.$el.find('[data-compHeader]').show();
+			that.$el.find('[data-comp]').show();
+			if(compFlag) { //if components selected
+				that.$el.find('[data-compHeader]').hide();
+				that.$el.find('[data-comp]').hide();
+				_.each(that.policyCollList, function(obj,i){
+					_.each(component,function(comp){
+						if(comp === obj.serviceDefName) {
+							var coll = that[obj.collName];
+							//clear previous query params
+							_.each(params, function(val, attr){
+								delete coll.queryParams[attr];
+							});
+							//Set default page state
+							coll.state = that.defaultPageState;
+							coll.queryParams = $.extend(coll.queryParams, params);
+							that.getResourceLists(obj.collName, obj.serviceDefName);
+							that.$el.find('[data-compHeader="'+comp+'"]').show();
+							that.$el.find('[data-comp="'+comp+'"]').show();
+							}
+						});
+					},this);
+				}
+			else { // show all tables if no search component values selected
+				that.$el.find('[data-compHeader]').show();
+				that.$el.find('[data-comp]').show();
+				_.each(this.policyCollList, function(obj,i){
+					var coll = this[obj.collName];
+					//clear previous query params
+					_.each(params, function(val, attr){
+						delete coll.queryParams[attr];
+					});
+					//Set default page state
+					coll.state = this.defaultPageState;
+					coll.queryParams = $.extend(coll.queryParams, params);
+					this.getResourceLists(obj.collName, obj.serviceDefName);
+					},this);
+				}
+					var rangerPolicyList = new RangerPolicyList();
+					var url = '';
+					if (groups == "") {
+						groups = undefined;
+					}
+					params = {
+						group : groups,
+						user : users,
+						polResource : rxName,
+						policyNamePartial : policyName
+					};
+					var url_string = XAUtil.getBaseUrl();
+					if(url_string.slice(-1) == "/") {
+						url_string = url_string.slice(0,-1);
+					}
+					url = url_string
+							+ this.getDownloadExcelUrl(this, component,
+									params);
+					this.previousSearchUrl = url;
+					this.searchedFlag = true;
+        },
 		autocompleteFilter	: function(e){
 			var $el = $(e.currentTarget);
 			var $button = $(e.currentTarget).parents('.btn-group').find('button').find('span').first();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/webapp/styles/xa.css
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/styles/xa.css b/security-admin/src/main/webapp/styles/xa.css
index 331cda1..df683b9 100644
--- a/security-admin/src/main/webapp/styles/xa.css
+++ b/security-admin/src/main/webapp/styles/xa.css
@@ -1908,3 +1908,7 @@ input[type="radio"], input[type="checkbox"] {margin-top: 0;}
     margin-top: -2px;
     font-size: 11px;
 }
+.backgrid > tbody > tr > td:nth-child(5) {
+  text-align: left !important;
+  width: 200px
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dbd0bba9/security-admin/src/main/webapp/templates/reports/UserAccessLayout_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/reports/UserAccessLayout_tmpl.html b/security-admin/src/main/webapp/templates/reports/UserAccessLayout_tmpl.html
index 1352882..8f201dd 100644
--- a/security-admin/src/main/webapp/templates/reports/UserAccessLayout_tmpl.html
+++ b/security-admin/src/main/webapp/templates/reports/UserAccessLayout_tmpl.html
@@ -32,12 +32,19 @@
 							</div>
 						</div>
 						<div class="control-group">
-							<label class="control-label">Resource</label>
-							<div class="controls">
-								<input type="text" name="resourceName" data-js="resourceName" class="input-xxlarge">
+							<div class="span4">
+								<label class="control-label" for="component">Component</label>
+								<div class="controls">
+									<input type=text data-id="component" name="componentType">
+								</div>
+						</div>
+						<div class="span4">
+								<label class="control-label" style="width:80px;">Resource</label>
+							 <div class="controls" style="margin-left:90px;">
+								<input type="text" name="resourceName" data-js="resourceName">
 							</div>
 						</div>
-
+					   </div>
 						<div class="control-group search-by">
 							<label class="control-label">Search By</label>
 							<div class="controls" data-js="searchBy">
@@ -73,25 +80,29 @@
 								</button>
 							</div>
 						</div>
-
 					</div>
-
 				</div>
 			</div>
 
 		</div>
 	</div>
-
+	<div class="row-fluid">
+	<a href="javascript:void(0)" data-id="downloadReport">
+	<span>
+		<button type="button" class="btn btn-primary btn-small btn-right" data-js="downloadBtn" title="Download all below policies" name="downloadPolicy">
+								<i class="icon-download-alt"></i>
+										Download
+			</button>
+	</span></a>
+	 </div>
 	<div class="row-fluid">
 		{{#each policyHeaderList}}
-			<h3 class="wrap-header bold reportSearchHeader" data-js="hdfsHeader"> {{capitaliseLetter this.serviceDefName}}
-				<span class="label label-yellow pull-right" data-js="hdfsSearchResult" ></span>
+			<h3 class="wrap-header bold reportSearchHeader" data-js="hdfsHeader" data-compHeader="{{this.serviceDefName}}"> {{capitaliseLetter this.serviceDefName}}
+				<span class="label label-yellow btn-right" data-js="hdfsSearchResult" ></span>
 			</h3>
-			<div class="wrap well position-relative">
+			<div class="wrap well position-relative" data-comp="{{this.serviceDefName}}">
 				<div  data-id="{{this.collName}}" class="hdfs-table showMoreLess"></div>
 			</div>
-		{{/each}}	
-
+		{{/each}}
 	</div>
-
 </div>