Skip to content

Commit d83bd0e

Browse files
committed
Support for alias based DLS/FLS evaluation
Signed-off-by: Nils Bandener <[email protected]>
1 parent c71488b commit d83bd0e

File tree

2 files changed

+79
-13
lines changed

2 files changed

+79
-13
lines changed

src/main/java/org/opensearch/security/privileges/dlsfls/AbstractRuleBasedPrivileges.java

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.logging.log4j.Logger;
2626

2727
import org.opensearch.cluster.metadata.IndexAbstraction;
28+
import org.opensearch.cluster.metadata.IndexMetadata;
2829
import org.opensearch.cluster.metadata.OptionallyResolvedIndices;
2930
import org.opensearch.cluster.metadata.ResolvedIndices;
3031
import org.opensearch.common.settings.Settings;
@@ -230,6 +231,46 @@ public boolean isUnrestricted(PrivilegesEvaluationContext context, String index)
230231
private boolean hasUnrestrictedRulesExplicit(PrivilegesEvaluationContext context, StatefulRules<SingleRule> statefulRules, String index)
231232
throws PrivilegesEvaluationException {
232233

234+
if (hasUnrestrictedRulesExplicitNoRecursion(context, statefulRules, index)) {
235+
return true;
236+
}
237+
238+
IndexAbstraction indexAbstraction = context.getIndicesLookup().get(index);
239+
if (indexAbstraction instanceof IndexAbstraction.Index) {
240+
for (String parent : getParents(indexAbstraction)) {
241+
if (hasUnrestrictedRulesExplicitNoRecursion(context, statefulRules, parent)) {
242+
return true;
243+
}
244+
}
245+
} else if (indexAbstraction instanceof IndexAbstraction.DataStream || indexAbstraction instanceof IndexAbstraction.Alias) {
246+
// If we got an alias or a data stream, we might be also unrestricted if all member indices are unrestricted
247+
248+
List<IndexMetadata> memberIndices = indexAbstraction.getIndices();
249+
int unrestrictedMemberIndices = 0;
250+
251+
for (IndexMetadata memberIndex : memberIndices) {
252+
if (hasUnrestrictedRulesExplicitNoRecursion(context, statefulRules, memberIndex.getIndex().getName())) {
253+
unrestrictedMemberIndices++;
254+
}
255+
}
256+
257+
if (unrestrictedMemberIndices == memberIndices.size()) {
258+
return true;
259+
}
260+
}
261+
262+
return false;
263+
}
264+
265+
/**
266+
* Should be only called by hasUnrestrictedRulesExplicit()
267+
*/
268+
private boolean hasUnrestrictedRulesExplicitNoRecursion(
269+
PrivilegesEvaluationContext context,
270+
StatefulRules<SingleRule> statefulRules,
271+
String index
272+
) throws PrivilegesEvaluationException {
273+
233274
if (statefulRules != null && statefulRules.covers(index)) {
234275
Set<String> roleWithoutRule = statefulRules.indexToRoleWithoutRule.get(index);
235276

@@ -246,17 +287,7 @@ private boolean hasUnrestrictedRulesExplicit(PrivilegesEvaluationContext context
246287
return true;
247288
}
248289

249-
IndexAbstraction indexAbstraction = context.getIndicesLookup().get(index);
250-
if (indexAbstraction != null) {
251-
for (String parent : getParents(indexAbstraction)) {
252-
if (hasUnrestrictedRulesExplicit(context, statefulRules, parent)) {
253-
return true;
254-
}
255-
}
256-
}
257-
258290
return false;
259-
260291
}
261292

262293
/**
@@ -283,9 +314,17 @@ private boolean hasRestrictedRulesExplicit(PrivilegesEvaluationContext context,
283314
}
284315

285316
IndexAbstraction indexAbstraction = context.getIndicesLookup().get(index);
286-
if (indexAbstraction != null) {
317+
if (indexAbstraction instanceof IndexAbstraction.Index) {
287318
for (String parent : getParents(indexAbstraction)) {
288-
if (hasRestrictedRulesExplicit(context, statefulRules, parent)) {
319+
if (hasRestrictedRulesExplicitNoRecursion(context, statefulRules, parent)) {
320+
return true;
321+
}
322+
}
323+
} else if (indexAbstraction instanceof IndexAbstraction.DataStream || indexAbstraction instanceof IndexAbstraction.Alias) {
324+
// If we got an alias or a data stream, we might be also restricted if there is a member index that is restricted
325+
326+
for (IndexMetadata memberIndex : indexAbstraction.getIndices()) {
327+
if (hasRestrictedRulesExplicitNoRecursion(context, statefulRules, memberIndex.getIndex().getName())) {
289328
return true;
290329
}
291330
}
@@ -294,6 +333,34 @@ private boolean hasRestrictedRulesExplicit(PrivilegesEvaluationContext context,
294333
return false;
295334
}
296335

336+
/**
337+
* Should be only called by hasRestrictedRulesExplicit()
338+
*/
339+
private boolean hasRestrictedRulesExplicitNoRecursion(
340+
PrivilegesEvaluationContext context,
341+
StatefulRules<SingleRule> statefulRules,
342+
String index
343+
) throws PrivilegesEvaluationException {
344+
345+
if (statefulRules != null && statefulRules.covers(index)) {
346+
Map<String, SingleRule> roleWithRule = statefulRules.indexToRoleToRule.get(index);
347+
348+
if (roleWithRule != null && CollectionUtils.containsAny(roleWithRule.keySet(), context.getMappedRoles())) {
349+
return true;
350+
}
351+
} else {
352+
if (this.staticRules.hasRestrictedPatterns(context, index)) {
353+
return true;
354+
}
355+
}
356+
357+
if (this.staticRules.hasRestrictedPatternTemplates(context, index)) {
358+
return true;
359+
}
360+
361+
return false;
362+
}
363+
297364
/**
298365
* Returns true if the user specified by the given context parameter has roles which apply for the index wildcard ("*")
299366
* and which specify DLS rules.

src/test/java/org/opensearch/security/filter/SecurityFilterTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import org.opensearch.security.privileges.PrivilegesConfiguration;
3535
import org.opensearch.security.privileges.ResourceAccessEvaluator;
3636
import org.opensearch.security.privileges.RoleMapper;
37-
import org.opensearch.security.privileges.ResourceAccessEvaluator;
3837
import org.opensearch.security.support.ConfigConstants;
3938
import org.opensearch.security.support.WildcardMatcher;
4039
import org.opensearch.threadpool.ThreadPool;

0 commit comments

Comments
 (0)