/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.test.web.test;

import java.net.HttpURLConnection;

import junit.framework.Test;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.log4j.Category;
import org.jboss.test.JBossClusteredTestCase;


/** Tests of web app single sign-on in a clustered environment
 * 
 * @author Brian Stansberry
 * @version $Revision: 1.3.2.1 $
 */
public class ClusteredSingleSignOnUnitTestCase 
      extends JBossClusteredTestCase
{   
   public ClusteredSingleSignOnUnitTestCase(String name)
   {
      super(name);
   }

   /** One time setup for all ClusteredSingleSignOnUnitTestCase unit tests
    */
   public static Test suite() throws Exception
   {
      Test t1 = JBossClusteredTestCase.getDeploySetup(ClusteredSingleSignOnUnitTestCase.class,
            "web-sso.ear");
      return t1;
   }

   /** Test single sign-on across two web apps using form based auth
    * 
    * @throws Exception
    */ 
   public void testFormAuthSingleSignOn() throws Exception
   {
      log.info("+++ testFormAuthSingleSignOn");
      String[] httpURLs  = super.getHttpURLs();

      String serverA = httpURLs[0];
      String serverB = httpURLs[1];
      log.info(System.getProperties());
      log.info("serverA: "+serverA);
      log.info("serverB: "+serverB);
      SSOBaseCase.executeFormAuthSingleSignOnTest(serverA, serverB, getLog());
   }
   
   /** 
    * Tests that use of transactions in ClusteredSSO does not interfere 
    * with session expiration thread.  See JBAS-2212.
    * 
    * TODO  this is a quick-and-dirty test to get JBoss 4.0.3 out;
    *       clearly needs to be refactored
    * 
    * @throws Exception
    */ 
   public void testSessionExpiration() 
         throws Exception
   {
      log.info("+++ testFormAuthSingleSignOn");
      String[] httpURLs  = super.getHttpURLs();

      String serverA = httpURLs[0];
      log.info(System.getProperties());
      log.info("serverA: "+serverA);
      
      // Start by accessing the secured index.html of war1
      HttpClient httpConn = new HttpClient();
      GetMethod indexGet = new GetMethod(serverA+"/war3/index.html");
      int responseCode = httpConn.executeMethod(indexGet);
      String body = indexGet.getResponseBodyAsString();
      assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK);
      assertTrue("Redirected to login page", body.indexOf("j_security_check") > 0 );

      HttpState state = httpConn.getState();
      Cookie[] cookies = state.getCookies();
      String sessionID = null;
      for(int c = 0; c < cookies.length; c ++)
      {
         Cookie k = cookies[c];
         if( k.getName().equalsIgnoreCase("JSESSIONID") )
            sessionID = k.getValue();
      }
      log.debug("Saw JSESSIONID="+sessionID);

      // Submit the login form
      PostMethod formPost = new PostMethod(serverA+"/war3/j_security_check");
      formPost.addRequestHeader("Referer", serverA+"/war3/login.html");
      formPost.addParameter("j_username", "jduke");
      formPost.addParameter("j_password", "theduke");
      responseCode = httpConn.executeMethod(formPost.getHostConfiguration(),
         formPost, state);
      String response = formPost.getStatusText();
      log.debug("responseCode="+responseCode+", response="+response);
      assertTrue("Saw HTTP_MOVED_TEMP("+responseCode+")",
         responseCode == HttpURLConnection.HTTP_MOVED_TEMP);

      //  Follow the redirect to the index.html page
      Header location = formPost.getResponseHeader("Location");
      String indexURI = location.getValue();
      GetMethod war1Index = new GetMethod(indexURI);
      responseCode = httpConn.executeMethod(war1Index.getHostConfiguration(),
         war1Index, state);
      assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK);
      body = war1Index.getResponseBodyAsString();
      if( body.indexOf("j_security_check") > 0 )
         fail("get of "+indexURI+" redirected to login page");

      // Wait more than 1 minute to let session time out
      try {
         Thread.sleep(75000);
      }
      catch (InterruptedException ie)
      {
         log.debug("Interrupted while waiting for session expiration");
      }
      
      // Try accessing war1 again
      war1Index = new GetMethod(serverA+"/war3/index.html");
      responseCode = httpConn.executeMethod(war1Index.getHostConfiguration(),
         war1Index, state);
      assertTrue("Get OK", responseCode == HttpURLConnection.HTTP_OK);
      body = war1Index.getResponseBodyAsString();
      log.debug("body: " + body);
      if( body.indexOf("j_security_check") < 0 )
         fail("get of /war1/index.html not redirected to login page");
      
   }
}
