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.jsp; 029 030import org.opencms.db.CmsLoginMessage; 031import org.opencms.file.CmsRequestContext; 032import org.opencms.file.CmsUser; 033import org.opencms.i18n.CmsMessageContainer; 034import org.opencms.main.CmsException; 035import org.opencms.main.CmsLog; 036import org.opencms.main.OpenCms; 037import org.opencms.security.CmsAuthentificationException; 038 039import java.io.IOException; 040import java.util.Date; 041 042import javax.servlet.http.HttpServletRequest; 043import javax.servlet.http.HttpServletResponse; 044import javax.servlet.http.HttpSession; 045import javax.servlet.jsp.PageContext; 046 047import org.apache.commons.logging.Log; 048 049/** 050 * Provides convenient wrappers useful to create user login pages.<p> 051 * 052 * Initialize this bean at the beginning of your JSP like this: 053 * <pre> 054 * <jsp:useBean id="cmslogin" class="org.opencms.jsp.CmsJspLoginBean"> 055 * <% cmslogin.init(pageContext, request, response); %> 056 * </jsp:useBean> 057 * </pre> 058 * <p> 059 * 060 * @since 6.0.0 061 */ 062public class CmsJspLoginBean extends CmsJspActionElement { 063 064 /** The log object for this class. */ 065 private static final Log LOG = CmsLog.getLog(CmsJspLoginBean.class); 066 067 /** Flag to indicate if a login was successful. */ 068 private CmsException m_loginException; 069 070 /** 071 * Empty constructor, required for every JavaBean.<p> 072 */ 073 public CmsJspLoginBean() { 074 075 // noop, you must call the init() method after you create an instance 076 } 077 078 /** 079 * Constructor, with parameters.<p> 080 * 081 * @param context the JSP page context object 082 * @param req the JSP request 083 * @param res the JSP response 084 */ 085 public CmsJspLoginBean(PageContext context, HttpServletRequest req, HttpServletResponse res) { 086 087 super(); 088 init(context, req, res); 089 } 090 091 /** 092 * Logs any login exception.<p> 093 * 094 * @param requestContext the request context 095 * @param userName the user name 096 * @param currentLoginException the exception to log 097 */ 098 public static void logLoginException( 099 CmsRequestContext requestContext, 100 String userName, 101 CmsException currentLoginException) { 102 103 if (currentLoginException instanceof CmsAuthentificationException) { 104 105 // the authentication of the user failed 106 if (org.opencms.security.Messages.ERR_LOGIN_FAILED_DISABLED_2 == currentLoginException.getMessageContainer().getKey()) { 107 108 // the user has been disabled 109 LOG.warn( 110 Messages.get().getBundle().key( 111 Messages.LOG_LOGIN_FAILED_DISABLED_3, 112 userName, 113 requestContext.addSiteRoot(requestContext.getUri()), 114 requestContext.getRemoteAddress())); 115 116 } else if (org.opencms.security.Messages.ERR_LOGIN_FAILED_TEMP_DISABLED_4 == currentLoginException.getMessageContainer().getKey()) { 117 118 // the user has been disabled 119 LOG.warn( 120 Messages.get().getBundle().key( 121 Messages.LOG_LOGIN_FAILED_TEMP_DISABLED_5, 122 new Object[] { 123 userName, 124 requestContext.addSiteRoot(requestContext.getUri()), 125 requestContext.getRemoteAddress(), 126 currentLoginException.getMessageContainer().getArgs()[2], 127 currentLoginException.getMessageContainer().getArgs()[3]})); 128 129 } else if (org.opencms.security.Messages.ERR_LOGIN_FAILED_NO_USER_2 == currentLoginException.getMessageContainer().getKey()) { 130 131 // the requested user does not exist in the database 132 LOG.warn( 133 Messages.get().getBundle().key( 134 Messages.LOG_LOGIN_FAILED_NO_USER_3, 135 userName, 136 requestContext.addSiteRoot(requestContext.getUri()), 137 requestContext.getRemoteAddress())); 138 139 } else if (org.opencms.security.Messages.ERR_LOGIN_FAILED_WITH_MESSAGE_1 == currentLoginException.getMessageContainer().getKey()) { 140 141 // logins have been disabled by the administration 142 long endTime = CmsLoginMessage.DEFAULT_TIME_END; 143 if (OpenCms.getLoginManager().getLoginMessage() != null) { 144 endTime = OpenCms.getLoginManager().getLoginMessage().getTimeEnd(); 145 } 146 LOG.info( 147 Messages.get().getBundle().key( 148 Messages.LOG_LOGIN_FAILED_WITH_MESSAGE_4, 149 new Object[] { 150 userName, 151 requestContext.addSiteRoot(requestContext.getUri()), 152 requestContext.getRemoteAddress(), 153 new Date(endTime)})); 154 155 } else { 156 157 // the user exists, so the password must have been wrong 158 CmsMessageContainer message = Messages.get().container( 159 Messages.LOG_LOGIN_FAILED_3, 160 userName, 161 requestContext.addSiteRoot(requestContext.getUri()), 162 requestContext.getRemoteAddress()); 163 if (OpenCms.getDefaultUsers().isUserAdmin(userName)) { 164 // someone tried to log in as "Admin", log this in a higher channel 165 LOG.error(message.key()); 166 } else { 167 LOG.warn(message.key()); 168 } 169 } 170 } else { 171 // the error was database related, there may be an issue with the setup 172 // write the exception to the log as well 173 LOG.error( 174 Messages.get().getBundle().key( 175 Messages.LOG_LOGIN_FAILED_DB_REASON_3, 176 userName, 177 requestContext.addSiteRoot(requestContext.getUri()), 178 requestContext.getRemoteAddress()), 179 currentLoginException); 180 } 181 } 182 183 /** 184 * Returns the link to the form that contains the login element.<p> 185 * 186 * @return the link to the form that contains the login element 187 */ 188 public String getFormLink() { 189 190 return link(getRequestContext().getUri()); 191 } 192 193 /** 194 * Returns the exception that was thrown after login, 195 * or null if no Exception was thrown (i.e. login was successful 196 * or not attempted).<p> 197 * 198 * @return the exception thrown after login 199 */ 200 public CmsException getLoginException() { 201 202 return m_loginException; 203 } 204 205 /** 206 * Returns the currently logged in user.<p> 207 * 208 * @return the currently logged in user 209 */ 210 public CmsUser getUser() { 211 212 return getRequestContext().getCurrentUser(); 213 } 214 215 /** 216 * Returns the user name of the currently logged in user.<p> 217 * 218 * @return the user name of the currently logged in user 219 */ 220 public String getUserName() { 221 222 return getRequestContext().getCurrentUser().getName(); 223 } 224 225 /** 226 * Returns true if the current user is not the guest user, 227 * i.e. if he already has logged in with some other user account.<p> 228 * 229 * @return true if the current user is already logged in 230 */ 231 public boolean isLoggedIn() { 232 233 return !getCmsObject().getRequestContext().getCurrentUser().isGuestUser(); 234 } 235 236 /** 237 * Indicates if a login was successful or not.<p> 238 * 239 * @return true if the login was successful 240 */ 241 public boolean isLoginSuccess() { 242 243 return (m_loginException == null); 244 } 245 246 /** 247 * Logs a system user in to OpenCms.<p> 248 * 249 * @param userName the users name 250 * @param password the password 251 */ 252 public void login(String userName, String password) { 253 254 login(userName, password, null); 255 } 256 257 /** 258 * Logs a system user into OpenCms.<p> 259 * 260 * Note that if a login project name is provided, this project must exist, 261 * otherwise the login is regarded as a failure even if the user data was correct.<p> 262 * 263 * @param userName the users name 264 * @param password the password 265 * @param projectName the project to switch to after login (if null project is not switched) 266 */ 267 public void login(String userName, String password, String projectName) { 268 269 HttpSession session = null; 270 m_loginException = null; 271 try { 272 273 // login the user and create a new session 274 CmsUser user = getCmsObject().readUser(userName); 275 OpenCms.getSessionManager().checkCreateSessionForUser(user); 276 getCmsObject().loginUser(userName, password, getRequestContext().getRemoteAddress()); 277 278 // make sure we have a new session after login for security reasons 279 session = getRequest().getSession(false); 280 if (session != null) { 281 session.invalidate(); 282 } 283 session = getRequest().getSession(true); 284 if (projectName != null) { 285 // if this fails, the login is regarded as a failure as well 286 getCmsObject().getRequestContext().setCurrentProject(getCmsObject().readProject(projectName)); 287 } 288 if (!getCmsObject().getRequestContext().getCurrentProject().isOnlineProject()) { 289 // in case the user is logged into an offline project, send any available login message 290 CmsLoginMessage loginMessage = OpenCms.getLoginManager().getLoginMessage(); 291 if ((loginMessage != null) && loginMessage.isActive()) { 292 OpenCms.getSessionManager().updateSessionInfo(getCmsObject(), getRequest()); 293 OpenCms.getSessionManager().sendBroadcast(null, loginMessage.getMessage(), user); 294 } 295 } 296 297 } catch (CmsException e) { 298 // the login has failed 299 m_loginException = e; 300 } 301 if (m_loginException == null) { 302 // login was successful 303 if (LOG.isInfoEnabled()) { 304 LOG.info( 305 Messages.get().getBundle().key( 306 Messages.LOG_LOGIN_SUCCESSFUL_3, 307 userName, 308 getRequestContext().addSiteRoot(getRequestContext().getUri()), 309 getRequestContext().getRemoteAddress())); 310 } 311 } else { 312 // login was not successful 313 if (session != null) { 314 session.invalidate(); 315 } 316 CmsException currentLoginException = m_loginException; 317 logLoginException(getRequestContext(), userName, currentLoginException); 318 } 319 } 320 321 /** 322 * Logs a system user in to OpenCms.<p> 323 * 324 * Note that if a login project name is provided, this project must exist, 325 * otherwise the login is regarded as a failure even if the user data was correct.<p> 326 * 327 * @param userName the users name 328 * @param password the password 329 * @param projectName the project to switch to after login (if null project is not switched) 330 * @param redirectUri the URI to redirect to after login (if null the current URI is used) 331 * 332 * @throws IOException in case redirect after login was not successful 333 */ 334 public void login(String userName, String password, String projectName, String redirectUri) throws IOException { 335 336 login(userName, password, projectName); 337 if (m_loginException == null) { 338 if (redirectUri != null) { 339 getResponse().sendRedirect( 340 OpenCms.getLinkManager().substituteLink(getCmsObject(), redirectUri, null, true)); 341 } else { 342 getResponse().sendRedirect(getFormLink()); 343 } 344 } 345 } 346 347 /** 348 * Logs a user out, i.e. destroys the current users session, 349 * after that the current page will be redirected to itself one time to ensure that 350 * the users session is truly destroyed.<p> 351 * 352 * @throws IOException if redirect after logout fails 353 */ 354 public void logout() throws IOException { 355 356 String loggedInUserName = getRequestContext().getCurrentUser().getName(); 357 HttpSession session = getRequest().getSession(false); 358 if (session != null) { 359 session.invalidate(); 360 /* we need this because a new session might be created after this method, 361 but before the session info is updated in OpenCmsCore.showResource. */ 362 getCmsObject().getRequestContext().setUpdateSessionEnabled(false); 363 } 364 // logout was successful 365 if (LOG.isInfoEnabled()) { 366 LOG.info( 367 Messages.get().getBundle().key( 368 Messages.LOG_LOGOUT_SUCCESFUL_3, 369 loggedInUserName, 370 getRequestContext().addSiteRoot(getRequestContext().getUri()), 371 getRequestContext().getRemoteAddress())); 372 } 373 getResponse().sendRedirect(getFormLink()); 374 } 375}