/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.rt.server;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.scout.commons.Base64Utility;
import org.eclipse.scout.commons.EncryptionUtility;
import org.eclipse.scout.commons.SoapHandlingUtility;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.commons.security.SimplePrincipal;
import org.eclipse.scout.http.servletfilter.FilterConfigInjection;
import org.eclipse.scout.http.servletfilter.security.SecureHttpServletRequestWrapper;
import org.eclipse.scout.rt.server.internal.Activator;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Transformation filter used to create a subject based on the soap headers containing a virtual request (from ajax,
 * rap)
 * <p>
 * If there is already a subject set as {@link Subject#getSubject(java.security.AccessControlContext)} then the filter
 * is transparent.
 * <p>
 * Reads the soap wsse header and transforms it to a subject with the user principal. The password is the triple-des
 * encoding of "${timestamp}:${username}" using the config.ini parameter <code>scout.ajax.token.key</code>
 * <p>
 * Normally this filters the alias /ajax
 * <p>
 * This filter is registered in the scout server plugin.xml as /ajax by default with order 1'000'010 and has the active
 * flag set to true
 */
public class SoapWsseJaasFilter implements Filter {
  private static final IScoutLogger LOG = ScoutLogManager.getLogger(SoapWsseJaasFilter.class);

  private static final byte[] tripleDesKey;
  static {
    String key = Activator.getDefault().getBundle().getBundleContext().getProperty("scout.ajax.token.key");
    if (key == null) {
      tripleDesKey = null;
    }
    else {
      tripleDesKey = new byte[24];
      byte[] keyBytes;
      try {
        keyBytes = key.getBytes("UTF-8");
        System.arraycopy(keyBytes, 0, tripleDesKey, 0, Math.min(keyBytes.length, tripleDesKey.length));
      }
      catch (UnsupportedEncodingException e) {
        LOG.error("reading property 'scout.ajax.token.key'", e);
      }
    }
  }

  private SAXParserFactory m_saxParserFactory;
  private FilterConfigInjection m_injection;

  @Override
  public void init(FilterConfig config0) throws ServletException {
    m_injection = new FilterConfigInjection(config0, getClass());
    try {
      m_saxParserFactory = SoapHandlingUtility.createSaxParserFactory();
    }
    catch (Exception e) {
      throw new ServletException(e);
    }
  }

  @Override
  public void destroy() {
    m_saxParserFactory = null;
    m_injection = null;
  }

  @Override
  public void doFilter(ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
    if (isSubjectSet()) {
      chain.doFilter(request, response);
      return;
    }
    FilterConfigInjection.FilterConfig config = m_injection.getConfig(request);
    if (!config.isActive()) {
      chain.doFilter(request, response);
      return;
    }

    InputStream httpIn = request.getInputStream();
    ByteArrayOutputStream cacheOut = new ByteArrayOutputStream();
    Subject subject;
    try {
      subject = parseSubject(httpIn, cacheOut);
    }
    catch (Throwable t) {
      LOG.warn("WS-Security check", t);
      ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
      return;
    }
    final InputStream cacheIn = new ByteArrayInputStream(cacheOut.toByteArray());
    cacheOut = null;
    //
    final HttpServletRequestWrapper replayRequest = new HttpServletRequestWrapper((HttpServletRequest) request) {
      @Override
      public ServletInputStream getInputStream() throws IOException {
        return new ServletInputStream() {
          @Override
          public int read() throws IOException {
            return cacheIn.read();
          }
        };
      }
    };
    continueChainWithPrincipal(subject, replayRequest, (HttpServletResponse) response, chain);
  }

  private void continueChainWithPrincipal(Subject subject, final HttpServletRequest req, final HttpServletResponse res, final FilterChain chain) throws IOException, ServletException {
    try {
      Subject.doAs(
          subject,
          new PrivilegedExceptionAction<Object>() {
            @Override
            public Object run() throws Exception {
              Principal principal = Subject.getSubject(AccessController.getContext()).getPrincipals().iterator().next();
              HttpServletRequest secureReq = new SecureHttpServletRequestWrapper(req, principal);
              chain.doFilter(secureReq, res);
              return null;
            }
          }
          );
    }
    catch (PrivilegedActionException e) {
      Throwable t = e.getCause();
      if (t instanceof IOException) {
        throw (IOException) t;
      }
      else if (t instanceof ServletException) {
        throw (ServletException) t;
      }
      else {
        throw new ServletException(t);
      }
    }
  }

  protected Subject parseSubject(final InputStream httpIn, final ByteArrayOutputStream cacheOut) throws Exception {
    InputStream filterIn = new InputStream() {
      @Override
      public int read() throws IOException {
        int ch = httpIn.read();
        if (ch < 0) {
          return ch;
        }
        cacheOut.write(ch);
        return ch;
      }

      @Override
      public int read(byte[] b) throws IOException {
        int n = httpIn.read(b);
        if (n <= 0) {
          return n;
        }
        cacheOut.write(b, 0, n);
        return n;
      }

      @Override
      public int read(byte[] b, int off, int len) throws IOException {
        int n = httpIn.read(b, off, len);
        if (n <= 0) {
          return n;
        }
        cacheOut.write(b, off, n);
        return n;
      }
    };
    WSSEUserTokenHandler handler = new WSSEUserTokenHandler();
    SoapHandlingUtility.createSaxParser(m_saxParserFactory).parse(new InputSource(filterIn), handler);
    return createSubject(cleanString(handler.user), cleanString(handler.tokenRaw), cleanString(handler.tokenEncoding));
  }

  /**
   * override this method to do additional checks on credentials
   */
  protected Subject createSubject(String user, String tokenRaw, String tokenEncoding) throws Exception {
    if (user == null || tokenRaw == null) {
      LOG.error("Ajax back-end call contains no ws-security token. Check if the config.ini of the /rap and the /ajax webapp contains the property 'scout.ajax.token.key'.");
      throw new SecurityException("SOAP header contains no ws-security token");
    }
    byte[] token = Base64Utility.decode(tokenRaw);
    String msg = new String(EncryptionUtility.decrypt(token, tripleDesKey), "UTF-8");
    String[] tupel = msg.split(":", 2);
    long timestamp = Long.parseLong(tupel[0]);
    String userRef = tupel[1];
    if (timestamp < 0L || userRef == null || !userRef.equals(user)) {
      throw new SecurityException("SOAP header contains no ws-security token");
    }
    Subject subject = new Subject();
    subject.getPrincipals().add(new SimplePrincipal(user));
    subject.setReadOnly();
    return subject;
  }

  private boolean isSubjectSet() {
    Subject subject = Subject.getSubject(AccessController.getContext());
    if (subject == null) {
      return false;
    }
    if (subject.getPrincipals().size() == 0) {
      return false;
    }
    String name = subject.getPrincipals().iterator().next().getName();
    if (name == null || name.trim().length() == 0) {
      return false;
    }
    return true;
  }

  private String cleanString(String s) {
    if (s == null) {
      return null;
    }
    s = s.trim();
    if (s.length() == 0) {
      return null;
    }
    if (s.equalsIgnoreCase("null")) {
      return null;
    }
    return s;
  }

  /**
   * <pre>
   * <wsse:Security soapenv:mustUnderstand="1">
   *   <wsse:UsernameToken>
   *     <wsse:Username>user</wsse:Username>
   *     <wsse:Password Type="http://...#Virtual">QDgxVkqYnuqk...==</wsse:Password>
   *   </wsse:UsernameToken>
   * </wsse:Security>
   * </pre>
   */
  private static class WSSEUserTokenHandler extends DefaultHandler {
    public String user;
    public String tokenEncoding;
    public String tokenRaw;
    //
    private boolean insideEnvelope;
    private boolean insideHeader;
    private boolean insideSecurity;
    private boolean insideUsernameToken;
    private boolean insideUsername;
    private boolean insidePasswort;
    private boolean done;

    @Override
    public void startElement(String namespaceURI, String localName, String qNameText, Attributes attributes) throws SAXException {
      if (done) {
        return;
      }
      QName qname = new QName(namespaceURI, localName);
      if (SoapHandlingUtility.SOAPENV_ENVELOPE_ELEMENT.equals(qname)) {
        insideEnvelope = true;
        return;
      }
      if (SoapHandlingUtility.SOAPENV_HEADER_ELEMENT.equals(qname)) {
        insideHeader = true;
        return;
      }
      if (SoapHandlingUtility.WSSE_SECURITY_ELEMENT.equals(qname)) {
        insideSecurity = true;
        return;
      }
      if (SoapHandlingUtility.WSSE_USERNAME_TOKEN_ELEMENT.equals(qname)) {
        insideUsernameToken = true;
        return;
      }
      if (SoapHandlingUtility.WSSE_USERNAME_ELEMENT.equals(qname)) {
        insideUsername = true;
        return;
      }
      if (SoapHandlingUtility.WSSE_PASSWORD_ELEMENT.equals(qname)) {
        insidePasswort = true;
        tokenEncoding = attributes.getValue("", SoapHandlingUtility.WSSE_PASSWORD_TYPE_ATTRIBUTE);
        return;
      }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
      if (done) {
        return;
      }
      if (insideEnvelope && insideHeader && insideSecurity && insideUsernameToken) {
        if (insideUsername) {
          user = new String(ch, start, length);
        }
        if (insidePasswort) {
          tokenRaw = new String(ch, start, length);
        }
      }

    }

    @Override
    public void endElement(String namespaceURI, String localName, String qNameText) throws SAXException {
      if (done) {
        return;
      }
      QName qname = new QName(namespaceURI, localName);
      if (SoapHandlingUtility.SOAPENV_ENVELOPE_ELEMENT.equals(qname)) {
        insideEnvelope = false;
        done = true;
        return;
      }
      if (SoapHandlingUtility.SOAPENV_HEADER_ELEMENT.equals(qname)) {
        insideHeader = false;
        return;
      }
      if (SoapHandlingUtility.WSSE_SECURITY_ELEMENT.equals(qname)) {
        insideSecurity = false;
        return;
      }
      if (SoapHandlingUtility.WSSE_USERNAME_TOKEN_ELEMENT.equals(qname)) {
        insideUsernameToken = false;
        return;
      }
      if (SoapHandlingUtility.WSSE_USERNAME_ELEMENT.equals(qname)) {
        insideUsername = false;
        return;
      }
      if (SoapHandlingUtility.WSSE_PASSWORD_ELEMENT.equals(qname)) {
        insidePasswort = false;
        return;
      }
    }
  }
}
