Index: lams_central/src/java/org/lamsfoundation/lams/web/SessionListener.java =================================================================== diff -u -rbade4b8bf18e8e7b609d3e3e643e8cae64869303 -r7f420dcfde4984d32bb8acedde964ca613c1cb6c --- lams_central/src/java/org/lamsfoundation/lams/web/SessionListener.java (.../SessionListener.java) (revision bade4b8bf18e8e7b609d3e3e643e8cae64869303) +++ lams_central/src/java/org/lamsfoundation/lams/web/SessionListener.java (.../SessionListener.java) (revision 7f420dcfde4984d32bb8acedde964ca613c1cb6c) @@ -35,6 +35,8 @@ import org.apache.log4j.Logger; import org.jboss.security.CacheableManager; +import org.lamsfoundation.lams.logevent.LogEvent; +import org.lamsfoundation.lams.logevent.service.ILogEventService; import org.lamsfoundation.lams.security.SimplePrincipal; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.util.Configuration; @@ -43,6 +45,8 @@ import org.lamsfoundation.lams.web.filter.LocaleFilter; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; /** * Listens for creation of HTTP sessions. Sets inactive timeout and default locale. @@ -51,6 +55,8 @@ public class SessionListener implements HttpSessionListener { private static CacheableManager authenticationManager; + private ILogEventService logEventService; + private static Logger log = Logger.getLogger(SessionListener.class); /** HttpSessionListener interface */ @@ -89,18 +95,30 @@ // clear the authentication cache when the session is invalidated HttpSession session = sessionEvent.getSession(); if (session != null) { - SessionManager.removeSessionByID(session.getId(), false, true); + boolean sessionFound = SessionManager.removeSessionByID(session.getId(), false, true); UserDTO userDTO = (UserDTO) session.getAttribute(AttributeNames.USER); if (userDTO != null) { String login = userDTO.getLogin(); Principal principal = new SimplePrincipal(login); SessionListener.authenticationManager.flushCache(principal); - // remove obsolete mappings to session - // the session is either already invalidated or will be very soon by another module - SessionManager.removeSessionByLogin(login, false); + if (sessionFound) { + String message = new StringBuilder("User ").append(login).append(" (").append(userDTO.getUserID()) + .append(") logged out").toString(); + getLogEventService().logEvent(LogEvent.TYPE_LOGOUT, userDTO.getUserID(), userDTO.getUserID(), null, + null, message); + } } } } + + private ILogEventService getLogEventService() { + if (logEventService == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getWebApplicationContext(SessionManager.getServletContext()); + logEventService = (ILogEventService) ctx.getBean("logEventService"); + } + return logEventService; + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20190201.sql =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20190201.sql (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20190201.sql (revision 7f420dcfde4984d32bb8acedde964ca613c1cb6c) @@ -0,0 +1,17 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; +SET FOREIGN_KEY_CHECKS=0; +----------------------Put all sql statements below here------------------------- + +-- LDEV-4767 Add new event types for log in and log out + +INSERT INTO lams_log_event_type VALUES (24, 'TYPE_LOGIN', 'SECURITY'), + (25, 'TYPE_LOGOUT', 'SECURITY'); + + +----------------------Put all sql statements above here------------------------- + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/integration/security/SsoHandler.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r7f420dcfde4984d32bb8acedde964ca613c1cb6c --- lams_common/src/java/org/lamsfoundation/lams/integration/security/SsoHandler.java (.../SsoHandler.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_common/src/java/org/lamsfoundation/lams/integration/security/SsoHandler.java (.../SsoHandler.java) (revision 7f420dcfde4984d32bb8acedde964ca613c1cb6c) @@ -189,6 +189,11 @@ getUserManagementService(session.getServletContext()).save(user); } + String message = new StringBuilder("User ").append(user.getLogin()).append(" (") + .append(user.getUserId()).append(") logged in").toString(); + getLogEventService(session.getServletContext()).logEvent(LogEvent.TYPE_LOGIN, user.getUserId(), + user.getUserId(), null, null, message); + } else { Integer failedAttempts = user.getFailedAttempts(); if (failedAttempts == null) { @@ -205,7 +210,7 @@ Long currentTimeMillis = System.currentTimeMillis(); Date date = new Date(currentTimeMillis + lockOutTimeMillis); user.setLockOutTime(date); - String message = new StringBuilder("User ").append(user.getLogin()).append("(") + String message = new StringBuilder("User ").append(user.getLogin()).append(" (") .append(user.getUserId()).append(") is locked out for ") .append(Configuration.getAsInt(ConfigurationKeys.LOCK_OUT_TIME)).append(" mins after ") .append(failedAttempts).append(" failed attempts.").toString(); Index: lams_common/src/java/org/lamsfoundation/lams/logevent/LogEvent.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -r7f420dcfde4984d32bb8acedde964ca613c1cb6c --- lams_common/src/java/org/lamsfoundation/lams/logevent/LogEvent.java (.../LogEvent.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_common/src/java/org/lamsfoundation/lams/logevent/LogEvent.java (.../LogEvent.java) (revision 7f420dcfde4984d32bb8acedde964ca613c1cb6c) @@ -75,6 +75,8 @@ public static final int TYPE_UNKNOWN = 21; // catch all for conversion public static final int TYPE_LIVE_EDIT = 22; // Start or end Live Edit of a lesson public static final int TYPE_TOOL_MARK_RELEASED = 23; // Mark released in tool + public static final int TYPE_LOGIN = 24; // user logged in + public static final int TYPE_LOGOUT = 25; // user logged out /** *************************************************************** */ Index: lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java =================================================================== diff -u -rfd2cfad55c7c517931f69334ce644d509ec28140 -r7f420dcfde4984d32bb8acedde964ca613c1cb6c --- lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java (.../SessionManager.java) (revision fd2cfad55c7c517931f69334ce644d509ec28140) +++ lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java (.../SessionManager.java) (revision 7f420dcfde4984d32bb8acedde964ca613c1cb6c) @@ -44,9 +44,9 @@ // singleton private static SessionManager sessionManager; - private static final Map sessionIdMapping = new ConcurrentHashMap(); - private static final Map loginMapping = new ConcurrentHashMap(); - private ThreadLocal currentSessionIdContainer = new ThreadLocal(); + private static final Map sessionIdMapping = new ConcurrentHashMap<>(); + private static final Map loginMapping = new ConcurrentHashMap<>(); + private ThreadLocal currentSessionIdContainer = new ThreadLocal<>(); // various classes need to have to access these private static ServletContext servletContext; @@ -132,7 +132,7 @@ /** * Unregisteres the session by the given ID. */ - public static void removeSessionByID(String sessionID, boolean invalidate, boolean clearLoginMapping) { + public static boolean removeSessionByID(String sessionID, boolean invalidate, boolean clearLoginMapping) { HttpSession session = SessionManager.getSession(sessionID); if (session != null) { SessionManager.sessionIdMapping.remove(sessionID); @@ -158,6 +158,8 @@ SessionManager.loginMapping.remove(login); } } + + return session != null; } /** @@ -210,11 +212,11 @@ * Lists all logins with their assigned sessions */ public static Map> getLoginToSessionIDMappings() { - Map> result = new TreeMap>(); + Map> result = new TreeMap<>(); for (Entry entry : loginMapping.entrySet()) { HttpSession session = entry.getValue(); UserDTO user = (UserDTO) session.getAttribute(AttributeNames.USER); - List sessionInfo = new LinkedList(); + List sessionInfo = new LinkedList<>(); sessionInfo.add(user.getFirstName()); sessionInfo.add(user.getLastName()); sessionInfo.add(session.getId());