/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.server.rpc;

import com.google.gwt.user.client.rpc.RpcTokenException;
import com.google.gwt.user.client.rpc.XsrfToken;
import com.google.gwt.user.client.rpc.XsrfTokenService;
import com.google.gwt.user.server.Util;
import com.google.gwt.util.tools.Utility;

import javax.servlet.http.Cookie;

/**
 * EXPERIMENTAL and subject to change. Do not use this in production code.
 * <p>
 *
 * </p>
 * RPC service to generate XSRF tokens.
 * <p>
 * Sample use of {@link XsrfTokenService}:
 *
 * <ol>
 * <li> Add {@link XsrfTokenServiceServlet} to {@code web.xml}:
 *
 * <pre>
 * &lt;servlet&gt;
 *   &lt;servlet-name&gt;xsrf&lt;/servlet-name&gt;
 *   &lt;servlet-class&gt;
 *     com.google.gwt.user.server.rpc.XsrfTokenServiceServlet
 *   &lt;/servlet-class&gt;
 * &lt;/servlet&gt;
 * &lt;servlet-mapping&gt;
 *   &lt;servlet-name&gt;xsrf&lt;/servlet-name&gt;
 *   &lt;url-pattern&gt;/gwt/xsrf&lt;/url-pattern&gt;
 * &lt;/servlet-mapping&gt;
 * </pre>
 *
 * <li> Specify session cookie name that is used for authentication. MD5 hash of
 * the session cookie's value will be used as an XSRF token:
 *
 * <pre>
 * &lt;context-param&gt;
 *   &lt;param-name&gt;gwt.xsrf.session_cookie_name&lt;/param-name&gt;
 *   &lt;param-value>JSESSIONID&lt;/param-value&gt;
 * &lt;/context-param&gt;
 * </pre>
 *
 * <li> To enforce XSRF token validation on each method call either mark RPC
 * interface as XSRF protected using {@link XsrfProtect} annotation or extend
 * {@link com.google.gwt.user.client.rpc.XsrfProtectedService} instead of
 * RemoteService. Use {@link NoXsrfProtect} to mark methods as not requiring
 * XSRF protection:
 *
 * <pre class="code">
 * public interface MyRpcService extends XsrfProtectedService {
 *   public void doStuff();
 * }
 * </pre>
 *
 * <li> Ensure that RPC's servlet implementation extends {@link
 * XsrfProtectedServiceServlet} instead of {@link RemoteServiceServlet}:
 *
 * <pre class="code">
 * public class MyRpcServiceServlet extends XsrfProtectedServiceServlet
 *     implements MyRpcService {
 *
 *   public void doStuff() {
 *     // ...
 *   }
 * }
 * </pre>
 *
 * <li> Obtain {@link XsrfToken} and set it on the RPC end point:
 *
 * <pre class="code">
 * XsrfTokenServiceAsync xsrf = (XsrfTokenServiceAsync)GWT.create(XsrfTokenService.class);
 *
 * ((ServiceDefTarget)xsrf).setServiceEntryPoint(GWT.getModuleBaseURL() + "xsrf");
 *
 * xsrf.getNewXsrfToken(new AsyncCallback&lt;XsrfToken&gt;() {
 *   public void onSuccess(XsrfToken result) {
 *     MyRpcServiceAsync rpc = (MyRpcServiceAsync)GWT.create(MyRpcService.class);
 *     ((HasRpcToken) rpc).setRpcToken(result);
 *     // make XSRF protection RPC calls using
 *     rpc.doStuff(new AsyncCallback&lt;Void&gt;() {
 *       // ...
 *     });
 *
 *   }
 *
 *   public void onFailure(Throwable caught) {
 *     try {
 *       throw caught;
 *     } catch (RpcTokenException e) {
 *       // Can be thrown for several reasons:
 *       //   - duplicate session cookie, which may be a sign of a cookie
 *       //     overwrite attack
 *       //   - XSRF token cannot be generated because session cookie isn't
 *       //     present
 *     } catch (Throwable e) {
 *       // unexpected
 *     }
 * });
 * </pre>
 * </ol>
 * </p>
 *
 * @see XsrfProtectedServiceServlet
 * @see XsrfProtect
 * @see NoXsrfProtect
 */
public class XsrfTokenServiceServlet extends RemoteServiceServlet
    implements XsrfTokenService {

  /**
   * Session cookie name initialization parameter.
   */
  public static final String COOKIE_NAME_PARAM =
    "gwt.xsrf.session_cookie_name";

  static final String COOKIE_NAME_NOT_SET_ERROR_MSG =
      "Session cookie name not set! Use '" + COOKIE_NAME_PARAM +
      "' context-param to specify session cookie name";

  /**
   * Session cookie name. Cookie's value is used to generate XSRF cookie.
   */
  private String sessionCookieName = null;

  /**
   * Default constructor.
   */
  public XsrfTokenServiceServlet() {
    this(null);
  }

  /**
   * Alternative constructor that accepts session cookie name instead of getting
   * it from {@link javax.servlet.ServletConfig} or {@link
   * javax.servlet.ServletContext}.
   */
  public XsrfTokenServiceServlet(String sessionCookieName) {
    this.sessionCookieName = sessionCookieName;
  }

  /**
   * Generates and returns new XSRF token.
   */
  public XsrfToken getNewXsrfToken() {
    return new XsrfToken(generateTokenValue());
  }

  /**
   * Servlet initialization.
   */
  @Override
  public void init() {
    // do not overwrite values set via constructor
    if (sessionCookieName == null) {
      sessionCookieName = getInitParameterValue(COOKIE_NAME_PARAM);
    }
    if (sessionCookieName == null) {
      throw new IllegalStateException(COOKIE_NAME_NOT_SET_ERROR_MSG);
    }
  }

  /**
   * Generates new XSRF token.
   *
   * @return session cookie MD5 hash.
   */
  private String generateTokenValue() {
    if (sessionCookieName == null) {
      throw new IllegalStateException(COOKIE_NAME_NOT_SET_ERROR_MSG);
    }
    // generate XSRF cookie using session cookie
    Cookie sessionCookie = Util.getCookie(getThreadLocalRequest(),
        sessionCookieName, false);
    if (sessionCookie == null || sessionCookie.getValue() == null ||
        sessionCookie.getValue().length() == 0) {
      throw new RpcTokenException("Session cookie is not set or empty! " +
          "Unable to generate XSRF cookie");
    }
    byte[] cookieBytes =  sessionCookie.getValue().getBytes();
    return Utility.toHexString(Utility.getMd5Digest(cookieBytes));
  }

  /**
   * Retrieves and returns specified initialization parameter first from
   * {@link ServletConfig} followed by {@link ServletContext}, if former returns
   * {@code null}.
   */
  private String getInitParameterValue(String name) {
    String paramValue = null;
    paramValue = getServletConfig().getInitParameter(name);
    if (paramValue == null) {
      paramValue = getServletContext().getInitParameter(name);
    }
    return paramValue;
  }
}
