summaryrefslogtreecommitdiffstats
path: root/gerrit-httpd
diff options
context:
space:
mode:
authorShawn Pearce <sop@google.com>2013-04-23 13:49:57 -0700
committerShawn Pearce <sop@google.com>2013-04-23 13:49:57 -0700
commitb216ac07ecddc4f32de2af574b3ce1d8b11cb8de (patch)
treefa94a313483f72ecb2eb2b208c9b4a75bed4cd3e /gerrit-httpd
parent98c89249c574d7a37c52825b9bb368cda35eca33 (diff)
Include site header, footer and CSS on OpenID login form
Bug: issue 1879 Change-Id: I1c583e01433d09627ac845288cd67db35029ae58
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/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
5 files changed, 230 insertions, 110 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/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>