From 1d1253e643c7951ad7a939990fc0ab31bdf5772e Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Fri, 20 Apr 2018 23:08:50 +0200 Subject: [PATCH] Rename expiration key on changeSessionId in RedisOperationsSessionRepository This commit ensures existing expiration key is renamed on changeSessionId operation in RedisOperationsSessionRepository. Previously, this key wasn't renamed which caused invalid invocations of SessionDestroyedEvent handling when key expired. Closes gh-1029 --- .../RedisOperationsSessionRepository.java | 7 +++- ...RedisOperationsSessionRepositoryTests.java | 33 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java index 95c4a7a5..c947031a 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java @@ -808,7 +808,12 @@ public class RedisOperationsSessionRepository implements if (!isNew()) { String originalSessionIdKey = getSessionKey(this.originalSessionId); String sessionIdKey = getSessionKey(sessionId); - RedisOperationsSessionRepository.this.sessionRedisOperations.rename(originalSessionIdKey, sessionIdKey); + RedisOperationsSessionRepository.this.sessionRedisOperations.rename( + originalSessionIdKey, sessionIdKey); + String originalExpiredKey = getExpiredKey(this.originalSessionId); + String expiredKey = getExpiredKey(sessionId); + RedisOperationsSessionRepository.this.sessionRedisOperations.rename( + originalExpiredKey, expiredKey); } this.originalSessionId = sessionId; } diff --git a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java index e89fcce1..b2b288c5 100644 --- a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java +++ b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java @@ -117,15 +117,46 @@ public class RedisOperationsSessionRepositoryTests { } @Test - public void changeSessionId() { + public void changeSessionIdWhenNotSaved() { + given(this.redisOperations.boundHashOps(anyString())) + .willReturn(this.boundHashOperations); + given(this.redisOperations.boundSetOps(anyString())) + .willReturn(this.boundSetOperations); + given(this.redisOperations.boundValueOps(anyString())) + .willReturn(this.boundValueOperations); + RedisSession createSession = this.redisRepository.createSession(); String originalId = createSession.getId(); String changeSessionId = createSession.changeSessionId(); + this.redisRepository.save(createSession); + + verify(this.redisOperations, never()).rename(anyString(), anyString()); assertThat(originalId).isNotEqualTo(changeSessionId); assertThat(createSession.getId()).isEqualTo(createSession.getId()); } + @Test + public void changeSessionIdWhenSaved() { + given(this.redisOperations.boundHashOps(anyString())) + .willReturn(this.boundHashOperations); + given(this.redisOperations.boundSetOps(anyString())) + .willReturn(this.boundSetOperations); + given(this.redisOperations.boundValueOps(anyString())) + .willReturn(this.boundValueOperations); + + RedisSession session = this.redisRepository.new RedisSession(this.cached); + session.setLastAccessedTime(session.getLastAccessedTime()); + String originalId = session.getId(); + String changeSessionId = session.changeSessionId(); + this.redisRepository.save(session); + + verify(this.redisOperations, times(2)).rename(anyString(), anyString()); + + assertThat(originalId).isNotEqualTo(changeSessionId); + assertThat(session.getId()).isEqualTo(session.getId()); + } + @Test public void createSessionDefaultMaxInactiveInterval() throws Exception { Session session = this.redisRepository.createSession();