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

// $Id: ClientLoginHandler.java,v 1.1.2.3 2005/04/12 16:07:45 starksm Exp $
package org.jboss.webservice.handler;

// $Id: ClientLoginHandler.java,v 1.1.2.3 2005/04/12 16:07:45 starksm Exp $

import org.jboss.axis.AxisFault;
import org.jboss.axis.MessageContext;
import org.jboss.axis.encoding.Base64;
import org.jboss.axis.handlers.BasicHandler;
import org.jboss.logging.Logger;
import org.jboss.security.SecurityAssociation;
import org.jboss.webservice.Constants;

import javax.xml.soap.Name;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import java.security.Principal;

/**
 * An Axis style handler that adds username/password as SOAP header elements.
 *
 * <soapenv:Header>
 *    <jbws:username actor="http://webservice.jboss.com/ws4ee/login" xmlns:jbws="http://webservice.jboss.com/ws4ee">kermit</jbws:username>
 *    <jbws:password actor="http://webservice.jboss.com/ws4ee/login" xmlns:jbws="http://webservice.jboss.com/ws4ee">thefrog</jbws:password>
 * </soapenv:Header>
 *
 * @author Thomas.Diesler@jboss.org
 * @since 27-April-2004
 */
public class ClientLoginHandler extends BasicHandler
{
   /** @since 4.0.2 */
   static final long serialVersionUID = -5105554242454628283L;

   // provide logging
   private static final Logger log = Logger.getLogger(ClientLoginHandler.class);

   /** Add the principal/credential from the MessageContext, if not given fall back to the SecurityAssociation.
    */
   public void invoke(MessageContext msgContext) throws AxisFault
   {
      String username = msgContext.getUsername();
      String password = msgContext.getPassword();

      if (username == null && password == null)
      {
         Principal principal = SecurityAssociation.getPrincipal();
         Object credential = SecurityAssociation.getCredential();

         if (principal != null)
            username = principal.getName();
         if (credential instanceof char[])
            password = new String((char[])credential);
         else if (credential != null)
            password = credential.toString();
      }

      if (username != null && password != null)
      {
         try
         {
            msgContext.setUsername(username);
            msgContext.setPassword(password);
            SOAPMessage soapMessage = msgContext.getMessage();
            SOAPHeader soapHeader = soapMessage.getSOAPPart().getEnvelope().getHeader();
            SOAPFactory soapFactory = SOAPFactory.newInstance();

            Name usrName = soapFactory.createName("username", "jbws", Constants.NAMESPACE);
            SOAPHeaderElement usrElement = soapHeader.addHeaderElement(usrName);
            usrElement.setActor(Constants.NAMESPACE + "/login");
            usrElement.addTextNode(username);

            password = Base64.encode(password.getBytes());

            Name pwdName = soapFactory.createName("password", "jbws", Constants.NAMESPACE);
            SOAPHeaderElement pwdElement = soapHeader.addHeaderElement(pwdName);
            pwdElement.setActor(Constants.NAMESPACE + "/login");
            pwdElement.addTextNode(password);
         }
         catch (SOAPException e)
         {
            log.error("Client login failed: " + e.toString());
            throw new AxisFault("Client login failed", e);
         }
      }
   }
}