diff --git a/contrib/themes/diffy/etc/GerritSite.css b/contrib/themes/diffy/etc/GerritSite.css
index 6fe8a3e88f..d4769579c2 100644
--- a/contrib/themes/diffy/etc/GerritSite.css
+++ b/contrib/themes/diffy/etc/GerritSite.css
@@ -12,19 +12,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#gerrit_topmenu {
+ left: 60px;
+ margin-right: 60px;
+ padding-right: 10px;
+ position: relative;
+}
-#gerrit_header {
+#diffy_logo {
display: block !important;
margin-bottom: -55px;
padding-left: 20px;
position: relative;
top: -45px;
- width: 100px;
-}
-
-#gerrit_topmenu {
- left: 100px;
- margin-right: 100px;
- padding-right: 10px;
- position: relative;
+ width: 60px;
}
diff --git a/contrib/themes/diffy/etc/GerritSiteHeader.html b/contrib/themes/diffy/etc/GerritSiteHeader.html
index 48ccfeceaf..89b4db5149 100644
--- a/contrib/themes/diffy/etc/GerritSiteHeader.html
+++ b/contrib/themes/diffy/etc/GerritSiteHeader.html
@@ -1,3 +1,5 @@
-

+
+

+
diff --git a/contrib/trivial_rebase.py b/contrib/trivial_rebase.py
index ff90b6c7c4..e5005a3f4a 100755
--- a/contrib/trivial_rebase.py
+++ b/contrib/trivial_rebase.py
@@ -226,7 +226,7 @@ class TrivialRebase:
# We don't care about previous submit attempts
continue
else:
- self.AppendAcctApproval(acct_approvals, approval['account_id'], '--%s %s' %
+ self.AppendAcctApproval(approval['account_id'], '--%s %s' %
(approval['category_id'].lower().replace(' ', '-'),
approval['value']))
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 schema;
private final Provider webSession;
private final AccountManager accountManager;
+ private final SiteHeaderFooter headers;
@Inject
BecomeAnyAccountLoginServlet(final Provider ws,
final SchemaFactory 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;
private final Provider urlProvider;
- private final SitePaths sitePaths;
+ private final SiteHeaderFooter headers;
@Inject
LdapLoginServlet(AccountManager accountManager,
Provider webSession,
@CanonicalWebUrl @Nullable Provider 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 @@
}
})();
+
- Sign In
-
-
- Username: |
-
-
- |
-
+
+
+
+
Sign In
+
+
+ Username: |
+
+
+ |
+
-
- Email Address: |
-
-
- |
-
+
+ Email Address: |
+
+
+ |
+
-
- Account ID: |
-
-
- |
-
+
+ Account ID: |
+
+
+ |
+
-
- Choose: |
- |
-
-
+
+ Choose: |
+ |
+
+
-
- Register
-
+
+ Register
+
+
+
+
+