From a7de79150052dc08056f1b9dd0d8158ca5930deb Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Tue, 17 Feb 2015 13:25:07 +0000 Subject: [PATCH] SSDM-1532: Configurable session time out in case of no-login. No login text appears also in GWT client. SVN: 33469 --- .../authentication/DefaultSessionManager.java | 29 +++++++++++++++---- .../DefaultSessionManagerTest.java | 2 +- .../web/client/ICommonClientService.java | 4 +-- .../web/client/ICommonClientServiceAsync.java | 2 +- .../application/ui/BasicLoginCallback.java | 8 +++-- .../web/server/CommonClientService.java | 10 +++---- .../generic/server/AbstractServer.java | 9 +++--- .../generic/server/OpenBisSessionManager.java | 24 +++++++++++---- .../source/java/genericApplicationContext.xml | 1 + 9 files changed, 61 insertions(+), 28 deletions(-) diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java b/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java index 7b926f31b0d..55e4ba9177c 100644 --- a/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java +++ b/authentication/source/java/ch/systemsx/cisd/authentication/DefaultSessionManager.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.authentication; +import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; @@ -53,6 +54,8 @@ import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer; */ public class DefaultSessionManager<T extends BasicSession> implements ISessionManager<T> { + public static final File NO_LOGIN_FILE = new File("./etc/nologin.html"); + private static final String LOGOUT_PREFIX = "LOGOUT: "; private static final String LOGIN_PREFIX_TEMPLATE = "(%dms) LOGIN: "; @@ -101,7 +104,7 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa } /** - * Sets the time of last activity (used to determine whether the session {@link #hasExpired()}. + * Sets the time of last activity (used to determine whether the session {@link #hasExpired(Long)}. */ void touch() { @@ -111,9 +114,11 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa /** * Returns <code>true</code> if the session has expired. */ - boolean hasExpired() + boolean hasExpired(Long sessionExpirationTimeOrNull) { - return System.currentTimeMillis() - lastActiveTime > session.getSessionExpirationTime(); + long sessionExpirationTime = sessionExpirationTimeOrNull == null ? + session.getSessionExpirationTime() : sessionExpirationTimeOrNull; + return System.currentTimeMillis() - lastActiveTime > sessionExpirationTime; } } @@ -134,6 +139,8 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa /** The time after which an inactive session will be expired (in milliseconds). */ private final int sessionExpirationPeriodMillis; + private final int sessionExpirationPeriodMillisNoLogin; + private final boolean tryEmailAsUserName; public DefaultSessionManager(final ISessionFactory<T> sessionFactory, @@ -142,13 +149,14 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa final IRemoteHostProvider remoteHostProvider, final int sessionExpirationPeriodMinutes) { this(sessionFactory, prefixGenerator, authenticationService, remoteHostProvider, - sessionExpirationPeriodMinutes, false); + sessionExpirationPeriodMinutes, 0, false); } public DefaultSessionManager(final ISessionFactory<T> sessionFactory, final ILogMessagePrefixGenerator<T> prefixGenerator, final IAuthenticationService authenticationService, - final IRemoteHostProvider remoteHostProvider, final int sessionExpirationPeriodMinutes, + final IRemoteHostProvider remoteHostProvider, final int sessionExpirationPeriodMinutes, + final int sessionExpirationPeriodMinutesNoLogin, final boolean tryEmailAsUserName) { @@ -165,6 +173,14 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa this.remoteHostProvider = remoteHostProvider; this.sessionExpirationPeriodMillis = (int) (sessionExpirationPeriodMinutes * DateUtils.MILLIS_PER_MINUTE); + if (sessionExpirationPeriodMinutesNoLogin > 0) + { + this.sessionExpirationPeriodMillisNoLogin + = (int) (sessionExpirationPeriodMinutesNoLogin * DateUtils.MILLIS_PER_MINUTE); + } else + { + this.sessionExpirationPeriodMillisNoLogin = sessionExpirationPeriodMillis; + } this.tryEmailAsUserName = tryEmailAsUserName; operationLog.info(String.format("Authentication service: '%s'", authenticationService @@ -341,7 +357,8 @@ public class DefaultSessionManager<T extends BasicSession> implements ISessionMa private boolean doSessionExpiration(final FullSession<T> session) { - return session != null && session.hasExpired(); + Long expTimeOrNull = NO_LOGIN_FILE.exists() ? (long) sessionExpirationPeriodMillisNoLogin : null; + return session != null && session.hasExpired(expTimeOrNull); } private void logAuthenticed(final T session, final long timeToLoginMillis) diff --git a/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java b/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java index 2144b4701f6..fded9c79073 100644 --- a/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java +++ b/authentication/sourceTest/java/ch/systemsx/cisd/authentication/DefaultSessionManagerTest.java @@ -103,7 +103,7 @@ public class DefaultSessionManagerTest private ISessionManager<BasicSession> createSessionManager(int sessionExpiration) { return new DefaultSessionManager(sessionFactory, prefixGenerator, authenticationService, - remoteHostProvider, sessionExpiration, true); + remoteHostProvider, sessionExpiration, 0, true); } @AfterMethod diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java index 58d3e4accf0..98d47191a62 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java @@ -137,9 +137,9 @@ public interface ICommonClientService extends IClientService /** * Keeps the logged in user session alive. * - * @return 'true' if session was successfully prolonged, 'false' otherwise + * @return <code>null</code> if session was successfully prolonged, otherwise the reason for failure. */ - public Boolean keepSessionAlive() throws UserFailureException; + public String keepSessionAlive() throws UserFailureException; /** * Returns a list of all spaces. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java index 59dac0eb1ac..182d99d7c16 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java @@ -133,7 +133,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedUiAction; public interface ICommonClientServiceAsync extends IClientServiceAsync { /** @see ICommonClientService#keepSessionAlive() */ - public void keepSessionAlive(final AsyncCallback<Boolean> asyncCallback); + public void keepSessionAlive(final AsyncCallback<String> asyncCallback); /** @see ICommonClientService#listSpaces(DefaultResultSetConfig) */ public void listSpaces(DefaultResultSetConfig<String, TableModelRowWithObject<Space>> criteria, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/BasicLoginCallback.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/BasicLoginCallback.java index e58680a5ab5..49e681dddfd 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/BasicLoginCallback.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/BasicLoginCallback.java @@ -107,15 +107,16 @@ public class BasicLoginCallback extends AbstractAsyncCallback<SessionContext> { // callback will cancel keeping session alive if something went wrong // or user logged out - AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() + AsyncCallback<String> callback = new AsyncCallback<String>() { @Override - public void onSuccess(Boolean result) + public void onSuccess(String reasonOrNull) { - if (result == false) + if (reasonOrNull != null) { cancel(); + MessageBox.alert("Session Expiration", reasonOrNull, null); } } @@ -123,6 +124,7 @@ public class BasicLoginCallback extends AbstractAsyncCallback<SessionContext> public void onFailure(Throwable caught) { cancel(); + MessageBox.alert("Server Connection", "Connection to the server is broken.", null); } }; viewContext.getCommonService().keepSessionAlive(callback); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java index 4505790890b..961b036d23e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java @@ -2488,17 +2488,17 @@ public final class CommonClientService extends AbstractClientService implements // -- @Override - public Boolean keepSessionAlive() + public String keepSessionAlive() throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { commonServer.keepSessionAlive(getSessionToken()); - return true; - } catch (final InvalidSessionException e) + return null; + } catch (final Exception e) { - // most probable cause - user logged out - return false; + String reason = getDisabledText(); + return reason == null ? "Session expired. Please, login again." : reason; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java index 351a12f82b3..614b133ea50 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java @@ -16,7 +16,6 @@ package ch.systemsx.cisd.openbis.generic.server; -import java.io.File; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; @@ -35,6 +34,7 @@ import org.apache.commons.lang.StringUtils; import org.springframework.dao.DataAccessException; import org.springframework.transaction.annotation.Transactional; +import ch.systemsx.cisd.authentication.DefaultSessionManager; import ch.systemsx.cisd.authentication.IPrincipalProvider; import ch.systemsx.cisd.authentication.ISessionManager; import ch.systemsx.cisd.authentication.Principal; @@ -467,7 +467,7 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp @Override public final SessionContextDTO tryAuthenticate(final String user, final String password) { - if (tryGetDisabledText() != null) + if (DefaultSessionManager.NO_LOGIN_FILE.exists()) { throw new UserFailureException("Login is disabled by the administrator."); } @@ -1037,12 +1037,11 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp protected static String tryGetDisabledText() { - File noLoginFile = new File("./etc/nologin.html"); - if (noLoginFile.exists() == false) + if (DefaultSessionManager.NO_LOGIN_FILE.exists() == false) { return null; } - return FileUtilities.loadToString(noLoginFile).trim(); + return FileUtilities.loadToString(DefaultSessionManager.NO_LOGIN_FILE).trim(); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java index 43980d0cd26..f6c982653eb 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/OpenBisSessionManager.java @@ -34,22 +34,36 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; */ public class OpenBisSessionManager extends DefaultSessionManager<Session> implements IOpenBisSessionManager { + private static final int DEFAULT_SESSION_EXPIRATION_PERIOD_FOR_NO_LOGIN = 10; + + private static final int getSessionExpirationPeriodMinutesForNoLogin(String property) + { + try + { + return Integer.parseInt(property); + } catch (NumberFormatException ex) + { + return DEFAULT_SESSION_EXPIRATION_PERIOD_FOR_NO_LOGIN; + } + } + IDAOFactory daoFactory; public OpenBisSessionManager(ISessionFactory<Session> sessionFactory, ILogMessagePrefixGenerator<Session> prefixGenerator, IAuthenticationService authenticationService, IRemoteHostProvider remoteHostProvider, int sessionExpirationPeriodMinutes, - boolean tryEmailAsUserName, IDAOFactory daoFactory) + String sessionExpirationPeriodMinutesForNoLogin, boolean tryEmailAsUserName, IDAOFactory daoFactory) { - super(sessionFactory, prefixGenerator, authenticationService, remoteHostProvider, sessionExpirationPeriodMinutes, tryEmailAsUserName); + super(sessionFactory, prefixGenerator, authenticationService, remoteHostProvider, sessionExpirationPeriodMinutes, + getSessionExpirationPeriodMinutesForNoLogin(sessionExpirationPeriodMinutesForNoLogin), tryEmailAsUserName); this.daoFactory = daoFactory; } public OpenBisSessionManager(ISessionFactory<Session> sessionFactory, ILogMessagePrefixGenerator<Session> prefixGenerator, IAuthenticationService authenticationService, IRemoteHostProvider remoteHostProvider, int sessionExpirationPeriodMinutes, - IDAOFactory daoFactory) + String sessionExpirationPeriodMinutesForNoLogin, IDAOFactory daoFactory) { - super(sessionFactory, prefixGenerator, authenticationService, remoteHostProvider, sessionExpirationPeriodMinutes); - this.daoFactory = daoFactory; + this(sessionFactory, prefixGenerator, authenticationService, remoteHostProvider, sessionExpirationPeriodMinutes, + sessionExpirationPeriodMinutesForNoLogin, false, daoFactory); } @Override diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml index 0af786405f4..ad181ae6fb3 100644 --- a/openbis/source/java/genericApplicationContext.xml +++ b/openbis/source/java/genericApplicationContext.xml @@ -125,6 +125,7 @@ </constructor-arg> <!-- The time after which an inactive session is expired by the service (in minutes). --> <constructor-arg value="${session-timeout}" /> + <constructor-arg value="${session-timeout-no-login}" /> <!-- Enable login with email addresses --> <constructor-arg value="true" /> <constructor-arg ref="dao-factory"/> -- GitLab