Remove auth token based REST API support

This never turned into a real implementation. Drop it and
look at other ways to do authentication.

Change-Id: I404c834e5e9d0d61248d28471785d825c136f3ad
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/RestApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/RestApi.java
index 650cacd..35aea60 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/RestApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/RestApi.java
@@ -44,11 +44,9 @@
 
   private class MyRequestCallback<T extends JavaScriptObject> implements
       RequestCallback {
-    private final boolean wasGet;
     private final AsyncCallback<T> cb;
 
-    public MyRequestCallback(boolean wasGet, AsyncCallback<T> cb) {
-      this.wasGet = wasGet;
+    MyRequestCallback(AsyncCallback<T> cb) {
       this.cb = cb;
     }
 
@@ -79,11 +77,6 @@
       }
       json = json.substring(JSON_MAGIC.length());
 
-      if (wasGet && json.startsWith("{\"_authkey\":")) {
-        RestApi.this.resendPost(cb, json);
-        return;
-      }
-
       T data;
       try {
         // javac generics bug
@@ -168,7 +161,7 @@
   public <T extends JavaScriptObject> void send(final AsyncCallback<T> cb) {
     RequestBuilder req = new RequestBuilder(RequestBuilder.GET, url.toString());
     req.setHeader("Accept", JsonConstants.JSON_TYPE);
-    req.setCallback(new MyRequestCallback<T>(true, cb));
+    req.setCallback(new MyRequestCallback<T>(cb));
     try {
       RpcStatus.INSTANCE.onRpcStart();
       req.send();
@@ -178,21 +171,6 @@
     }
   }
 
-  private <T extends JavaScriptObject> void resendPost(
-      final AsyncCallback<T> cb, String token) {
-    RequestBuilder req = new RequestBuilder(RequestBuilder.POST, url.toString());
-    req.setHeader("Accept", JsonConstants.JSON_TYPE);
-    req.setHeader("Content-Type", JsonConstants.JSON_TYPE);
-    req.setRequestData(token);
-    req.setCallback(new MyRequestCallback<T>(false, cb));
-    try {
-      req.send();
-    } catch (RequestException e) {
-      RpcStatus.INSTANCE.onRpcComplete();
-      cb.onFailure(e);
-    }
-  }
-
   private static boolean isJsonBody(Response res) {
     return isContentType(res, JsonConstants.JSON_TYPE);
   }
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestTokenVerifier.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestTokenVerifier.java
deleted file mode 100644
index 783ebc7..0000000
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestTokenVerifier.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (C) 2012 The Android Open Source Project
-//
-// 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.gerrit.httpd;
-
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.server.mail.RegisterNewEmailSender;
-
-/** Verifies the token sent by {@link RegisterNewEmailSender}. */
-public interface RestTokenVerifier {
-  /**
-   * Construct a token to verify a REST PUT request.
-   *
-   * @param user the caller that wants to make a PUT request
-   * @param url the URL being requested
-   * @return an unforgeable string to send to the user as the body of a GET
-   *         request. Presenting the string in a follow-up POST request provides
-   *         proof the user has the ability to read messages sent to thier
-   *         browser and they likely aren't making the request via XSRF.
-   */
-  public String sign(Account.Id user, String url);
-
-  /**
-   * Decode a token previously created.
-   *
-   * @param user the user making the verify request.
-   * @param url the url user is attempting to access.
-   * @param token the string created by sign.
-   * @throws InvalidTokenException the token is invalid, expired, malformed,
-   *         etc.
-   */
-  public void verify(Account.Id user, String url, String token)
-      throws InvalidTokenException;
-
-  /** Exception thrown when a token does not parse correctly. */
-  public static class InvalidTokenException extends Exception {
-    private static final long serialVersionUID = 1L;
-
-    public InvalidTokenException() {
-      super("Invalid token");
-    }
-
-    public InvalidTokenException(Throwable cause) {
-      super("Invalid token", cause);
-    }
-  }
-}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/SignedTokenRestTokenVerifier.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/SignedTokenRestTokenVerifier.java
deleted file mode 100644
index 83d6caa..0000000
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/SignedTokenRestTokenVerifier.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (C) 2012 The Android Open Source Project
-//
-// 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.gerrit.httpd;
-
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.server.config.AuthConfig;
-import com.google.gwtjsonrpc.server.SignedToken;
-import com.google.gwtjsonrpc.server.ValidToken;
-import com.google.gwtjsonrpc.server.XsrfException;
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-
-import org.eclipse.jgit.util.Base64;
-
-import java.io.UnsupportedEncodingException;
-
-/** Verifies the token sent by {@link RestApiServlet}. */
-public class SignedTokenRestTokenVerifier implements RestTokenVerifier {
-  private final SignedToken restToken;
-
-  public static class Module extends AbstractModule {
-    @Override
-    protected void configure() {
-      bind(RestTokenVerifier.class).to(SignedTokenRestTokenVerifier.class);
-    }
-  }
-
-  @Inject
-  SignedTokenRestTokenVerifier(AuthConfig config) {
-    restToken = config.getRestToken();
-  }
-
-  @Override
-  public String sign(Account.Id user, String url) {
-    try {
-      String payload = String.format("%s:%s", user, url);
-      byte[] utf8 = payload.getBytes("UTF-8");
-      String base64 = Base64.encodeBytes(utf8);
-      return restToken.newToken(base64);
-    } catch (XsrfException e) {
-      throw new IllegalArgumentException(e);
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  @Override
-  public void verify(Account.Id user, String url, String tokenString)
-      throws InvalidTokenException {
-    ValidToken token;
-    try {
-      token = restToken.checkToken(tokenString, null);
-    } catch (XsrfException err) {
-      throw new InvalidTokenException(err);
-    }
-    if (token == null || token.getData() == null || token.getData().isEmpty()) {
-      throw new InvalidTokenException();
-    }
-
-    String payload;
-    try {
-      payload = new String(Base64.decode(token.getData()), "UTF-8");
-    } catch (UnsupportedEncodingException err) {
-      throw new InvalidTokenException(err);
-    }
-
-    int colonPos = payload.indexOf(':');
-    if (colonPos == -1) {
-      throw new InvalidTokenException();
-    }
-
-    Account.Id tokenUser;
-    try {
-      tokenUser = Account.Id.parse(payload.substring(0, colonPos));
-    } catch (IllegalArgumentException err) {
-      throw new InvalidTokenException(err);
-    }
-
-    String tokenUrl = payload.substring(colonPos+1);
-
-    if (!tokenUser.equals(user) || !tokenUrl.equals(url)) {
-      throw new InvalidTokenException();
-    }
-  }
-}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/TokenVerifiedRestApiServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/TokenVerifiedRestApiServlet.java
deleted file mode 100644
index 98a1b57..0000000
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/TokenVerifiedRestApiServlet.java
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright (C) 2012 The Android Open Source Project
-//
-// 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.gerrit.httpd;
-
-import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
-import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Maps;
-import com.google.gerrit.httpd.RestTokenVerifier.InvalidTokenException;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.OutputFormat;
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonParser;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.Enumeration;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-
-public abstract class TokenVerifiedRestApiServlet extends RestApiServlet {
-  private static final long serialVersionUID = 1L;
-  private static final String FORM_ENCODED = "application/x-www-form-urlencoded";
-  private static final String UTF_8 = "UTF-8";
-  private static final String AUTHKEY_NAME = "_authkey";
-  private static final String AUTHKEY_HEADER = "X-authkey";
-
-  private final Gson gson;
-  private final Provider<CurrentUser> userProvider;
-  private final RestTokenVerifier verifier;
-
-  @Inject
-  protected TokenVerifiedRestApiServlet(Provider<CurrentUser> userProvider,
-      RestTokenVerifier verifier) {
-    super(userProvider);
-    this.gson = OutputFormat.JSON_COMPACT.newGson();
-    this.userProvider = userProvider;
-    this.verifier = verifier;
-  }
-
-  /**
-   * Process the (possibly state changing) request.
-   *
-   * @param req incoming HTTP request.
-   * @param res outgoing response.
-   * @param requestData JSON object representing the HTTP request parameters.
-   *        Null if the request body was not supplied in JSON format.
-   * @throws IOException
-   * @throws ServletException
-   */
-  protected abstract void doRequest(HttpServletRequest req,
-      HttpServletResponse res,
-      @Nullable JsonObject requestData) throws IOException, ServletException;
-
-  @Override
-  protected final void doGet(HttpServletRequest req, HttpServletResponse res)
-      throws ServletException, IOException {
-    CurrentUser user = userProvider.get();
-    if (!(user instanceof IdentifiedUser)) {
-      sendError(res, SC_UNAUTHORIZED, "API requires authentication");
-      return;
-    }
-
-    TokenInfo info = new TokenInfo();
-    info._authkey = verifier.sign(
-        ((IdentifiedUser) user).getAccountId(),
-        computeUrl(req));
-
-    ByteArrayOutputStream buf = new ByteArrayOutputStream();
-    String type;
-    buf.write(JSON_MAGIC);
-    if (acceptsJson(req)) {
-      type = JSON_TYPE;
-      buf.write(gson.toJson(info).getBytes(UTF_8));
-    } else {
-      type = FORM_ENCODED;
-      buf.write(String.format("%s=%s",
-          AUTHKEY_NAME,
-          URLEncoder.encode(info._authkey, UTF_8)).getBytes(UTF_8));
-    }
-
-    res.setContentType(type);
-    res.setCharacterEncoding(UTF_8);
-    res.setHeader("Content-Disposition", "attachment");
-    send(req, res, buf.toByteArray());
-  }
-
-  @Override
-  protected final void doPost(HttpServletRequest req, HttpServletResponse res)
-      throws IOException, ServletException {
-    CurrentUser user = userProvider.get();
-    if (!(user instanceof IdentifiedUser)) {
-      sendError(res, SC_UNAUTHORIZED, "API requires authentication");
-      return;
-    }
-
-    ParsedBody body;
-    if (JSON_TYPE.equals(req.getContentType())) {
-      body = parseJson(req, res);
-    } else if (FORM_ENCODED.equals(req.getContentType())) {
-      body = parseForm(req, res);
-    } else {
-      sendError(res, SC_BAD_REQUEST, String.format(
-          "Expected Content-Type: %s or %s",
-          JSON_TYPE, FORM_ENCODED));
-      return;
-    }
-
-    if (body == null) {
-      return;
-    }
-
-    if (Strings.isNullOrEmpty(body._authkey)) {
-      String h = req.getHeader(AUTHKEY_HEADER);
-      if (Strings.isNullOrEmpty(h)) {
-        sendError(res, SC_BAD_REQUEST, String.format(
-            "Expected %s in request body or %s in HTTP headers",
-            AUTHKEY_NAME, AUTHKEY_HEADER));
-        return;
-      }
-      body._authkey = URLDecoder.decode(h, UTF_8);
-    }
-
-    try {
-      verifier.verify(
-          ((IdentifiedUser) user).getAccountId(),
-          computeUrl(req),
-          body._authkey);
-    } catch (InvalidTokenException err) {
-      sendError(res, SC_BAD_REQUEST,
-          String.format("Invalid or expired %s", AUTHKEY_NAME));
-      return;
-    }
-
-    doRequest(body.req, res, body.json);
-  }
-
-  private static ParsedBody parseJson(HttpServletRequest req,
-      HttpServletResponse res) throws IOException {
-    try {
-      JsonElement element = new JsonParser().parse(req.getReader());
-      if (!element.isJsonObject()) {
-        sendError(res, SC_BAD_REQUEST, "Expected JSON object in request body");
-        return null;
-      }
-
-      ParsedBody body = new ParsedBody();
-      body.req = req;
-      body.json = (JsonObject) element;
-      JsonElement authKey = body.json.remove(AUTHKEY_NAME);
-      if (authKey != null
-          && authKey.isJsonPrimitive()
-          && authKey.getAsJsonPrimitive().isString()) {
-        body._authkey = authKey.getAsString();
-      }
-      return body;
-    } catch (JsonParseException e) {
-      sendError(res, SC_BAD_REQUEST, "Invalid JSON object in request body");
-      return null;
-    }
-  }
-
-  private static ParsedBody parseForm(HttpServletRequest req,
-      HttpServletResponse res) throws IOException {
-    ParsedBody body = new ParsedBody();
-    body.req = new WrappedRequest(req);
-    body._authkey = req.getParameter(AUTHKEY_NAME);
-    return body;
-  }
-
-  private static String computeUrl(HttpServletRequest req) {
-    StringBuffer url = req.getRequestURL();
-    String qs = req.getQueryString();
-    if (!Strings.isNullOrEmpty(qs)) {
-      url.append('?').append(qs);
-    }
-    return url.toString();
-  }
-
-  private static class TokenInfo {
-    String _authkey;
-  }
-
-  private static class ParsedBody {
-    HttpServletRequest req;
-    String _authkey;
-    JsonObject json;
-  }
-
-  private static class WrappedRequest extends HttpServletRequestWrapper {
-    @SuppressWarnings("rawtypes")
-    private Map parameters;
-
-    WrappedRequest(HttpServletRequest req) {
-      super(req);
-    }
-
-    @Override
-    public String getParameter(String name) {
-      if (AUTHKEY_NAME.equals(name)) {
-        return null;
-      }
-      return super.getParameter(name);
-    }
-
-    @Override
-    public String[] getParameterValues(String name) {
-      if (AUTHKEY_NAME.equals(name)) {
-        return null;
-      }
-      return super.getParameterValues(name);
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    @Override
-    public Map getParameterMap() {
-      Map m = parameters;
-      if (m == null) {
-        m = super.getParameterMap();
-        if (m.containsKey(AUTHKEY_NAME)) {
-          m = Maps.newHashMap(m);
-          m.remove(AUTHKEY_NAME);
-        }
-        parameters = m;
-      }
-      return m;
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    @Override
-    public Enumeration getParameterNames() {
-      return Iterators.asEnumeration(getParameterMap().keySet().iterator());
-    }
-  }
-}
-
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index c164d48..7d27482 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -22,7 +22,6 @@
 import com.google.gerrit.httpd.GitOverHttpModule;
 import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider;
 import com.google.gerrit.httpd.RequestContextFilter;
-import com.google.gerrit.httpd.SignedTokenRestTokenVerifier;
 import com.google.gerrit.httpd.WebModule;
 import com.google.gerrit.httpd.WebSshGlueModule;
 import com.google.gerrit.httpd.auth.openid.OpenIdModule;
@@ -295,7 +294,6 @@
     modules.add(new DefaultCacheFactory.Module());
     modules.add(new SmtpEmailSender.Module());
     modules.add(new SignedTokenEmailTokenVerifier.Module());
-    modules.add(new SignedTokenRestTokenVerifier.Module());
     modules.add(new PluginModule());
     if (httpd) {
       modules.add(new CanonicalWebUrlModule() {
diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
index b352d4f..6dab0d3 100644
--- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
+++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
@@ -231,7 +231,6 @@
     modules.add(new DefaultCacheFactory.Module());
     modules.add(new SmtpEmailSender.Module());
     modules.add(new SignedTokenEmailTokenVerifier.Module());
-    modules.add(new SignedTokenRestTokenVerifier.Module());
     modules.add(new PluginModule());
     modules.add(new CanonicalWebUrlModule() {
       @Override