Add ability to handle multiple user domains

git-svn-id: https://svn.apache.org/repos/asf/manifoldcf/integration/solr-3.x/trunk@1536506 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/mcf/src/java/org/apache/solr/mcf/ManifoldCFQParserPlugin.java b/mcf/src/java/org/apache/solr/mcf/ManifoldCFQParserPlugin.java
index 133b75b..113991b 100644
--- a/mcf/src/java/org/apache/solr/mcf/ManifoldCFQParserPlugin.java
+++ b/mcf/src/java/org/apache/solr/mcf/ManifoldCFQParserPlugin.java
@@ -53,8 +53,15 @@
 {
   /** The component name */
   static final public String COMPONENT_NAME = "mcf";
-  /** The parameter that is supposed to contain the authenticated user name, possibly including the domain */
+  /** The parameter that is supposed to contain the authenticated user name, possibly including the AD domain */
   static final public String AUTHENTICATED_USER_NAME = "AuthenticatedUserName";
+  /** The parameter that is supposed to contain the MCF authorization domain, if any */
+  static final public String AUTHENTICATED_USER_DOMAIN = "AuthenticatedUserDomain";
+  /** If there are more than one user/domain, this prefix will allow us to get the users... */
+  static final public String AUTHENTICATED_USER_NAME_PREFIX = "AuthenticatedUserName_";
+  /** If there are more than one user/domain, this prefix will allow us to get the authorization domains... */
+  static final public String AUTHENTICATED_USER_DOMAIN_PREFIX = "AuthenticatedUserDomain_";
+  
   /** This parameter is an array of strings, which contain the tokens to use if there is no authenticated user name.
    * It's meant to work with mod_authz_annotate,
    * running under Apache */
@@ -151,11 +158,36 @@
 
       List<String> userAccessTokens;
       
+      // Map from domain to user
+      Map<String,String> domainMap = new HashMap<String,String>();
+      
       // 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+i);
+          if (userName == null)
+            break;
+          if (domain == null)
+            domain = "";
+          domainMap.put(domain,userName);
+        }
+      }
       
       // If this parameter is empty or does not exist, we have to presume this is a guest, and treat them accordingly
-      if (authenticatedUserName == null || authenticatedUserName.length() == 0)
+      if (domainMap.size() == 0)
       {
         // No authenticated user name.
         // mod_authz_annotate may be in use upstream, so look for tokens from it.
@@ -178,7 +210,18 @@
       }
       else
       {
-        LOG.info("Trying to match docs for user '"+authenticatedUserName+"'");
+        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)
@@ -187,7 +230,7 @@
         }
         try
         {
-          userAccessTokens = getAccessTokens(authenticatedUserName);
+          userAccessTokens = getAccessTokens(domainMap);
         }
         catch (IOException e)
         {
@@ -253,11 +296,27 @@
     // Protected methods
     
     /** Get access tokens given a username */
-    protected List<String> getAccessTokens(String authenticatedUserName)
+    protected List<String> getAccessTokens(Map<String,String> domainMap)
       throws IOException
     {
       // We can make this more complicated later, with support for https etc., but this is enough to demonstrate how it all should work.
-      String theURL = authorityBaseURL + "/UserACLs?username="+URLEncoder.encode(authenticatedUserName,"utf-8");
+      StringBuilder urlBuffer = new StringBuilder(authorityBaseURL);
+      urlBuffer.append("/UserACLs");
+      int i = 0;
+      for (String domain : domainMap.keySet())
+      {
+        if (i = 0)
+        {
+          urlBuffer.append("?");
+          first = false;
+        }
+        else
+          urlBuffer.append("&");
+        urlBuffer.append("username_").append(Integer.toString(i)).append("=").append(URLEncoder.encode(domainMap.get(domain),"utf-8")).append("&")
+          .append("domain_").append(Integer.toString(i)).append("=").append(URLEncoder.encode(domain,"utf-8"));
+        i++;
+      }
+      String theURL = urlBuffer.toString();
         
       GetMethod method = new GetMethod(theURL);
       try
diff --git a/mcf/src/java/org/apache/solr/mcf/ManifoldCFSearchComponent.java b/mcf/src/java/org/apache/solr/mcf/ManifoldCFSearchComponent.java
index 65d8e07..fe057c2 100644
--- a/mcf/src/java/org/apache/solr/mcf/ManifoldCFSearchComponent.java
+++ b/mcf/src/java/org/apache/solr/mcf/ManifoldCFSearchComponent.java
@@ -45,8 +45,15 @@
 {
   /** The component name */
   static final public String COMPONENT_NAME = "mcf";
-  /** The parameter that is supposed to contain the authenticated user name, possibly including the domain */
+  /** The parameter that is supposed to contain the authenticated user name, possibly including the AD domain */
   static final public String AUTHENTICATED_USER_NAME = "AuthenticatedUserName";
+  /** The parameter that is supposed to contain the MCF authorization domain, if any */
+  static final public String AUTHENTICATED_USER_DOMAIN = "AuthenticatedUserDomain";
+  /** If there are more than one user/domain, this prefix will allow us to get the users... */
+  static final public String AUTHENTICATED_USER_NAME_PREFIX = "AuthenticatedUserName_";
+  /** If there are more than one user/domain, this prefix will allow us to get the authorization domains... */
+  static final public String AUTHENTICATED_USER_DOMAIN_PREFIX = "AuthenticatedUserDomain_";
+  
   /** This parameter is an array of strings, which contain the tokens to use if there is no authenticated user name.
    * It's meant to work with mod_authz_annotate,
    * running under Apache */
@@ -127,7 +134,7 @@
     
     // Log that we got here
     //LOG.info("prepare() entry params:\n" + params + "\ncontext: " + rb.req.getContext());
-		
+                
     String qry = (String)params.get(CommonParams.Q);
     if (qry != null)
     {
@@ -142,11 +149,36 @@
 
     List<String> userAccessTokens;
     
+    // Map from domain to user
+    Map<String,String> domainMap = new HashMap<String,String>();
+      
     // 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+i);
+        if (userName == null)
+          break;
+        if (domain == null)
+          domain = "";
+        domainMap.put(domain,userName);
+      }
+    }
+      
     // If this parameter is empty or does not exist, we have to presume this is a guest, and treat them accordingly
-    if (authenticatedUserName == null || authenticatedUserName.length() == 0)
+    if (domainMap.size() == 0)
     {
       // No authenticated user name.
       // mod_authz_annotate may be in use upstream, so look for tokens from it.
@@ -169,14 +201,25 @@
     }
     else
     {
-      LOG.info("Trying to match docs for user '"+authenticatedUserName+"'");
+      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(authenticatedUserName);
+      userAccessTokens = getAccessTokens(domainMap);
     }
 
     BooleanQuery bq = new BooleanQuery();
@@ -281,11 +324,27 @@
   // Protected methods
   
   /** Get access tokens given a username */
-  protected List<String> getAccessTokens(String authenticatedUserName)
+  protected List<String> getAccessTokens(Map<String,String> domainMap)
     throws IOException
   {
     // We can make this more complicated later, with support for https etc., but this is enough to demonstrate how it all should work.
-    String theURL = authorityBaseURL + "/UserACLs?username="+URLEncoder.encode(authenticatedUserName,"utf-8");
+    StringBuilder urlBuffer = new StringBuilder(authorityBaseURL);
+    urlBuffer.append("/UserACLs");
+    int i = 0;
+    for (String domain : domainMap.keySet())
+    {
+      if (i = 0)
+      {
+        urlBuffer.append("?");
+        first = false;
+      }
+      else
+        urlBuffer.append("&");
+      urlBuffer.append("username_").append(Integer.toString(i)).append("=").append(URLEncoder.encode(domainMap.get(domain),"utf-8")).append("&")
+        .append("domain_").append(Integer.toString(i)).append("=").append(URLEncoder.encode(domain,"utf-8"));
+      i++;
+    }
+    String theURL = urlBuffer.toString();
       
     GetMethod method = new GetMethod(theURL);
     try