public void prepare()

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 bq = new BooleanQuery();
    //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));
  }