package org.jblooming.security.businessLogic; import org.jblooming.ApplicationException; import org.jblooming.PlatformRuntimeException; import org.jblooming.ldap.LdapUtilities; import org.jblooming.scheduler.Scheduler; import org.jblooming.tracer.Tracer; import org.jblooming.agenda.CompanyCalendar; import org.jblooming.operator.Operator; import org.jblooming.persistence.PersistenceHome; import org.jblooming.persistence.exceptions.PersistenceException; import org.jblooming.persistence.exceptions.FindException; import org.jblooming.system.SystemConstants; import org.jblooming.utilities.JSP; import org.jblooming.waf.SessionState; import org.jblooming.waf.constants.Commands; import org.jblooming.waf.constants.OperatorConstants; import org.jblooming.waf.constants.Fields; import org.jblooming.waf.exceptions.ActionException; import org.jblooming.waf.html.state.ScreenElementStatus; import org.jblooming.waf.settings.ApplicationState; import org.jblooming.waf.settings.PlatformConfiguration; import org.jblooming.waf.settings.I18n; import org.jblooming.waf.view.ClientEntry; import org.jblooming.waf.view.PageState; import org.jblooming.waf.view.ClientEntries; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.security.NoSuchAlgorithmException; import java.util.Iterator; import java.util.Date; /** * @author Pietro Polsinelli ppolsinelli@open-lab.com */ public class LoginAction { public void login(PageState pageState, HttpServletRequest request, HttpServletResponse response) throws PersistenceException, ApplicationException { if (pageState.getCommand() != null && pageState.getCommand().equals(Commands.LOGOUT)) { pageState.setClientEntries(new ClientEntries()); return; } Operator user = null; String password = null; String auth_type = ApplicationState.getApplicationSetting(SystemConstants.AUTHENTICATION_TYPE); // ----------------------------------------------------- LDAP_AUTHENTICATION ---------------------------------------------------------------------------- if (SystemConstants.ENABLE_AUTHENTICATION_TYPE.ENABLE_LDAP_AUTHENTICATION.toString().equals(auth_type)) { user = ldapAuthentication(pageState); // ----------------------------------------------------- LDAP_AUTHENTICATION_WITH_STANDARD_FALLBACK ---------------------------------------------------------------------------- } else if (SystemConstants.ENABLE_AUTHENTICATION_TYPE.ENABLE_LDAP_AUTHENTICATION_WITH_FALLBACK_ON_STANDARD.toString().equals(auth_type)) { user = ldapAuthentication(pageState); if (user == null){ pageState.getEntry(OperatorConstants.FLD_LOGIN_NAME).errorCode =null; pageState.getEntry(OperatorConstants.FLD_LOGIN_NEW_PWD).errorCode =null; user = standardAuthentication(pageState); } // ----------------------------------------------------- HTTP_AUTHENTICATION ---------------------------------------------------------------------------- } else if (SystemConstants.ENABLE_AUTHENTICATION_TYPE.ENABLE_HTTP_AUTHENTICATION.toString().equals(auth_type)) { user = httpAuthentication(pageState, request); // ----------------------------------------------------- STANDARD_AUTHENTICATION ---------------------------------------------------------------------------- } else { user = standardAuthentication(pageState); } if (user != null && pageState.validEntries()) { SessionState sm = pageState.getSessionState(); Operator op = (Operator) PersistenceHome.findByPrimaryKey(PlatformConfiguration.defaultOperatorSubclass, Integer.parseInt(user.getId().toString())); doLog(op, sm); /*if (pageState.getEntry("REMEMBER_ME").checkFieldValue()) pageState.sessionState.setAttribute("SAVE_PSW_IN_COOKIE", password); */ pageState.setCommand(Commands.FIND); } } private Operator standardAuthentication(PageState pageState) throws PersistenceException, ApplicationException { String password; Operator user = null; try { ClientEntry ceName = pageState.getEntryAndSetRequired(OperatorConstants.FLD_LOGIN_NAME); ClientEntry cePassword = pageState.getEntry(OperatorConstants.FLD_PWD); password = cePassword.stringValue(); String username = ceName.stringValue(); String newPassword = null; try { user = Operator.authenticateUser(password, username, pageState.getApplication().isLoginCookieEnabled()); } catch (org.jblooming.security.SecurityException e) { cePassword.errorCode = e.getMessage(); } catch (FindException e) { ceName.errorCode = e.getMessage(); } if (pageState.validEntries()) { final String pass_exp = ApplicationState.getApplicationSetting(SystemConstants.FLD_PASSWORD_EXPIRY); int maxDaysPassed = 0; try { maxDaysPassed = pass_exp != null ? Integer.parseInt(pass_exp) : 0; } catch (Throwable e) { Tracer.platformLogger.error("Invalid password expiry value in global settings:" + SystemConstants.FLD_PASSWORD_EXPIRY + "=" + pass_exp, e); } if ((maxDaysPassed > 0 && user.getLastPasswordChangeDate() != null && ((System.currentTimeMillis() - user.getLastPasswordChangeDate().getTime()) / (CompanyCalendar.MILLIS_IN_HOUR * 24)) > maxDaysPassed)) { try { ClientEntry ceNewPassword = pageState.getEntryAndSetRequired(OperatorConstants.FLD_LOGIN_NEW_PWD); ClientEntry ceNewPasswordConfirm = pageState.getEntryAndSetRequired(OperatorConstants.FLD_LOGIN_NEW_PWD_RETYPE); if (!ceNewPassword.stringValue().equals(ceNewPasswordConfirm.stringValue())) { ceNewPasswordConfirm.errorCode = "ERR_PASSWORD_MUST_BE_IDENTICAL"; throw new ActionException(); } final Iterator lastPasswordIterator = user.getLastPasswordIterator(); while (lastPasswordIterator.hasNext()) { String s = (String) lastPasswordIterator.next(); try { if (s.equals(user.computePassword(ceNewPassword.stringValue()))) { ceNewPassword.errorCode = "ERR_PASSWORD_ALREADY_USED"; throw new ActionException(); } } catch (NoSuchAlgorithmException e) { throw new ApplicationException(e); } } //passed all obstacles newPassword = ceNewPassword.stringValue(); if (newPassword != null) { user.changePassword(newPassword); } } catch (ActionException e) { } } } } catch (ActionException e) { } return user; } private Operator httpAuthentication(PageState pageState, HttpServletRequest request) throws PersistenceException { Operator user = null; if (request.getRemoteUser() != null) { user = Operator.findByLoginName(request.getRemoteUser()); } else { pageState.getEntry(OperatorConstants.FLD_LOGIN_NAME).errorCode = SystemConstants.ENABLE_AUTHENTICATION_TYPE.ENABLE_HTTP_AUTHENTICATION + "=yes on " + PlatformConfiguration.globalSettingsFileName + " but no user (request.getRemoteUser()) is provided by the web app context "; } return user; } private Operator ldapAuthentication(PageState pageState) { String password; String username = pageState.getEntryAndSetRequired(OperatorConstants.FLD_LOGIN_NAME).stringValueNullIfEmpty(); password = pageState.getEntry(OperatorConstants.FLD_PWD).stringValueNullIfEmpty(); Operator user = null; String domain = ApplicationState.getApplicationSetting(LdapUtilities.DOMAIN_NAME); String provider = ApplicationState.getApplicationSetting(LdapUtilities.PROVIDER_URL); String secAuth = ApplicationState.getApplicationSetting(LdapUtilities.SECURITY_AUTHENTICATION); if (username != null && password != null) { String msgError = LdapUtilities.checkUser(provider, domain, username, secAuth, password); if (msgError != null) { pageState.getEntry(OperatorConstants.FLD_LOGIN_NAME).errorCode = I18n.get("ERR_INVALID_LOGIN") + " (LDAP)"; } else { //got authorized; now search user try { user = Operator.findByLoginName(username); } catch (PersistenceException e) { Tracer.platformLogger.debug(e); } if (user == null) { boolean create = Fields.TRUE.equals(ApplicationState.getApplicationSetting(LdapUtilities.CREATE_USERS_ON_LOGIN)); if (create) { user = createPlatformUserFromLDAP(username, pageState); } else { pageState.getEntry(OperatorConstants.FLD_LOGIN_NAME).errorCode = I18n.get("ERR_INVALID_LOGIN") + " (LDAP)"; } } } } else { pageState.getEntry(OperatorConstants.FLD_LOGIN_NAME).errorCode = I18n.get("ERR_INVALID_LOGIN") + " (LDAP)"; } return user; } protected Operator createPlatformUserFromLDAP(String username, PageState pageState) { throw new PlatformRuntimeException("LoginAction:createPlatformUserFromLDAP you must provide your implementation"); } public static void doLog(Operator op, SessionState sessionState) throws PersistenceException, ApplicationException { op.setLastLoggedOn(new Date()); op.store(); sessionState.setLoggedOperator(op); sessionState.screenElementsStatus = ScreenElementStatus.getInstanceFromOptions(op); //no skin reset sessionState.setSkin(SessionState.createSkin(ApplicationState.contextPath, "", ApplicationState.platformConfiguration.defaultApplication.getRootFolder())); if (ApplicationState.platformConfiguration.schedulerRunsByDefault && !Scheduler.isRunning()) { ApplicationState.applicationSettings.put(SystemConstants.ADMIN_MESSAGE, "Scheduler is NOT running. Start it in admin -> monitoring -> scheduler monitor"); } //reset locale on session String language = op.getOption(OperatorConstants.FLD_SELECT_LANG); if (JSP.ex(language)) sessionState.setLocale(I18n.getLocale(language)); } public void logout(PageState pageState, HttpServletRequest request, HttpServletResponse response) { request.getSession().removeAttribute(Fields.SESSION); //session.invalidate DOES NOT WORK IN TOMCAT! //this is meant to bind SessionState to a NEW http session; // but with this, SessionState is bound to the old, dying http session // and after 1 minute the user is logged out (by http session)!!! //request.getSession().setMaxInactiveInterval(1); //so we keep the SAME http session, and we hope for the best pageState.sessionState = null; pageState.sessionState = SessionState.getSessionState(request); request.getSession().setAttribute("CMD_LOG_OUT_PARAM_SESSION_KEY", "y"); // add graziella - per evitare che il ping si repeta anche dopo il log out } }