Create a debug mode only method of logging in to Gerrit
Currently the hosted mode debug session is crashing on my 64 bit Ubuntu
desktop anytime I try to use an OpenID login. As a work around we now
have a servlet that can authenticate the browser as any user identity
desired, provided that the JRE was started with a system property that
permits its usage, and that we were launched from the hosted mode shell
as the servlet is not mapped in the main web.xml.
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/gerrit_debug.launch b/gerrit_debug.launch
index 5c022a4..9f54123 100644
--- a/gerrit_debug.launch
+++ b/gerrit_debug.launch
@@ -23,5 +23,5 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out gwt_www com.google.gerrit.Gerrit/Gerrit.html"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.maven.ide.eclipse.launchconfig.sourcepathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M -DGerritServer=${resource_loc:/gerrit/src/main/java/GerritServer.properties}"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M -DGerritServer=${resource_loc:/gerrit/src/main/java/GerritServer.properties} -Dcom.google.gerrit.server.BecomeAnyAccountLoginServlet=true"/>
</launchConfiguration>
diff --git a/gerrit_macos.launch b/gerrit_macos.launch
index 3058fcd..e10cb2a 100644
--- a/gerrit_macos.launch
+++ b/gerrit_macos.launch
@@ -25,5 +25,5 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out gwt_www com.google.gerrit.Gerrit/Gerrit.html"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.maven.ide.eclipse.launchconfig.sourcepathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M -XstartOnFirstThread -DGerritServer=${resource_loc:/gerrit/src/main/java/GerritServer.properties}"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M -XstartOnFirstThread -DGerritServer=${resource_loc:/gerrit/src/main/java/GerritServer.properties} -Dcom.google.gerrit.server.BecomeAnyAccountLoginServlet=true"/>
</launchConfiguration>
diff --git a/src/main/java/com/google/gerrit/Gerrit.gwt.xml b/src/main/java/com/google/gerrit/Gerrit.gwt.xml
index 6075922..d56c42d 100644
--- a/src/main/java/com/google/gerrit/Gerrit.gwt.xml
+++ b/src/main/java/com/google/gerrit/Gerrit.gwt.xml
@@ -57,4 +57,8 @@
class='com.google.gerrit.server.SuggestServiceSrv'/>
<servlet path='/rpc/SystemInfoService'
class='com.google.gerrit.server.SystemInfoServiceSrv'/>
+
+ <!-- Hosted mode debugging ONLY -->
+ <servlet path='/__BecomeAnyAccount'
+ class='com.google.gerrit.server.BecomeAnyAccountLoginServlet'/>
</module>
diff --git a/src/main/java/com/google/gerrit/client/Gerrit.java b/src/main/java/com/google/gerrit/client/Gerrit.java
index 0f1200c..95307e7 100644
--- a/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -320,19 +320,23 @@
if (signedIn) {
whoAmI();
menuBar.addItem(new LinkMenuItem(C.menuSettings(), Link.SETTINGS));
+ boolean signout = false;
switch (Common.getGerritConfig().getLoginType()) {
case HTTP:
break;
case OPENID:
default:
- menuBar.addItem(C.menuSignOut(), new Command() {
- public void execute() {
- doSignOut();
- }
- });
+ signout = true;
break;
}
+ if (signout || (GWT.isClient() && !GWT.isScript())) {
+ menuBar.addItem(C.menuSignOut(), new Command() {
+ public void execute() {
+ doSignOut();
+ }
+ });
+ }
} else {
switch (Common.getGerritConfig().getLoginType()) {
case HTTP:
@@ -347,6 +351,14 @@
});
break;
}
+ if (GWT.isClient() && !GWT.isScript()) {
+ menuBar.addItem("Become", new Command() {
+ public void execute() {
+ final String base = GWT.getModuleBaseURL();
+ Window.Location.assign(base + "__BecomeAnyAccount");
+ }
+ });
+ }
}
menuBar.lastInGroup();
diff --git a/src/main/java/com/google/gerrit/server/BecomeAnyAccountLoginServlet.java b/src/main/java/com/google/gerrit/server/BecomeAnyAccountLoginServlet.java
new file mode 100644
index 0000000..ac9e69f
--- /dev/null
+++ b/src/main/java/com/google/gerrit/server/BecomeAnyAccountLoginServlet.java
@@ -0,0 +1,169 @@
+// Copyright (C) 2009 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.server;
+
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.reviewdb.Account;
+import com.google.gerrit.client.reviewdb.ReviewDb;
+import com.google.gerrit.client.rpc.Common;
+import com.google.gwtjsonrpc.server.XsrfException;
+import com.google.gwtorm.client.OrmException;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class BecomeAnyAccountLoginServlet extends HttpServlet {
+ private boolean allowed;
+ private GerritServer server;
+
+ @Override
+ public void init(final ServletConfig config) throws ServletException {
+ super.init(config);
+ try {
+ allowed = Boolean.getBoolean(getClass().getName());
+ } catch (SecurityException se) {
+ allowed = false;
+ }
+
+ try {
+ server = GerritServer.getInstance();
+ } catch (OrmException e) {
+ throw new ServletException("Cannot load GerritServer", e);
+ } catch (XsrfException e) {
+ throw new ServletException("Cannot load GerritServer", e);
+ }
+ }
+
+ @Override
+ protected void doGet(final HttpServletRequest req,
+ final HttpServletResponse rsp) throws IOException {
+ if (!allowed) {
+ rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ rsp.setContentType("text/html");
+ final ServletOutputStream out = rsp.getOutputStream();
+ out.print("<html>");
+ out.print("<form method=\"POST\"><b>ssh_user_name:</b> "
+ + "<input type=\"text\" size=\"30\" name=\"ssh_user_name\" />"
+ + "<input type=\"submit\" value=\"Become Account\" />" + "</form>");
+ out.print("<form method=\"POST\"><b>preferred_email:</b> "
+ + "<input type=\"text\" size=\"30\" name=\"preferred_email\" />"
+ + "<input type=\"submit\" value=\"Become Account\" />" + "</form>");
+ out.print("<form method=\"POST\"><b>account_id:</b> "
+ + "<input type=\"text\" size=\"12\" name=\"account_id\" />"
+ + "<input type=\"submit\" value=\"Become Account\" />" + "</form>");
+ out.print("</html>");
+ }
+
+ @Override
+ protected void doPost(final HttpServletRequest req,
+ final HttpServletResponse rsp) throws IOException {
+ if (!allowed) {
+ rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ final List<Account> accounts;
+ if (req.getParameter("ssh_user_name") != null) {
+ accounts = bySshUserName(rsp, req.getParameter("ssh_user_name"));
+
+ } else if (req.getParameter("preferred_email") != null) {
+ accounts = byPreferredEmail(rsp, req.getParameter("preferred_email"));
+
+ } else if (req.getParameter("account_id") != null) {
+ accounts = byAccountId(rsp, req.getParameter("account_id"));
+
+ } else {
+ doGet(req, rsp);
+ return;
+ }
+
+ if (accounts.size() == 1) {
+ final Account account = accounts.get(0);
+ final Cookie c = new Cookie(Gerrit.ACCOUNT_COOKIE, "");
+ c.setPath(req.getContextPath() + "/");
+ new AccountCookie(account.getId(), false).set(c, server);
+ rsp.addCookie(c);
+ rsp.sendRedirect("Gerrit.html");
+
+ } else {
+ rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
+ }
+
+ private List<Account> bySshUserName(final HttpServletResponse rsp,
+ final String userName) {
+ try {
+ final ReviewDb db = Common.getSchemaFactory().open();
+ try {
+ return db.accounts().bySshUserName(userName).toList();
+ } finally {
+ db.close();
+ }
+ } catch (OrmException e) {
+ getServletContext().log("cannot query database", e);
+ return Collections.<Account> emptyList();
+ }
+ }
+
+ private List<Account> byPreferredEmail(final HttpServletResponse rsp,
+ final String email) {
+ try {
+ final ReviewDb db = Common.getSchemaFactory().open();
+ try {
+ return db.accounts().byPreferredEmail(email).toList();
+ } finally {
+ db.close();
+ }
+ } catch (OrmException e) {
+ getServletContext().log("cannot query database", e);
+ return Collections.<Account> emptyList();
+ }
+ }
+
+ private List<Account> byAccountId(final HttpServletResponse rsp,
+ final String idStr) {
+ final Account.Id id;
+ try {
+ id = Account.Id.parse(idStr);
+ } catch (NumberFormatException nfe) {
+ return Collections.<Account> emptyList();
+ }
+ try {
+ final ReviewDb db = Common.getSchemaFactory().open();
+ try {
+ final Account account = db.accounts().get(id);
+ return account != null ? Collections.<Account> singletonList(account)
+ : Collections.<Account> emptyList();
+ } finally {
+ db.close();
+ }
+ } catch (OrmException e) {
+ getServletContext().log("cannot query database", e);
+ return Collections.<Account> emptyList();
+ }
+ }
+}