Replace certificates with tokens in its-phabricator

Certificates are deprecated and confusing behaviour.

Removes use of conduit.connect as that was for if you used a certificate
and was deprecated.

Though it's super easy to change to tokens.

You just need to get your token at /conduit/login/.

Change-Id: I94972341df10cd2b69c905867d908323fde6117c
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacade.java b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacade.java
index 5d171de..dad638c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacade.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacade.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -39,21 +39,18 @@
   private static final Logger log = LoggerFactory.getLogger(PhabricatorItsFacade.class);
 
   private static final String GERRIT_CONFIG_URL = "url";
-  private static final String GERRIT_CONFIG_USERNAME = "username";
-  private static final String GERRIT_CONFIG_CERTIFICATE = "certificate";
+  private static final String GERRIT_CONFIG_TOKEN = "token";
 
   private final Conduit conduit;
 
   @Inject
   public PhabricatorItsFacade(@PluginName String pluginName,
       @GerritServerConfig Config cfg) {
-    final String url = cfg.getString(pluginName, null, GERRIT_CONFIG_URL);
-    final String username = cfg.getString(pluginName, null,
-            GERRIT_CONFIG_USERNAME);
-    final String certificate = cfg.getString(pluginName, null,
-            GERRIT_CONFIG_CERTIFICATE);
+    String url = cfg.getString(pluginName, null, GERRIT_CONFIG_URL);
+    String token = cfg.getString(pluginName, null,
+            GERRIT_CONFIG_TOKEN);
 
-    this.conduit = new Conduit(url, username, certificate);
+    this.conduit = new Conduit(url, token);
   }
 
   @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/Conduit.java b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/Conduit.java
index d2d4ae2..fc43b91 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/Conduit.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/Conduit.java
@@ -1,4 +1,4 @@
-//Copyright (C) 2014 The Android Open Source Project
+//Copyright (C) 2017 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.
@@ -49,66 +49,33 @@
 
   private static final Logger log = LoggerFactory.getLogger(Conduit.class);
 
-  public static final int CONDUIT_VERSION = 6;
+  public static final int CONDUIT_VERSION = 7;
 
   private final ConduitConnection conduitConnection;
   private final Gson gson;
 
-  private String username;
-  private String certificate;
-
-  private String sessionKey;
+  private String token;
 
   public Conduit(final String baseUrl) {
-    this(baseUrl, null, null);
+    this(baseUrl, null);
   }
 
-  public Conduit(final String baseUrl, final String username, final String certificate) {
+  public Conduit(final String baseUrl, final String token) {
     this.conduitConnection = new ConduitConnection(baseUrl);
-    this.username = username;
-    this.certificate = certificate;
+    this.token = token;
     this.gson = new Gson();
-    resetSession();
   }
 
-  private void resetSession() {
-    sessionKey = null;
-  }
-
-  public void setUsername(String username) {
-    this.username = username;
-    resetSession();
-  }
-
-  public void setCertificate(String certificate) {
-    this.certificate = certificate;
-    resetSession();
-  }
-
-  /**
-   * Adds session parameters to a Map of parameters
-   * <p/>
-   * If there is no active session, a new one is opened
-   * <p/>
-   * This method overrides the params' __conduit__ value.
-   *
-   * @param params The Map to add session paramaters to
-   */
-  private void fillInSession(Map<String, Object> params) throws ConduitException {
-    if (sessionKey == null) {
-      log.debug("Trying to start new session");
-      conduitConnect();
-    }
-    Map<String, Object> conduitParams = new HashMap<>();
-    conduitParams.put("sessionKey",sessionKey);
-    params.put("__conduit__", conduitParams);
+  public void setToekn(String token) {
+    this.token = token;
   }
 
   /**
    * Runs the API's 'conduit.ping' method
    */
   public ConduitPing conduitPing() throws ConduitException {
-    JsonElement callResult = conduitConnection.call("conduit.ping");
+    Map<String, Object> params = new HashMap<>();
+    JsonElement callResult = conduitConnection.call("conduit.ping", params, token);
     JsonObject callResultWrapper = new JsonObject();
     callResultWrapper.add("hostname", callResult);
     ConduitPing result = gson.fromJson(callResultWrapper, ConduitPing.class);
@@ -116,60 +83,13 @@
   }
 
   /**
-   * Runs the API's 'conduit.connect' method
-   */
-  public ConduitConnect conduitConnect() throws ConduitException {
-    Map<String, Object> params = new HashMap<>();
-    params.put("client", "its-phabricator");
-    params.put("clientVersion", CONDUIT_VERSION);
-    params.put("user", username);
-
-    // According to phabricator/src/applications/conduit/method/ConduitConnectConduitAPIMethod.php,
-    // the authToken needs to be an integer that is within 15 minutes of the
-    // server's current timestamp.
-    long authToken = System.currentTimeMillis() / 1000;
-    params.put("authToken", authToken);
-
-    // According to phabricator/src/applications/conduit/method/ConduitConnectConduitAPIMethod.php,
-    // The signature is the SHA1 of the concatenation of the authToken (as
-    // string) and the certificate (The long sequence of digits and lowercase
-    // hat get written into ~/.arcrc after "arc install-certificate").
-    String authSignatureInput = Long.toString(authToken) + certificate;
-
-    MessageDigest sha1;
-    try {
-      sha1 = MessageDigest.getInstance("SHA-1");
-    } catch (NoSuchAlgorithmException e) {
-      throw new ConduitException("Failed to compute authSignature, as no "
-          + "SHA-1 algorithm implementation was found", e);
-    }
-    byte[] authSignatureRaw;
-    try {
-      authSignatureRaw = sha1.digest(authSignatureInput.getBytes("UTF-8"));
-    } catch (UnsupportedEncodingException e) {
-      throw new ConduitException("Failed to convert authSignature input to "
-          + "UTF-8 String", e);
-    }
-    String authSignatureUC = DatatypeConverter.printHexBinary(authSignatureRaw);
-    String authSignature = authSignatureUC.toLowerCase();
-    params.put("authSignature", authSignature);
-
-    JsonElement callResult = conduitConnection.call("conduit.connect", params);
-
-    ConduitConnect result = gson.fromJson(callResult, ConduitConnect.class);
-    sessionKey = result.getSessionKey();
-    return result;
-  }
-
-  /**
    * Runs the API's 'maniphest.Info' method
    */
   public ManiphestInfo maniphestInfo(int taskId) throws ConduitException {
     Map<String, Object> params = new HashMap<>();
-    fillInSession(params);
     params.put("task_id", taskId);
 
-    JsonElement callResult = conduitConnection.call("maniphest.info", params);
+    JsonElement callResult = conduitConnection.call("maniphest.info", params, token);
     ManiphestInfo result = gson.fromJson(callResult, ManiphestInfo.class);
     return result;
   }
@@ -193,7 +113,6 @@
    */
   public ManiphestEdit maniphestEdit(int taskId, String comment, Iterable<String> projects) throws ConduitException {
     HashMap<String, Object> params = new HashMap<>();
-    fillInSession(params);
     List<Object> list = new ArrayList<>();
     HashMap<String, Object> params2 = new HashMap<>();
     if (comment != null) {
@@ -214,7 +133,7 @@
     }
     params.put("objectIdentifier", taskId);
 
-    JsonElement callResult = conduitConnection.call("maniphest.edit", params);
+    JsonElement callResult = conduitConnection.call("maniphest.edit", params, token);
     ManiphestEdit result = gson.fromJson(callResult, ManiphestEdit.class);
     return result;
   }
@@ -224,10 +143,9 @@
    */
   public ProjectInfo projectQuery(String name) throws ConduitException {
     Map<String, Object> params = new HashMap<>();
-    fillInSession(params);
     params.put("names", Arrays.asList(name));
 
-    JsonElement callResult = conduitConnection.call("project.query", params);
+    JsonElement callResult = conduitConnection.call("project.query", params, token);
     QueryResult queryResult = gson.fromJson(callResult, QueryResult.class);
     JsonObject queryResultData = queryResult.getData().getAsJsonObject();
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java
index 2233df0..cf74e0e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java
@@ -1,4 +1,4 @@
-//Copyright (C) 2014 The Android Open Source Project
+//Copyright (C) 2017 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.
@@ -34,7 +34,6 @@
 import java.util.HashMap;
 import java.util.Map;
 
-
 /**
  * Abstracts the connection to Conduit API
  */
@@ -74,8 +73,8 @@
    * @return The call's result, if there has been no error
    * @throws ConduitException
    */
-  JsonElement call(String method) throws ConduitException {
-    return call(method, new HashMap<String, Object>());
+  JsonElement call(String method, String token) throws ConduitException {
+    return call(method, new HashMap<String, Object>(), token);
   }
 
   /**
@@ -86,12 +85,18 @@
    * @return The call's result, if there has been no error
    * @throws ConduitException
    */
-  JsonElement call(String method, Map<String, Object> params) throws ConduitException {
+  JsonElement call(String method, Map<String, Object> params, String token) throws ConduitException {
     String methodUrl = apiUrlBase + method;
 
     HttpPost httppost = new HttpPost(methodUrl);
 
 
+    if (token != null) {
+      Map<String, Object> conduitParams = new HashMap<>();
+      conduitParams.put("token", token);
+      params.put("__conduit__", conduitParams);
+    }
+
     String json = gson.toJson(params);
 
     log.trace("Calling phabricator method " + method
diff --git a/src/main/resources/Documentation/config-connectivity.md b/src/main/resources/Documentation/config-connectivity.md
index 5adc0d0..daa947a 100644
--- a/src/main/resources/Documentation/config-connectivity.md
+++ b/src/main/resources/Documentation/config-connectivity.md
@@ -10,22 +10,11 @@
 
 ```
 [@PLUGIN@]
-  url=http://my.phabricator.instance.example.org
-  username=USERNAME_TO_CONNECT_TO_BUGZILLA
-  certificate=CERTIFICATE_FOR_ABOVE_USERNAME
+  url = http://my.phabricator.instance.example.org
+  token = TOKEN_FOR_ABOVE_USERNAME
 ```
 
-Note that the certificate is not the user's password. It is … well … the users
-certificate … which is a 255 character long sequence of lowercase letters and
-digits. To get the certificate, run
-
-```
-arc install-certificate http://my.phabricator.instance.example.org
-```
-
-And follow the instructions on the screen. Once the procedure of logging in to
-the Phabricator instance in your browser and copying tokens around is complete,
-you'll find the certificate in `~/.arcrc`.
+You can get your token by going to http://my.phabricator.instance.example.org/conduit/login/
 
 [Back to @PLUGIN@ documentation index][index]
 
diff --git a/src/main/resources/Documentation/upgrade.md b/src/main/resources/Documentation/upgrade.md
new file mode 100644
index 0000000..462fc78
--- /dev/null
+++ b/src/main/resources/Documentation/upgrade.md
@@ -0,0 +1,6 @@
+Users upgrading from the stable-2.13 branch to stable-2.14 or higher please note that this includes
+a breaking change for `@PLUGIN@`.
+
+Certificates and username field have been removed and replaced with tokens.
+
+To setup tokens please follow [Setting up tokens][config-connectivity]
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacadeTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacadeTest.java
index 4a9012e..6910332 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacadeTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/PhabricatorItsFacadeTest.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -80,9 +80,7 @@
   private void mockUnconnectablePhabricator() {
     expect(serverConfig.getString("its-phabricator",  null, "url"))
     .andReturn("<no-url>").anyTimes();
-    expect(serverConfig.getString("its-phabricator",  null, "username"))
-    .andReturn("none").anyTimes();
-    expect(serverConfig.getString("its-phabricator",  null, "certificate"))
+    expect(serverConfig.getString("its-phabricator",  null, "token"))
     .andReturn("none").anyTimes();
   }
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
index b4936e4..e167d10 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
@@ -1,4 +1,4 @@
-//Copyright (C) 2014 The Android Open Source Project
+//Copyright (C) 2017 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.
@@ -42,21 +42,24 @@
 @PrepareForTest(Conduit.class)
 public class ConduitTest extends LoggingMockingTestCase {
   private final static String URL = "urlFoo";
-  private final static String USERNAME = "usernameFoo";
-  private final static String CERTIFICATE = "certificateFoo";
+  private final static String TOKEN = "tokenFoo";
 
   private ConduitConnection connection;
 
   public void testConduitPingPass() throws Exception {
     mockConnection();
 
-    expect(connection.call("conduit.ping"))
+    resetToStrict(connection);
+
+    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
+
+    expect(connection.call(eq("conduit.ping"), capture(paramsCaptureRelevant), eq(TOKEN)))
       .andReturn(new JsonPrimitive("foo"))
       .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ConduitPing actual = conduit.conduitPing();
 
@@ -66,15 +69,19 @@
   public void testConduitPingConnectionFail() throws Exception {
     mockConnection();
 
+    resetToStrict(connection);
+
     ConduitException conduitException = new ConduitException();
 
-    expect(connection.call("conduit.ping"))
+    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
+
+    expect(connection.call(eq("conduit.ping"), capture(paramsCaptureRelevant), eq(TOKEN)))
       .andThrow(conduitException)
       .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     try {
       conduit.conduitPing();
@@ -84,95 +91,30 @@
     }
   }
 
-  public void testConduitConnectPass() throws Exception {
-    mockConnection();
-
-    JsonObject ret = new JsonObject();
-    ret.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCapture = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCapture)))
-      .andReturn(ret)
-      .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
-
-    ConduitConnect conduitConnect = conduit.conduitConnect();
-
-    Map<String, Object> params = paramsCapture.getValue();
-    assertEquals("Usernames do not match", USERNAME, params.get("user"));
-
-    assertEquals("Session keys don't match", "KeyFoo",
-        conduitConnect.getSessionKey());
-  }
-
-  public void testConduitConnectConnectionFail() throws Exception {
-    mockConnection();
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCapture = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCapture)))
-      .andThrow(conduitException)
-      .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
-
-    try {
-      conduit.conduitConnect();
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-
-    Map<String, Object> params = paramsCapture.getValue();
-    assertEquals("Usernames do not match", USERNAME, params.get("user"));
-  }
-
   public void testManiphestInfoPass() throws Exception {
     mockConnection();
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
+    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
     JsonObject retRelevant = new JsonObject();
     retRelevant.add("id", new JsonPrimitive(42));
 
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ManiphestInfo maniphestInfo = conduit.maniphestInfo(42);
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
 
     assertEquals("ManiphestInfo's id does not match", 42, maniphestInfo.getId());
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testManiphestInfoFailConnect() throws Exception {
@@ -180,15 +122,15 @@
 
     ConduitException conduitException = new ConduitException();
 
-    Capture<Map<String, Object>> paramsCapture = new Capture<>();
+    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("conduit.connect"), capture(paramsCapture)))
+    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
       .andThrow(conduitException)
       .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     try {
       conduit.maniphestInfo(42);
@@ -196,11 +138,6 @@
     } catch (ConduitException e) {
       assertSame(conduitException, e);
     }
-
-    Map<String, Object> params = paramsCapture.getValue();
-    assertEquals("Usernames do not match", USERNAME, params.get("user"));
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testManiphestInfoFailRelevant() throws Exception {
@@ -208,26 +145,17 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     ConduitException conduitException = new ConduitException();
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
       .andThrow(conduitException)
       .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     try {
       conduit.maniphestInfo(42);
@@ -236,13 +164,8 @@
       assertSame(conduitException, e);
     }
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testManiphestEditPassComment() throws Exception {
@@ -250,39 +173,25 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     JsonObject retRelevant = new JsonObject();
     retRelevant.add("id", new JsonPrimitive(42));
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("maniphest.update"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.update"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ManiphestEdit maniphestEdit = conduit.maniphestEdit(42, "foo");
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
 
     assertEquals("ManiphestInfo's id does not match", 42, maniphestEdit.getId());
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testManiphestEditPassProjects() throws Exception {
@@ -290,42 +199,28 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     JsonObject retRelevant = new JsonObject();
     retRelevant.add("id", new JsonPrimitive(42));
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ManiphestEdit maniphestEdit = conduit.maniphestEdit(42,
         Arrays.asList("foo", "bar"));
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
     assertEquals("Task projects are not set", Arrays.asList("foo", "bar"),
         paramsRelevant.get("projectPHIDs"));
 
     assertEquals("ManiphestEdit's id does not match", 42, maniphestEdit.getId());
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testManiphestEditPassCommentAndProjects() throws Exception {
@@ -333,34 +228,22 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     JsonObject retRelevant = new JsonObject();
     retRelevant.add("id", new JsonPrimitive(42));
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ManiphestEdit maniphestEdit = conduit.maniphestEdit(42, "baz",
         Arrays.asList("foo", "bar"));
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
     assertEquals("Task comment is not set", "baz", paramsRelevant.get("comments"));
@@ -368,8 +251,6 @@
         paramsRelevant.get("projectPHIDs"));
 
     assertEquals("ManiphestUpdate's id does not match", 42, maniphestEdit.getId());
-
-    assertLogMessageContains("Trying to start new session");
   }
 
 
@@ -380,13 +261,13 @@
 
     Capture<Map<String, Object>> paramsCapture = new Capture<>();
 
-    expect(connection.call(eq("conduit.connect"), capture(paramsCapture)))
+    expect(connection.call(eq("conduit.connect"), capture(paramsCapture), eq(TOKEN)))
       .andThrow(conduitException)
       .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, null);
 
     try {
       conduit.maniphestEdit(42, "foo");
@@ -394,11 +275,6 @@
     } catch (ConduitException e) {
       assertSame(conduitException, e);
     }
-
-    Map<String, Object> params = paramsCapture.getValue();
-    assertEquals("Usernames do not match", USERNAME, params.get("user"));
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testManiphestEditFailRelevant() throws Exception {
@@ -406,26 +282,17 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     ConduitException conduitException = new ConduitException();
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
       .andThrow(conduitException)
       .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     try {
       conduit.maniphestEdit(42, "foo");
@@ -434,13 +301,8 @@
       assertSame(conduitException, e);
     }
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testConnectionReuse() throws Exception {
@@ -448,39 +310,24 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     JsonObject retRelevant = new JsonObject();
     retRelevant.add("id", new JsonPrimitive(42));
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
-    ConduitConnect conduitConnect = conduit.conduitConnect();
     ManiphestInfo maniphestInfo = conduit.maniphestInfo(42);
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
 
-    assertEquals("Session keys don't match", "KeyFoo", conduitConnect.getSessionKey());
-
     assertEquals("ManiphestInfo's id does not match", 42, maniphestInfo.getId());
   }
 
@@ -489,15 +336,6 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     JsonObject projectInfoJson = new JsonObject();
     projectInfoJson.addProperty("name", "foo");
     projectInfoJson.addProperty("phid", "PHID-PROJ-bar");
@@ -510,27 +348,22 @@
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ProjectInfo projectInfo = conduit.projectQuery("foo");
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     List<String> expectedNames = Arrays.asList("foo");
     assertEquals("Project name does not match", expectedNames,
         paramsRelevant.get("names"));
 
     assertEquals("ProjectInfo's name does not match", "foo", projectInfo.getName());
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   public void testProjectQueryPassMultipleResults() throws Exception {
@@ -538,15 +371,6 @@
 
     resetToStrict(connection);
 
-    JsonObject retConnect = new JsonObject();
-    retConnect.add("sessionKey", new JsonPrimitive("KeyFoo"));
-
-    Capture<Map<String, Object>> paramsCaptureConnect = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCaptureConnect)))
-      .andReturn(retConnect)
-      .once();
-
     JsonObject projectInfoJson1 = new JsonObject();
     projectInfoJson1.addProperty("name", "foo1");
     projectInfoJson1.addProperty("phid", "PHID-PROJ-bar1");
@@ -569,27 +393,22 @@
 
     Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
 
-    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant)))
+    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant), eq(TOKEN)))
     .andReturn(retRelevant)
     .once();
 
     replayMocks();
 
-    Conduit conduit = new Conduit(URL, USERNAME, CERTIFICATE);
+    Conduit conduit = new Conduit(URL, TOKEN);
 
     ProjectInfo projectInfo = conduit.projectQuery("foo2");
 
-    Map<String, Object> paramsConnect = paramsCaptureConnect.getValue();
-    assertEquals("Usernames do not match", USERNAME, paramsConnect.get("user"));
-
     Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
     List<String> expectedNames = Arrays.asList("foo2");
     assertEquals("Project name does not match", expectedNames,
         paramsRelevant.get("names"));
 
     assertEquals("ProjectInfo's name does not match", "foo2", projectInfo.getName());
-
-    assertLogMessageContains("Trying to start new session");
   }
 
   private void mockConnection() throws Exception {