diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java index 864e04e15..ef5d7d5af 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java @@ -38,23 +38,19 @@ /** * Roller session handles session startup and shutdown. - * - * @web.listener */ public class RollerSession implements HttpSessionListener, HttpSessionActivationListener, Serializable { - static final long serialVersionUID = 5890132909166913727L; - + private static final long serialVersionUID = 5890132909166913727L; + // the id of the user represented by this session private String userName = null; private static final Log log; public static final String ROLLER_SESSION = "org.apache.roller.weblogger.rollersession"; - public static final String ERROR_MESSAGE = "rollererror_message"; - public static final String STATUS_MESSAGE = "rollerstatus_message"; - + static{ WebloggerConfig.init(); // must be called before calls to logging APIs log = LogFactory.getLog(RollerSession.class); @@ -68,12 +64,17 @@ public static RollerSession getRollerSession(HttpServletRequest request) { HttpSession session = request.getSession(false); if (session != null) { rollerSession = (RollerSession)session.getAttribute(ROLLER_SESSION); - + if (rollerSession == null) { - // HttpSession with no RollerSession? - // Must be a session that was de-serialized from a previous run. rollerSession = new RollerSession(); session.setAttribute(ROLLER_SESSION, rollerSession); + } else if (rollerSession.getAuthenticatedUser() != null) { + RollerSessionManager sessionManager = RollerSessionManager.getInstance(); + if (sessionManager.get(rollerSession.getAuthenticatedUser().getUserName()) == null) { + // session not present in cache means that it is invalid + rollerSession = new RollerSession(); + session.setAttribute(ROLLER_SESSION, rollerSession); + } } Principal principal = request.getUserPrincipal(); @@ -124,47 +125,14 @@ public static RollerSession getRollerSession(HttpServletRequest request) { return rollerSession; } - - - /** Create session's Roller instance */ - @Override - public void sessionCreated(HttpSessionEvent se) { - RollerSession rollerSession = new RollerSession(); - se.getSession().setAttribute(ROLLER_SESSION, rollerSession); - } - - @Override - public void sessionDestroyed(HttpSessionEvent se) { - clearSession(se); - } - - - /** Init session as if it was new */ - @Override - public void sessionDidActivate(HttpSessionEvent se) { - } - - - /** - * Purge session before passivation. Because Roller currently does not - * support session recovery, failover, migration, or whatever you want - * to call it when sessions are saved and then restored at some later - * point in time. - */ - @Override - public void sessionWillPassivate(HttpSessionEvent se) { - clearSession(se); - } - - /** * Authenticated user associated with this session. */ public User getAuthenticatedUser() { User authenticUser = null; - if(userName != null) { + if (userName != null) { try { UserManager mgr = WebloggerFactory.getWeblogger().getUserManager(); authenticUser = mgr.getUserByUserName(userName); @@ -175,16 +143,16 @@ public User getAuthenticatedUser() { return authenticUser; } - - + /** * Authenticated user associated with this session. */ public void setAuthenticatedUser(User authenticatedUser) { this.userName = authenticatedUser.getUserName(); + RollerSessionManager sessionManager = RollerSessionManager.getInstance(); + sessionManager.register(authenticatedUser.getUserName(), this); } - - + private void clearSession(HttpSessionEvent se) { HttpSession session = se.getSession(); try { diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionManager.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionManager.java new file mode 100644 index 000000000..dca4e11c0 --- /dev/null +++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionManager.java @@ -0,0 +1,63 @@ +package org.apache.roller.weblogger.ui.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.roller.weblogger.pojos.User; +import org.apache.roller.weblogger.util.cache.Cache; +import org.apache.roller.weblogger.util.cache.CacheHandlerAdapter; +import org.apache.roller.weblogger.util.cache.CacheManager; + +import java.util.HashMap; +import java.util.Map; + +public class RollerSessionManager { + private static final Log log = LogFactory.getLog(RollerSessionManager.class); + private static final String CACHE_ID = "roller.session.cache"; + + private final Cache sessionCache; + + public static RollerSessionManager getInstance() { + return RollerSessionManager.SingletonHolder.INSTANCE; + } + + private static class SingletonHolder { + private static final RollerSessionManager INSTANCE = new RollerSessionManager(); + } + + private class SessionCacheHandler extends CacheHandlerAdapter { + public void invalidateUser(User user) { + if (user != null && user.getUserName() != null) { + sessionCache.remove(user.getUserName()); + } + } + } + + private RollerSessionManager() { + Map cacheProps = new HashMap<>(); + cacheProps.put("id", CACHE_ID); + this.sessionCache = CacheManager.constructCache(null, cacheProps); + SessionCacheHandler cacheHandler = new SessionCacheHandler(); + CacheManager.registerHandler(cacheHandler); + } + + public void register(String userName, RollerSession session) { + if (userName != null && session != null) { + this.sessionCache.put(userName, session); + log.debug("Registered session for user: " + userName); + } + } + + public RollerSession get(String userName) { + if (userName != null) { + return (RollerSession) this.sessionCache.get(userName); + } + return null; + } + + public void invalidate(String userName) { + if (userName != null) { + this.sessionCache.remove(userName); + log.debug("Invalidated session for user: " + userName); + } + } +} diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java index 6284e46b5..e8aea6703 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java @@ -37,6 +37,7 @@ import org.apache.roller.weblogger.pojos.GlobalPermission; import org.apache.roller.weblogger.pojos.User; import org.apache.roller.weblogger.pojos.WeblogPermission; +import org.apache.roller.weblogger.ui.core.RollerSessionManager; import org.apache.roller.weblogger.ui.struts2.core.Register; import org.apache.roller.weblogger.ui.struts2.util.UIAction; import org.apache.struts2.interceptor.validation.SkipValidation; @@ -165,6 +166,18 @@ public String save() { // reset password if set if (!StringUtils.isEmpty(getBean().getPassword())) { user.resetPassword(getBean().getPassword()); + + // invalidate user's session if it's not user executing this action + if (!getAuthenticatedUser().getUserName().equals(user.getUserName())) { + RollerSessionManager sessionManager = RollerSessionManager.getInstance(); + sessionManager.invalidate(user.getUserName()); + } + } + + // if user is disabled and not the same as the user executing this action, then invalidate their session + if (!user.getEnabled() && !getAuthenticatedUser().getUserName().equals(user.getUserName())) { + RollerSessionManager sessionManager = RollerSessionManager.getInstance(); + sessionManager.invalidate(user.getUserName()); } try { diff --git a/app/src/main/java/org/apache/roller/weblogger/util/cache/CacheHandlerAdapter.java b/app/src/main/java/org/apache/roller/weblogger/util/cache/CacheHandlerAdapter.java new file mode 100644 index 000000000..1d8cc5a1b --- /dev/null +++ b/app/src/main/java/org/apache/roller/weblogger/util/cache/CacheHandlerAdapter.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ +package org.apache.roller.weblogger.util.cache; + +import org.apache.roller.weblogger.pojos.*; + +public class CacheHandlerAdapter implements CacheHandler { + + @Override + public void invalidate(WeblogEntry entry) { + } + + @Override + public void invalidate(Weblog website) { + } + + @Override + public void invalidate(WeblogBookmark bookmark) { + } + + @Override + public void invalidate(WeblogBookmarkFolder folder) { + } + + @Override + public void invalidate(WeblogEntryComment comment) { + } + + @Override + public void invalidate(User user) { + } + + @Override + public void invalidate(WeblogCategory category) { + } + + @Override + public void invalidate(WeblogTemplate template) { + } +}