summaryrefslogtreecommitdiffstats
path: root/gerrit-httpd
diff options
context:
space:
mode:
authorShawn Pearce <sop@google.com>2013-04-25 09:31:52 -0700
committerShawn Pearce <sop@google.com>2013-04-25 09:31:52 -0700
commit2a707bdefee91dca342d6e0a64c94aeb59aa6b4b (patch)
tree6d394d0dae1ce9882803da7cf4d07d06aa133a31 /gerrit-httpd
parent2244c3a0b48c94e60ecb33976efe7d84d1522513 (diff)
parent376da31e92527def686395182e1efbd6f54354cc (diff)
Merge branch 'stable-2.6'
* stable-2.6: Make Diffy in Diffy theme smaller Remove unnecessary @SuppressWarnings annotations in ChangeControl Update documentation to clarify how to set Global Capabilities Distinguish between error and timeout in intraline diff error message Replace Hashtable with ConcurrentMap Fix login redirect loop when auth.type = HTTP Include site header, footer and CSS on OpenID login form TrivialRebase: Fix custom categories
Diffstat (limited to 'gerrit-httpd')
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java9
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java11
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java53
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/template/SiteHeaderFooter.java150
-rw-r--r--gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/become/BecomeAnyAccount.html88
-rw-r--r--gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html40
6 files changed, 237 insertions, 114 deletions
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java
index 83f4088fe0..932f8f0b4b 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java
@@ -21,6 +21,7 @@ import com.google.common.base.Strings;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.WebSession;
+import com.google.gerrit.httpd.template.SiteHeaderFooter;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -60,14 +61,18 @@ class BecomeAnyAccountLoginServlet extends HttpServlet {
private final SchemaFactory<ReviewDb> schema;
private final Provider<WebSession> webSession;
private final AccountManager accountManager;
+ private final SiteHeaderFooter headers;
@Inject
BecomeAnyAccountLoginServlet(final Provider<WebSession> ws,
final SchemaFactory<ReviewDb> sf,
- final AccountManager am, final ServletContext servletContext) {
+ final AccountManager am,
+ final ServletContext servletContext,
+ SiteHeaderFooter shf) {
webSession = ws;
schema = sf;
accountManager = am;
+ headers = shf;
}
@Override
@@ -149,7 +154,7 @@ class BecomeAnyAccountLoginServlet extends HttpServlet {
private byte[] prepareHtmlOutput() throws IOException, OrmException {
final String pageName = "BecomeAnyAccount.html";
- final Document doc = HtmlDomUtil.parseFile(getClass(), pageName);
+ Document doc = headers.parse(getClass(), pageName);
if (doc == null) {
throw new FileNotFoundException("No " + pageName + " in webapp");
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
index f6cd8c1805..adca95e66e 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
@@ -119,14 +119,17 @@ class HttpAuthFilter implements Filter {
WebSession session = sessionProvider.get();
if (session.isSignedIn()) {
String user = getRemoteUser(req);
- AccountExternalId.Key id = session.getLastLoginExternalId();
- return user != null
- && id != null
- && id.equals(new AccountExternalId.Key(SCHEME_GERRIT, user));
+ return user == null || correctUser(user, session);
}
return false;
}
+ private static boolean correctUser(String user, WebSession session) {
+ AccountExternalId.Key id = session.getLastLoginExternalId();
+ return id != null
+ && id.equals(new AccountExternalId.Key(SCHEME_GERRIT, user));
+ }
+
String getRemoteUser(HttpServletRequest req) {
if (AUTHORIZATION.equals(loginHeader)) {
String user = emptyToNull(req.getRemoteUser());
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java
index 1d7b376850..cfae86c8ba 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java
@@ -19,6 +19,7 @@ import com.google.common.base.Strings;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.WebSession;
+import com.google.gerrit.httpd.template.SiteHeaderFooter;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AccountUserNameException;
@@ -26,7 +27,6 @@ import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult;
import com.google.gerrit.server.auth.AuthenticationUnavailableException;
import com.google.gerrit.server.config.CanonicalWebUrl;
-import com.google.gerrit.server.config.SitePaths;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -37,7 +37,6 @@ import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import java.io.File;
import java.io.IOException;
import javax.annotation.Nullable;
@@ -57,17 +56,17 @@ class LdapLoginServlet extends HttpServlet {
private final AccountManager accountManager;
private final Provider<WebSession> webSession;
private final Provider<String> urlProvider;
- private final SitePaths sitePaths;
+ private final SiteHeaderFooter headers;
@Inject
LdapLoginServlet(AccountManager accountManager,
Provider<WebSession> webSession,
@CanonicalWebUrl @Nullable Provider<String> urlProvider,
- SitePaths sitePaths) {
+ SiteHeaderFooter headers) {
this.accountManager = accountManager;
this.webSession = webSession;
this.urlProvider = urlProvider;
- this.sitePaths = sitePaths;
+ this.headers = headers;
if (Strings.isNullOrEmpty(urlProvider.get())) {
log.error("gerrit.canonicalWebUrl must be set in gerrit.config");
@@ -83,13 +82,7 @@ class LdapLoginServlet extends HttpServlet {
cancel += "#" + token;
}
- Document doc =
- HtmlDomUtil.parseFile(LdapLoginServlet.class, "LoginForm.html");
-
- injectCssFile(doc, "gerrit_sitecss", sitePaths.site_css);
- injectXmlFile(doc, "gerrit_header", sitePaths.site_header);
- injectXmlFile(doc, "gerrit_footer", sitePaths.site_footer);
-
+ Document doc = headers.parse(LdapLoginServlet.class, "LoginForm.html");
HtmlDomUtil.find(doc, "hostName").setTextContent(req.getServerName());
HtmlDomUtil.find(doc, "login_form").setAttribute("action", self);
HtmlDomUtil.find(doc, "cancel_link").setAttribute("href", cancel);
@@ -114,42 +107,6 @@ class LdapLoginServlet extends HttpServlet {
}
}
- private void injectCssFile(final Document hostDoc, final String id,
- final File src) throws IOException {
- final Element banner = HtmlDomUtil.find(hostDoc, id);
- if (banner != null) {
- while (banner.getFirstChild() != null) {
- banner.removeChild(banner.getFirstChild());
- }
-
- String css = HtmlDomUtil.readFile(src.getParentFile(), src.getName());
- if (css == null) {
- banner.getParentNode().removeChild(banner);
- } else {
- banner.removeAttribute("id");
- banner.appendChild(hostDoc.createCDATASection("\n" + css + "\n"));
- }
- }
- }
-
- private void injectXmlFile(final Document hostDoc, final String id,
- final File src) throws IOException {
- final Element banner = HtmlDomUtil.find(hostDoc, id);
- if (banner != null) {
- while (banner.getFirstChild() != null) {
- banner.removeChild(banner.getFirstChild());
- }
-
- Document html = HtmlDomUtil.parseFile(src);
- if (html == null) {
- banner.getParentNode().removeChild(banner);
- } else {
- final Element content = html.getDocumentElement();
- banner.appendChild(hostDoc.importNode(content, true));
- }
- }
- }
-
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/template/SiteHeaderFooter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/template/SiteHeaderFooter.java
new file mode 100644
index 0000000000..321f032ba4
--- /dev/null
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/template/SiteHeaderFooter.java
@@ -0,0 +1,150 @@
+// Copyright (C) 2013 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.template;
+
+import com.google.common.base.Strings;
+import com.google.gerrit.httpd.HtmlDomUtil;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import org.eclipse.jgit.lib.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.io.File;
+import java.io.IOException;
+
+@Singleton
+public class SiteHeaderFooter {
+ private static final Logger log = LoggerFactory.getLogger(SiteHeaderFooter.class);
+
+ private final boolean refreshHeaderFooter;
+ private final SitePaths sitePaths;
+ private volatile Template template;
+
+ @Inject
+ SiteHeaderFooter(@GerritServerConfig Config cfg, SitePaths sitePaths) {
+ this.refreshHeaderFooter = cfg.getBoolean("site", "refreshHeaderFooter", true);
+ this.sitePaths = sitePaths;
+
+ Template t = new Template(sitePaths);
+ try {
+ t.load();
+ } catch (IOException e) {
+ log.warn("Cannot load site header or footer", e);
+ }
+ template = t;
+ }
+
+ public Document parse(Class<?> clazz, String name) throws IOException {
+ Template t = template;
+ if (refreshHeaderFooter && t.isStale()) {
+ t = new Template(sitePaths);
+ try {
+ t.load();
+ template = t;
+ } catch (IOException e) {
+ log.warn("Cannot refresh site header or footer", e);
+ t = template;
+ }
+ }
+
+ Document doc = HtmlDomUtil.parseFile(clazz, name);
+ injectCss(doc, "gerrit_sitecss", t.css);
+ injectXml(doc, "gerrit_header", t.header);
+ injectXml(doc, "gerrit_footer", t.footer);
+ return doc;
+ }
+
+ private void injectCss(Document doc, String id, String content) {
+ Element e = HtmlDomUtil.find(doc, id);
+ if (e != null) {
+ if (!Strings.isNullOrEmpty(content)) {
+ while (e.getFirstChild() != null) {
+ e.removeChild(e.getFirstChild());
+ }
+ e.removeAttribute("id");
+ e.appendChild(doc.createCDATASection("\n" + content + "\n"));
+ } else {
+ e.getParentNode().removeChild(e);
+ }
+ }
+ }
+
+ private void injectXml(Document doc, String id, Element d) {
+ Element e = HtmlDomUtil.find(doc, id);
+ if (e != null) {
+ if (d != null) {
+ while (e.getFirstChild() != null) {
+ e.removeChild(e.getFirstChild());
+ }
+ e.appendChild(doc.importNode(d, true));
+ } else {
+ e.getParentNode().removeChild(e);
+ }
+ }
+ }
+
+ private static class Template {
+ private final FileInfo cssFile;
+ private final FileInfo headerFile;
+ private final FileInfo footerFile;
+
+ String css;
+ Element header;
+ Element footer;
+
+ Template(SitePaths site) {
+ cssFile = new FileInfo(site.site_css);
+ headerFile = new FileInfo(site.site_header);
+ footerFile = new FileInfo(site.site_footer);
+ }
+
+ void load() throws IOException {
+ css = HtmlDomUtil.readFile(
+ cssFile.path.getParentFile(),
+ cssFile.path.getName());
+ header = readXml(headerFile);
+ footer = readXml(footerFile);
+ }
+
+ boolean isStale() {
+ return cssFile.isStale() || headerFile.isStale() || footerFile.isStale();
+ }
+
+ private static Element readXml(FileInfo src) throws IOException {
+ Document d = HtmlDomUtil.parseFile(src.path);
+ return d != null ? d.getDocumentElement() : null;
+ }
+ }
+
+ private static class FileInfo {
+ final File path;
+ final long time;
+
+ FileInfo(File p) {
+ path = p;
+ time = path.lastModified();
+ }
+
+ boolean isStale() {
+ return time != path.lastModified();
+ }
+ }
+}
diff --git a/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/become/BecomeAnyAccount.html b/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/become/BecomeAnyAccount.html
index a4e3cca497..3548b9af93 100644
--- a/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/become/BecomeAnyAccount.html
+++ b/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/become/BecomeAnyAccount.html
@@ -29,51 +29,59 @@
}
})();
</script>
+ <style id="gerrit_sitecss" type="text/css"></style>
</head>
<body>
- <h2>Sign In</h2>
- <table border="0">
- <tr>
- <th>Username:</th>
- <td>
- <form method="GET">
- <input type="text" size="30" name="user_name" />
- <input type="submit" value="Become Account" />
- </form>
- </td>
- </tr>
+ <div id="gerrit_topmenu" style="height:45px;" class="gerritTopMenu"></div>
+ <div id="gerrit_header"></div>
+ <div id="gerrit_body" class="gerritBody">
+ <h2>Sign In</h2>
+ <table border="0">
+ <tr>
+ <th>Username:</th>
+ <td>
+ <form method="GET">
+ <input type="text" size="30" name="user_name" />
+ <input type="submit" value="Become Account" />
+ </form>
+ </td>
+ </tr>
- <tr>
- <th>Email Address:</th>
- <td>
- <form method="GET">
- <input type="text" size="30" name="preferred_email" />
- <input type="submit" value="Become Account" />
- </form>
- </td>
- </tr>
+ <tr>
+ <th>Email Address:</th>
+ <td>
+ <form method="GET">
+ <input type="text" size="30" name="preferred_email" />
+ <input type="submit" value="Become Account" />
+ </form>
+ </td>
+ </tr>
- <tr>
- <th>Account ID:</th>
- <td>
- <form method="GET">
- <input type="text" size="12" name="account_id" />
- <input type="submit" value="Become Account" />
- </form>
- </td>
- </tr>
+ <tr>
+ <th>Account ID:</th>
+ <td>
+ <form method="GET">
+ <input type="text" size="12" name="account_id" />
+ <input type="submit" value="Become Account" />
+ </form>
+ </td>
+ </tr>
- <tr>
- <th>Choose:</th>
- <td id="userlist"/>
- </tr>
- </table>
+ <tr>
+ <th>Choose:</th>
+ <td id="userlist"/>
+ </tr>
+ </table>
- <hr />
- <h2>Register</h2>
- <form method="POST">
- <input type="hidden" name="action" value="create_account" />
- <input type="submit" value="New Account" />
- </form>
+ <hr />
+ <h2>Register</h2>
+ <form method="POST">
+ <input type="hidden" name="action" value="create_account" />
+ <input type="submit" value="New Account" />
+ </form>
+ </div>
+ <div style="clear: both; margin-top: 15px; padding-top: 2px; margin-bottom: 15px;">
+ <div id="gerrit_footer"></div>
+ </div>
</body>
</html>
diff --git a/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html b/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html
index f7a388eb9d..57bc7f4058 100644
--- a/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html
+++ b/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html
@@ -13,7 +13,7 @@
margin-left: 45px;
}
</style>
- <style id="gerrit_sitecss" type="text/css"></style>
+ <style id="gerrit_sitecss" type="text/css"></style>
</head>
<body>
<div id="gerrit_topmenu" style="height:45px;" class="gerritTopMenu"></div>
@@ -56,28 +56,28 @@
</tr>
</table>
</form>
-
- <script type="text/javascript">
- var login_form = document.getElementById('login_form');
- var f_user = document.getElementById('f_user');
- var f_pass = document.getElementById('f_pass');
- f_user.onkeydown = function(e) {
- if (e.keyCode == 13) {
- f_pass.focus();
- return false;
- }
- }
- f_pass.onkeydown = function(e) {
- if (e.keyCode == 13) {
- login_form.submit();
- return false;
- }
- }
- f_user.focus();
- </script>
<div style="clear: both; margin-top: 15px; padding-top: 2px; margin-bottom: 15px;">
<div id="gerrit_footer"></div>
</div>
</div>
+
+ <script type="text/javascript">
+ var login_form = document.getElementById('login_form');
+ var f_user = document.getElementById('f_user');
+ var f_pass = document.getElementById('f_pass');
+ f_user.onkeydown = function(e) {
+ if (e.keyCode == 13) {
+ f_pass.focus();
+ return false;
+ }
+ }
+ f_pass.onkeydown = function(e) {
+ if (e.keyCode == 13) {
+ login_form.submit();
+ return false;
+ }
+ }
+ f_user.focus();
+ </script>
</body>
</html>