Fix successful login redirection to keep parameters

Login screen accept a token to redirect to on successful login but
if the token contained parameters, they were dropped.

Encode/decode the token to fix this issue.

When a URL has a pound sign, it is included in the token as well.
This removes the hardcoded behaviour to include a pound sign in every
redirect URL. Will now be able to use login redirection for URLs with
no pound sign (e.g. GitWeb)

Change-Id: If8a74a74ce11f79389895e4d036b06a1e81abbe5
This commit is contained in:
Simon Lei
2014-06-04 10:40:20 -04:00
parent cdfbcbccf6
commit 71891446a5
8 changed files with 29 additions and 30 deletions

View File

@@ -336,7 +336,15 @@ public class Gerrit implements EntryPoint {
} else if (token.startsWith("/")) {
token = token.substring(1);
}
return selfRedirect("/login/" + token);
UrlBuilder builder = new UrlBuilder();
builder.setProtocol(Location.getProtocol());
builder.setHost(Location.getHost());
String port = Location.getPort();
if (port != null && !port.isEmpty()) {
builder.setPort(Integer.parseInt(port));
}
return builder.buildString() + ("/login/" + URL.encodePathSegment("#/" + token));
}
public static String selfRedirect(String suffix) {

View File

@@ -14,20 +14,22 @@
package com.google.gerrit.httpd;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.restapi.Url;
import javax.servlet.http.HttpServletRequest;
public class LoginUrlToken {
private static final String DEFAULT_TOKEN = '#' + PageLinks.MINE;
public static String getToken(HttpServletRequest req) {
String token = req.getPathInfo();
if (Strings.isNullOrEmpty(token)) {
token = PageLinks.MINE;
} else if (!token.startsWith("/")) {
token = "/" + token;
}
return token;
public static String getToken(final HttpServletRequest req){
String encodedToken = req.getPathInfo();
if (Strings.isNullOrEmpty(encodedToken)) {
return DEFAULT_TOKEN;
} else {
return CharMatcher.is('/').trimLeadingFrom(Url.decode(encodedToken));
}
}
}

View File

@@ -21,6 +21,7 @@ import com.google.common.base.Strings;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.LoginUrlToken;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.httpd.template.SiteHeaderFooter;
import com.google.gerrit.reviewdb.client.Account;
@@ -132,11 +133,12 @@ class BecomeAnyAccountLoginServlet extends HttpServlet {
}
rdr.append("gwt.codesvr=").append(req.getParameter("gwt.codesvr"));
}
rdr.append('#');
if (res.isNew()) {
rdr.append(PageLinks.REGISTER);
rdr.append('#' + PageLinks.REGISTER);
} else {
rdr.append(LoginUrlToken.getToken(req));
}
rdr.append(PageLinks.MINE);
rsp.sendRedirect(rdr.toString());
} else {

View File

@@ -80,10 +80,6 @@ class HttpLoginServlet extends HttpServlet {
protected void doGet(final HttpServletRequest req,
final HttpServletResponse rsp) throws ServletException, IOException {
final String token = LoginUrlToken.getToken(req);
if ("/logout".equals(token) || "/signout".equals(token)) {
req.getRequestDispatcher("/logout").forward(req, rsp);
return;
}
CacheHeaders.setNotCacheable(rsp);
final String user = authFilter.getRemoteUser(req);
@@ -131,9 +127,8 @@ class HttpLoginServlet extends HttpServlet {
rdr.append(authConfig.getRegisterPageUrl());
} else {
rdr.append(urlProvider.get(req));
rdr.append('#');
if (arsp.isNew() && !token.startsWith(PageLinks.REGISTER + "/")) {
rdr.append(PageLinks.REGISTER);
rdr.append('#' + PageLinks.REGISTER);
}
rdr.append(token);
}

View File

@@ -53,7 +53,6 @@ public class HttpsClientSslCertLoginServlet extends HttpServlet {
final HttpServletResponse rsp) throws IOException {
final StringBuilder rdr = new StringBuilder();
rdr.append(urlProvider.get());
rdr.append('#');
rdr.append(LoginUrlToken.getToken(req));
CacheHeaders.setNotCacheable(rsp);

View File

@@ -73,10 +73,7 @@ class LdapLoginServlet extends HttpServlet {
@Nullable String errorMessage) throws IOException {
String self = req.getRequestURI();
String cancel = Objects.firstNonNull(urlProvider.get(req), "/");
String token = LoginUrlToken.getToken(req);
if (!token.equals("/")) {
cancel += "#" + token;
}
cancel += LoginUrlToken.getToken(req);
Document doc = headers.parse(LdapLoginServlet.class, "LoginForm.html");
HtmlDomUtil.find(doc, "hostName").setTextContent(req.getServerName());
@@ -144,7 +141,6 @@ class LdapLoginServlet extends HttpServlet {
StringBuilder dest = new StringBuilder();
dest.append(urlProvider.get(req));
dest.append('#');
dest.append(LoginUrlToken.getToken(req));
CacheHeaders.setNotCacheable(res);

View File

@@ -221,10 +221,7 @@ class LoginForm extends HttpServlet {
boolean link, @Nullable String errorMessage) throws IOException {
String self = req.getRequestURI();
String cancel = Objects.firstNonNull(urlProvider != null ? urlProvider.get() : "/", "/");
String token = LoginUrlToken.getToken(req);
if (!token.equals("/")) {
cancel += "#" + token;
}
cancel += LoginUrlToken.getToken(req);
Document doc = header.parse(LoginForm.class, "LoginForm.html");
HtmlDomUtil.find(doc, "hostName").setTextContent(req.getServerName());

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.httpd.auth.openid;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.auth.openid.OpenIdUrls;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.httpd.CanonicalWebUrl;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.reviewdb.client.Account;
@@ -483,11 +484,10 @@ class OpenIdServiceImpl {
final StringBuilder rdr = new StringBuilder();
rdr.append(urlProvider.get(req));
rdr.append('#');
if (isNew && !token.startsWith(PageLinks.REGISTER + "/")) {
rdr.append(PageLinks.REGISTER);
rdr.append('#' + PageLinks.REGISTER);
}
rdr.append(token);
rdr.append(Url.decode(token));
rsp.sendRedirect(rdr.toString());
}