001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace; 029 030import org.opencms.db.CmsLoginMessage; 031import org.opencms.db.CmsUserSettings; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsProject; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.i18n.CmsAcceptLanguageHeaderParser; 037import org.opencms.i18n.CmsEncoder; 038import org.opencms.i18n.CmsMessageContainer; 039import org.opencms.json.JSONArray; 040import org.opencms.json.JSONException; 041import org.opencms.json.JSONObject; 042import org.opencms.jsp.CmsJspLoginBean; 043import org.opencms.main.CmsException; 044import org.opencms.main.CmsLog; 045import org.opencms.main.OpenCms; 046import org.opencms.security.CmsCustomLoginException; 047import org.opencms.security.CmsOrganizationalUnit; 048import org.opencms.ui.CmsVaadinUtils; 049import org.opencms.ui.apps.CmsPageEditorConfiguration; 050import org.opencms.ui.login.CmsLoginUI; 051import org.opencms.util.CmsRequestUtil; 052import org.opencms.util.CmsStringUtil; 053import org.opencms.util.CmsUriSplitter; 054 055import java.io.IOException; 056import java.util.ArrayList; 057import java.util.Calendar; 058import java.util.Date; 059import java.util.GregorianCalendar; 060import java.util.Iterator; 061import java.util.List; 062import java.util.Locale; 063 064import javax.servlet.http.Cookie; 065import javax.servlet.http.HttpServletRequest; 066import javax.servlet.http.HttpServletResponse; 067import javax.servlet.http.HttpSession; 068import javax.servlet.jsp.PageContext; 069 070import org.apache.commons.logging.Log; 071 072/** 073 * Handles the login of Users to the OpenCms workplace.<p> 074 * 075 * @since 6.0.0 076 */ 077public class CmsLogin extends CmsJspLoginBean { 078 079 /** Action constant: Default action, display the dialog. */ 080 public static final int ACTION_DISPLAY = 0; 081 082 /** Action constant: Login successful. */ 083 public static final int ACTION_LOGIN = 1; 084 085 /** Action constant: Logout. */ 086 public static final int ACTION_LOGOUT = 2; 087 088 /** The parameter name for the "getoulist" action. */ 089 public static final String PARAM_ACTION_GETOULIST = "getoulist"; 090 091 /** The parameter name for the "login" action. */ 092 public static final String PARAM_ACTION_LOGIN = "login"; 093 094 /** The parameter name for the "logout" action. */ 095 public static final String PARAM_ACTION_LOGOUT = "logout"; 096 097 /** The html id for the login form. */ 098 public static final String PARAM_FORM = "ocLoginForm"; 099 100 /** The parameter name for the organizational unit. */ 101 public static final String PARAM_OUFQN = "ocOuFqn"; 102 103 /** The parameter name for the search organizational unit. */ 104 public static final String PARAM_OUSEARCH = "ocOuSearch"; 105 106 /** The parameter name for the password. */ 107 public static final String PARAM_PASSWORD = "ocPword"; 108 109 /** The parameter name for the PC type. */ 110 public static final String PARAM_PCTYPE = "ocPcType"; 111 112 /** The parameter name for the organizational unit. */ 113 public static final String PARAM_PREDEF_OUFQN = "ocPredefOuFqn"; 114 115 /** The parameter name for the user name. */ 116 public static final String PARAM_USERNAME = "ocUname"; 117 118 /** The parameter name for the workplace data. */ 119 public static final String PARAM_WPDATA = "ocWpData"; 120 121 /** PC type constant: private PC. */ 122 public static final String PCTYPE_PRIVATE = "private"; 123 124 /** PC type constant: public PC. */ 125 public static final String PCTYPE_PUBLIC = "public"; 126 127 /** The oufqn cookie name. */ 128 private static final String COOKIE_OUFQN = "OpenCmsOuFqn"; 129 130 /** The PC type cookie name. */ 131 private static final String COOKIE_PCTYPE = "OpenCmsPcType"; 132 133 /** The username cookie name. */ 134 private static final String COOKIE_USERNAME = "OpenCmsUserName"; 135 136 /** The workplace data cookie name, value stores following information: ${left},${top},${width},${height}. */ 137 private static final String COOKIE_WP_DATA = "OpenCmsWpData"; 138 139 /** The log object for this class. */ 140 private static final Log LOG = CmsLog.getLog(CmsLogin.class); 141 142 /** The action to perform. */ 143 private int m_action; 144 145 /** The value of the "login" action parameter. */ 146 private String m_actionLogin; 147 148 /** The value of the "logout" action parameter. */ 149 private String m_actionLogout; 150 151 /** The path to open if direct edit is selected as start view. */ 152 private String m_directEditPath; 153 154 /** The locale to use for display, this will not be the workplace locale, but the browser locale. */ 155 private Locale m_locale; 156 157 /** The message to display with the dialog in a JavaScrip alert. */ 158 private CmsMessageContainer m_message; 159 160 /** The selected organizational unit. */ 161 private CmsOrganizationalUnit m_ou; 162 163 /** The value of the organizational unit parameter. */ 164 private String m_oufqn; 165 166 /** The list of all organizational units. */ 167 private List<CmsOrganizationalUnit> m_ous; 168 169 /** The value of the password parameter. */ 170 private String m_password; 171 172 /** The value of the PC type parameter. */ 173 private String m_pcType; 174 175 /** The redirect URL after a successful login. */ 176 private String m_requestedResource; 177 178 /** The value of the user name parameter. */ 179 private String m_username; 180 181 /** 182 * Public constructor for login page.<p> 183 * 184 * @param context the JSP page context object 185 * @param req the JSP request 186 * @param res the JSP response 187 */ 188 public CmsLogin(PageContext context, HttpServletRequest req, HttpServletResponse res) { 189 190 super(context, req, res); 191 192 // this page must never be cached 193 res.setDateHeader(CmsRequestUtil.HEADER_LAST_MODIFIED, System.currentTimeMillis()); 194 CmsRequestUtil.setNoCacheHeaders(res); 195 m_locale = getLocaleForRequest(req); 196 } 197 198 /** 199 * Gets the copyright information HTML.<p> 200 * 201 * @param locale the locale for which to get the copyright info 202 * 203 * @return the copyright info HTML 204 */ 205 public static String getCopyrightHtml(Locale locale) { 206 207 StringBuffer html = new StringBuffer(); 208 html.append("<div style=\"text-align: center; font-size: 10px; white-space: nowrap;\">"); 209 html.append("<a href=\"http://www.opencms.org\" target=\"_blank\">OpenCms</a> "); 210 html.append(Messages.get().getBundle(locale).key(Messages.GUI_LOGIN_OPENCMS_IS_FREE_SOFTWARE_0)); 211 html.append("</div>\n"); 212 html.append("<div style=\"text-align: center; font-size: 10px; white-space: nowrap;\">"); 213 html.append(Messages.get().getBundle(locale).key(Messages.GUI_LOGIN_TRADEMARKS_0)); 214 html.append("</div>\n"); 215 html.append("<div style=\"text-align: center; font-size: 10px; white-space: nowrap;\">"); 216 html.append("© 2002 - 2015 Alkacon Software GmbH & Co. KG. "); 217 html.append(Messages.get().getBundle(locale).key(Messages.GUI_LOGIN_RIGHTS_RESERVED_0)); 218 html.append("</div>\n"); 219 return html.toString(); 220 } 221 222 /** 223 * Returns the direct edit path from the user settings, or <code>null</code> if not set.<p> 224 * 225 * @param cms the CMS context to use 226 * @param userSettings the user settings 227 * 228 * @return the direct edit path 229 */ 230 public static String getDirectEditPath(CmsObject cms, CmsUserSettings userSettings) { 231 232 if (userSettings.getStartView().equals(CmsWorkplace.VIEW_DIRECT_EDIT) 233 | userSettings.getStartView().equals(CmsPageEditorConfiguration.APP_ID)) { 234 235 try { 236 CmsObject cloneCms = OpenCms.initCmsObject(cms); 237 String startSite = CmsWorkplace.getStartSiteRoot(cloneCms, userSettings); 238 cloneCms.getRequestContext().setSiteRoot(startSite); 239 String projectName = userSettings.getStartProject(); 240 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(projectName)) { 241 cloneCms.getRequestContext().setCurrentProject(cloneCms.readProject(projectName)); 242 } 243 String folder = userSettings.getStartFolder(); 244 CmsResource targetRes = cloneCms.readDefaultFile(folder); 245 if (targetRes != null) { 246 return cloneCms.getSitePath(targetRes); 247 } 248 } catch (Exception e) { 249 LOG.debug(e.getLocalizedMessage(), e); 250 } 251 } 252 return null; 253 } 254 255 /** 256 * Gets the list of OUs which should be selectable in the login dialog.<p> 257 * 258 * @param cms the CMS context to use 259 * @param predefOu the predefined OU 260 * 261 * @return the list of organizational units for the OU selector 262 */ 263 public static List<CmsOrganizationalUnit> getOrgUnitsForLoginDialog(CmsObject cms, String predefOu) { 264 265 List<CmsOrganizationalUnit> result = new ArrayList<CmsOrganizationalUnit>(); 266 try { 267 if (predefOu == null) { 268 result.add(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "")); 269 result.addAll(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, "", true)); 270 Iterator<CmsOrganizationalUnit> itOus = result.iterator(); 271 while (itOus.hasNext()) { 272 CmsOrganizationalUnit ou = itOus.next(); 273 if (ou.hasFlagHideLogin() || ou.hasFlagWebuser()) { 274 itOus.remove(); 275 } 276 } 277 } else { 278 result.add(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, predefOu)); 279 } 280 } catch (CmsException e) { 281 LOG.error(e.getLocalizedMessage(), e); 282 } 283 return result; 284 285 } 286 287 /** 288 * Gets the window title for a given locale.<p> 289 * 290 * @param locale the locale 291 * @return the window title 292 */ 293 public static String getTitle(Locale locale) { 294 295 return Messages.get().getBundle(locale).key(Messages.GUI_LOGIN_TITLE_0); 296 } 297 298 /** 299 * Initializes the site and project for a CMS context after login, and returns the workplace settings for the corresponding user.<p> 300 * 301 * @param cms the CMS context which should be initialized 302 * @return the workplace set 303 */ 304 public static CmsWorkplaceSettings initSiteAndProject(CmsObject cms) { 305 306 CmsWorkplaceSettings workplaceSettings = CmsWorkplace.initWorkplaceSettings(cms, null, false); 307 String startSite = CmsWorkplace.getStartSiteRoot(cms, workplaceSettings); 308 // switch to the preferred site 309 workplaceSettings.setSite(startSite); 310 cms.getRequestContext().setSiteRoot(startSite); 311 // store the workplace settings 312 CmsUserSettings settings = workplaceSettings.getUserSettings(); 313 // get the direct edit path 314 315 try { 316 CmsProject project = cms.readProject(settings.getStartProject()); 317 if (OpenCms.getOrgUnitManager().getAllAccessibleProjects(cms, project.getOuFqn(), false).contains( 318 project)) { 319 // user has access to the project, set this as current project 320 workplaceSettings.setProject(project.getUuid()); 321 cms.getRequestContext().setCurrentProject(project); 322 } 323 } catch (CmsException e) { 324 // unable to set the startup project, bad but not critical 325 LOG.warn( 326 Messages.get().getBundle().key( 327 Messages.LOG_LOGIN_NO_STARTUP_PROJECT_2, 328 cms.getRequestContext().getCurrentUser().getName(), 329 settings.getStartProject()), 330 e); 331 } 332 return workplaceSettings; 333 } 334 335 /** 336 * Sets the cookie data.<p> 337 * 338 * @param pcType the pctype value 339 * @param username the username value 340 * @param oufqn the oufqn value 341 * 342 * @param request the current request 343 * @param response the current response 344 */ 345 public static void setCookieData( 346 String pcType, 347 String username, 348 String oufqn, 349 HttpServletRequest request, 350 HttpServletResponse response) { 351 352 // set the PC type cookie only if security dialog is enabled 353 if (OpenCms.getLoginManager().isEnableSecurity() && CmsStringUtil.isNotEmpty(pcType)) { 354 Cookie pcTypeCookie = getCookie(request, COOKIE_PCTYPE); 355 pcTypeCookie.setValue(pcType); 356 setCookie(pcTypeCookie, false, request, response); 357 } 358 359 // only store user name and OU cookies on private PC types 360 if (PCTYPE_PRIVATE.equals(pcType)) { 361 // set the user name cookie 362 Cookie userNameCookie = getCookie(request, COOKIE_USERNAME); 363 userNameCookie.setValue(username); 364 setCookie(userNameCookie, false, request, response); 365 366 // set the organizational unit cookie 367 Cookie ouFqnCookie = getCookie(request, COOKIE_OUFQN); 368 ouFqnCookie.setValue(oufqn); 369 setCookie(ouFqnCookie, false, request, response); 370 } else if (OpenCms.getLoginManager().isEnableSecurity() && PCTYPE_PUBLIC.equals(pcType)) { 371 // delete user name and organizational unit cookies 372 Cookie userNameCookie = getCookie(request, COOKIE_USERNAME); 373 setCookie(userNameCookie, true, request, response); 374 Cookie ouFqnCookie = getCookie(request, COOKIE_OUFQN); 375 setCookie(ouFqnCookie, true, request, response); 376 377 } 378 } 379 380 /** 381 * Checks that the user name and password are not empty, and returns an error message if they are.<p> 382 * 383 * @param username the user name 384 * @param password the password 385 * 386 * @return the error message, or null if the user name and password are OK 387 */ 388 public static CmsMessageContainer validateUserAndPasswordNotEmpty(String username, String password) { 389 390 boolean userEmpty = CmsStringUtil.isEmpty(username); 391 boolean passwordEmpty = CmsStringUtil.isEmpty(password); 392 393 // login was requested 394 if (userEmpty && passwordEmpty) { 395 return Messages.get().container(Messages.GUI_LOGIN_NO_DATA_0); 396 } else if (userEmpty) { 397 return Messages.get().container(Messages.GUI_LOGIN_NO_NAME_0); 398 } else if (passwordEmpty) { 399 return Messages.get().container(Messages.GUI_LOGIN_NO_PASSWORD_0); 400 } 401 return null; 402 } 403 404 /** 405 * Returns the cookie with the given name, if not cookie is found a new one is created.<p> 406 * 407 * @param request the current request 408 * @param name the name of the cookie 409 * 410 * @return the cookie 411 */ 412 protected static Cookie getCookie(HttpServletRequest request, String name) { 413 414 Cookie[] cookies = request.getCookies(); 415 for (int i = 0; (cookies != null) && (i < cookies.length); i++) { 416 if (name.equalsIgnoreCase(cookies[i].getName())) { 417 return cookies[i]; 418 } 419 } 420 return new Cookie(name, ""); 421 } 422 423 /** 424 * Sets the cookie in the response.<p> 425 * 426 * @param cookie the cookie to set 427 * @param delete flag to determine if the cookir should be deleted 428 * @param request the current request 429 * @param response the current response 430 */ 431 protected static void setCookie( 432 Cookie cookie, 433 boolean delete, 434 HttpServletRequest request, 435 HttpServletResponse response) { 436 437 if (request.getAttribute(PARAM_PREDEF_OUFQN) != null) { 438 // prevent the use of cookies if using a direct ou login url 439 return; 440 } 441 int maxAge = 0; 442 if (!delete) { 443 // set the expiration date of the cookie to six months from today 444 GregorianCalendar cal = new GregorianCalendar(); 445 cal.add(Calendar.MONTH, 6); 446 maxAge = (int)((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000); 447 } 448 cookie.setMaxAge(maxAge); 449 // set the path 450 cookie.setPath(CmsStringUtil.joinPaths(OpenCms.getStaticExportManager().getVfsPrefix(), "/system/login")); 451 // set the cookie 452 response.addCookie(cookie); 453 } 454 455 /** 456 * Returns the best matching locale for the given request.<p> 457 * 458 * @param req the request 459 * 460 * @return the locale 461 */ 462 private static Locale getLocaleForRequest(HttpServletRequest req) { 463 464 CmsAcceptLanguageHeaderParser parser = new CmsAcceptLanguageHeaderParser( 465 req, 466 OpenCms.getWorkplaceManager().getDefaultLocale()); 467 List<Locale> acceptedLocales = parser.getAcceptedLocales(); 468 List<Locale> workplaceLocales = OpenCms.getWorkplaceManager().getLocales(); 469 Locale locale = OpenCms.getLocaleManager().getFirstMatchingLocale(acceptedLocales, workplaceLocales); 470 if (locale == null) { 471 // no match found - use OpenCms default locale 472 locale = OpenCms.getWorkplaceManager().getDefaultLocale(); 473 } 474 return locale; 475 } 476 477 /** 478 * Returns the HTML code for selecting an organizational unit.<p> 479 * 480 * @return the HTML code for selecting an organizational unit 481 */ 482 public String buildOrgUnitSelector() { 483 484 StringBuffer html = new StringBuffer(); 485 html.append("<select style='width: 100%;' size='1' "); 486 appendId(html, PARAM_OUFQN); 487 html.append(">\n"); 488 for (CmsOrganizationalUnit ou : getOus()) { 489 String selected = ""; 490 if (ou.getName().equals(m_oufqn) 491 || (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_oufqn) && ou.getName().equals(m_oufqn.substring(1)))) { 492 selected = " selected='selected'"; 493 } 494 html.append("<option value='").append(ou.getName()).append("'").append(selected).append(">"); 495 html.append(ou.getDisplayName(m_locale)); 496 html.append("</option>\n"); 497 } 498 html.append("</select>\n"); 499 return html.toString(); 500 } 501 502 /** 503 * Returns the HTML for the login dialog in it's current state.<p> 504 * 505 * @return the HTML for the login dialog 506 * 507 * @throws IOException in case a redirect fails 508 * @throws CmsException in case displaying the login dialog fails 509 */ 510 public String displayDialog() throws IOException, CmsException { 511 512 if ((OpenCms.getSiteManager().getSites().size() > 1) 513 && !OpenCms.getSiteManager().isWorkplaceRequest(getRequest())) { 514 515 // this is a multi site-configuration, but not a request to the configured Workplace site 516 // do not send any redirects to the workplace site for security reasons 517 getResponse().sendError(HttpServletResponse.SC_NOT_FOUND); 518 return null; 519 } 520 521 CmsObject cms = getCmsObject(); 522 if (shouldUseNewLogin() && (cms.getRequestContext().getCurrentUser().isGuestUser())) { 523 if (getRequest().getParameter(PARAM_ACTION_LOGOUT) != null) { 524 getResponse().sendRedirect(OpenCms.getLinkManager().substituteLink(cms, "/system/login")); 525 return ""; 526 } else { 527 return CmsLoginUI.displayVaadinLoginDialog(getRequest(), getResponse()); 528 } 529 } 530 531 m_message = null; 532 if (cms.getRequestContext().getCurrentUser().isGuestUser()) { 533 // user is not currently logged in 534 m_action = ACTION_DISPLAY; 535 m_username = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_USERNAME); 536 if (m_username != null) { 537 // remove white spaces, can only lead to confusion on user name 538 m_username = m_username.trim(); 539 } 540 m_password = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_PASSWORD); 541 m_actionLogin = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_ACTION_LOGIN); 542 m_oufqn = getRequest().getParameter(PARAM_OUFQN); 543 if (m_oufqn == null) { 544 m_oufqn = getPreDefOuFqn(); 545 } 546 if (OpenCms.getLoginManager().isEnableSecurity()) { 547 // security option is enabled, try to get PC type from request parameter 548 m_pcType = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_PCTYPE); 549 } else { 550 // if security option is disabled, just set PC type to "private" to get common login dialog 551 m_pcType = PCTYPE_PRIVATE; 552 } 553 554 // try to get some info from a cookie 555 getCookieData(); 556 557 // set PC type to "public" as default if not already set by cookie, request or if security option is disabled 558 if (m_pcType == null) { 559 m_pcType = PCTYPE_PUBLIC; 560 } 561 } else { 562 // user is already logged in 563 m_oufqn = cms.getRequestContext().getOuFqn(); 564 m_action = ACTION_LOGIN; 565 m_actionLogout = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_ACTION_LOGOUT); 566 } 567 568 if (m_oufqn == null) { 569 m_oufqn = CmsOrganizationalUnit.SEPARATOR; 570 } 571 572 String actionGetOus = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_ACTION_GETOULIST); 573 if (Boolean.TRUE.toString().equals(actionGetOus)) { 574 return getJsonOrgUnitList(); 575 } 576 577 // initialize the right ou 578 m_ou = null; 579 try { 580 m_ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(getCmsObject(), m_oufqn); 581 } catch (CmsException e) { 582 m_oufqn = CmsOrganizationalUnit.SEPARATOR; 583 try { 584 m_ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(getCmsObject(), m_oufqn); 585 } catch (CmsException exc) { 586 LOG.error(exc.getLocalizedMessage(), exc); 587 } 588 } 589 590 // initialize the requested resource 591 m_requestedResource = CmsRequestUtil.getNotEmptyParameter( 592 getRequest(), 593 CmsWorkplaceManager.PARAM_LOGIN_REQUESTED_RESOURCE); 594 if (m_requestedResource == null) { 595 // no resource was requested, use default workplace URI 596 m_requestedResource = CmsVaadinUtils.getWorkplaceLink(); 597 } 598 599 if (Boolean.valueOf(m_actionLogin).booleanValue()) { 600 CmsMessageContainer emptyValidation = validateUserAndPasswordNotEmpty(m_username, m_password); 601 if (emptyValidation != null) { 602 m_message = emptyValidation; 603 } else { 604 605 // try to login with the given user information 606 login((m_oufqn == null ? CmsOrganizationalUnit.SEPARATOR : m_oufqn) + m_username, m_password); 607 608 if (getLoginException() == null) { 609 // the login was successful 610 m_action = ACTION_LOGIN; 611 612 CmsWorkplaceSettings settings = initSiteAndProject(cms); 613 getRequest().getSession().setAttribute(CmsWorkplaceManager.SESSION_WORKPLACE_SETTINGS, settings); 614 m_directEditPath = getDirectEditPath(cms, settings.getUserSettings()); 615 } else { 616 // there was an error during login 617 CmsException loginException = getLoginException(); 618 619 if (org.opencms.security.Messages.ERR_LOGIN_FAILED_DISABLED_2 == loginException.getMessageContainer().getKey()) { 620 // the user account is disabled 621 m_message = Messages.get().container(Messages.GUI_LOGIN_FAILED_DISABLED_0); 622 } else if (org.opencms.security.Messages.ERR_LOGIN_FAILED_TEMP_DISABLED_4 == loginException.getMessageContainer().getKey()) { 623 // the user account is temporarily disabled because of too many login failures 624 m_message = Messages.get().container(Messages.GUI_LOGIN_FAILED_TEMP_DISABLED_0); 625 } else if (org.opencms.security.Messages.ERR_LOGIN_FAILED_WITH_MESSAGE_1 == loginException.getMessageContainer().getKey()) { 626 // all logins have been disabled be the Administration 627 CmsLoginMessage loginMessage = OpenCms.getLoginManager().getLoginMessage(); 628 if (loginMessage != null) { 629 m_message = Messages.get().container( 630 Messages.GUI_LOGIN_FAILED_WITH_MESSAGE_1, 631 loginMessage.getMessage()); 632 } 633 } 634 if (m_message == null) { 635 if (loginException instanceof CmsCustomLoginException) { 636 m_message = loginException.getMessageContainer(); 637 } else { 638 // any other error - display default message 639 m_message = Messages.get().container(Messages.GUI_LOGIN_FAILED_0); 640 } 641 } 642 } 643 } 644 } else if (Boolean.valueOf(m_actionLogout).booleanValue()) { 645 m_action = ACTION_LOGOUT; 646 // store the workplace window data 647 Cookie wpDataCookie = getCookie(getRequest(), COOKIE_WP_DATA); 648 String wpData = CmsRequestUtil.getNotEmptyParameter(getRequest(), PARAM_WPDATA); 649 if (wpData != null) { 650 wpData = CmsEncoder.escapeXml(wpData); 651 wpDataCookie.setValue(wpData); 652 setCookie(wpDataCookie, false, getRequest(), getResponse()); 653 } 654 // after logout this will automatically redirect to the login form again 655 logout(); 656 return null; 657 } 658 659 if (m_action == ACTION_LOGIN) { 660 // clear message 661 m_message = null; 662 // login is successful, check if the requested resource can be read 663 CmsUriSplitter splitter = new CmsUriSplitter(m_requestedResource, true); 664 String resource = splitter.getPrefix(); 665 if (CmsStringUtil.isEmptyOrWhitespaceOnly(resource)) { 666 // bad resource name, use workplace as default 667 resource = CmsWorkplace.JSP_WORKPLACE_URI; 668 } 669 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_directEditPath) 670 && !getCmsObject().existsResource(resource, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { 671 // requested resource does either not exist or is not readable by user 672 if (CmsWorkplace.JSP_WORKPLACE_URI.equals(resource)) { 673 // we know the Workplace exists, so the user does not have access to the Workplace 674 // probably this is a "Guest" user in a default setup where "Guest" has no access to the Workplace 675 m_message = Messages.get().container(Messages.GUI_LOGIN_FAILED_NO_WORKPLACE_PERMISSIONS_0); 676 m_action = ACTION_DISPLAY; 677 } else if (getCmsObject().existsResource(CmsWorkplace.JSP_WORKPLACE_URI)) { 678 // resource does either not exist or is not readable, but general workplace permissions are granted 679 m_message = Messages.get().container(Messages.GUI_LOGIN_UNKNOWN_RESOURCE_1, m_requestedResource); 680 m_requestedResource = CmsWorkplace.JSP_WORKPLACE_URI; 681 } else { 682 // resource does not exist and no general workplace permissions granted 683 m_message = Messages.get().container( 684 Messages.GUI_LOGIN_FAILED_NO_TARGET_PERMISSIONS_1, 685 m_requestedResource); 686 m_action = ACTION_DISPLAY; 687 } 688 } 689 if (m_action == ACTION_DISPLAY) { 690 //the login was invalid 691 m_requestedResource = null; 692 // destroy the generated session 693 HttpSession session = getRequest().getSession(false); 694 if (session != null) { 695 session.invalidate(); 696 } 697 setCookieData(getRequest(), getResponse()); 698 } else { 699 // successfully logged in, so set the cookie 700 setCookieData(getRequest(), getResponse()); 701 } 702 } 703 704 return displayLoginForm(); 705 } 706 707 /** 708 * Gets the login info from the cookies.<p> 709 */ 710 public void getCookieData() { 711 712 // get the PC type cookie 713 Cookie pcTypeCookie = getCookie(getRequest(), COOKIE_PCTYPE); 714 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(pcTypeCookie.getValue())) { 715 // only set the data if needed 716 if (m_pcType == null) { 717 m_pcType = pcTypeCookie.getValue(); 718 } 719 } 720 if ("null".equals(m_pcType)) { 721 m_pcType = null; 722 } 723 // get other cookies only on private PC types (or if security option is disabled) 724 if ((m_pcType == null) || PCTYPE_PRIVATE.equals(m_pcType)) { 725 // get the user name cookie 726 Cookie userNameCookie = getCookie(getRequest(), COOKIE_USERNAME); 727 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(userNameCookie.getValue())) { 728 // only set the data if needed 729 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_username)) { 730 m_username = userNameCookie.getValue(); 731 } 732 if (m_pcType == null) { 733 // set PC type to private PC if the user cookie is found 734 m_pcType = PCTYPE_PRIVATE; 735 } 736 } 737 if ("null".equals(m_username)) { 738 m_username = null; 739 } 740 // get the organizational unit cookie 741 Cookie ouFqnCookie = getCookie(getRequest(), COOKIE_OUFQN); 742 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(ouFqnCookie.getValue())) { 743 // only set the data if needed 744 if (m_oufqn == null) { 745 m_oufqn = ouFqnCookie.getValue(); 746 } 747 } 748 if ("null".equals(m_oufqn)) { 749 m_oufqn = null; 750 } 751 } 752 } 753 754 /** 755 * @see org.opencms.jsp.CmsJspLoginBean#getFormLink() 756 */ 757 @Override 758 public String getFormLink() { 759 760 if (getPreDefOuFqn() == null) { 761 return super.getFormLink(); 762 } 763 String preDefOuFqn = (String)getRequest().getAttribute(PARAM_PREDEF_OUFQN); 764 try { 765 OpenCms.getOrgUnitManager().readOrganizationalUnit(getCmsObject(), preDefOuFqn); 766 } catch (CmsException e) { 767 // organizational unit does not exist 768 return super.getFormLink(); 769 } 770 return link("/system/login" + CmsEncoder.escapeXml(preDefOuFqn)); 771 } 772 773 /** 774 * Returns the available organizational units as JSON array string.<p> 775 * 776 * @return the available organizational units as JSON array string 777 */ 778 public String getJsonOrgUnitList() { 779 780 List<CmsOrganizationalUnit> allOus = getOus(); 781 List<JSONObject> jsonOus = new ArrayList<JSONObject>(allOus.size()); 782 int index = 0; 783 for (CmsOrganizationalUnit ou : allOus) { 784 JSONObject jsonObj = new JSONObject(); 785 try { 786 // 1: OU fully qualified name 787 jsonObj.put("name", ou.getName()); 788 // 2: OU display name 789 jsonObj.put("displayname", ou.getDisplayName(m_locale)); 790 // 3: OU simple name 791 jsonObj.put("simplename", ou.getSimpleName()); 792 // 4: OU description 793 jsonObj.put("description", ou.getDescription(m_locale)); 794 // 5: selection flag 795 boolean isSelected = false; 796 if (ou.getName().equals(m_oufqn) 797 || (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_oufqn) 798 && ou.getName().equals(m_oufqn.substring(1)))) { 799 isSelected = true; 800 } 801 jsonObj.put("active", isSelected); 802 // 6: level of the OU 803 jsonObj.put("level", CmsResource.getPathLevel(ou.getName())); 804 // 7: OU index 805 jsonObj.put("index", index); 806 // add the generated JSON object to the result list 807 jsonOus.add(jsonObj); 808 index++; 809 } catch (JSONException e) { 810 // error creating JSON object, skip this OU 811 } 812 } 813 // generate a JSON array from the JSON object list 814 JSONArray jsonArr = new JSONArray(jsonOus); 815 return jsonArr.toString(); 816 } 817 818 /** 819 * Sets the cookie data.<p> 820 * 821 * @param request the current request 822 * @param response the current response 823 */ 824 public void setCookieData(HttpServletRequest request, HttpServletResponse response) { 825 826 setCookieData(m_pcType, m_username, m_oufqn, request, response); 827 } 828 829 /** 830 * Appends the JavaScript for the login screen to the given HTML buffer.<p> 831 * 832 * @param html the HTML buffer to append the script to 833 * @param message the message to display after an unsuccessful login 834 */ 835 protected void appendDefaultLoginScript(StringBuffer html, CmsMessageContainer message) { 836 837 html.append("<script src=\""); 838 html.append(CmsWorkplace.getSkinUri()).append("jquery/packed/jquery.js"); 839 html.append("\"></script>\n"); 840 html.append("<script >\n"); 841 if (message != null) { 842 html.append("function showAlert() {\n"); 843 html.append("\talert(\""); 844 html.append(CmsStringUtil.escapeJavaScript(message.key(m_locale))); 845 html.append("\");\n"); 846 html.append("}\n"); 847 } 848 html.append("var orgUnitShow = false;\n"); 849 html.append("var orgUnits = null;\n"); 850 html.append("var activeOu = -1;\n"); 851 html.append("var searchTimeout;\n"); 852 html.append("var searchDefaultValue = \""); 853 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_SEARCH_0)); 854 html.append("\";\n"); 855 856 // triggers the options to select the OU to login to 857 html.append("function orgUnitSelection() {\n"); 858 html.append("\tif (!orgUnitShow) {\n"); 859 html.append("\t\tif (orgUnits == null) {\n"); 860 html.append("\t\t\t$.post(\""); 861 html.append(getFormLink()); 862 html.append("\", { "); 863 html.append(PARAM_ACTION_GETOULIST); 864 html.append(": \"true\" }"); 865 html.append(", function(data){ fillOrgUnits(data); });\n"); 866 html.append("\t\t}\n"); 867 html.append("\t\tdocument.getElementById('ouSelId').style.display = 'block';\n"); 868 html.append("\t\tdocument.getElementById('ouLabelId').style.display = 'block';\n"); 869 html.append("\t\tdocument.getElementById('ouSearchId').style.display = 'block';\n"); 870 html.append("\t\tdocument.getElementById('ouBtnId').value = '"); 871 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_SELECT_OFF_0)); 872 html.append("';\n"); 873 html.append("\t} else {\n"); 874 html.append("\t\tdocument.getElementById('ouSelId').style.display = 'none';\n"); 875 html.append("\t\tdocument.getElementById('ouLabelId').style.display = 'none';\n"); 876 html.append("\t\tdocument.getElementById('ouSearchId').style.display = 'none';\n"); 877 html.append("\t\tdocument.getElementById('ouBtnId').value = '"); 878 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_SELECT_ON_0)); 879 html.append("';\n"); 880 html.append("\t}\n"); 881 html.append("\torgUnitShow = !orgUnitShow;\n"); 882 html.append("\tdocument.getElementById('titleId').style.display = 'block';\n"); 883 html.append("\tdocument.getElementById('titleIdOu').style.display = 'none';\n"); 884 html.append("}\n"); 885 886 // creates the HTML for the OUs to login to 887 html.append("function fillOrgUnits(data) {\n"); 888 html.append("\torgUnits = eval(data);\n"); 889 html.append("\tvar html = \"\";\n"); 890 html.append("\tvar foundOu = false;\n"); 891 html.append("\tvar activeIndex = -1;\n"); 892 html.append("\tfor (var i = 0; i < orgUnits.length; i++) {\n"); 893 html.append("\t\tvar currOu = orgUnits[i];\n"); 894 html.append("\t\tvar actClass = \"\";\n"); 895 html.append("\t\tif (currOu.active == true) {\n"); 896 html.append("\t\t\t// this is the active OU\n"); 897 html.append("\t\t\tactiveOu = currOu.index;\n"); 898 html.append("\t\t\tactClass = \" class=\\\"active\\\"\";\n"); 899 html.append("\t\t}\n"); 900 html.append("\t\tvar actStyle = \"\";\n"); 901 html.append("\t\tif (currOu.level > 0) {\n"); 902 html.append("\t\t\tactStyle = \" style=\\\"margin-left: \" + (currOu.level * 20) + \"px;\\\"\";\n"); 903 html.append("\t\t}\n"); 904 html.append("\t\thtml += \"<div\";\n"); 905 html.append("\t\thtml += actClass;\n"); 906 html.append("\t\thtml += actStyle;\n"); 907 html.append("\t\thtml += \" id=\\\"ou\" + currOu.index;\n"); 908 html.append("\t\thtml += \"\\\" onclick=\\\"selectOu('\";\n"); 909 html.append("\t\thtml += currOu.name;\n"); 910 html.append("\t\thtml += \"', \" + currOu.index;\n"); 911 html.append("\t\thtml += \");\\\"><span class=\\\"name\\\">\";\n"); 912 html.append("\t\thtml += currOu.description;\n"); 913 html.append("\t\thtml += \"</span>\";\n"); 914 html.append("\t\tif (currOu.name != \"\") {\n"); 915 html.append("\t\t\thtml += \"<span class=\\\"path\\\"\";\n"); 916 html.append("\t\t\thtml += \" title=\\\"\";\n"); 917 html.append("\t\t\thtml += currOu.name;\n"); 918 html.append("\t\t\thtml += \"\\\">\";\n"); 919 html.append("\t\t\thtml += currOu.simplename;\n"); 920 html.append("\t\t\thtml += \"</span>\";\n"); 921 html.append("\t\t}\n"); 922 html.append("\t\thtml += \"</div>\";\n"); 923 html.append("\t}\n"); 924 html.append( 925 "\thtml += \"<div id=\\\"nooufound\\\" style=\\\"display: none;\\\"><span class=\\\"name\\\">\";\n"); 926 html.append("\thtml += \""); 927 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_SEARCH_NORESULTS_0)); 928 html.append("\";\n"); 929 html.append("\thtml += \"</span></div>\";\n"); 930 html.append("\t$(\"#ouSelId\").append(html);\n"); 931 html.append("\t$(\"#ouSelId\").slideDown();\n"); 932 html.append("\tscrollToActiveOu();\n"); 933 html.append("}\n"); 934 935 // shows the list of OUs matching the search term or all OUs if the search term is empty 936 html.append("function showOrgUnits(searchTerm) {\n"); 937 html.append("\tvar html = \"\";\n"); 938 html.append("\tvar foundOu = false;\n"); 939 html.append("\tfor (var i = 0; i < orgUnits.length; i++) {\n"); 940 html.append("\t\tvar currOu = orgUnits[i];\n"); 941 html.append("\t\tif (searchTerm != \"\") {\n"); 942 html.append("\t\t\tvar stLower = searchTerm.toLowerCase();\n"); 943 html.append( 944 "\t\t\tif (currOu.name.toLowerCase().indexOf(stLower )== -1 && currOu.description.toLowerCase().indexOf(stLower) == -1) {\n"); 945 html.append("\t\t\t\t$(\"#ou\" + i + \":visible\").slideUp();\n"); 946 html.append("\t\t\t} else {\n"); 947 html.append("\t\t\t\t$(\"#ou\" + i + \":hidden\").slideDown();\n"); 948 html.append("\t\t\t\t$(\"#ou\" + i).removeAttr(\"style\");\n"); 949 html.append("\t\t\t\tfoundOu = true;\n"); 950 html.append("\t\t\t}\n"); 951 html.append("\t\t} else {\n"); 952 html.append("\t\t\tfoundOu = true;\n"); 953 html.append("\t\t\tvar actStyle = \"\";\n"); 954 html.append("\t\t\tif (currOu.level > 0) {\n"); 955 html.append("\t\t\t\tactStyle = \"margin-left: \" + (currOu.level * 20) + \"px;\";\n"); 956 html.append("\t\t\t}\n"); 957 html.append("\t\t\t$(\"#ou\" + i).attr(\"style\", actStyle);\n"); 958 html.append("\t\t\t$(\"#ou\" + i + \":hidden\").slideDown();\n"); 959 html.append("\t\t}\n"); 960 html.append("\t}\n"); 961 html.append("\tif (searchTerm != \"\" && foundOu == false) {\n"); 962 html.append("\t\t$(\"#nooufound:hidden\").slideDown();\n"); 963 html.append("\t} else {\n"); 964 html.append("\t\t$(\"#nooufound:visible\").slideUp();\n"); 965 html.append("\t}\n"); 966 html.append("\tif (searchTerm == \"\") {\n"); 967 html.append("\t\tscrollToActiveOu();\n"); 968 html.append("\t}\n"); 969 html.append("}\n"); 970 971 // selects the OU to login to 972 html.append("function selectOu(ouPath, ouIndex) {\n"); 973 html.append("\tif (ouIndex != -1 && ouIndex != activeOu) {\n"); 974 html.append("\t\t$(\"#ou\" + ouIndex).addClass(\"active\");\n"); 975 html.append("\t\torgUnits[ouIndex].active = true;\n"); 976 html.append("\t\t$(\"#"); 977 html.append(PARAM_OUFQN); 978 html.append("\").val(ouPath);\n"); 979 html.append("\t\tif (activeOu != -1) {\n"); 980 html.append("\t\t\torgUnits[activeOu].active = false;\n"); 981 html.append("\t\t\t$(\"#ou\" + activeOu).removeClass();\n"); 982 html.append("\t\t}\n"); 983 html.append("\t\tactiveOu = ouIndex;\n"); 984 html.append("\t}\n"); 985 html.append("}\n"); 986 987 // filters the OUs by the provided search term using a timeout, called by the onkeyup event of the search input field 988 html.append("function searchOu() {\n"); 989 html.append("\tvar searchElem = $(\"#"); 990 html.append(PARAM_OUSEARCH); 991 html.append("\");\n"); 992 html.append("\tvar searchTerm = searchElem.val();\n"); 993 html.append("\tif (searchTerm == searchDefaultValue) {"); 994 html.append("\t\tsearchTerm = \"\";"); 995 html.append("\t}"); 996 html.append("\tclearTimeout(searchTimeout);\n"); 997 html.append("\tsearchTimeout = setTimeout(\"showOrgUnits(\\\"\" + trim(searchTerm) + \"\\\");\", 750);\n"); 998 html.append("}\n"); 999 1000 // sets the value of the OU search input field, called by the onfocus and onblur event of the field 1001 html.append("function checkOuValue() {\n"); 1002 html.append("\tvar searchElem = $(\"#"); 1003 html.append(PARAM_OUSEARCH); 1004 html.append("\");\n"); 1005 html.append("\tif (searchElem.val() == searchDefaultValue) {"); 1006 html.append("\t\tsearchElem.val(\"\");"); 1007 html.append("\t\tsearchElem.removeAttr(\"class\");"); 1008 html.append("\t} else if (searchElem.val() == \"\") {"); 1009 html.append("\t\tsearchElem.val(searchDefaultValue);"); 1010 html.append("\t\tsearchElem.attr(\"class\", \"inactive\");"); 1011 html.append("\t}"); 1012 html.append("}\n"); 1013 1014 // scrolls to the currently selected OU if it is out of visible range 1015 html.append("function scrollToActiveOu() {\n"); 1016 html.append("\tif (activeOu != -1) {\n"); 1017 html.append("\t\tvar activeOffset = $(\"#ou\" + activeOu).offset().top;\n"); 1018 html.append("\t\tvar parentOffset = $(\"#ouSelId\").offset().top;\n"); 1019 html.append("\t\tactiveOffset = activeOffset - parentOffset;\n"); 1020 html.append("\t\tif (activeOffset > $(\"#ouSelId\").height()) {;\n"); 1021 html.append("\t\t\t$(\"#ouSelId\").animate({scrollTop: activeOffset}, 500);\n"); 1022 html.append("\t\t};\n"); 1023 html.append("\t}\n"); 1024 html.append("}\n"); 1025 1026 // function to check IE version, in case of a version < IE8 login will be disabled and an error message shown. 1027 html.append("function checkBrowser(){\n "); 1028 html.append("var div = document.createElement(\"div\");\n"); 1029 html.append("div.innerHTML = \"<!--[if lt IE 8]><i></i><![endif]-->\";\n"); 1030 html.append("var isIeLessThan8 = (div.getElementsByTagName(\"i\").length == 1);\n"); 1031 html.append("if (isIeLessThan8) {\n $('#"); 1032 html.append(PARAM_FORM); 1033 html.append( 1034 "').after('<div style=\"color: #B31B34; font-weight: bold; font-size: 14px; margin: 20px; text-align: center;\">"); 1035 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_UNSUPPORTED_BROWSER_0)); 1036 html.append("</div>');\n $('#"); 1037 html.append(PARAM_FORM); 1038 html.append( 1039 "').css(\"display\",\"none\"); /** $('input').attr('disabled', 'disabled');\n alert('wrong browser'); */\n}\n}\n"); 1040 1041 // called when the login form page is loaded 1042 html.append("function doOnload() {\n checkBrowser();\n"); 1043 html.append("\tdocument."); 1044 html.append(PARAM_FORM); 1045 html.append("."); 1046 html.append(PARAM_USERNAME); 1047 html.append(".select();\n"); 1048 html.append("\tdocument."); 1049 html.append(PARAM_FORM); 1050 html.append("."); 1051 html.append(PARAM_USERNAME); 1052 html.append(".focus();\n"); 1053 if (message != null) { 1054 html.append("\tshowAlert();\n"); 1055 } 1056 html.append("}\n"); 1057 1058 // helper function to trim a given string 1059 html.append("function trim (myStr) {\n"); 1060 html.append("\treturn myStr.replace(/^\\s+/, '').replace (/\\s+$/, '');\n"); 1061 html.append("}\n"); 1062 1063 html.append("</script>\n"); 1064 } 1065 1066 /** 1067 * Appends the JavaScript that opens the Direct Edit window after a successful login 1068 * to the given HTML buffer.<p> 1069 * 1070 * @param html the html buffer to append the script to 1071 */ 1072 protected void appendDirectEditOpenerScript(StringBuffer html) { 1073 1074 html.append("<script >\n"); 1075 html.append("function doOnload() {\n"); 1076 1077 // the window's name must be the same as in: 1078 // system/workplace/resources/commons/explorer.js 1079 html.append("window.name='preview';"); 1080 html.append("window.location.replace('"); 1081 html.append(link(m_directEditPath)); 1082 html.append("');"); 1083 1084 html.append("}\n"); 1085 html.append("</script>\n"); 1086 } 1087 1088 /** 1089 * Appends the HTML form name/id code for the given id to the given html.<p> 1090 * 1091 * @param html the html where to append the id to 1092 * @param id the id to append 1093 */ 1094 protected void appendId(StringBuffer html, String id) { 1095 1096 html.append(" name=\""); 1097 html.append(id); 1098 html.append("\" id=\""); 1099 html.append(id); 1100 html.append("\" "); 1101 } 1102 1103 /** 1104 * Appends the JavaScript that opens the Workplace window after a successful login 1105 * to the given HTML buffer.<p> 1106 * 1107 * @param html the html buffer to append the script to 1108 * @param requestedResource the requested resource to open in a new window 1109 * @param message the message to display if the originally requested resource is not available 1110 */ 1111 protected void appendWorkplaceOpenerScript( 1112 StringBuffer html, 1113 String requestedResource, 1114 CmsMessageContainer message) { 1115 1116 String winId = "OpenCms" + System.currentTimeMillis(); 1117 1118 html.append("<script >\n"); 1119 1120 html.append("function doOnload() {\n"); 1121 1122 // display missing resource warning if required 1123 if (message != null) { 1124 html.append("\talert(\""); 1125 html.append(CmsStringUtil.escapeJavaScript(message.key(m_locale))); 1126 html.append("\");\n"); 1127 } 1128 1129 // display login message if required 1130 CmsLoginMessage loginMessage = OpenCms.getLoginManager().getLoginMessage(); 1131 if ((loginMessage != null) && (loginMessage.isActive())) { 1132 String msg; 1133 if (loginMessage.isLoginForbidden()) { 1134 // login forbidden for normal users, current user must be Administrator 1135 msg = Messages.get().container( 1136 Messages.GUI_LOGIN_SUCCESS_WITH_MESSAGE_2, 1137 loginMessage.getMessage(), 1138 new Date(loginMessage.getTimeEnd())).key(m_locale); 1139 } else { 1140 // just display the message 1141 msg = loginMessage.getMessage(); 1142 } 1143 html.append("\talert(\""); 1144 html.append(CmsStringUtil.escapeJavaScript(msg)); 1145 html.append("\");\n"); 1146 } 1147 1148 String openResource = requestedResource; 1149 1150 // check if user agreement should be shown 1151 CmsLoginUserAgreement agreementInfo = new CmsLoginUserAgreement(this); 1152 if (agreementInfo.isShowUserAgreement()) { 1153 openResource = agreementInfo.getConfigurationVfsPath() 1154 + "?" 1155 + CmsLoginUserAgreement.PARAM_WPRES 1156 + "=" 1157 + requestedResource; 1158 } 1159 1160 html.append("\tvar openUri = \""); 1161 html.append(link(openResource)); 1162 html.append("\";\n"); 1163 html.append("\tvar workplaceWin = openWorkplace(openUri, \""); 1164 html.append(winId); 1165 html.append("\");\n"); 1166 html.append("\tif (window.name != \""); 1167 html.append(winId); 1168 html.append("\") {\n"); 1169 html.append("\t\twindow.opener = workplaceWin;\n"); 1170 html.append("\t\tif (workplaceWin != null) {\n"); 1171 html.append("\t\t\twindow.close();\n"); 1172 html.append("\t\t}\n"); 1173 html.append("\t}\n"); 1174 html.append("}\n"); 1175 1176 html.append("function openWorkplace(url, name) {\n"); 1177 1178 Cookie wpDataCookie = getCookie(getRequest(), COOKIE_WP_DATA); 1179 boolean useCookieData = false; 1180 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(wpDataCookie.getValue())) { 1181 String[] winValues = CmsStringUtil.splitAsArray(wpDataCookie.getValue(), '|'); 1182 if (winValues.length == 4) { 1183 useCookieData = true; 1184 html.append("\tvar winLeft = ").append(winValues[0]).append(";\n"); 1185 html.append("\tvar winTop = ").append(winValues[1]).append(";\n"); 1186 html.append("\tvar winWidth = ").append(winValues[2]).append(";\n"); 1187 html.append("\tvar winHeight = ").append(winValues[3]).append(";\n"); 1188 } 1189 } 1190 1191 if (!useCookieData) { 1192 html.append("\tvar isInWin = (window.name.match(/^OpenCms\\d+$/) != null);\n"); 1193 html.append("\tvar winHeight = 0, winWidth = 0, winTop = 0, winLeft = 0;\n"); 1194 html.append("\tif (window.innerHeight) {\n"); 1195 // Mozilla 1196 html.append("\t\twinHeight = window.innerHeight;\n"); 1197 html.append("\t\twinWidth = window.innerWidth;\n"); 1198 html.append("\t} else if (document.documentElement && document.documentElement.clientHeight) {\n"); 1199 // IE 6 "strict" mode 1200 html.append("\t\twinHeight = document.documentElement.clientHeight;\n"); 1201 html.append("\t\twinWidth = document.documentElement.clientWidth;\n"); 1202 html.append("\t} else if (document.body && document.body.clientHeight) {\n"); 1203 // IE 5, IE 6 "relaxed" mode 1204 html.append("\t\twinHeight = document.body.clientWidth;\n"); 1205 html.append("\t\twinWidth = document.body.clientHeight;\n"); 1206 html.append("\t}\n"); 1207 html.append("\tif (window.screenY) {\n"); 1208 // Mozilla 1209 html.append("\t\twinTop = window.screenY;\n"); 1210 html.append("\t\twinLeft = window.screenX;\n"); 1211 html.append("\t\tif (! isInWin) {\n"); 1212 html.append("\t\t\twinTop += 25;\n"); 1213 html.append("\t\t\twinLeft += 25;\n"); 1214 html.append("\t\t}\n"); 1215 html.append("\t} else if (window.screenTop) {\n"); 1216 // IE 1217 html.append("\t\twinTop = window.screenTop;\n"); 1218 html.append("\t\twinLeft = window.screenLeft;\n"); 1219 html.append("\t}\n"); 1220 html.append("\n"); 1221 } 1222 1223 if (requestedResource.startsWith(CmsWorkplace.VFS_PATH_WORKPLACE)) { 1224 html.append( 1225 "\tvar openerStr = \"width=\" + winWidth + \",height=\" + winHeight + \",left=\" + winLeft + \",top=\" + winTop + \",scrollbars=no,location=no,toolbar=no,menubar=no,directories=no,status=yes,resizable=yes\";\n"); 1226 } else { 1227 html.append( 1228 "\tvar openerStr = \"width=\" + winWidth + \",height=\" + winHeight + \",left=\" + winLeft + \",top=\" + winTop + \",scrollbars=yes,location=yes,toolbar=yes,menubar=yes,directories=no,status=yes,resizable=yes\";\n"); 1229 } 1230 html.append("\tvar OpenCmsWin = window.open(url, name, openerStr);\n"); 1231 html.append("\n"); 1232 html.append("\ttry{\n"); 1233 html.append("\t\tif (! OpenCmsWin.opener) {\n"); 1234 html.append("\t\t\tOpenCmsWin.opener = self;\n"); 1235 html.append("\t\t}\n"); 1236 html.append("\t\tif (OpenCmsWin.focus) {\n"); 1237 html.append("\t\t\tOpenCmsWin.focus();\n"); 1238 html.append("\t\t}\n"); 1239 html.append("\t} catch (e) {}\n"); 1240 html.append("\n"); 1241 html.append("\treturn OpenCmsWin;\n"); 1242 html.append("}\n"); 1243 1244 html.append("</script>\n"); 1245 } 1246 1247 /** 1248 * Returns the HTML for the login form.<p> 1249 * 1250 * @return the HTML for the login form 1251 */ 1252 protected String displayLoginForm() { 1253 1254 StringBuffer html = new StringBuffer(8192); 1255 1256 html.append("<!DOCTYPE html>\n"); 1257 html.append("<html><head>\n"); 1258 html.append("<title>"); 1259 html.append(getTitle(m_locale)); 1260 1261 html.append("</title>\n"); 1262 1263 String encoding = getRequestContext().getEncoding(); 1264 html.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset="); 1265 html.append(encoding); 1266 html.append("\">\n"); 1267 1268 // append workplace CSS 1269 html.append("<link rel=\"stylesheet\" type=\"text/css\" href=\""); 1270 html.append(CmsWorkplace.getStyleUri(this, "workplace.css")); 1271 html.append("\">\n"); 1272 1273 // append favicon relation 1274 html.append("<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\""); 1275 html.append(CmsWorkplace.getSkinUri()).append("commons/favicon.ico"); 1276 html.append("\">\n"); 1277 1278 if (m_action == ACTION_DISPLAY) { 1279 // append default script 1280 appendDefaultLoginScript(html, m_message); 1281 } else if (m_action == ACTION_LOGIN) { 1282 // append window opener script 1283 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_directEditPath)) { 1284 appendDirectEditOpenerScript(html); 1285 } else { 1286 appendWorkplaceOpenerScript(html, m_requestedResource, m_message); 1287 } 1288 } 1289 1290 html.append("</head>\n"); 1291 1292 html.append("<body class=\"dialog\" onload=\"doOnload();\">\n"); 1293 1294 html.append("<div style=\"text-align: center; padding-top: 50px;\">"); 1295 html.append("<img src=\""); 1296 html.append(CmsWorkplace.getResourceUri("commons/login_logo.png")); 1297 html.append("\" alt=\"OpenCms Logo\">"); 1298 html.append("</div>\n"); 1299 1300 html.append("<table class=\"logindialog\" cellpadding=\"0\" cellspacing=\"0\"><tr><td>\n"); 1301 html.append("<table class=\"dialogbox\" cellpadding=\"0\" cellspacing=\"0\"><tr><td>\n"); 1302 html.append("<div class=\"dialoghead\">"); 1303 1304 if (m_oufqn == null) { 1305 m_oufqn = CmsOrganizationalUnit.SEPARATOR; 1306 } 1307 if (m_action == ACTION_DISPLAY) { 1308 html.append("<div id='titleId'"); 1309 if (!m_oufqn.equals(CmsOrganizationalUnit.SEPARATOR)) { 1310 html.append(" style='display: none;'"); 1311 } 1312 html.append(">\n"); 1313 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_HEADLINE_0)); 1314 html.append("</div>\n"); 1315 html.append("<div id='titleIdOu'"); 1316 if (m_oufqn.equals(CmsOrganizationalUnit.SEPARATOR)) { 1317 html.append(" style='display: none;'"); 1318 } 1319 html.append(">\n"); 1320 html.append( 1321 Messages.get().getBundle(m_locale).key( 1322 Messages.GUI_LOGIN_HEADLINE_SELECTED_ORGUNIT_1, 1323 m_ou.getDescription(getCmsObject().getRequestContext().getLocale()))); 1324 html.append("</div>\n"); 1325 } else if (m_action == ACTION_LOGIN) { 1326 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_HEADLINE_ALREADY_IN_0)); 1327 } 1328 1329 html.append("</div>\n"); 1330 1331 if (m_action == ACTION_DISPLAY) { 1332 // start form 1333 html.append("<form style=\"margin: 0px; padding: 0px;\" action=\""); 1334 html.append(getFormLink()); 1335 html.append("\""); 1336 if (PCTYPE_PUBLIC.equals(m_pcType)) { 1337 html.append(" autocomplete=\"off\""); 1338 } 1339 appendId(html, PARAM_FORM); 1340 html.append("method=\"POST\">\n"); 1341 } 1342 1343 html.append("<div class=\"dialogcontent\">\n"); 1344 html.append("<table border=\"0\">\n"); 1345 1346 // show security option box if enabled in configuration 1347 if ((m_action == ACTION_DISPLAY) && OpenCms.getLoginManager().isEnableSecurity()) { 1348 html.append("<tr>\n"); 1349 html.append("<td rowspan=\"2\">\n"); 1350 // security image should not be shown any more 1351 //html.append("<img src=\""); 1352 //html.append(CmsWorkplace.getResourceUri("commons/login_security.png")); 1353 //html.append("\" height=\"48\" width=\"48\" alt=\"\">"); 1354 html.append("</td>\n"); 1355 html.append("<td colspan=\"2\" style=\"white-space: nowrap;\">\n"); 1356 html.append("<div style=\"padding-bottom: 5px;\"><b>"); 1357 html.append( 1358 CmsStringUtil.escapeHtml(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_SECURITY_0))); 1359 html.append("</b></div>\n"); 1360 html.append("</td>\n"); 1361 html.append("</tr>\n"); 1362 html.append("<tr>\n"); 1363 html.append("<td colspan=\"2\" style=\"white-space: nowrap;\">"); 1364 html.append("<div class=\"loginsecurity\">"); 1365 html.append("<input type=\"radio\" value=\""); 1366 html.append(PCTYPE_PUBLIC); 1367 html.append("\" name=\""); 1368 html.append(PARAM_PCTYPE); 1369 html.append("\""); 1370 if (PCTYPE_PUBLIC.equals(m_pcType)) { 1371 html.append(" checked=\"checked\""); 1372 } 1373 html.append("> "); 1374 html.append( 1375 CmsStringUtil.escapeHtml(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_PCTYPE_PUBLIC_0))); 1376 html.append("<br/>"); 1377 html.append("<input type=\"radio\" value=\""); 1378 html.append(PCTYPE_PRIVATE); 1379 html.append("\" name=\""); 1380 html.append(PARAM_PCTYPE); 1381 html.append("\""); 1382 if (PCTYPE_PRIVATE.equals(m_pcType)) { 1383 html.append(" checked=\"checked\""); 1384 } 1385 html.append("> "); 1386 html.append( 1387 CmsStringUtil.escapeHtml(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_PCTYPE_PRIVATE_0))); 1388 html.append("</div></td>\n"); 1389 html.append("</tr>\n"); 1390 } 1391 1392 html.append("<tr>\n"); 1393 html.append("<td></td>\n<td colspan=\"2\" style=\"white-space: nowrap;\">\n"); 1394 html.append("<div style=\"padding-bottom: 10px;\">"); 1395 1396 if (m_action == ACTION_DISPLAY) { 1397 html.append(CmsStringUtil.escapeHtml(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_MESSAGE_0))); 1398 } else if (m_action == ACTION_LOGIN) { 1399 html.append( 1400 CmsStringUtil.escapeHtml( 1401 Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_MESSAGE_ALREADY_IN_0))); 1402 } 1403 1404 html.append("</div>\n"); 1405 html.append("</td>\n"); 1406 html.append("</tr>\n"); 1407 1408 html.append("<tr>\n"); 1409 1410 html.append("<td style=\"width: 60px; text-align: center; vertical-align: top\" rowspan=\"5\">"); 1411 html.append("<img src=\""); 1412 html.append(CmsWorkplace.getResourceUri("commons/login.png")); 1413 html.append("\" height=\"48\" width=\"48\" alt=\"\">"); 1414 html.append("</td>\n"); 1415 1416 html.append("<td style=\"white-space: nowrap;\"><b>"); 1417 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_USERNAME_0)); 1418 html.append("</b> </td>\n"); 1419 html.append("<td style=\"width: 300px; white-space: nowrap;\">"); 1420 1421 if (m_action == ACTION_DISPLAY) { 1422 // append input for user name 1423 html.append("<input style=\"width: 300px;\" type=\"text\""); 1424 if (PCTYPE_PUBLIC.equals(m_pcType)) { 1425 html.append(" autocomplete=\"off\""); 1426 } 1427 appendId(html, PARAM_USERNAME); 1428 html.append("value=\""); 1429 html.append( 1430 (CmsStringUtil.isEmpty(m_username) || PCTYPE_PUBLIC.equals(m_pcType)) 1431 ? "" 1432 : CmsEncoder.escapeXml(m_username)); 1433 html.append("\">"); 1434 } else if (m_action == ACTION_LOGIN) { 1435 // append name of user that has been logged in 1436 html.append(getRequestContext().getCurrentUser().getFullName()); 1437 } 1438 1439 html.append("</td>\n"); 1440 html.append("</tr>\n"); 1441 1442 if (m_action == ACTION_DISPLAY) { 1443 // append 2 rows: input for user name and login button 1444 html.append("<tr>\n"); 1445 html.append("<td style=\"white-space: nowrap;\"><b>"); 1446 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_PASSWORD_0)); 1447 html.append("</b> </td>\n"); 1448 html.append("<td style=\"width: 300px; white-space: nowrap;\">"); 1449 html.append("<input style=\"width: 300px;\" type=\"password\""); 1450 if (PCTYPE_PUBLIC.equals(m_pcType)) { 1451 html.append(" autocomplete=\"off\""); 1452 } 1453 appendId(html, PARAM_PASSWORD); 1454 html.append(">"); 1455 html.append("</td>\n"); 1456 html.append("</tr>\n"); 1457 1458 html.append("<tr>\n"); 1459 html.append("<td style=\"white-space: nowrap;\"><div id='ouLabelId' style='display: none;'><b>"); 1460 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_0)).append( 1461 "</b> \n"); 1462 html.append("</div></td>\n"); 1463 html.append( 1464 "<td style=\"width: 300px; white-space: nowrap;\"><div id='ouSearchId' style='display: none;'><input class=\"inactive\" style=\"width: 300px;\" type=\"text\" value=\""); 1465 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_SEARCH_0)); 1466 html.append("\""); 1467 appendId(html, PARAM_OUSEARCH); 1468 html.append(" onfocus=\"checkOuValue();\""); 1469 html.append(" onblur=\"checkOuValue();\""); 1470 html.append(" onkeyup=\"searchOu();\""); 1471 html.append("/>"); 1472 html.append("<input type=\"hidden\" value=\""); 1473 html.append(m_oufqn == null ? "" : m_oufqn); 1474 html.append("\""); 1475 appendId(html, PARAM_OUFQN); 1476 html.append("/>"); 1477 html.append("</div></td>\n"); 1478 html.append("</tr>\n"); 1479 1480 html.append("<tr>\n"); 1481 html.append("<td colspan=\"2\"><div id='ouSelId' style='display: none;'>"); 1482 html.append("</div></td>\n"); 1483 html.append("</tr>\n"); 1484 1485 html.append("<tr>\n"); 1486 html.append("<td>\n"); 1487 html.append("</td>\n"); 1488 html.append("<td style=\"white-space: nowrap;\">\n"); 1489 html.append("<input type=\"hidden\""); 1490 appendId(html, PARAM_ACTION_LOGIN); 1491 html.append("value=\"true\">\n"); 1492 1493 if (m_requestedResource != null) { 1494 html.append("<input type=\"hidden\""); 1495 appendId(html, CmsWorkplaceManager.PARAM_LOGIN_REQUESTED_RESOURCE); 1496 html.append("value=\""); 1497 html.append(CmsEncoder.escapeXml(m_requestedResource)); 1498 html.append("\">\n"); 1499 } 1500 1501 html.append("<input class=\"loginbutton\" type=\"submit\" value=\""); 1502 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_BUTTON_0)); 1503 html.append("\">\n"); 1504 1505 if ((getOus().size() > 1) 1506 && ((getPreDefOuFqn() == null) || getPreDefOuFqn().equals(CmsOrganizationalUnit.SEPARATOR))) { 1507 // options 1508 html.append(" <input id='ouBtnId' class='loginbutton' type='button' value='"); 1509 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_ORGUNIT_SELECT_ON_0)); 1510 html.append("' onclick='javascript:orgUnitSelection();'>\n"); 1511 } 1512 html.append("</td>\n"); 1513 html.append("</tr>\n"); 1514 } else if (m_action == ACTION_LOGIN) { 1515 // append 2 rows: one empty, other for button with re-open window script 1516 html.append("<tr><td></td><td></td></tr>\n"); 1517 1518 html.append("<tr>\n"); 1519 html.append("<td></td>\n"); 1520 html.append("<td style=\"width:100%; white-space: nowrap;\">\n"); 1521 html.append("<input class=\"loginbutton\" type=\"button\" value=\""); 1522 html.append(Messages.get().getBundle(m_locale).key(Messages.GUI_LOGIN_BUTTON_ALREADY_IN_0)); 1523 html.append("\" onclick=\"doOnload()\">\n"); 1524 html.append("</td>\n"); 1525 html.append("</tr>\n"); 1526 } 1527 1528 html.append("</table>\n"); 1529 html.append("</div>"); 1530 1531 if (m_action == ACTION_DISPLAY) { 1532 // end form 1533 html.append("</form>\n"); 1534 } 1535 1536 html.append("</td></tr></table>\n"); 1537 html.append("</td></tr></table>\n"); 1538 html.append(getCopyrightHtml(m_locale)); 1539 1540 html.append("<noscript>\n"); 1541 html.append( 1542 "<div style=\"text-align: center; font-size: 14px; border: 2px solid black; margin: 50px; padding: 20px; background-color: red; color: white; white-space: nowrap;\"><b>"); 1543 html.append( 1544 CmsStringUtil.escapeHtml( 1545 Messages.get().getBundle(m_locale).key( 1546 Messages.GUI_LOGIN_NOSCRIPT_1, 1547 OpenCms.getSiteManager().getWorkplaceSiteMatcher()))); 1548 html.append("</b></div>\n"); 1549 html.append("</noscript>\n"); 1550 1551 html.append("</body></html>"); 1552 1553 return html.toString(); 1554 } 1555 1556 /** 1557 * Returns all organizational units in the system.<p> 1558 * 1559 * @return a list of {@link CmsOrganizationalUnit} objects 1560 */ 1561 protected List<CmsOrganizationalUnit> getOus() { 1562 1563 if (m_ous == null) { 1564 m_ous = getOrgUnitsForLoginDialog(getCmsObject(), getPreDefOuFqn()); 1565 } 1566 return m_ous; 1567 } 1568 1569 /** 1570 * Returns the predefined organizational unit fqn.<p> 1571 * 1572 * This is normally selected by url, and set by the {@link CmsWorkplaceLoginHandler}.<p> 1573 * 1574 * @return the predefined organizational unit fqn 1575 */ 1576 protected String getPreDefOuFqn() { 1577 1578 if (Boolean.valueOf(m_actionLogout).booleanValue() && (getRequest().getAttribute(PARAM_PREDEF_OUFQN) == null)) { 1579 String oufqn = getCmsObject().getRequestContext().getOuFqn(); 1580 if (!oufqn.startsWith(CmsOrganizationalUnit.SEPARATOR)) { 1581 oufqn = CmsOrganizationalUnit.SEPARATOR + oufqn; 1582 } 1583 getRequest().setAttribute(CmsLogin.PARAM_PREDEF_OUFQN, oufqn); 1584 } 1585 return (String)getRequest().getAttribute(PARAM_PREDEF_OUFQN); 1586 } 1587 1588 private boolean shouldUseNewLogin() { 1589 1590 return true; 1591 } 1592}