Skip to content

Commit f835ca2

Browse files
RANGER-5407: In Atlas Service for some of the default policies wrong permissions seen (apache#791)
1 parent e00ac90 commit f835ca2

File tree

1 file changed

+169
-34
lines changed

1 file changed

+169
-34
lines changed

security-admin/src/main/java/org/apache/ranger/patch/PatchForAtlasPolicyUpdateForEntityRead_J10064.java

Lines changed: 169 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,49 @@
1717

1818
package org.apache.ranger.patch;
1919

20+
import org.apache.commons.collections.CollectionUtils;
2021
import org.apache.ranger.biz.ServiceDBStore;
2122
import org.apache.ranger.db.RangerDaoManager;
2223
import org.apache.ranger.entity.XXPolicy;
2324
import org.apache.ranger.entity.XXService;
2425
import org.apache.ranger.entity.XXServiceDef;
2526
import org.apache.ranger.plugin.model.RangerPolicy;
2627
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
28+
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
2729
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
2830
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
31+
import org.apache.ranger.rest.ServiceRESTUtil;
2932
import org.apache.ranger.util.CLIUtil;
3033
import org.slf4j.Logger;
3134
import org.slf4j.LoggerFactory;
3235
import org.springframework.beans.factory.annotation.Autowired;
3336
import org.springframework.stereotype.Component;
3437

38+
import java.util.ArrayList;
39+
import java.util.Arrays;
40+
import java.util.Collections;
3541
import java.util.Iterator;
3642
import java.util.List;
43+
import java.util.ListIterator;
3744
import java.util.Map;
45+
import java.util.stream.Collectors;
3846

3947
@Component
4048
public class PatchForAtlasPolicyUpdateForEntityRead_J10064 extends org.apache.ranger.patch.BaseLoader {
4149
private static final Logger logger = LoggerFactory.getLogger(PatchForAtlasPolicyUpdateForEntityRead_J10064.class);
4250

43-
private static final String RESOURCE_ENTITY_TYPE = "entity-type";
4451
private static final String ENTITY_READ = "entity-read";
52+
53+
private static final String RESOURCE_ENTITY_TYPE = "entity-type";
4554
private static final String RESOURCE_ENTITY_LABEL = "entity-label";
4655
private static final String RESOURCE_ENTITY_BUSINESS_METADATA = "entity-business-metadata";
4756

57+
private static final String POLICY_NAME_ENTITY_BASE = "all - entity-type, entity-classification, entity";
58+
private static final String POLICY_NAME_ENTITY_CLASSIFICATION = "all - entity-type, entity-classification, entity, classification";
59+
60+
private static final List<String> ATLAS_RESOURCE_ENTITY = new ArrayList<>(Arrays.asList("entity-type", "entity-classification", "entity"));
61+
private static final List<String> CLASSIFICATION_ACCESS_TYPES = new ArrayList<>(Arrays.asList("entity-remove-classification", "entity-add-classification", "entity-update-classification"));
62+
4863
@Autowired
4964
RangerDaoManager daoMgr;
5065

@@ -88,26 +103,21 @@ public void execLoad() {
88103
logger.info("==> PatchForAtlasPolicyUpdateForEntityRead_J10064.execLoad()");
89104

90105
try {
91-
updateAtlasPolicyForEntityReadAccessType();
106+
updateAtlasPolicyForAccessType();
92107
} catch (Exception e) {
93108
throw new RuntimeException("Error while updating " + EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_ATLAS_NAME + " service-def", e);
94109
}
95110

96111
logger.info("<== PatchForAtlasPolicyUpdateForEntityRead_J10064.execLoad()");
97112
}
98113

99-
private boolean removeIfEntityReadPermissionExist(RangerPolicyItem item) {
100-
return item.getAccesses().removeIf(itemAccess -> itemAccess.getType().equals(ENTITY_READ));
101-
}
102-
103-
private void updateAtlasPolicyForEntityReadAccessType() throws Exception {
104-
logger.info("==> updateAtlasPolicyForEntityReadAccessType() ");
114+
private void updateAtlasPolicyForAccessType() throws Exception {
115+
logger.info("==> updateAtlasPolicyForAccessType()");
105116

106117
XXServiceDef xXServiceDefObj = daoMgr.getXXServiceDef().findByName(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_ATLAS_NAME);
107118

108119
if (xXServiceDefObj == null) {
109-
logger.debug("ServiceDef not found with name :{}", EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_ATLAS_NAME);
110-
120+
logger.debug("ServiceDef not found with name: {}", EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_ATLAS_NAME);
111121
return;
112122
}
113123

@@ -117,39 +127,164 @@ private void updateAtlasPolicyForEntityReadAccessType() throws Exception {
117127
for (XXService xxService : xxServices) {
118128
List<XXPolicy> xxPolicies = daoMgr.getXXPolicy().findByServiceId(xxService.getId());
119129

130+
List<RangerPolicyItem> defaultEntityReadItems = new ArrayList<>();
131+
List<RangerPolicyItem> defaultClassificationItems = new ArrayList<>();
132+
120133
for (XXPolicy xxPolicy : xxPolicies) {
121134
RangerPolicy rPolicy = svcDBStore.getPolicy(xxPolicy.getId());
122135

123-
final Map<String, RangerPolicyResource> policyResources = rPolicy.getResources();
124-
final boolean isNonEntityResourceType = policyResources.containsKey(RESOURCE_ENTITY_LABEL)
125-
|| policyResources.containsKey(RESOURCE_ENTITY_BUSINESS_METADATA);
126-
boolean isUpdated = false;
127-
128-
if (policyResources.containsKey(RESOURCE_ENTITY_TYPE) && isNonEntityResourceType) {
129-
List<RangerPolicyItem> policyItems = rPolicy.getPolicyItems();
130-
if (policyItems != null) {
131-
Iterator<RangerPolicyItem> itemIterator = policyItems.iterator();
132-
while (itemIterator.hasNext()) {
133-
RangerPolicyItem item = itemIterator.next();
134-
if (removeIfEntityReadPermissionExist(item)) {
135-
if (item.getAccesses().isEmpty()) {
136-
itemIterator.remove();
137-
logger.debug("Removing empty policy item from policy ID: {}", rPolicy.getId());
138-
}
139-
isUpdated = true;
140-
}
141-
}
142-
}
143-
}
136+
boolean isUpdated = processPolicyForAccessUpdate(rPolicy, defaultEntityReadItems, defaultClassificationItems);
144137

145138
if (isUpdated) {
146139
svcDBStore.updatePolicy(rPolicy);
147-
logger.info("PatchForAtlasPolicyUpdateForEntityRead_J10064: updated policy (id={}, name={}) to remove {} permission",
148-
rPolicy.getId(), rPolicy.getName(), ENTITY_READ);
140+
logger.info("PatchForAtlasPolicyUpdateForEntityRead_J10064: updated policy (id={}, name={}) for service {} to remove/filter permissions",
141+
rPolicy.getId(), rPolicy.getName(), xxService.getName());
149142
}
150143
}
144+
145+
applyAggregatedDefaultPolicyUpdate(POLICY_NAME_ENTITY_BASE, defaultEntityReadItems, xxService);
146+
applyAggregatedDefaultPolicyUpdate(POLICY_NAME_ENTITY_CLASSIFICATION, defaultClassificationItems, xxService);
147+
}
148+
149+
logger.info("<== updateAtlasPolicyForAccessType()");
150+
}
151+
152+
private boolean processPolicyForAccessUpdate(RangerPolicy rPolicy, List<RangerPolicyItem> entityReadDefaults, List<RangerPolicyItem> classificationDefaults) {
153+
final Map<String, RangerPolicyResource> policyResources = rPolicy.getResources();
154+
155+
if (policyResources == null) {
156+
return false;
157+
}
158+
159+
final boolean isNonEntityResourceType = policyResources.containsKey(RESOURCE_ENTITY_TYPE) &&
160+
(policyResources.containsKey(RESOURCE_ENTITY_LABEL) || policyResources.containsKey(RESOURCE_ENTITY_BUSINESS_METADATA));
161+
162+
if (isNonEntityResourceType) {
163+
return removeEntityReadAccess(rPolicy, entityReadDefaults);
164+
}
165+
166+
if (isEntityResource(policyResources)) {
167+
return filterClassificationAccess(rPolicy, classificationDefaults);
168+
}
169+
170+
return false;
171+
}
172+
173+
private boolean isEntityResource(Map<String, RangerPolicyResource> policyResources) {
174+
if (policyResources == null || policyResources.size() != ATLAS_RESOURCE_ENTITY.size()) {
175+
return false;
176+
}
177+
178+
return policyResources.keySet().containsAll(ATLAS_RESOURCE_ENTITY);
179+
}
180+
181+
private boolean removeEntityReadAccess(RangerPolicy rPolicy, List<RangerPolicyItem> defaultEntityReadItems) {
182+
List<RangerPolicyItem> policyItems = rPolicy.getPolicyItems();
183+
if (CollectionUtils.isEmpty(policyItems)) {
184+
return false;
151185
}
152186

153-
logger.info("<== updateAtlasPolicyForEntityReadAccessType() ");
187+
boolean isUpdated = false;
188+
Iterator<RangerPolicyItem> itemIterator = policyItems.iterator();
189+
while (itemIterator.hasNext()) {
190+
RangerPolicyItem item = itemIterator.next();
191+
192+
boolean wasAccessRemoved = item.getAccesses().removeIf(itemAccess -> ENTITY_READ.equals(itemAccess.getType()));
193+
194+
if (wasAccessRemoved) {
195+
isUpdated = true;
196+
197+
RangerPolicyItem policyItemForentityRead = new RangerPolicyItem();
198+
policyItemForentityRead.setUsers(item.getUsers());
199+
policyItemForentityRead.setGroups(item.getGroups());
200+
policyItemForentityRead.setRoles(item.getRoles());
201+
policyItemForentityRead.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ENTITY_READ)));
202+
policyItemForentityRead.setDelegateAdmin(item.getDelegateAdmin());
203+
204+
if (!defaultEntityReadItems.contains(policyItemForentityRead)) {
205+
defaultEntityReadItems.add(policyItemForentityRead);
206+
}
207+
208+
if (item.getAccesses().isEmpty()) {
209+
itemIterator.remove();
210+
logger.debug("Removing empty policy item from policy ID: {}", rPolicy.getId());
211+
}
212+
}
213+
}
214+
return isUpdated;
215+
}
216+
217+
private boolean filterClassificationAccess(RangerPolicy policy, List<RangerPolicyItem> defaultClassificationItems) {
218+
List<RangerPolicyItem> policyItems = policy.getPolicyItems();
219+
if (CollectionUtils.isEmpty(policyItems)) {
220+
return false;
221+
}
222+
223+
boolean isUpdated = false;
224+
ListIterator<RangerPolicyItem> policyItemIterator = policyItems.listIterator();
225+
226+
while (policyItemIterator.hasNext()) {
227+
RangerPolicyItem policyItem = policyItemIterator.next();
228+
List<RangerPolicyItemAccess> accesses = policyItem.getAccesses();
229+
230+
if (CollectionUtils.isNotEmpty(accesses)) {
231+
List<RangerPolicyItemAccess> accessesToRemove = accesses.stream()
232+
.filter(access -> CLASSIFICATION_ACCESS_TYPES.contains(access.getType())).collect(Collectors.toList());
233+
234+
boolean removed = accesses.removeAll(accessesToRemove);
235+
236+
if (removed) {
237+
isUpdated = true;
238+
239+
RangerPolicyItem policyItemForClassification = new RangerPolicyItem();
240+
policyItemForClassification.setUsers(policyItem.getUsers());
241+
policyItemForClassification.setGroups(policyItem.getGroups());
242+
policyItemForClassification.setRoles(policyItem.getRoles());
243+
policyItemForClassification.setAccesses(accessesToRemove);
244+
policyItemForClassification.setDelegateAdmin(policyItem.getDelegateAdmin());
245+
246+
if (!defaultClassificationItems.contains(policyItemForClassification)) {
247+
defaultClassificationItems.add(policyItemForClassification);
248+
}
249+
}
250+
251+
// Remove the policy item if all accesses were filtered out
252+
if (accesses.isEmpty()) {
253+
policyItemIterator.remove();
254+
logger.debug("Removing empty policy item from policy ID: {}", policy.getId());
255+
}
256+
}
257+
}
258+
259+
return isUpdated;
260+
}
261+
262+
private void applyAggregatedDefaultPolicyUpdate(String policyName, List<RangerPolicyItem> itemsToAdd, XXService service) {
263+
if (CollectionUtils.isEmpty(itemsToAdd)) {
264+
return;
265+
}
266+
267+
try {
268+
XXPolicy xxPolicy = daoMgr.getXXPolicy().findByNameAndServiceId(policyName, service.getId());
269+
270+
if (xxPolicy == null) {
271+
return;
272+
}
273+
274+
RangerPolicy existingPolicy = svcDBStore.getPolicy(xxPolicy.getId());
275+
276+
RangerPolicy appliedPolicy = new RangerPolicy();
277+
appliedPolicy.setPolicyItems(itemsToAdd);
278+
279+
// Merge itemsToAdd into the existingPolicy
280+
ServiceRESTUtil.mergeExactMatchPolicyForResource(existingPolicy, appliedPolicy);
281+
282+
svcDBStore.updatePolicy(existingPolicy);
283+
284+
logger.info("Successfully Added {} policy-items to default policy (id={}, name={}) for service {}",
285+
itemsToAdd.size(), existingPolicy.getId(), existingPolicy.getName(), service.getName());
286+
} catch (Exception e) {
287+
logger.error("Error updating default policy '{}' for service {}", policyName, service.getName(), e);
288+
}
154289
}
155290
}

0 commit comments

Comments
 (0)