Merge pull request #823 from mposolda/master

KEYCLOAK-788 Ensure expired ClientSessions removed during UserSessionPro...
This commit is contained in:
Marek Posolda 2014-10-30 23:34:27 +01:00
commit 65362be4dd
4 changed files with 47 additions and 1 deletions

View file

@ -210,6 +210,15 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
for (String id : map.keySet()) { for (String id : map.keySet()) {
removeUserSession(realm, id); removeUserSession(realm, id);
} }
map = new MapReduceTask(sessionCache)
.mappedWith(ClientSessionMapper.create(realm.getId()).expiredRefresh(expiredRefresh).requireNullUserSession(true).emitKey())
.reducedWith(new FirstResultReducer())
.execute();
for (String id : map.keySet()) {
tx.remove(sessionCache, id);
}
} }
@Override @Override

View file

@ -28,6 +28,10 @@ public class ClientSessionMapper implements Mapper<String, SessionEntity, String
private String userSession; private String userSession;
private Long expiredRefresh;
private Boolean requireNullUserSession = false;
public static ClientSessionMapper create(String realm) { public static ClientSessionMapper create(String realm) {
return new ClientSessionMapper(realm); return new ClientSessionMapper(realm);
} }
@ -52,6 +56,16 @@ public class ClientSessionMapper implements Mapper<String, SessionEntity, String
return this; return this;
} }
public ClientSessionMapper expiredRefresh(long expiredRefresh) {
this.expiredRefresh = expiredRefresh;
return this;
}
public ClientSessionMapper requireNullUserSession(boolean requireNullUserSession) {
this.requireNullUserSession = requireNullUserSession;
return this;
}
@Override @Override
public void map(String key, SessionEntity e, Collector collector) { public void map(String key, SessionEntity e, Collector collector) {
if (!realm.equals(e.getRealm())) { if (!realm.equals(e.getRealm())) {
@ -72,6 +86,14 @@ public class ClientSessionMapper implements Mapper<String, SessionEntity, String
return; return;
} }
if (requireNullUserSession && entity.getUserSession() != null) {
return;
}
if (expiredRefresh != null && entity.getTimestamp() > expiredRefresh) {
return;
}
switch (emit) { switch (emit) {
case KEY: case KEY:
collector.emit(key, key); collector.emit(key, key);

View file

@ -194,7 +194,7 @@ public class MemUserSessionProvider implements UserSessionProvider {
Iterator<ClientSessionEntity> citr = clientSessions.values().iterator(); Iterator<ClientSessionEntity> citr = clientSessions.values().iterator();
while (citr.hasNext()) { while (citr.hasNext()) {
ClientSessionEntity c = citr.next(); ClientSessionEntity c = citr.next();
if (c.getSession() == null && c.getTimestamp() < Time.currentTime() - realm.getSsoSessionIdleTimeout()) { if (c.getSession() == null && c.getRealmId().equals(realm.getId()) && c.getTimestamp() < Time.currentTime() - realm.getSsoSessionIdleTimeout()) {
citr.remove(); citr.remove();
} }
} }

View file

@ -244,12 +244,15 @@ public class UserSessionProviderTest {
@Test @Test
public void testRemoveUserSessionsByExpired() { public void testRemoveUserSessionsByExpired() {
session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm)); session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm));
ClientModel client = realm.findClient("test-app");
try { try {
Set<String> expired = new HashSet<String>(); Set<String> expired = new HashSet<String>();
Set<String> expiredClientSessions = new HashSet<String>();
Time.setOffset(-(realm.getSsoSessionMaxLifespan() + 1)); Time.setOffset(-(realm.getSsoSessionMaxLifespan() + 1));
expired.add(session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true).getId()); expired.add(session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true).getId());
expiredClientSessions.add(session.sessions().createClientSession(realm, client).getId());
Time.setOffset(0); Time.setOffset(0);
UserSessionModel s = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.1", "form", true); UserSessionModel s = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.1", "form", true);
@ -257,9 +260,15 @@ public class UserSessionProviderTest {
s.setLastSessionRefresh(0); s.setLastSessionRefresh(0);
expired.add(s.getId()); expired.add(s.getId());
ClientSessionModel clSession = session.sessions().createClientSession(realm, client);
clSession.setUserSession(s);
expiredClientSessions.add(clSession.getId());
Set<String> valid = new HashSet<String>(); Set<String> valid = new HashSet<String>();
Set<String> validClientSessions = new HashSet<String>();
valid.add(session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true).getId()); valid.add(session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true).getId());
validClientSessions.add(session.sessions().createClientSession(realm, client).getId());
resetSession(); resetSession();
@ -269,10 +278,16 @@ public class UserSessionProviderTest {
for (String e : expired) { for (String e : expired) {
assertNull(session.sessions().getUserSession(realm, e)); assertNull(session.sessions().getUserSession(realm, e));
} }
for (String e : expiredClientSessions) {
assertNull(session.sessions().getClientSession(realm, e));
}
for (String v : valid) { for (String v : valid) {
assertNotNull(session.sessions().getUserSession(realm, v)); assertNotNull(session.sessions().getUserSession(realm, v));
} }
for (String e : validClientSessions) {
assertNotNull(session.sessions().getClientSession(realm, e));
}
} finally { } finally {
Time.setOffset(0); Time.setOffset(0);
} }