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


RANGER-913 : Improvements on Reports page in Ranger Admin

Signed-off-by: Gautam Borad <[email protected]>


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 <[email protected]>
Authored: Thu Apr 14 12:55:46 2016 +0530
Committer: Gautam Borad <[email protected]>
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>


Reply via email to