source: trunk/www/main.jsp @ 7529

Last change on this file since 7529 was 7529, checked in by Nicklas Nordborg, 3 years ago

References #2131: Add support for installing multiple authentication managers

If there are more than one installed login manager the login page now displays a selection list with the ability to switch between them.

One "problem" is that the CSS and javascript for all login managers are loaded and CSS rules may not work well together. For example, if the Yubikey and OTP extensions are both enabled, the yubikey icon is displayed in the "Login" field also for the OTP login. On the other hand, the OTP icon is always displayed in the help text...

To fix this the extensions need to update their CSS rules so that they only apply when their own login form is active. To help with this, BASE will set an attribute on the <body> tag:

  <body data-login-form="id-of-login-form">

where id-of-login-form' is the value returned by the LoginFormAction?.getId()` method. Scripts should also check this value.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.2 KB
Line 
1<%-- $Id: main.jsp 7529 2018-11-26 07:30:41Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg
5  Copyright (C) 2007 Nicklas Nordborg
6
7  This file is part of BASE - BioArray Software Environment.
8  Available at http://base.thep.lu.se/
9
10  BASE is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License
12  as published by the Free Software Foundation; either version 3
13  of the License, or (at your option) any later version.
14
15  BASE is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with BASE. If not, see <http://www.gnu.org/licenses/>.
22  ------------------------------------------------------------------
23
24  This is the front page of BASE. It displays a login form
25  and some of the relevant news items.
26
27  @param login The value to display in the login input field.
28  @param error An error message that should be displayed
29
30  @author Nicklas
31  @version 2.0
32--%>
33<%@ page pageEncoding="UTF-8" session="false"
34  import="net.sf.basedb.core.Application"
35  import="net.sf.basedb.core.SessionControl"
36  import="net.sf.basedb.core.DbControl"
37  import="net.sf.basedb.core.News"
38  import="net.sf.basedb.core.ItemQuery"
39  import="net.sf.basedb.core.ItemResultIterator"
40  import="net.sf.basedb.core.query.Orders"
41  import="net.sf.basedb.core.query.Hql"
42  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
43  import="net.sf.basedb.util.extensions.ActionIterator"
44  import="net.sf.basedb.clients.web.Base"
45  import="net.sf.basedb.clients.web.util.HTML"
46  import="net.sf.basedb.util.formatter.Formatter"
47  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
48  import="net.sf.basedb.clients.web.extensions.JspContext"
49  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
50  import="net.sf.basedb.clients.web.servlet.RssNewsFeed"
51  import="net.sf.basedb.clients.web.extensions.login.LoginFormAction"
52  import="net.sf.basedb.clients.web.extensions.login.LoginFormBean"
53  import="net.sf.basedb.clients.web.extensions.login.FieldInfo"
54  import="net.sf.basedb.util.Values"
55  import="java.util.Date"
56  import="java.util.Map"
57  import="java.util.TreeMap"
58%>
59<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
60<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
61<%! 
62// If value is null, return "", else <prefix>+<value>+<suffix>
63String valueIfNotNull(String prefix, String value, String suffix)
64{
65  return value == null ? "" : prefix+value+suffix;
66}
67%>
68<%
69final String login = Values.getString(request.getParameter("login"), "");
70final String error = Values.getString(request.getParameter("error"), null);
71final String requestedLoginForm = Values.getString(request.getParameter("loginForm"), null);
72final String root = request.getContextPath()+"/";
73
74final SessionControl sc = Base.getSessionControl(pageContext, true);
75final String ID = sc.getId();
76final Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
77final DbControl dc = sc.newDbControl();
78
79try
80{
81  String broadcastTitle = (String)application.getAttribute("broadcast.title");
82  String broadcastMessage = (String)application.getAttribute("broadcast.message");
83  boolean denyLogin = Boolean.TRUE.equals(application.getAttribute("broadcast.deny-login"));
84  ItemResultIterator<News> news = null;
85  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext);
86  ExtensionsInvoker<LoginFormAction> invoker = (ExtensionsInvoker<LoginFormAction>)ExtensionsControl.useExtensions(jspContext, "net.sf.basedb.clients.web.login-form");
87
88  LoginFormAction loginAction = null;
89  String selectedLoginForm = null;
90  Map<String, String> allForms = new TreeMap<String, String>();
91 
92  ActionIterator<LoginFormAction> it = invoker.iterate();
93  while (it.hasNext())
94  {
95    LoginFormAction action = it.next();
96    if (action != null)
97    {
98      String formId = action.getId();
99      if (formId == null) formId = it.getExtension().getId();
100      String displayName = action.getDisplayName();
101      if (displayName == null) displayName = it.getExtension().getAbout().getName();
102      allForms.put(formId, displayName);
103     
104      if (loginAction == null || formId.equals(requestedLoginForm))
105      {
106        loginAction = action;
107        selectedLoginForm = formId;
108      }
109    }
110  }
111  if (loginAction == null)
112  {
113    LoginFormBean bean  = new LoginFormBean();
114    bean.setRememberLastLogin(true);
115    bean.setLoginField(FieldInfo.DEFAULT_LOGIN);
116    bean.setPasswordField(FieldInfo.DEFAULT_PASSWORD);
117    loginAction = bean;
118  }
119
120  FieldInfo loginField = loginAction.getLoginField();
121  FieldInfo passwordField = loginAction.getPasswordField();
122  FieldInfo extraField = loginAction.getExtraField();
123  %>
124  <base:page type="default">
125  <base:head styles="login.css" scripts="exception.js,~login.js">
126    <ext:scripts context="<%=jspContext%>" />
127    <ext:stylesheets context="<%=jspContext%>" />
128  </base:head>
129  <base:body style="padding-top: 5em;" data-login-form="<%=Values.getString(selectedLoginForm)%>">
130    <form name="login" action="login.jsp" method="post">
131    <input type="hidden" name="ID" value="<%=ID%>">
132    <input type="hidden" name="useAutoStartPage" value="1">
133    <input type="hidden" name="deviceToken" value="">
134   
135    <table style="margin: auto; width: 700px;">
136    <tr>
137    <td>
138      <%
139      if (loginAction.getHelp() != null)
140      {
141        %>
142        <div class="messagecontainer help" style="margin-bottom: 1em; font-style: italic;" id="login-help">
143        <%=loginAction.getHelp() %>
144        </div>
145        <%
146      }
147      if (error != null) 
148      {
149        %>
150        <div class="messagecontainer error" style="margin-top: 1em; margin-bottom: 1em;"><%=error%></div>
151        <%
152      }
153      if (allForms.size() > 1)
154      {
155        %>
156        <div style="text-align: right; margin-bottom: 0.25em;">
157          <b>Login with</b>
158          <select name="loginForm" id="loginForm" style="min-width: 10em;">
159          <%
160          for (Map.Entry<String, String> entry : allForms.entrySet())
161          {
162            String formId = entry.getKey();
163            %>
164            <option value="<%=formId%>" <%=formId.equals(selectedLoginForm) ? "selected" : ""%>><%=HTML.encodeTags(entry.getValue()) %>
165            <%
166          }
167          %>
168          </select>
169        </div>
170        <%
171      }
172      else if (selectedLoginForm != null)
173      {
174        %>
175        <input type="hidden" name="loginForm" value="<%=selectedLoginForm%>">
176        <%
177      }
178      %>
179      <table style="width: 100%; border-collapse: separate;">
180      <tr>
181        <td class="base-logo"><img src="images/baselogo.png" alt="BASE logo"></td>
182        <td style="width: 515px;">
183          <div id="loginform">
184          <table style="width: 100%;">
185            <tr <%=valueIfNotNull("class=\"", loginField.getClazz(), "\"")%> id="login-row">
186              <th class="bg-filled-100"><%=loginField.getPrompt() %></th>
187              <td colspan="2"><input class="text" name="login" id="login"
188                type="<%=loginField.hasHiddenCharacters() ? "password" : "text"%>"
189                value="<%=loginAction.rememberLastLogin() ? HTML.encodeTags(login) : ""%>" 
190                <%=denyLogin ? "disabled" : ""%>
191                <%=valueIfNotNull("style=\"", loginField.getStyle(), "\"") %>
192                <%=valueIfNotNull("title=\"", loginField.getTooltip(), "\"") %>
193                <%=valueIfNotNull("placeholder=\"", loginField.getPlaceHolder(), "\"") %>
194                <%=loginAction.rememberLastLogin() ? "" : "autocomplete=\"off\" data-use-last-login=\"0\""%>
195                maxlength="100" 
196                tabindex="1">
197              </td>
198            </tr>
199            <tr <%=valueIfNotNull("class=\"", passwordField.getClazz(), "\"")%> id="password-row">
200              <th class="bg-filled-100"><%=passwordField.getPrompt() %></th>
201              <td><input class="text" name="password" id="password"
202                type="<%=passwordField.hasHiddenCharacters() ? "password" : "text"%>"
203                <%=denyLogin ? "disabled" : ""%>
204                <%=valueIfNotNull("style=\"", passwordField.getStyle(), "\"") %>
205                <%=valueIfNotNull("title=\"", passwordField.getTooltip(), "\"") %>
206                <%=valueIfNotNull("placeholder=\"", passwordField.getPlaceHolder(), "\"") %>
207                maxlength="80"
208                tabindex="2">
209              </td>
210              <td <%=extraField != null?"rowspan=\"2\"" : "" %> style="vertical-align: bottom;"><base:button 
211                id="btnLogin"
212                subclass="<%=denyLogin ? "disabled" : ""%>"
213                image="login.png" title="Login" 
214                tooltip="<%=HTML.encodeTags(broadcastTitle)%>" tabindex="4" /></td>
215            </tr>
216            <%
217            if (extraField != null)
218            {
219              %>
220              <tr <%=valueIfNotNull("class=\"", extraField.getClazz(), "\"")%> id="extra-row">
221                <th class="bg-filled-100"><%=extraField.getPrompt() %></th>
222                <td><input class="text" name="extraField" id="extraField"
223                  type="<%=extraField.hasHiddenCharacters() ? "password" : "text"%>"
224                  <%=denyLogin ? "disabled" : ""%>
225                  <%=valueIfNotNull("style=\"", extraField.getStyle(), "\"") %>
226                  <%=valueIfNotNull("title=\"", extraField.getTooltip(), "\"") %>
227                  <%=valueIfNotNull("placeholder=\"", extraField.getPlaceHolder(), "\"") %>
228                  maxlength="80"
229                  tabindex="3">
230                </td>
231              </tr>
232              <%
233            }
234            %>
235            <tr>
236              <th class="bg-filled-100 subprompt"></th>
237              <td colspan="2">
238              <%
239              String forgotPassword = sc.getClientDefaultSetting("server.forgotten.password");
240              String getAccount = sc.getClientDefaultSetting("server.get.account");
241              if (forgotPassword != null)
242              {
243                %>
244                <base:icon id="forgotPassword" image="bullet.png" 
245                  tooltip="Click here if you have forgotten your password">Forgot your password?</base:icon>
246                <%
247              }
248              if (getAccount != null)
249              {
250                %>
251                <base:icon id="getAccount" image="bullet.png" 
252                  tooltip="Click here if you want to get an account on this server">Get an account!</base:icon>
253                <%
254              }
255              %>
256              </td>
257            </tr>
258            </table>
259          </div>
260        </td>
261      </tr>
262      </table>
263      <%
264      if (denyLogin)
265      {
266        %>
267        <div class="messagecontainer help" id="denyLogin">
268          <b><%=HTML.encodeTags(broadcastTitle) %> (login disabled)</b><br>
269          <%=HTML.niceFormat(broadcastMessage)%>
270          <base:buttongroup style="margin-top: 1em;">
271            <base:button id="btnLoginAnyway" title="Login anyway" image="login.png" tooltip="At your own risk!" />
272          </base:buttongroup>
273        </div>
274        <%
275      }
276      %>
277      <%
278      String aboutServer = sc.getClientDefaultSetting("server.about");
279      if (aboutServer != null)
280      {
281        %>
282        <h3 style="margin-top: 1em;">About this server</h3>
283        <p>
284          <%=aboutServer%>
285        </p>
286        <base:icon id="aboutServer" image="bullet.png">More about this server</base:icon>
287        <%
288      }
289      %>
290     
291      <h3 style="margin-top: 1em;">News and announcements
292      <%
293      if (RssNewsFeed.isEnabled()) 
294      {
295        %>
296        <a href="info/news.rss" 
297          title="Subscribe to news from this BASE server"
298          ><base:icon image="rss.png" style="float: right;" /></a>
299        <%
300      }
301      %>
302      </h3>
303      <div id="news" class="news">
304      <%
305      if (broadcastTitle != null)
306      {
307        %>
308        <div class="item note sticky">
309          <div class="headline">
310            <span class="date"><%=dateFormatter.format(new Date())%></span>
311            <%=HTML.encodeTags(broadcastTitle)%><%=denyLogin ? " (login disabled)" : "" %>
312          </div>
313          <div class="text"><%=HTML.niceFormat(broadcastMessage)%></div>
314        </div>
315        <% 
316      }
317     
318      ItemQuery<News> query = News.getQuery();
319      query.order(Orders.desc(Hql.property("sticky")));
320      query.order(Orders.desc(Hql.property("newsDate")));
321      query.order(Orders.desc(Hql.property("id")));
322      query.setCacheResult(true);
323      query.setReturnTotalCount(true);
324      news = query.iterate(dc);
325      int numListed = 0;
326      while (news.hasNext())
327      {
328        News n = news.next();
329        if (numListed >= 10 && !n.isSticky()) break;
330        %>
331        <div class="item <%=n.isSticky() ? "note sticky" : ""%>">
332          <div class="headline">
333            <span class="date"><%=dateFormatter.format(n.getNewsDate())%></span>
334            <%=HTML.encodeTags(n.getName())%>
335          </div>
336          <div class="text"><%=HTML.niceFormat(n.getDescription())%></div>
337        </div>
338        <%
339        numListed++;
340      }
341      if (numListed < news.getTotalCount())
342      {
343        %>
344        <base:icon image="bullet.png" /><a href="info/news.jsp" 
345          title="Show older news..."><%=news.getTotalCount()-numListed%> more</a>
346        <%
347      }
348      %>
349      </div>
350    </td>
351    </tr>
352    </table>
353
354    </form>
355  </base:body>
356  </base:page>
357  <%
358}
359finally
360{
361  if (dc != null) dc.close();
362}
363%>
364
Note: See TracBrowser for help on using the repository browser.