Skip to content

Commit 9887eb7

Browse files
anandN872mneethiraj
authored andcommitted
RANGER-4749: added TagREST APIs to retrieve by resource and get paginated resources along with associated tags
Signed-off-by: Madhan Neethiraj <[email protected]>
1 parent 3fab587 commit 9887eb7

File tree

11 files changed

+609
-26
lines changed

11 files changed

+609
-26
lines changed

agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java

100644100755
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.ranger.plugin.model.AuditFilter;
2727
import org.apache.ranger.plugin.model.RangerGds.RangerTagDataMaskInfo;
2828
import org.apache.ranger.plugin.model.RangerPrincipal;
29+
import org.apache.ranger.plugin.model.RangerTag;
2930
import org.apache.ranger.plugin.model.RangerValidityRecurrence;
3031
import org.apache.ranger.plugin.model.RangerValiditySchedule;
3132
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
@@ -51,6 +52,7 @@ public class JsonUtils {
5152
private static final Type TYPE_LIST_RANGER_TAG_MASK_INFO = new TypeToken<List<RangerTagDataMaskInfo>>() {}.getType();
5253
private static final Type TYPE_MAP_RANGER_MASK_INFO = new TypeToken<Map<String, RangerPolicyItemDataMaskInfo>>() {}.getType();
5354
private static final Type TYPE_MAP_RANGER_POLICY_RESOURCE = new TypeToken<Map<String, RangerPolicyResource>>() {}.getType();
55+
private static final Type TYPE_LIST_RANGER_TAG = new TypeToken<List<RangerTag>>() {}.getType();
5456

5557
private static final ThreadLocal<Gson> gson = new ThreadLocal<Gson>() {
5658
@Override
@@ -189,6 +191,15 @@ public static List<RangerPrincipal> jsonToRangerPrincipalList(String jsonStr) {
189191
}
190192
}
191193

194+
public static List<RangerTag> jsonToRangerTagList(String jsonStr) {
195+
try {
196+
return gson.get().fromJson(jsonStr, TYPE_LIST_RANGER_TAG);
197+
} catch (Exception e) {
198+
LOG.error("Cannot get List<RangerTag> from " + jsonStr, e);
199+
return null;
200+
}
201+
}
202+
192203
public static Map<String, RangerPolicyItemDataMaskInfo> jsonToMapMaskInfo(String jsonStr) {
193204
try {
194205
return gson.get().fromJson(jsonStr, TYPE_MAP_RANGER_MASK_INFO);
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.ranger.plugin.model;
21+
22+
import java.util.List;
23+
24+
import org.codehaus.jackson.annotate.JsonAutoDetect;
25+
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
26+
import org.codehaus.jackson.map.annotate.JsonSerialize;
27+
28+
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
29+
@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
30+
@JsonIgnoreProperties(ignoreUnknown=true)
31+
public class RangerServiceResourceWithTags extends RangerServiceResource implements java.io.Serializable {
32+
private static final long serialVersionUID = 1L;
33+
34+
private List<RangerTag> associatedTags;
35+
36+
public List<RangerTag> getAssociatedTags() {
37+
return associatedTags;
38+
}
39+
40+
public void setAssociatedTags(List<RangerTag> associatedTags) {
41+
this.associatedTags = associatedTags;
42+
}
43+
44+
@Override
45+
public StringBuilder toString(StringBuilder sb) {
46+
sb.append("RangerServiceResourceWithTags={ ");
47+
48+
super.toString(sb);
49+
50+
sb.append("associatedTags=[");
51+
if (associatedTags != null) {
52+
String prefix = "";
53+
54+
for (RangerTag associatedTag : associatedTags) {
55+
sb.append(prefix);
56+
57+
associatedTag.toString(sb);
58+
59+
prefix = ", ";
60+
}
61+
}
62+
sb.append("] ");
63+
64+
sb.append(" }");
65+
66+
return sb;
67+
}
68+
}

agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public class SearchFilter {
7676

7777
public static final String TAG_DEF_ID = "tagDefId"; // search
7878
public static final String TAG_DEF_GUID = "tagDefGuid"; // search
79+
public static final String TAG_NAMES = "tagNames"; // search
7980
public static final String TAG_TYPE = "tagType"; // search
8081
public static final String TAG_TYPE_PARTIAL = "tagTypePartial"; // search
8182
public static final String TAG_SOURCE = "tagSource"; // search
@@ -88,6 +89,7 @@ public class SearchFilter {
8889
public static final String TAG_RESOURCE_GUID = "resourceGuid"; // search
8990
public static final String TAG_RESOURCE_SERVICE_NAME = "resourceServiceName"; // search
9091
public static final String TAG_RESOURCE_SIGNATURE = "resourceSignature"; // search
92+
public static final String TAG_RESOURCE_ELEMENTS = "resourceElements"; // search
9193
public static final String TAG_MAP_ID = "tagResourceMapId"; // search
9294
public static final String TAG_MAP_GUID = "tagResourceMapGuid"; // search
9395

security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java

100644100755
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.ArrayList;
2323
import java.util.Arrays;
24+
import java.util.HashMap;
2425
import java.util.HashSet;
2526
import java.util.List;
2627
import java.util.Map;
@@ -45,6 +46,7 @@
4546
import org.apache.ranger.entity.XXTagDef;
4647
import org.apache.ranger.entity.XXTagResourceMap;
4748
import org.apache.ranger.plugin.model.*;
49+
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
4850
import org.apache.ranger.plugin.model.validation.RangerValidityScheduleValidator;
4951
import org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
5052
import org.apache.ranger.plugin.store.AbstractTagStore;
@@ -59,7 +61,9 @@
5961
import org.apache.ranger.service.RangerTagDefService;
6062
import org.apache.ranger.service.RangerTagResourceMapService;
6163
import org.apache.ranger.service.RangerTagService;
64+
import org.apache.ranger.view.RangerServiceResourceWithTagsList;
6265
import org.apache.ranger.service.RangerServiceResourceService;
66+
import org.apache.ranger.service.RangerServiceResourceWithTagsService;
6367
import org.slf4j.Logger;
6468
import org.slf4j.LoggerFactory;
6569
import org.springframework.beans.factory.annotation.Autowired;
@@ -89,6 +93,9 @@ public class TagDBStore extends AbstractTagStore {
8993
@Autowired
9094
RangerServiceResourceService rangerServiceResourceService;
9195

96+
@Autowired
97+
RangerServiceResourceWithTagsService rangerServiceResourceWithTagsService;
98+
9299
@Autowired
93100
RangerTagResourceMapService rangerTagResourceMapService;
94101

@@ -714,6 +721,10 @@ public PList<RangerServiceResource> getPaginatedServiceResources(SearchFilter fi
714721
return ret;
715722
}
716723

724+
public RangerServiceResourceWithTagsList getPaginatedServiceResourcesWithTags(SearchFilter filter) throws Exception {
725+
return rangerServiceResourceWithTagsService.searchServiceResourcesWithTags(filter);
726+
}
727+
717728

718729
@Override
719730
public RangerTagResourceMap createTagResourceMap(RangerTagResourceMap tagResourceMap) throws Exception {
@@ -1386,4 +1397,56 @@ private void deleteTagDef(RangerTagDef tagDef) throws Exception {
13861397
}
13871398
}
13881399
}
1400+
1401+
public RangerServiceResource getRangerServiceResource(String serviceName, Map<String, String[]> resourceMap) {
1402+
if (LOG.isDebugEnabled()) {
1403+
LOG.debug("==> TagDBStore.getRangerServiceResource(): serviceName={" + serviceName + "}");
1404+
}
1405+
1406+
Map<String, RangerPolicyResource> resourceElements = new HashMap<>();
1407+
1408+
for (Map.Entry<String, String[]> entry : resourceMap.entrySet()) {
1409+
String[] parts = entry.getKey().split("\\.");
1410+
String[] valueArray = entry.getValue();
1411+
1412+
if (parts.length < 1 || valueArray == null) {
1413+
continue;
1414+
}
1415+
1416+
String key = parts[0];
1417+
1418+
RangerPolicyResource policyResource = resourceElements.get(key);
1419+
1420+
if (policyResource == null) {
1421+
policyResource = new RangerPolicyResource();
1422+
1423+
resourceElements.put(key, policyResource);
1424+
}
1425+
1426+
if (parts.length == 1) {
1427+
List<String> valueList = new ArrayList<>();
1428+
1429+
for (String str : valueArray) {
1430+
valueList.add(str.trim());
1431+
}
1432+
} else if (parts.length == 2 && valueArray[0] != null) {
1433+
String subKey = parts[1];
1434+
String value = valueArray[0];
1435+
1436+
if (subKey.equalsIgnoreCase("isExcludes")) {
1437+
policyResource.setIsExcludes(Boolean.parseBoolean(value.trim()));
1438+
} else if (subKey.equalsIgnoreCase("isRecursive")) {
1439+
policyResource.setIsRecursive(Boolean.parseBoolean(value.trim()));
1440+
}
1441+
}
1442+
}
1443+
1444+
RangerServiceResource ret = new RangerServiceResource(serviceName, resourceElements);
1445+
1446+
if (LOG.isDebugEnabled()) {
1447+
LOG.debug("<== TagDBStore.getRangerServiceResource(): (serviceName={" + serviceName + "} RangerServiceResource={" + ret + "})");
1448+
}
1449+
1450+
return ret;
1451+
}
13891452
}

security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@
1919

2020
package org.apache.ranger.common;
2121

22-
import java.util.ArrayList;
23-
import java.util.Date;
24-
import java.util.HashMap;
25-
import java.util.List;
26-
import java.util.Map;
22+
import java.util.*;
2723

2824
import javax.annotation.Nonnull;
2925
import javax.persistence.EntityManager;
@@ -106,6 +102,7 @@ public SearchFilter getSearchFilter(@Nonnull HttpServletRequest request, List<So
106102
ret.setParam(SearchFilter.TAG_SERVICE_NAME_PARTIAL, request.getParameter(SearchFilter.TAG_SERVICE_NAME_PARTIAL));
107103
ret.setParam(SearchFilter.TAG_RESOURCE_GUID, request.getParameter(SearchFilter.TAG_RESOURCE_GUID));
108104
ret.setParam(SearchFilter.TAG_RESOURCE_SIGNATURE, request.getParameter(SearchFilter.TAG_RESOURCE_SIGNATURE));
105+
ret.setParam(SearchFilter.TAG_RESOURCE_ELEMENTS, request.getParameter(SearchFilter.TAG_RESOURCE_ELEMENTS));
109106
ret.setParam(SearchFilter.TAG_DEF_GUID, request.getParameter(SearchFilter.TAG_DEF_GUID));
110107
ret.setParam(SearchFilter.TAG_DEF_ID, request.getParameter(SearchFilter.TAG_DEF_ID));
111108
ret.setParam(SearchFilter.TAG_ID, request.getParameter(SearchFilter.TAG_ID));
@@ -358,6 +355,45 @@ private StringBuilder buildWhereClause(SearchFilter searchCriteria,
358355
whereClause.append(" ) ");
359356
}
360357

358+
} else {
359+
whereClause.append(" and ")
360+
.append(searchField.getFieldName())
361+
.append(" in ")
362+
.append(" (:").append(searchField.getClientFieldName()).append(")");
363+
}
364+
} else {
365+
whereClause.append(" and ").append(searchField.getCustomCondition());
366+
}
367+
}
368+
} else if (isMultiValue && searchField.getDataType() == SearchField.DATA_TYPE.STR_LIST) {
369+
List<String> strValueList = new ArrayList<>();
370+
371+
for (Object value : multiValue) {
372+
strValueList.add(String.valueOf(value));
373+
}
374+
375+
if (!strValueList.isEmpty()) {
376+
if (searchField.getCustomCondition() == null) {
377+
if (strValueList.size() <= minInListLength) {
378+
whereClause.append(" and ");
379+
380+
if (strValueList.size() > 1) {
381+
whereClause.append(" ( ");
382+
}
383+
384+
for (int count = 0; count < strValueList.size(); count++) {
385+
if (count > 0) {
386+
whereClause.append(" or ");
387+
}
388+
389+
whereClause.append(searchField.getFieldName()).append("= :")
390+
.append(searchField.getClientFieldName()).append("_").append(count);
391+
}
392+
393+
if (strValueList.size() > 1) {
394+
whereClause.append(" ) ");
395+
}
396+
361397
} else {
362398
whereClause.append(" and ")
363399
.append(searchField.getFieldName())
@@ -477,6 +513,22 @@ protected void resolveQueryParams(Query query, SearchFilter searchCriteria, List
477513
query.setParameter(searchField.getClientFieldName(), intValueList);
478514
}
479515
}
516+
} else if (isMultiValue && searchField.getDataType() == SearchField.DATA_TYPE.STR_LIST) {
517+
List<String> strValueList = new ArrayList<>();
518+
519+
for (Object value : multiValue) {
520+
strValueList.add(String.valueOf(value));
521+
}
522+
523+
if (!strValueList.isEmpty()) {
524+
if (strValueList.size() <= minInListLength) {
525+
for (int idx = 0; idx < strValueList.size(); idx++) {
526+
query.setParameter(searchField.getClientFieldName() + "_" + idx, strValueList.get(idx));
527+
}
528+
} else {
529+
query.setParameter(searchField.getClientFieldName(), strValueList);
530+
}
531+
}
480532
} else if (searchField.getDataType() == SearchField.DATA_TYPE.INTEGER) {
481533
Integer paramVal = restErrorUtil.parseInt(searchCriteria.getParam(searchField.getClientFieldName()),
482534
"Invalid value for " + searchField.getClientFieldName(),
@@ -599,6 +651,42 @@ public void extractIntList(HttpServletRequest request, SearchFilter searchFilter
599651
}
600652
}
601653

654+
public void extractStringList(HttpServletRequest request, SearchFilter searchFilter, String paramName,
655+
String userFriendlyParamName, String listName, String[] validValues, String regEx) {
656+
String[] values = getParamMultiValues(request, paramName);
657+
658+
if (values != null) {
659+
List<String> stringList = new ArrayList<>(values.length);
660+
661+
for (String value : values) {
662+
if (!stringUtil.isEmpty(regEx)) {
663+
restErrorUtil.validateString(value, regEx, "Invalid value for " + userFriendlyParamName, MessageEnums.INVALID_INPUT_DATA, null, paramName);
664+
}
665+
666+
stringList.add(value);
667+
}
668+
669+
searchFilter.setMultiValueParam(paramName, stringList.toArray());
670+
}
671+
}
672+
673+
public Map<String, String[]> getMultiValueParamsWithPrefix(HttpServletRequest request, String prefix, boolean stripPrefix) {
674+
Map<String, String[]> ret = new HashMap<String, String[]>();
675+
for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()) {
676+
String name = e.getKey();
677+
String[] values = e.getValue();
678+
679+
if (!StringUtils.isEmpty(name) && !ArrayUtils.isEmpty(values)
680+
&& name.startsWith(prefix)) {
681+
if(stripPrefix) {
682+
name = name.substring(prefix.length());
683+
}
684+
ret.put(name, values);
685+
}
686+
}
687+
return ret;
688+
}
689+
602690
/**
603691
* @param request
604692
* @param paramName

0 commit comments

Comments
 (0)