Turn the code into a FilterBuilder builder.
git-svn-id: https://svn.apache.org/repos/asf/manifoldcf/integration/elasticsearch/trunk@1454684 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index c26ca8d..a032dee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,6 @@
<!-- Move these to the parent pom, when I create a parent pom -->
<properties>
<elasticsearch.version>0.20.5</elasticsearch.version>
- <lucene.version>3.6.2</lucene.version>
<junit.version>4.8.2</junit.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.16</log4j.version>
@@ -54,13 +53,6 @@
</dependency>
<dependency>
- <groupId>org.apache.lucene</groupId>
- <artifactId>lucene-core</artifactId>
- <version>${lucene.version}</version>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpcomponent.version}</version>
diff --git a/src/main/java/org/apache/manifoldcf/elasticsearch/QueryModifierException.java b/src/main/java/org/apache/manifoldcf/elasticsearch/AuthorizerException.java
similarity index 75%
rename from src/main/java/org/apache/manifoldcf/elasticsearch/QueryModifierException.java
rename to src/main/java/org/apache/manifoldcf/elasticsearch/AuthorizerException.java
index 5d50e49..80fdfbd 100644
--- a/src/main/java/org/apache/manifoldcf/elasticsearch/QueryModifierException.java
+++ b/src/main/java/org/apache/manifoldcf/elasticsearch/AuthorizerException.java
@@ -18,19 +18,19 @@
*/
package org.apache.manifoldcf.elasticsearch;
-/** This class represents the main Java API for modifying Lucene queries
-* within ElasticSearch. It is a singleton class whose main public method
+/** This class represents exceptions for authorizing ElasticSearch requests
+* to include security. It is a singleton class whose main public method
* is thread-safe.
*/
-public class QueryModifierException extends Exception
+public class AuthorizerException extends Exception
{
/** Constructor */
- public QueryModifierException(String message)
+ public AuthorizerException(String message)
{
super(message);
}
- public QueryModifierException(String message, Throwable cause)
+ public AuthorizerException(String message, Throwable cause)
{
super(message,cause);
}
diff --git a/src/main/java/org/apache/manifoldcf/elasticsearch/QueryModifier.java b/src/main/java/org/apache/manifoldcf/elasticsearch/MCFAuthorizer.java
similarity index 70%
rename from src/main/java/org/apache/manifoldcf/elasticsearch/QueryModifier.java
rename to src/main/java/org/apache/manifoldcf/elasticsearch/MCFAuthorizer.java
index e2b4601..1c05d32 100644
--- a/src/main/java/org/apache/manifoldcf/elasticsearch/QueryModifier.java
+++ b/src/main/java/org/apache/manifoldcf/elasticsearch/MCFAuthorizer.java
@@ -22,8 +22,9 @@
import java.util.*;
import java.net.*;
-import org.apache.lucene.search.*;
-import org.apache.lucene.index.*;
+import org.elasticsearch.index.query.FilterBuilder;
+import org.elasticsearch.index.query.BoolFilterBuilder;
+import org.elasticsearch.index.query.TermFilterBuilder;
import org.apache.http.client.HttpClient;
import org.apache.http.HttpStatus;
@@ -43,18 +44,18 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/** This class represents the main Java API for modifying Lucene queries
-* within ElasticSearch. It is a singleton class whose main public method
+/** This class represents the main Java API for modifying SearchRequestBuilder
+* objects within ElasticSearch. It is a singleton class whose main public method
* is thread-safe.
*/
-public class QueryModifier
+public class MCFAuthorizer
{
/** Special token for null security fields */
static final public String NOSECURITY_TOKEN = "__nosecurity__";
/** A logger we can use */
- private static final Logger LOG = LoggerFactory.getLogger(QueryModifier.class);
+ private static final Logger LOG = LoggerFactory.getLogger(MCFAuthorizer.class);
// Member variables
@@ -71,7 +72,7 @@
protected final HttpClient httpClient;
/** Constructor, which includes configuration information */
- public QueryModifier(ConfigurationParameters cp)
+ public MCFAuthorizer(ConfigurationParameters cp)
{
authorityBaseURL = cp.authorityServiceBaseURL;
fieldAllowDocument = cp.allowFieldPrefix+"document";
@@ -114,13 +115,12 @@
connectionManager.shutdown();
}
- /** Main method for wrapping a query with appropriate security.
- *@param userQuery is the user query to wrap.
+ /** Main method for building a filter representing appropriate security.
*@param authenticatedUserName is a user name in the form "user@domain".
- *@return the wrapped query enforcing ManifoldCF security.
+ *@return the filter builder.
*/
- public Query wrapQuery(Query userQuery, String authenticatedUserName)
- throws QueryModifierException
+ public FilterBuilder buildAuthorizationFilter(String authenticatedUserName)
+ throws AuthorizerException
{
if (authorityBaseURL == null)
throw new IllegalStateException("Authority base URL required for finding access tokens for a user");
@@ -130,23 +130,22 @@
LOG.info("Trying to match docs for user '"+authenticatedUserName+"'");
- return wrapQuery(userQuery,getAccessTokens(authenticatedUserName));
+ return buildAuthorizationFilter(getAccessTokens(authenticatedUserName));
}
- /** Main method for wrapping a query with appropriate security.
- *@param userQuery is the user query to wrap.
- *@param userAccessTokens are a set of tokens to use to wrap the query (presumably from mod_authz_annotate, upstream)
+ /** Main method for building a filter representing appropriate security.
+ *@param userAccessTokens are a set of tokens to use to construct the filter (presumably from mod_authz_annotate, upstream)
*@return the wrapped query enforcing ManifoldCF security.
*/
- public Query wrapQuery(Query userQuery, List<String> userAccessTokens)
- throws QueryModifierException
+ public FilterBuilder buildAuthorizationFilter(List<String> userAccessTokens)
+ throws AuthorizerException
{
- BooleanQuery bq = new BooleanQuery();
+ BoolFilterBuilder bq = new BoolFilterBuilder();
- Query allowShareOpen = new TermQuery(new Term(fieldAllowShare,NOSECURITY_TOKEN));
- Query denyShareOpen = new TermQuery(new Term(fieldDenyShare,NOSECURITY_TOKEN));
- Query allowDocumentOpen = new TermQuery(new Term(fieldAllowDocument,NOSECURITY_TOKEN));
- Query denyDocumentOpen = new TermQuery(new Term(fieldDenyDocument,NOSECURITY_TOKEN));
+ FilterBuilder allowShareOpen = new TermFilterBuilder(fieldAllowShare,NOSECURITY_TOKEN);
+ FilterBuilder denyShareOpen = new TermFilterBuilder(fieldDenyShare,NOSECURITY_TOKEN);
+ FilterBuilder allowDocumentOpen = new TermFilterBuilder(fieldAllowDocument,NOSECURITY_TOKEN);
+ FilterBuilder denyDocumentOpen = new TermFilterBuilder(fieldDenyDocument,NOSECURITY_TOKEN);
if (userAccessTokens == null || userAccessTokens.size() == 0)
{
@@ -155,52 +154,47 @@
// (fieldAllowShare is empty AND fieldDenyShare is empty AND fieldAllowDocument is empty AND fieldDenyDocument is empty)
// We're trying to map to: -(fieldAllowShare:*) , which should be pretty efficient in Solr because it is negated. If this turns out not to be so, then we should
// have the SolrConnector inject a special token into these fields when they otherwise would be empty, and we can trivially match on that token.
- bq.add(allowShareOpen,BooleanClause.Occur.MUST);
- bq.add(denyShareOpen,BooleanClause.Occur.MUST);
- bq.add(allowDocumentOpen,BooleanClause.Occur.MUST);
- bq.add(denyDocumentOpen,BooleanClause.Occur.MUST);
+ bq.must(allowShareOpen);
+ bq.must(denyShareOpen);
+ bq.must(allowDocumentOpen);
+ bq.must(denyDocumentOpen);
}
else
{
// Extend the query appropriately for each user access token.
- bq.add(calculateCompleteSubquery(fieldAllowShare,fieldDenyShare,allowShareOpen,denyShareOpen,userAccessTokens),
- BooleanClause.Occur.MUST);
- bq.add(calculateCompleteSubquery(fieldAllowDocument,fieldDenyDocument,allowDocumentOpen,denyDocumentOpen,userAccessTokens),
- BooleanClause.Occur.MUST);
+ bq.must(calculateCompleteSubquery(fieldAllowShare,fieldDenyShare,allowShareOpen,denyShareOpen,userAccessTokens));
+ bq.must(calculateCompleteSubquery(fieldAllowDocument,fieldDenyDocument,allowDocumentOpen,denyDocumentOpen,userAccessTokens));
}
- // Concatenate with the user's original query.
- BooleanQuery rval = new BooleanQuery();
- rval.add(new ConstantScoreQuery(bq),BooleanClause.Occur.MUST);
- rval.add(userQuery,BooleanClause.Occur.MUST);
- return rval;
+ return bq;
}
/** Calculate a complete subclause, representing something like:
* ((fieldAllowShare is empty AND fieldDenyShare is empty) OR fieldAllowShare HAS token1 OR fieldAllowShare HAS token2 ...)
* AND fieldDenyShare DOESN'T_HAVE token1 AND fieldDenyShare DOESN'T_HAVE token2 ...
*/
- protected static Query calculateCompleteSubquery(String allowField, String denyField, Query allowOpen, Query denyOpen, List<String> userAccessTokens)
+ protected static FilterBuilder calculateCompleteSubquery(String allowField, String denyField, FilterBuilder allowOpen, FilterBuilder denyOpen, List<String> userAccessTokens)
{
- BooleanQuery bq = new BooleanQuery();
- bq.setMaxClauseCount(1000000);
+ BoolFilterBuilder bq = new BoolFilterBuilder();
+ // No ES equivalent - hope this is done right inside
+ //bq.setMaxClauseCount(1000000);
// Add the empty-acl case
- BooleanQuery subUnprotectedClause = new BooleanQuery();
- subUnprotectedClause.add(allowOpen,BooleanClause.Occur.MUST);
- subUnprotectedClause.add(denyOpen,BooleanClause.Occur.MUST);
- bq.add(subUnprotectedClause,BooleanClause.Occur.SHOULD);
+ BoolFilterBuilder subUnprotectedClause = new BoolFilterBuilder();
+ subUnprotectedClause.must(allowOpen);
+ subUnprotectedClause.must(denyOpen);
+ bq.should(subUnprotectedClause);
for (String accessToken : userAccessTokens)
{
- bq.add(new TermQuery(new Term(allowField,accessToken)),BooleanClause.Occur.SHOULD);
- bq.add(new TermQuery(new Term(denyField,accessToken)),BooleanClause.Occur.MUST_NOT);
+ bq.should(new TermFilterBuilder(allowField,accessToken));
+ bq.mustNot(new TermFilterBuilder(denyField,accessToken));
}
return bq;
}
/** Get access tokens given a username */
protected List<String> getAccessTokens(String authenticatedUserName)
- throws QueryModifierException
+ throws AuthorizerException
{
try
{
@@ -213,7 +207,7 @@
if (rval != 200)
{
String response = EntityUtils.toString(httpResponse.getEntity(),"utf-8");
- throw new QueryModifierException("Couldn't fetch user's access tokens from ManifoldCF authority service: "+Integer.toString(rval)+"; "+response);
+ throw new AuthorizerException("Couldn't fetch user's access tokens from ManifoldCF authority service: "+Integer.toString(rval)+"; "+response);
}
InputStream is = httpResponse.getEntity().getContent();
try
@@ -268,7 +262,7 @@
}
catch (IOException e)
{
- throw new QueryModifierException("IO exception: "+e.getMessage(),e);
+ throw new AuthorizerException("IO exception: "+e.getMessage(),e);
}
}