Skip to content

Commit

Permalink
Get a working proof of concept
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Perkins <[email protected]>
  • Loading branch information
cwperks committed Jan 8, 2025
1 parent 963210c commit 7d64454
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public void onResponse(SearchResponse searchResponse) {

for (SearchHit hit : hits) {
System.out.println("hit: " + hit.getSourceAsMap());
System.out.println("hit score: " + hit.getScore());
try {
XContentParser parser = XContentHelper.createParser(
xContentRegistry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,8 @@ public void onIndexModule(IndexModule indexModule) {
ciol,
evaluator,
dlsFlsValve::getCurrentConfig,
dlsFlsBaseContext
dlsFlsBaseContext,
namedXContentRegistry.get()
)
);
System.out.println("this.indicesToListen: " + this.indicesToListen);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@ private class DlsGetEvaluator {
private final boolean hasDeletions;

public DlsGetEvaluator(final Query dlsQuery, final LeafReader in, boolean applyDlsHere) throws IOException {
if (dlsQuery != null && applyDlsHere) {
// System.out.println("DlsGetEvaluator");
// System.out.println("dlsQuery: " + dlsQuery);
// System.out.println("applyDlsHere: " + applyDlsHere);
// if (dlsQuery != null && applyDlsHere) {
if (dlsQuery != null) {
// borrowed from Apache Lucene (Copyright Apache Software Foundation (ASF))
// https://github.com/apache/lucene-solr/blob/branch_6_3/lucene/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java
final IndexSearcher searcher = new IndexSearcher(DlsFlsFilterLeafReader.this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.LongSupplier;
import java.util.function.Supplier;
Expand All @@ -29,20 +30,28 @@
import org.opensearch.cluster.metadata.IndexMetadata;
import org.opensearch.cluster.service.ClusterService;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.xcontent.json.JsonXContent;
import org.opensearch.core.index.shard.ShardId;
import org.opensearch.core.xcontent.DeprecationHandler;
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.index.IndexService;
import org.opensearch.index.mapper.SeqNoFieldMapper;
import org.opensearch.index.query.AbstractQueryBuilder;
import org.opensearch.index.query.QueryBuilder;
import org.opensearch.index.query.QueryShardContext;
import org.opensearch.index.shard.ShardUtils;
import org.opensearch.security.auditlog.AuditLog;
import org.opensearch.security.compliance.ComplianceIndexingOperationListener;
import org.opensearch.security.privileges.DocumentAllowList;
import org.opensearch.security.privileges.PrivilegesConfigurationValidationException;
import org.opensearch.security.privileges.PrivilegesEvaluationContext;
import org.opensearch.security.privileges.PrivilegesEvaluationException;
import org.opensearch.security.privileges.PrivilegesEvaluator;
import org.opensearch.security.privileges.dlsfls.DlsFlsBaseContext;
import org.opensearch.security.privileges.dlsfls.DlsFlsProcessedConfig;
import org.opensearch.security.privileges.dlsfls.DlsRestriction;
import org.opensearch.security.privileges.dlsfls.DocumentPrivileges;
import org.opensearch.security.privileges.dlsfls.FieldMasking;
import org.opensearch.security.privileges.dlsfls.FieldPrivileges;
import org.opensearch.security.support.ConfigConstants;
Expand All @@ -61,6 +70,7 @@ public class SecurityFlsDlsIndexSearcherWrapper extends SystemIndexSearcherWrapp
private final LongSupplier nowInMillis;
private final Supplier<DlsFlsProcessedConfig> dlsFlsProcessedConfigSupplier;
private final DlsFlsBaseContext dlsFlsBaseContext;
private final NamedXContentRegistry xContentRegistry;

public SecurityFlsDlsIndexSearcherWrapper(
final IndexService indexService,
Expand All @@ -71,7 +81,8 @@ public SecurityFlsDlsIndexSearcherWrapper(
final ComplianceIndexingOperationListener ciol,
final PrivilegesEvaluator evaluator,
final Supplier<DlsFlsProcessedConfig> dlsFlsProcessedConfigSupplier,
final DlsFlsBaseContext dlsFlsBaseContext
final DlsFlsBaseContext dlsFlsBaseContext,
final NamedXContentRegistry xContentRegistry
) {
super(indexService, settings, adminDNs, evaluator);
Set<String> metadataFieldsCopy;
Expand All @@ -94,6 +105,7 @@ public SecurityFlsDlsIndexSearcherWrapper(
this.clusterService = clusterService;
this.indexService = indexService;
this.auditlog = auditlog;
this.xContentRegistry = xContentRegistry;
final boolean allowNowinDlsQueries = settings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS, false);
if (allowNowinDlsQueries) {
nowInMillis = () -> System.currentTimeMillis();
Expand All @@ -110,13 +122,14 @@ public SecurityFlsDlsIndexSearcherWrapper(
protected DirectoryReader dlsFlsWrap(final DirectoryReader reader, boolean isAdmin) throws IOException {

final ShardId shardId = ShardUtils.extractShardId(reader);
assert shardId != null;
PrivilegesEvaluationContext privilegesEvaluationContext = this.dlsFlsBaseContext.getPrivilegesEvaluationContext();

if (log.isTraceEnabled()) {
log.trace("dlsFlsWrap(); index: {}; privilegeEvaluationContext: {}", index.getName(), privilegesEvaluationContext);
}

if (isAdmin || privilegesEvaluationContext == null) {
if ((isAdmin || privilegesEvaluationContext == null) && !shardId.getIndexName().equals(".sample_extension_resources")) {
return new DlsFlsFilterLeafReader.DlsFlsDirectoryReader(
reader,
FieldPrivileges.FlsRule.ALLOW_ALL,
Expand All @@ -131,11 +144,78 @@ protected DirectoryReader dlsFlsWrap(final DirectoryReader reader, boolean isAdm
);
}

System.out.println("shardID: " + shardId.getIndexName());

if (shardId.getIndexName().equals(".sample_extension_resources")) {
System.out.println("dlsFlsWarp: " + shardId.getIndexName() + " is .sample_extension_resources");
}

try {

DlsFlsProcessedConfig config = this.dlsFlsProcessedConfigSupplier.get();
DlsRestriction dlsRestriction;

if (shardId.getIndex().getName().equals(".sample_extension_resources")) {
String queryString = """
{ "bool": {
"should": [
{
"term": {
"resource_user.name": "resource_sharing_test_user"
}
},
{
"terms": {
"share_with.backend_roles": ["admin"]
}
},
{
"term": {
"share_with.users": "dne"
}
}
],
"minimum_should_match": 1
}
}
""";
System.out.println("queryString: " + queryString);
dlsRestriction = new DlsRestriction(
List.of(new DocumentPrivileges.RenderedDlsQuery(parseQuery(queryString, xContentRegistry), queryString))
);
QueryShardContext queryShardContext = this.indexService.newQueryShardContext(shardId.getId(), null, nowInMillis, null);
Query dlsQuery = dlsQuery = new ConstantScoreQuery(dlsRestriction.toBooleanQueryBuilder(queryShardContext, null).build());
String action = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_ACTION_NAME);
System.out.println("action: " + threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_ACTION_NAME));
if (action.startsWith("indices:data/read/search")) {
return new DlsFlsFilterLeafReader.DlsFlsDirectoryReader(
reader,
FieldPrivileges.FlsRule.ALLOW_ALL,
dlsQuery,
indexService,
threadContext,
clusterService,
auditlog,
FieldMasking.FieldMaskingRule.ALLOW_ALL,
shardId,
metaFields
);
} else {
return new DlsFlsFilterLeafReader.DlsFlsDirectoryReader(
reader,
FieldPrivileges.FlsRule.ALLOW_ALL,
null,
indexService,
threadContext,
clusterService,
auditlog,
FieldMasking.FieldMaskingRule.ALLOW_ALL,
shardId,
metaFields
);
}
}

if (!this.dlsFlsBaseContext.isDlsDoneOnFilterLevel()) {
dlsRestriction = config.getDocumentPrivileges().getRestriction(privilegesEvaluationContext, index.getName());
} else {
Expand Down Expand Up @@ -199,8 +279,26 @@ protected DirectoryReader dlsFlsWrap(final DirectoryReader reader, boolean isAdm
);

} catch (PrivilegesEvaluationException e) {
System.out.println("caught PrivilegesEvaluationException: " + e.getMessage());
log.error("Error while evaluating DLS/FLS for {}", this.index.getName(), e);
throw new OpenSearchException("Error while evaluating DLS/FLS", e);
} catch (PrivilegesConfigurationValidationException e) {
System.out.println("caught exception: " + e.getMessage());
throw new RuntimeException(e);
}
}

protected QueryBuilder parseQuery(String queryString, NamedXContentRegistry xContentRegistry)
throws PrivilegesConfigurationValidationException {
try {
XContentParser parser = JsonXContent.jsonXContent.createParser(
xContentRegistry,
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
queryString
);
return AbstractQueryBuilder.parseInnerQueryBuilder(parser);
} catch (Exception e) {
throw new PrivilegesConfigurationValidationException("Invalid DLS query: " + queryString, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public class DlsRestriction extends AbstractRuleBasedPrivileges.Rule {

private final ImmutableList<DocumentPrivileges.RenderedDlsQuery> queries;

DlsRestriction(List<DocumentPrivileges.RenderedDlsQuery> queries) {
public DlsRestriction(List<DocumentPrivileges.RenderedDlsQuery> queries) {
this.queries = ImmutableList.copyOf(queries);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public static class RenderedDlsQuery {
private final QueryBuilder queryBuilder;
private final String renderedSource;

RenderedDlsQuery(QueryBuilder queryBuilder, String renderedSource) {
public RenderedDlsQuery(QueryBuilder queryBuilder, String renderedSource) {
this.queryBuilder = queryBuilder;
this.renderedSource = renderedSource;
}
Expand Down

0 comments on commit 7d64454

Please sign in to comment.