in src/main/java/org/apache/solr/mcf/ManifoldCFSearchComponent.java [158:297]
public void prepare(ResponseBuilder rb) throws IOException
{
SolrParams params = rb.req.getParams();
if (!params.getBool(COMPONENT_NAME, true) || params.get(ShardParams.SHARDS) != null)
return;
// Log that we got here
//LOG.info("prepare() entry params:\n" + params + "\ncontext: " + rb.req.getContext());
String qry = params.get(CommonParams.Q);
if (qry != null)
{
//Check global allowed searches
for (String ga : globalAllowed)
{
if (qry.equalsIgnoreCase(ga.trim()))
// Allow this query through unchanged
return;
}
}
List<String> userAccessTokens;
// Map from domain to user
Map<String,String> domainMap = new HashMap<>();
// Get the authenticated user name from the parameters
String authenticatedUserName = params.get(AUTHENTICATED_USER_NAME);
if (authenticatedUserName != null)
{
String authenticatedUserDomain = params.get(AUTHENTICATED_USER_DOMAIN);
if (authenticatedUserDomain == null)
authenticatedUserDomain = "";
domainMap.put(authenticatedUserDomain, authenticatedUserName);
}
else
{
// Look for user names/domains using the prefix
int i = 0;
while (true)
{
String userName = params.get(AUTHENTICATED_USER_NAME_PREFIX+i);
String domain = params.get(AUTHENTICATED_USER_DOMAIN_PREFIX+i);
if (userName == null)
break;
if (domain == null)
domain = "";
domainMap.put(domain,userName);
i++;
}
}
// If this parameter is empty or does not exist, we have to presume this is a guest, and treat them accordingly
if (domainMap.size() == 0)
{
// No authenticated user name.
// mod_authz_annotate may be in use upstream, so look for tokens from it.
userAccessTokens = new ArrayList<>();
String[] passedTokens = params.getParams(USER_TOKENS);
if (passedTokens == null)
{
// Only return 'public' documents (those with no security tokens at all)
LOG.info("Default no-user response (open documents only)");
}
else
{
// Only return 'public' documents (those with no security tokens at all)
LOG.info("Group tokens received from caller");
userAccessTokens.addAll(Arrays.asList(passedTokens));
}
}
else
{
if(LOG.isInfoEnabled()){
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for (String domain : domainMap.keySet())
{
if (!first)
sb.append(",");
else
first = false;
sb.append(domain).append(":").append(domainMap.get(domain));
}
sb.append("]");
LOG.info("Trying to match docs for user '"+sb.toString()+"'");
}
// Valid authenticated user name. Look up access tokens for the user.
// Check the configuration arguments for validity
if (authorityBaseURL == null)
{
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error initializing ManifoldCFSecurityFilter component: 'AuthorityServiceBaseURL' init parameter required");
}
userAccessTokens = getAccessTokens(domainMap);
}
BooleanQuery.Builder bq = new BooleanQuery.Builder();
//bf.setMaxClauseCount(100000);
Query allowShareOpen = new TermQuery(new Term(fieldAllowShare,NOSECURITY_TOKEN));
Query denyShareOpen = new TermQuery(new Term(fieldDenyShare,NOSECURITY_TOKEN));
Query allowParentOpen = new TermQuery(new Term(fieldAllowParent,NOSECURITY_TOKEN));
Query denyParentOpen = new TermQuery(new Term(fieldDenyParent,NOSECURITY_TOKEN));
Query allowDocumentOpen = new TermQuery(new Term(fieldAllowDocument,NOSECURITY_TOKEN));
Query denyDocumentOpen = new TermQuery(new Term(fieldDenyDocument,NOSECURITY_TOKEN));
if (userAccessTokens.size() == 0)
{
// Only open documents can be included.
// That query is:
// (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(allowParentOpen,BooleanClause.Occur.MUST);
bq.add(denyParentOpen,BooleanClause.Occur.MUST);
bq.add(allowDocumentOpen,BooleanClause.Occur.MUST);
bq.add(denyDocumentOpen,BooleanClause.Occur.MUST);
}
else
{
// Extend the query appropriately for each user access token.
bq.add(calculateCompleteSubquery(fieldAllowShare,fieldDenyShare,allowShareOpen,denyShareOpen,userAccessTokens),
BooleanClause.Occur.MUST);
bq.add(calculateCompleteSubquery(fieldAllowParent,fieldDenyParent,allowParentOpen,denyParentOpen,userAccessTokens),
BooleanClause.Occur.MUST);
bq.add(calculateCompleteSubquery(fieldAllowDocument,fieldDenyDocument,allowDocumentOpen,denyDocumentOpen,userAccessTokens),
BooleanClause.Occur.MUST);
}
// Concatenate with the user's original query.
List<Query> list = rb.getFilters();
if (list == null)
{
list = new ArrayList<>();
rb.setFilters(list);
}
list.add(new ConstantScoreQuery(bq.build()));
}