Convert user / client session entities into interface
This commit is contained in:
parent
9cb38087b4
commit
3bb4081bd1
9 changed files with 222 additions and 461 deletions
|
@ -56,11 +56,6 @@ public interface MapUserLoginFailureEntity extends AbstractEntity, UpdatableEnti
|
||||||
setLastFailure(null);
|
setLastFailure(null);
|
||||||
setLastIPFailure(null);
|
setLastIPFailure(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%s@%08x", getId(), hashCode());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getRealmId();
|
String getRealmId();
|
||||||
|
|
|
@ -67,6 +67,10 @@ import org.keycloak.models.map.user.MapUserCredentialEntityImpl;
|
||||||
import org.keycloak.models.map.user.MapUserEntityImpl;
|
import org.keycloak.models.map.user.MapUserEntityImpl;
|
||||||
import org.keycloak.models.map.user.MapUserFederatedIdentityEntityImpl;
|
import org.keycloak.models.map.user.MapUserFederatedIdentityEntityImpl;
|
||||||
import org.keycloak.models.map.storage.ModelEntityUtil;
|
import org.keycloak.models.map.storage.ModelEntityUtil;
|
||||||
|
import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity;
|
||||||
|
import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntityImpl;
|
||||||
|
import org.keycloak.models.map.userSession.MapUserSessionEntity;
|
||||||
|
import org.keycloak.models.map.userSession.MapUserSessionEntityImpl;
|
||||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
|
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
|
||||||
|
@ -131,6 +135,8 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide
|
||||||
.constructor(MapRootAuthenticationSessionEntity.class, MapRootAuthenticationSessionEntityImpl::new)
|
.constructor(MapRootAuthenticationSessionEntity.class, MapRootAuthenticationSessionEntityImpl::new)
|
||||||
.constructor(MapAuthenticationSessionEntity.class, MapAuthenticationSessionEntityImpl::new)
|
.constructor(MapAuthenticationSessionEntity.class, MapAuthenticationSessionEntityImpl::new)
|
||||||
.constructor(MapUserLoginFailureEntity.class, MapUserLoginFailureEntityImpl::new)
|
.constructor(MapUserLoginFailureEntity.class, MapUserLoginFailureEntityImpl::new)
|
||||||
|
.constructor(MapUserSessionEntity.class, MapUserSessionEntityImpl::new)
|
||||||
|
.constructor(MapAuthenticatedClientSessionEntity.class, MapAuthenticatedClientSessionEntityImpl::new)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private static final Map<String, StringKeyConverter> KEY_CONVERTERS = new HashMap<>();
|
private static final Map<String, StringKeyConverter> KEY_CONVERTERS = new HashMap<>();
|
||||||
|
|
|
@ -491,7 +491,7 @@ public class MapFieldPredicates {
|
||||||
|
|
||||||
private static MapModelCriteriaBuilder<Object, MapUserSessionEntity, UserSessionModel> checkUserSessionContainsAuthenticatedClientSession(MapModelCriteriaBuilder<Object, MapUserSessionEntity, UserSessionModel> mcb, Operator op, Object[] values) {
|
private static MapModelCriteriaBuilder<Object, MapUserSessionEntity, UserSessionModel> checkUserSessionContainsAuthenticatedClientSession(MapModelCriteriaBuilder<Object, MapUserSessionEntity, UserSessionModel> mcb, Operator op, Object[] values) {
|
||||||
String clientId = ensureEqSingleValue(UserSessionModel.SearchableFields.CLIENT_ID, "client_id", op, values);
|
String clientId = ensureEqSingleValue(UserSessionModel.SearchableFields.CLIENT_ID, "client_id", op, values);
|
||||||
Function<MapUserSessionEntity, ?> getter = use -> (use.getAuthenticatedClientSessions().containsKey(clientId));
|
Function<MapUserSessionEntity, ?> getter = use -> (use.getAuthenticatedClientSession(clientId) != null);
|
||||||
return mcb.fieldCompare(Boolean.TRUE::equals, getter);
|
return mcb.fieldCompare(Boolean.TRUE::equals, getter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +41,8 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTimestamp() {
|
public int getTimestamp() {
|
||||||
return entity.getTimestamp();
|
Integer timestamp = entity.getTimestamp();
|
||||||
|
return timestamp != null ? timestamp : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,7 +67,8 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCurrentRefreshTokenUseCount() {
|
public int getCurrentRefreshTokenUseCount() {
|
||||||
return entity.getCurrentRefreshTokenUseCount();
|
Integer currentRefreshTokenUseCount = entity.getCurrentRefreshTokenUseCount();
|
||||||
|
return currentRefreshTokenUseCount != null ? currentRefreshTokenUseCount : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -75,7 +78,7 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNote(String name) {
|
public String getNote(String name) {
|
||||||
return (name != null) ? entity.getNotes().get(name) : null;
|
return (name != null) ? entity.getNote(name) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,7 +87,7 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
entity.removeNote(name);
|
entity.removeNote(name);
|
||||||
} else {
|
} else {
|
||||||
entity.addNote(name, value);
|
entity.setNote(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +101,8 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getNotes() {
|
public Map<String, String> getNotes() {
|
||||||
return entity.getNotes();
|
Map<String, String> notes = entity.getNotes();
|
||||||
|
return notes == null ? Collections.emptyMap() : Collections.unmodifiableMap(notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,51 +16,25 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.models.map.userSession;
|
package org.keycloak.models.map.userSession;
|
||||||
|
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
|
||||||
import org.keycloak.models.map.common.AbstractEntity;
|
import org.keycloak.models.map.common.AbstractEntity;
|
||||||
|
|
||||||
|
import org.keycloak.models.map.common.DeepCloner;
|
||||||
import org.keycloak.models.map.common.UpdatableEntity;
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
*/
|
*/
|
||||||
public class MapAuthenticatedClientSessionEntity extends UpdatableEntity.Impl implements AbstractEntity {
|
@GenerateEntityImplementations(
|
||||||
|
inherits = "org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity.AbstractAuthenticatedClientSessionEntity"
|
||||||
|
)
|
||||||
|
@DeepCloner.Root
|
||||||
|
public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, UpdatableEntity {
|
||||||
|
|
||||||
|
public abstract class AbstractAuthenticatedClientSessionEntity extends UpdatableEntity.Impl implements MapAuthenticatedClientSessionEntity {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String userSessionId;
|
|
||||||
private String realmId;
|
|
||||||
private String clientId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag signalizing that any of the setters has been meaningfully used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private String authMethod;
|
|
||||||
private String redirectUri;
|
|
||||||
private volatile int timestamp;
|
|
||||||
private long expiration;
|
|
||||||
private String action;
|
|
||||||
|
|
||||||
private Map<String, String> notes = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private String currentRefreshToken;
|
|
||||||
private int currentRefreshTokenUseCount;
|
|
||||||
|
|
||||||
private boolean offline;
|
|
||||||
|
|
||||||
public MapAuthenticatedClientSessionEntity() {}
|
|
||||||
|
|
||||||
public MapAuthenticatedClientSessionEntity(String id, String userSessionId, String realmId, String clientId, boolean offline) {
|
|
||||||
this.id = id;
|
|
||||||
this.userSessionId = userSessionId;
|
|
||||||
this.realmId = realmId;
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.offline = offline;
|
|
||||||
this.timestamp = Time.currentTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -73,127 +47,44 @@ public class MapAuthenticatedClientSessionEntity extends UpdatableEntity.Impl im
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.updated |= id != null;
|
this.updated |= id != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmId() {
|
|
||||||
return realmId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmId(String realmId) {
|
String getRealmId();
|
||||||
this.updated |= !Objects.equals(this.realmId, realmId);
|
void setRealmId(String realmId);
|
||||||
this.realmId = realmId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientId() {
|
String getClientId();
|
||||||
return clientId;
|
void setClientId(String clientId);
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientId(String clientId) {
|
String getUserSessionId();
|
||||||
this.updated |= !Objects.equals(this.clientId, clientId);
|
void setUserSessionId(String userSessionId);
|
||||||
this.clientId = clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserSessionId() {
|
String getAuthMethod();
|
||||||
return userSessionId;
|
void setAuthMethod(String authMethod);
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserSessionId(String userSessionId) {
|
String getRedirectUri();
|
||||||
this.updated |= !Objects.equals(this.userSessionId, userSessionId);
|
void setRedirectUri(String redirectUri);
|
||||||
this.userSessionId = userSessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthMethod() {
|
Integer getTimestamp();
|
||||||
return authMethod;
|
void setTimestamp(Integer timestamp);
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthMethod(String authMethod) {
|
Long getExpiration();
|
||||||
this.updated |= !Objects.equals(this.authMethod, authMethod);
|
void setExpiration(Long expiration);
|
||||||
this.authMethod = authMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRedirectUri() {
|
String getAction();
|
||||||
return redirectUri;
|
void setAction(String action);
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedirectUri(String redirectUri) {
|
Map<String, String> getNotes();
|
||||||
this.updated |= !Objects.equals(this.redirectUri, redirectUri);
|
void setNotes(Map<String, String> notes);
|
||||||
this.redirectUri = redirectUri;
|
String getNote(String name);
|
||||||
}
|
Boolean removeNote(String name);
|
||||||
|
void setNote(String name, String value);
|
||||||
|
|
||||||
public int getTimestamp() {
|
String getCurrentRefreshToken();
|
||||||
return timestamp;
|
void setCurrentRefreshToken(String currentRefreshToken);
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(int timestamp) {
|
Integer getCurrentRefreshTokenUseCount();
|
||||||
this.updated |= this.timestamp != timestamp;
|
void setCurrentRefreshTokenUseCount(Integer currentRefreshTokenUseCount);
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getExpiration() {
|
Boolean isOffline();
|
||||||
return expiration;
|
void setOffline(Boolean offline);
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpiration(long expiration) {
|
|
||||||
this.updated |= this.expiration != expiration;
|
|
||||||
this.expiration = expiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAction() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(String action) {
|
|
||||||
this.updated |= !Objects.equals(this.action, action);
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getNotes() {
|
|
||||||
return notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNotes(Map<String, String> notes) {
|
|
||||||
this.updated |= !Objects.equals(this.notes, notes);
|
|
||||||
this.notes = notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String removeNote(String name) {
|
|
||||||
String note = this.notes.remove(name);
|
|
||||||
this.updated |= note != null;
|
|
||||||
return note;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addNote(String name, String value) {
|
|
||||||
this.updated |= !Objects.equals(this.notes.put(name, value), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCurrentRefreshToken() {
|
|
||||||
return currentRefreshToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentRefreshToken(String currentRefreshToken) {
|
|
||||||
this.updated |= !Objects.equals(this.currentRefreshToken, currentRefreshToken);
|
|
||||||
this.currentRefreshToken = currentRefreshToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentRefreshTokenUseCount() {
|
|
||||||
return currentRefreshTokenUseCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentRefreshTokenUseCount(int currentRefreshTokenUseCount) {
|
|
||||||
this.updated |= this.currentRefreshTokenUseCount != currentRefreshTokenUseCount;
|
|
||||||
this.currentRefreshTokenUseCount = currentRefreshTokenUseCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOffline() {
|
|
||||||
return offline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOffline(boolean offline) {
|
|
||||||
this.updated |= this.offline != offline;
|
|
||||||
this.offline = offline;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%s@%08x", getId(), hashCode());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,17 +83,20 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRememberMe() {
|
public boolean isRememberMe() {
|
||||||
return entity.isRememberMe();
|
Boolean rememberMe = entity.isRememberMe();
|
||||||
|
return rememberMe != null ? rememberMe : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStarted() {
|
public int getStarted() {
|
||||||
return entity.getStarted();
|
Integer started = entity.getStarted();
|
||||||
|
return started != null ? started : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLastSessionRefresh() {
|
public int getLastSessionRefresh() {
|
||||||
return entity.getLastSessionRefresh();
|
Integer lastSessionRefresh = entity.getLastSessionRefresh();
|
||||||
|
return lastSessionRefresh != null ? lastSessionRefresh : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,7 +106,8 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOffline() {
|
public boolean isOffline() {
|
||||||
return entity.isOffline();
|
Boolean offline = entity.isOffline();
|
||||||
|
return offline != null ? offline : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -111,8 +115,13 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
Map<String, AuthenticatedClientSessionModel> result = new HashMap<>();
|
Map<String, AuthenticatedClientSessionModel> result = new HashMap<>();
|
||||||
List<String> removedClientUUIDS = new LinkedList<>();
|
List<String> removedClientUUIDS = new LinkedList<>();
|
||||||
|
|
||||||
|
Map<String, String> authenticatedClientSessions = entity.getAuthenticatedClientSessions();
|
||||||
|
if (authenticatedClientSessions == null) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
} else {
|
||||||
// to avoid concurrentModificationException
|
// to avoid concurrentModificationException
|
||||||
Map<String, String> authenticatedClientSessions = new HashMap<>(entity.getAuthenticatedClientSessions());
|
authenticatedClientSessions = new HashMap<>(authenticatedClientSessions);
|
||||||
|
}
|
||||||
|
|
||||||
authenticatedClientSessions.forEach((clientUUID, clientSessionId) -> {
|
authenticatedClientSessions.forEach((clientUUID, clientSessionId) -> {
|
||||||
ClientModel client = realm.getClientById(clientUUID);
|
ClientModel client = realm.getClientById(clientUUID);
|
||||||
|
@ -135,7 +144,7 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticatedClientSessionModel getAuthenticatedClientSessionByClient(String clientUUID) {
|
public AuthenticatedClientSessionModel getAuthenticatedClientSessionByClient(String clientUUID) {
|
||||||
String clientSessionId = entity.getAuthenticatedClientSessions().get(clientUUID);
|
String clientSessionId = entity.getAuthenticatedClientSession(clientUUID);
|
||||||
|
|
||||||
if (clientSessionId == null) {
|
if (clientSessionId == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -155,7 +164,7 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNote(String name) {
|
public String getNote(String name) {
|
||||||
return (name != null) ? entity.getNotes().get(name) : null;
|
return (name != null) ? entity.getNote(name) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -164,7 +173,7 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
entity.removeNote(name);
|
entity.removeNote(name);
|
||||||
} else {
|
} else {
|
||||||
entity.addNote(name, value);
|
entity.setNote(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +187,8 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getNotes() {
|
public Map<String, String> getNotes() {
|
||||||
return entity.getNotes();
|
Map<String, String> notes = entity.getNotes();
|
||||||
|
return notes == null ? Collections.emptyMap() : Collections.unmodifiableMap(notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -212,9 +222,9 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||||
String correspondingSessionId = entity.getNote(CORRESPONDING_SESSION_ID);
|
String correspondingSessionId = entity.getNote(CORRESPONDING_SESSION_ID);
|
||||||
entity.setNotes(new ConcurrentHashMap<>());
|
entity.setNotes(new ConcurrentHashMap<>());
|
||||||
if (correspondingSessionId != null)
|
if (correspondingSessionId != null)
|
||||||
entity.addNote(CORRESPONDING_SESSION_ID, correspondingSessionId);
|
entity.setNote(CORRESPONDING_SESSION_ID, correspondingSessionId);
|
||||||
|
|
||||||
entity.clearAuthenticatedClientSessions();
|
entity.setAuthenticatedClientSessions(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,82 +16,28 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.models.map.userSession;
|
package org.keycloak.models.map.userSession;
|
||||||
|
|
||||||
import org.keycloak.common.util.Time;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
|
||||||
import org.keycloak.models.map.common.AbstractEntity;
|
import org.keycloak.models.map.common.AbstractEntity;
|
||||||
|
|
||||||
|
import org.keycloak.models.map.common.DeepCloner;
|
||||||
import org.keycloak.models.map.common.UpdatableEntity;
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||||
*/
|
*/
|
||||||
public class MapUserSessionEntity extends UpdatableEntity.Impl implements AbstractEntity {
|
@GenerateEntityImplementations(
|
||||||
|
inherits = "org.keycloak.models.map.userSession.MapUserSessionEntity.AbstractUserSessionEntity"
|
||||||
|
)
|
||||||
|
@DeepCloner.Root
|
||||||
|
public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity {
|
||||||
|
|
||||||
|
public abstract class AbstractUserSessionEntity extends UpdatableEntity.Impl implements MapUserSessionEntity {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
private String realmId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag signalizing that any of the setters has been meaningfully used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private String userId;
|
|
||||||
|
|
||||||
private String brokerSessionId;
|
|
||||||
private String brokerUserId;
|
|
||||||
|
|
||||||
private String loginUsername;
|
|
||||||
|
|
||||||
private String ipAddress;
|
|
||||||
|
|
||||||
private String authMethod;
|
|
||||||
|
|
||||||
private boolean rememberMe;
|
|
||||||
|
|
||||||
private int started;
|
|
||||||
|
|
||||||
private int lastSessionRefresh;
|
|
||||||
|
|
||||||
private long expiration;
|
|
||||||
|
|
||||||
private Map<String, String> notes = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private UserSessionModel.State state;
|
|
||||||
|
|
||||||
private UserSessionModel.SessionPersistenceState persistenceState = UserSessionModel.SessionPersistenceState.PERSISTENT;
|
|
||||||
|
|
||||||
private Map<String, String> authenticatedClientSessions = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private boolean offline;
|
|
||||||
|
|
||||||
public MapUserSessionEntity() {}
|
|
||||||
|
|
||||||
public MapUserSessionEntity(String id, String realmId) {
|
|
||||||
this.id = id;
|
|
||||||
this.realmId = realmId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapUserSessionEntity(String id, RealmModel realm, UserModel user, String loginUsername, String ipAddress,
|
|
||||||
String authMethod, boolean rememberMe, String brokerSessionId, String brokerUserId,
|
|
||||||
boolean offline) {
|
|
||||||
this.id = id;
|
|
||||||
this.realmId = realm.getId();
|
|
||||||
this.userId = user.getId();
|
|
||||||
this.loginUsername = loginUsername;
|
|
||||||
this.ipAddress = ipAddress;
|
|
||||||
this.authMethod = authMethod;
|
|
||||||
this.rememberMe = rememberMe;
|
|
||||||
this.brokerSessionId = brokerSessionId;
|
|
||||||
this.brokerUserId = brokerUserId;
|
|
||||||
this.started = Time.currentTime();
|
|
||||||
this.lastSessionRefresh = started;
|
|
||||||
this.offline = offline;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
|
@ -103,182 +49,60 @@ public class MapUserSessionEntity extends UpdatableEntity.Impl implements Abstra
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.updated |= id != null;
|
this.updated |= id != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRealmId() {
|
|
||||||
return realmId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealmId(String realmId) {
|
String getRealmId();
|
||||||
this.updated |= !Objects.equals(this.realmId, realmId);
|
void setRealmId(String realmId);
|
||||||
this.realmId = realmId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserId() {
|
String getUserId();
|
||||||
return userId;
|
void setUserId(String userId);
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserId(String userId) {
|
String getBrokerSessionId();
|
||||||
this.updated |= !Objects.equals(this.userId, userId);
|
void setBrokerSessionId(String brokerSessionId);
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBrokerSessionId() {
|
String getBrokerUserId();
|
||||||
return brokerSessionId;
|
void setBrokerUserId(String brokerUserId);
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrokerSessionId(String brokerSessionId) {
|
String getLoginUsername();
|
||||||
this.updated |= !Objects.equals(this.brokerSessionId, brokerSessionId);
|
void setLoginUsername(String loginUsername);
|
||||||
this.brokerSessionId = brokerSessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBrokerUserId() {
|
String getIpAddress();
|
||||||
return brokerUserId;
|
void setIpAddress(String ipAddress);
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrokerUserId(String brokerUserId) {
|
String getAuthMethod();
|
||||||
this.updated |= !Objects.equals(this.brokerUserId, brokerUserId);
|
void setAuthMethod(String authMethod);
|
||||||
this.brokerUserId = brokerUserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLoginUsername() {
|
Boolean isRememberMe();
|
||||||
return loginUsername;
|
void setRememberMe(Boolean rememberMe);
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginUsername(String loginUsername) {
|
Integer getStarted();
|
||||||
this.updated |= !Objects.equals(this.loginUsername, loginUsername);
|
void setStarted(Integer started);
|
||||||
this.loginUsername = loginUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIpAddress() {
|
Integer getLastSessionRefresh();
|
||||||
return ipAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIpAddress(String ipAddress) {
|
void setLastSessionRefresh(Integer lastSessionRefresh);
|
||||||
this.updated |= !Objects.equals(this.ipAddress, ipAddress);
|
|
||||||
this.ipAddress = ipAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthMethod() {
|
Long getExpiration();
|
||||||
return authMethod;
|
void setExpiration(Long expiration);
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthMethod(String authMethod) {
|
Map<String, String> getNotes();
|
||||||
this.updated |= !Objects.equals(this.authMethod, authMethod);
|
String getNote(String name);
|
||||||
this.authMethod = authMethod;
|
void setNotes(Map<String, String> notes);
|
||||||
}
|
Boolean removeNote(String name);
|
||||||
|
void setNote(String name, String value);
|
||||||
|
|
||||||
public boolean isRememberMe() {
|
UserSessionModel.State getState();
|
||||||
return rememberMe;
|
void setState(UserSessionModel.State state);
|
||||||
}
|
|
||||||
|
|
||||||
public void setRememberMe(boolean rememberMe) {
|
Map<String, String> getAuthenticatedClientSessions();
|
||||||
this.updated |= this.rememberMe != rememberMe;
|
void setAuthenticatedClientSessions(Map<String, String> authenticatedClientSessions);
|
||||||
this.rememberMe = rememberMe;
|
String getAuthenticatedClientSession(String clientUUID);
|
||||||
}
|
void setAuthenticatedClientSession(String clientUUID, String clientSessionId);
|
||||||
|
Boolean removeAuthenticatedClientSession(String clientUUID);
|
||||||
|
|
||||||
public int getStarted() {
|
Boolean isOffline();
|
||||||
return started;
|
void setOffline(Boolean offline);
|
||||||
}
|
|
||||||
|
|
||||||
public void setStarted(int started) {
|
UserSessionModel.SessionPersistenceState getPersistenceState();
|
||||||
this.updated |= this.started != started;
|
void setPersistenceState(UserSessionModel.SessionPersistenceState persistenceState);
|
||||||
this.started = started;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastSessionRefresh() {
|
|
||||||
return lastSessionRefresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastSessionRefresh(int lastSessionRefresh) {
|
|
||||||
this.updated |= this.lastSessionRefresh != lastSessionRefresh;
|
|
||||||
this.lastSessionRefresh = lastSessionRefresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getExpiration() {
|
|
||||||
return expiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpiration(long expiration) {
|
|
||||||
this.updated |= this.expiration != expiration;
|
|
||||||
this.expiration = expiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getNotes() {
|
|
||||||
return notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNote(String name) {
|
|
||||||
return notes.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNotes(Map<String, String> notes) {
|
|
||||||
this.updated |= !Objects.equals(this.notes, notes);
|
|
||||||
this.notes = notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String removeNote(String name) {
|
|
||||||
String note = this.notes.remove(name);
|
|
||||||
this.updated |= note != null;
|
|
||||||
return note;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addNote(String name, String value) {
|
|
||||||
this.updated |= !Objects.equals(this.notes.put(name, value), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSessionModel.State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(UserSessionModel.State state) {
|
|
||||||
this.updated |= !Objects.equals(this.state, state);
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getAuthenticatedClientSessions() {
|
|
||||||
return authenticatedClientSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthenticatedClientSessions(Map<String, String> authenticatedClientSessions) {
|
|
||||||
this.updated |= !Objects.equals(this.authenticatedClientSessions, authenticatedClientSessions);
|
|
||||||
this.authenticatedClientSessions = authenticatedClientSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAuthenticatedClientSession(String clientId, String clientSessionId) {
|
|
||||||
this.updated |= !Objects.equals(this.authenticatedClientSessions.put(clientId, clientSessionId), clientSessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String removeAuthenticatedClientSession(String clientId) {
|
|
||||||
String entity = this.authenticatedClientSessions.remove(clientId);
|
|
||||||
this.updated |= entity != null;
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearAuthenticatedClientSessions() {
|
|
||||||
this.updated |= !authenticatedClientSessions.isEmpty();
|
|
||||||
this.authenticatedClientSessions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOffline() {
|
|
||||||
return offline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOffline(boolean offline) {
|
|
||||||
this.updated |= this.offline != offline;
|
|
||||||
this.offline = offline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSessionModel.SessionPersistenceState getPersistenceState() {
|
|
||||||
return persistenceState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPersistenceState(UserSessionModel.SessionPersistenceState persistenceState) {
|
|
||||||
this.updated |= !Objects.equals(this.persistenceState, persistenceState);
|
|
||||||
this.persistenceState = persistenceState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%s@%08x", getId(), hashCode());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
private Function<MapUserSessionEntity, UserSessionModel> userEntityToAdapterFunc(RealmModel realm) {
|
private Function<MapUserSessionEntity, UserSessionModel> userEntityToAdapterFunc(RealmModel realm) {
|
||||||
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
|
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
|
||||||
return (origEntity) -> {
|
return (origEntity) -> {
|
||||||
if (origEntity.getExpiration() <= Time.currentTime()) {
|
long expiration = origEntity.getExpiration() != null ? origEntity.getExpiration() : 0l;
|
||||||
|
if (expiration <= Time.currentTime()) {
|
||||||
if (Objects.equals(origEntity.getPersistenceState(), TRANSIENT)) {
|
if (Objects.equals(origEntity.getPersistenceState(), TRANSIENT)) {
|
||||||
transientUserSessions.remove(origEntity.getId());
|
transientUserSessions.remove(origEntity.getId());
|
||||||
}
|
}
|
||||||
|
@ -110,7 +111,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
UserSessionModel userSession) {
|
UserSessionModel userSession) {
|
||||||
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
|
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
|
||||||
return origEntity -> {
|
return origEntity -> {
|
||||||
if (origEntity.getExpiration() <= Time.currentTime()) {
|
long expiration = origEntity.getExpiration() != null ? origEntity.getExpiration() : 0l;
|
||||||
|
if (expiration <= Time.currentTime()) {
|
||||||
userSession.removeAuthenticatedClientSessions(Arrays.asList(origEntity.getClientId()));
|
userSession.removeAuthenticatedClientSessions(Arrays.asList(origEntity.getClientId()));
|
||||||
clientSessionTx.delete(origEntity.getId());
|
clientSessionTx.delete(origEntity.getId());
|
||||||
return null;
|
return null;
|
||||||
|
@ -141,9 +143,10 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticatedClientSessionModel createClientSession(RealmModel realm, ClientModel client, UserSessionModel userSession) {
|
public AuthenticatedClientSessionModel createClientSession(RealmModel realm, ClientModel client, UserSessionModel userSession) {
|
||||||
MapAuthenticatedClientSessionEntity entity =
|
MapAuthenticatedClientSessionEntity entity = createAuthenticatedClientSessionEntityInstance(null, userSession.getId(),
|
||||||
new MapAuthenticatedClientSessionEntity(null, userSession.getId(), realm.getId(), client.getId(), false);
|
realm.getId(), client.getId(), false);
|
||||||
entity.getNotes().put(AuthenticatedClientSessionModel.STARTED_AT_NOTE, String.valueOf(entity.getTimestamp()));
|
String started = entity.getTimestamp() != null ? String.valueOf(entity.getTimestamp()) : String.valueOf(0);
|
||||||
|
entity.setNote(AuthenticatedClientSessionModel.STARTED_AT_NOTE, started);
|
||||||
setClientSessionExpiration(entity, realm, client);
|
setClientSessionExpiration(entity, realm, client);
|
||||||
|
|
||||||
LOG.tracef("createClientSession(%s, %s, %s)%s", realm, client, userSession, getShortStackTrace());
|
LOG.tracef("createClientSession(%s, %s, %s)%s", realm, client, userSession, getShortStackTrace());
|
||||||
|
@ -156,7 +159,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
throw new IllegalStateException("User session entity does not exist: " + userSession.getId());
|
throw new IllegalStateException("User session entity does not exist: " + userSession.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
userSessionEntity.addAuthenticatedClientSession(client.getId(), entity.getId());
|
userSessionEntity.setAuthenticatedClientSession(client.getId(), entity.getId());
|
||||||
|
|
||||||
return clientEntityToAdapterFunc(realm, client, userSession).apply(entity);
|
return clientEntityToAdapterFunc(realm, client, userSession).apply(entity);
|
||||||
}
|
}
|
||||||
|
@ -204,13 +207,15 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
id = UUID.randomUUID().toString();
|
id = UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
entity = new MapUserSessionEntity(id, realm, user, loginUsername, ipAddress, authMethod, rememberMe, brokerSessionId, brokerUserId, false);
|
entity = createUserSessionEntityInstance(id, realm.getId(), user.getId(), loginUsername, ipAddress, authMethod,
|
||||||
|
rememberMe, brokerSessionId, brokerUserId, false);
|
||||||
transientUserSessions.put(entity.getId(), entity);
|
transientUserSessions.put(entity.getId(), entity);
|
||||||
} else {
|
} else {
|
||||||
if (id != null && userSessionTx.read(id) != null) {
|
if (id != null && userSessionTx.read(id) != null) {
|
||||||
throw new ModelDuplicateException("User session exists: " + id);
|
throw new ModelDuplicateException("User session exists: " + id);
|
||||||
}
|
}
|
||||||
entity = new MapUserSessionEntity(id, realm, user, loginUsername, ipAddress, authMethod, rememberMe, brokerSessionId, brokerUserId, false);
|
entity = createUserSessionEntityInstance(id, realm.getId(), user.getId(), loginUsername, ipAddress, authMethod,
|
||||||
|
rememberMe, brokerSessionId, brokerUserId, false);
|
||||||
entity = userSessionTx.create(entity);
|
entity = userSessionTx.create(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,14 +466,14 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
|
|
||||||
MapAuthenticatedClientSessionEntity clientSessionEntity = createAuthenticatedClientSessionInstance(clientSession, offlineUserSession, true);
|
MapAuthenticatedClientSessionEntity clientSessionEntity = createAuthenticatedClientSessionInstance(clientSession, offlineUserSession, true);
|
||||||
int currentTime = Time.currentTime();
|
int currentTime = Time.currentTime();
|
||||||
clientSessionEntity.getNotes().put(AuthenticatedClientSessionModel.STARTED_AT_NOTE, String.valueOf(currentTime));
|
clientSessionEntity.setNote(AuthenticatedClientSessionModel.STARTED_AT_NOTE, String.valueOf(currentTime));
|
||||||
clientSessionEntity.setTimestamp(currentTime);
|
clientSessionEntity.setTimestamp(currentTime);
|
||||||
setClientSessionExpiration(clientSessionEntity, clientSession.getRealm(), clientSession.getClient());
|
setClientSessionExpiration(clientSessionEntity, clientSession.getRealm(), clientSession.getClient());
|
||||||
clientSessionEntity = clientSessionTx.create(clientSessionEntity);
|
clientSessionEntity = clientSessionTx.create(clientSessionEntity);
|
||||||
|
|
||||||
Optional<MapUserSessionEntity> userSessionEntity = getOfflineUserSessionEntityStream(clientSession.getRealm(), offlineUserSession.getId()).findFirst();
|
Optional<MapUserSessionEntity> userSessionEntity = getOfflineUserSessionEntityStream(clientSession.getRealm(), offlineUserSession.getId()).findFirst();
|
||||||
if (userSessionEntity.isPresent()) {
|
if (userSessionEntity.isPresent()) {
|
||||||
userSessionEntity.get().addAuthenticatedClientSession(clientSession.getClient().getId(), clientSessionEntity.getId());
|
userSessionEntity.get().setAuthenticatedClientSession(clientSession.getClient().getId(), clientSessionEntity.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientEntityToAdapterFunc(clientSession.getRealm(),
|
return clientEntityToAdapterFunc(clientSession.getRealm(),
|
||||||
|
@ -544,8 +549,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
|
|
||||||
persistentUserSessions.stream()
|
persistentUserSessions.stream()
|
||||||
.map(pus -> {
|
.map(pus -> {
|
||||||
MapUserSessionEntity userSessionEntity = new MapUserSessionEntity(null, pus.getRealm(), pus.getUser(),
|
MapUserSessionEntity userSessionEntity = createUserSessionEntityInstance(null, pus.getRealm().getId(),
|
||||||
pus.getLoginUsername(), pus.getIpAddress(), pus.getAuthMethod(),
|
pus.getUser().getId(), pus.getLoginUsername(), pus.getIpAddress(), pus.getAuthMethod(),
|
||||||
pus.isRememberMe(), pus.getBrokerSessionId(), pus.getBrokerUserId(), offline);
|
pus.isRememberMe(), pus.getBrokerSessionId(), pus.getBrokerUserId(), offline);
|
||||||
|
|
||||||
for (Map.Entry<String, AuthenticatedClientSessionModel> entry : pus.getAuthenticatedClientSessions().entrySet()) {
|
for (Map.Entry<String, AuthenticatedClientSessionModel> entry : pus.getAuthenticatedClientSessions().entrySet()) {
|
||||||
|
@ -555,7 +560,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
clientSession.setTimestamp(userSessionEntity.getLastSessionRefresh());
|
clientSession.setTimestamp(userSessionEntity.getLastSessionRefresh());
|
||||||
|
|
||||||
clientSession = clientSessionTx.create(clientSession);
|
clientSession = clientSessionTx.create(clientSession);
|
||||||
userSessionEntity.addAuthenticatedClientSession(entry.getKey(), clientSession.getId());
|
userSessionEntity.setAuthenticatedClientSession(entry.getKey(), clientSession.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return userSessionEntity;
|
return userSessionEntity;
|
||||||
|
@ -581,7 +586,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
// check if it's an offline user session
|
// check if it's an offline user session
|
||||||
MapUserSessionEntity userSessionEntity = userSessionTx.read(withCriteria(mcb)).findFirst().orElse(null);
|
MapUserSessionEntity userSessionEntity = userSessionTx.read(withCriteria(mcb)).findFirst().orElse(null);
|
||||||
if (userSessionEntity != null) {
|
if (userSessionEntity != null) {
|
||||||
if (userSessionEntity.isOffline()) {
|
if (Boolean.TRUE.equals(userSessionEntity.isOffline())) {
|
||||||
return Stream.of(userSessionEntity);
|
return Stream.of(userSessionEntity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -619,32 +624,23 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapUserSessionEntity createUserSessionEntityInstance(UserSessionModel userSession, boolean offline) {
|
private MapUserSessionEntity createUserSessionEntityInstance(UserSessionModel userSession, boolean offline) {
|
||||||
MapUserSessionEntity entity = new MapUserSessionEntity(null, userSession.getRealm().getId());
|
MapUserSessionEntity entity = createUserSessionEntityInstance(null, userSession.getRealm().getId(), userSession.getUser().getId(),
|
||||||
|
userSession.getLoginUsername(), userSession.getIpAddress(), userSession.getAuthMethod(), userSession.isRememberMe(),
|
||||||
|
userSession.getBrokerSessionId(), userSession.getBrokerUserId(), offline);
|
||||||
|
|
||||||
entity.setAuthMethod(userSession.getAuthMethod());
|
|
||||||
entity.setBrokerSessionId(userSession.getBrokerSessionId());
|
|
||||||
entity.setBrokerUserId(userSession.getBrokerUserId());
|
|
||||||
entity.setIpAddress(userSession.getIpAddress());
|
|
||||||
entity.setNotes(new ConcurrentHashMap<>(userSession.getNotes()));
|
entity.setNotes(new ConcurrentHashMap<>(userSession.getNotes()));
|
||||||
entity.addNote(CORRESPONDING_SESSION_ID, userSession.getId());
|
entity.setNote(CORRESPONDING_SESSION_ID, userSession.getId());
|
||||||
|
|
||||||
entity.clearAuthenticatedClientSessions();
|
|
||||||
entity.setRememberMe(userSession.isRememberMe());
|
|
||||||
entity.setState(userSession.getState());
|
entity.setState(userSession.getState());
|
||||||
entity.setLoginUsername(userSession.getLoginUsername());
|
|
||||||
entity.setUserId(userSession.getUser().getId());
|
|
||||||
|
|
||||||
entity.setStarted(userSession.getStarted());
|
entity.setStarted(userSession.getStarted());
|
||||||
entity.setLastSessionRefresh(userSession.getLastSessionRefresh());
|
entity.setLastSessionRefresh(userSession.getLastSessionRefresh());
|
||||||
entity.setOffline(offline);
|
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapAuthenticatedClientSessionEntity createAuthenticatedClientSessionInstance(AuthenticatedClientSessionModel clientSession,
|
private MapAuthenticatedClientSessionEntity createAuthenticatedClientSessionInstance(AuthenticatedClientSessionModel clientSession,
|
||||||
UserSessionModel userSession, boolean offline) {
|
UserSessionModel userSession, boolean offline) {
|
||||||
MapAuthenticatedClientSessionEntity entity = new MapAuthenticatedClientSessionEntity(null,
|
MapAuthenticatedClientSessionEntity entity = createAuthenticatedClientSessionEntityInstance(null, userSession.getId(),
|
||||||
userSession.getId(), clientSession.getRealm().getId(), clientSession.getClient().getId(), offline);
|
clientSession.getRealm().getId(), clientSession.getClient().getId(), offline);
|
||||||
|
|
||||||
entity.setAction(clientSession.getAction());
|
entity.setAction(clientSession.getAction());
|
||||||
entity.setAuthMethod(clientSession.getProtocol());
|
entity.setAuthMethod(clientSession.getProtocol());
|
||||||
|
@ -655,4 +651,36 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MapUserSessionEntity createUserSessionEntityInstance(String id, String realmId, String userId, String loginUsername, String ipAddress,
|
||||||
|
String authMethod, boolean rememberMe, String brokerSessionId, String brokerUserId,
|
||||||
|
boolean offline) {
|
||||||
|
MapUserSessionEntityImpl userSessionEntity = new MapUserSessionEntityImpl();
|
||||||
|
userSessionEntity.setId(id);
|
||||||
|
userSessionEntity.setRealmId(realmId);
|
||||||
|
userSessionEntity.setUserId(userId);
|
||||||
|
userSessionEntity.setLoginUsername(loginUsername);
|
||||||
|
userSessionEntity.setIpAddress(ipAddress);
|
||||||
|
userSessionEntity.setAuthMethod(authMethod);
|
||||||
|
userSessionEntity.setRememberMe(rememberMe);
|
||||||
|
userSessionEntity.setBrokerSessionId(brokerSessionId);
|
||||||
|
userSessionEntity.setBrokerUserId(brokerUserId);
|
||||||
|
userSessionEntity.setOffline(offline);
|
||||||
|
userSessionEntity.setStarted(Time.currentTime());
|
||||||
|
userSessionEntity.setLastSessionRefresh(userSessionEntity.getStarted());
|
||||||
|
return userSessionEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapAuthenticatedClientSessionEntity createAuthenticatedClientSessionEntityInstance(String id, String userSessionId, String realmId,
|
||||||
|
String clientId, boolean offline) {
|
||||||
|
MapAuthenticatedClientSessionEntityImpl clientSessionEntity = new MapAuthenticatedClientSessionEntityImpl();
|
||||||
|
clientSessionEntity.setId(id);
|
||||||
|
clientSessionEntity.setUserSessionId(userSessionId);
|
||||||
|
clientSessionEntity.setRealmId(realmId);
|
||||||
|
clientSessionEntity.setClientId(clientId);
|
||||||
|
clientSessionEntity.setOffline(offline);
|
||||||
|
clientSessionEntity.setTimestamp(Time.currentTime());
|
||||||
|
return clientSessionEntity;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,11 @@ import org.keycloak.protocol.oidc.OIDCConfigAttributes;
|
||||||
public class SessionExpiration {
|
public class SessionExpiration {
|
||||||
|
|
||||||
public static void setClientSessionExpiration(MapAuthenticatedClientSessionEntity entity, RealmModel realm, ClientModel client) {
|
public static void setClientSessionExpiration(MapAuthenticatedClientSessionEntity entity, RealmModel realm, ClientModel client) {
|
||||||
if (entity.isOffline()) {
|
long timestamp = entity.getTimestamp() != null ? entity.getTimestamp() : 0l;
|
||||||
long sessionExpires = entity.getTimestamp() + realm.getOfflineSessionIdleTimeout();
|
if (Boolean.TRUE.equals(entity.isOffline())) {
|
||||||
|
long sessionExpires = timestamp + realm.getOfflineSessionIdleTimeout();
|
||||||
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
||||||
sessionExpires = entity.getTimestamp() + realm.getOfflineSessionMaxLifespan();
|
sessionExpires = timestamp + realm.getOfflineSessionMaxLifespan();
|
||||||
|
|
||||||
long clientOfflineSessionMaxLifespan;
|
long clientOfflineSessionMaxLifespan;
|
||||||
String clientOfflineSessionMaxLifespanPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_OFFLINE_SESSION_MAX_LIFESPAN);
|
String clientOfflineSessionMaxLifespanPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_OFFLINE_SESSION_MAX_LIFESPAN);
|
||||||
|
@ -41,12 +42,12 @@ public class SessionExpiration {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientOfflineSessionMaxLifespan > 0) {
|
if (clientOfflineSessionMaxLifespan > 0) {
|
||||||
long clientOfflineSessionMaxExpiration = entity.getTimestamp() + clientOfflineSessionMaxLifespan;
|
long clientOfflineSessionMaxExpiration = timestamp + clientOfflineSessionMaxLifespan;
|
||||||
sessionExpires = Math.min(sessionExpires, clientOfflineSessionMaxExpiration);
|
sessionExpires = Math.min(sessionExpires, clientOfflineSessionMaxExpiration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long expiration = entity.getTimestamp() + realm.getOfflineSessionIdleTimeout();
|
long expiration = timestamp + realm.getOfflineSessionIdleTimeout();
|
||||||
|
|
||||||
long clientOfflineSessionIdleTimeout;
|
long clientOfflineSessionIdleTimeout;
|
||||||
String clientOfflineSessionIdleTimeoutPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
String clientOfflineSessionIdleTimeoutPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
||||||
|
@ -57,13 +58,13 @@ public class SessionExpiration {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientOfflineSessionIdleTimeout > 0) {
|
if (clientOfflineSessionIdleTimeout > 0) {
|
||||||
long clientOfflineSessionIdleExpiration = entity.getTimestamp() + clientOfflineSessionIdleTimeout;
|
long clientOfflineSessionIdleExpiration = timestamp + clientOfflineSessionIdleTimeout;
|
||||||
expiration = Math.min(expiration, clientOfflineSessionIdleExpiration);
|
expiration = Math.min(expiration, clientOfflineSessionIdleExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.setExpiration(Math.min(expiration, sessionExpires));
|
entity.setExpiration(Math.min(expiration, sessionExpires));
|
||||||
} else {
|
} else {
|
||||||
long sessionExpires = (long) entity.getTimestamp() + (realm.getSsoSessionMaxLifespanRememberMe() > 0
|
long sessionExpires = timestamp + (realm.getSsoSessionMaxLifespanRememberMe() > 0
|
||||||
? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan());
|
? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan());
|
||||||
|
|
||||||
long clientSessionMaxLifespan;
|
long clientSessionMaxLifespan;
|
||||||
|
@ -75,11 +76,11 @@ public class SessionExpiration {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientSessionMaxLifespan > 0) {
|
if (clientSessionMaxLifespan > 0) {
|
||||||
long clientSessionMaxExpiration = entity.getTimestamp() + clientSessionMaxLifespan;
|
long clientSessionMaxExpiration = timestamp + clientSessionMaxLifespan;
|
||||||
sessionExpires = Math.min(sessionExpires, clientSessionMaxExpiration);
|
sessionExpires = Math.min(sessionExpires, clientSessionMaxExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
long expiration = (long) entity.getTimestamp() + (realm.getSsoSessionIdleTimeoutRememberMe() > 0
|
long expiration = timestamp + (realm.getSsoSessionIdleTimeoutRememberMe() > 0
|
||||||
? realm.getSsoSessionIdleTimeoutRememberMe() : realm.getSsoSessionIdleTimeout());
|
? realm.getSsoSessionIdleTimeoutRememberMe() : realm.getSsoSessionIdleTimeout());
|
||||||
|
|
||||||
long clientSessionIdleTimeout;
|
long clientSessionIdleTimeout;
|
||||||
|
@ -91,7 +92,7 @@ public class SessionExpiration {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientSessionIdleTimeout > 0) {
|
if (clientSessionIdleTimeout > 0) {
|
||||||
long clientSessionIdleExpiration = entity.getTimestamp() + clientSessionIdleTimeout;
|
long clientSessionIdleExpiration = timestamp + clientSessionIdleTimeout;
|
||||||
expiration = Math.min(expiration, clientSessionIdleExpiration);
|
expiration = Math.min(expiration, clientSessionIdleExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,20 +101,22 @@ public class SessionExpiration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setUserSessionExpiration(MapUserSessionEntity entity, RealmModel realm) {
|
public static void setUserSessionExpiration(MapUserSessionEntity entity, RealmModel realm) {
|
||||||
if (entity.isOffline()) {
|
int started = entity.getStarted() != null ? entity.getStarted() : 0;
|
||||||
long sessionExpires = entity.getLastSessionRefresh() + realm.getOfflineSessionIdleTimeout();
|
long lastSessionRefresh = entity.getLastSessionRefresh() != null ? entity.getLastSessionRefresh() : 0l;
|
||||||
|
if (Boolean.TRUE.equals(entity.isOffline())) {
|
||||||
|
long sessionExpires = lastSessionRefresh + realm.getOfflineSessionIdleTimeout();
|
||||||
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
||||||
sessionExpires = entity.getStarted() + realm.getOfflineSessionMaxLifespan();
|
sessionExpires = started + realm.getOfflineSessionMaxLifespan();
|
||||||
|
|
||||||
long clientOfflineSessionMaxLifespan = realm.getClientOfflineSessionMaxLifespan();
|
long clientOfflineSessionMaxLifespan = realm.getClientOfflineSessionMaxLifespan();
|
||||||
|
|
||||||
if (clientOfflineSessionMaxLifespan > 0) {
|
if (clientOfflineSessionMaxLifespan > 0) {
|
||||||
long clientOfflineSessionMaxExpiration = entity.getStarted() + clientOfflineSessionMaxLifespan;
|
long clientOfflineSessionMaxExpiration = started + clientOfflineSessionMaxLifespan;
|
||||||
sessionExpires = Math.min(sessionExpires, clientOfflineSessionMaxExpiration);
|
sessionExpires = Math.min(sessionExpires, clientOfflineSessionMaxExpiration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long expiration = entity.getLastSessionRefresh() + realm.getOfflineSessionIdleTimeout();
|
long expiration = lastSessionRefresh + realm.getOfflineSessionIdleTimeout();
|
||||||
|
|
||||||
long clientOfflineSessionIdleTimeout = realm.getClientOfflineSessionIdleTimeout();
|
long clientOfflineSessionIdleTimeout = realm.getClientOfflineSessionIdleTimeout();
|
||||||
|
|
||||||
|
@ -124,26 +127,26 @@ public class SessionExpiration {
|
||||||
|
|
||||||
entity.setExpiration(Math.min(expiration, sessionExpires));
|
entity.setExpiration(Math.min(expiration, sessionExpires));
|
||||||
} else {
|
} else {
|
||||||
long sessionExpires = (long) entity.getStarted()
|
long sessionExpires = (long) started
|
||||||
+ (entity.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0
|
+ (Boolean.TRUE.equals(entity.isRememberMe()) && realm.getSsoSessionMaxLifespanRememberMe() > 0
|
||||||
? realm.getSsoSessionMaxLifespanRememberMe()
|
? realm.getSsoSessionMaxLifespanRememberMe()
|
||||||
: realm.getSsoSessionMaxLifespan());
|
: realm.getSsoSessionMaxLifespan());
|
||||||
|
|
||||||
long clientSessionMaxLifespan = realm.getClientSessionMaxLifespan();
|
long clientSessionMaxLifespan = realm.getClientSessionMaxLifespan();
|
||||||
|
|
||||||
if (clientSessionMaxLifespan > 0) {
|
if (clientSessionMaxLifespan > 0) {
|
||||||
long clientSessionMaxExpiration = entity.getStarted() + clientSessionMaxLifespan;
|
long clientSessionMaxExpiration = started + clientSessionMaxLifespan;
|
||||||
sessionExpires = Math.min(sessionExpires, clientSessionMaxExpiration);
|
sessionExpires = Math.min(sessionExpires, clientSessionMaxExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
long expiration = (long) entity.getLastSessionRefresh() + (entity.isRememberMe() && realm.getSsoSessionIdleTimeoutRememberMe() > 0
|
long expiration = lastSessionRefresh + (Boolean.TRUE.equals(entity.isRememberMe()) && realm.getSsoSessionIdleTimeoutRememberMe() > 0
|
||||||
? realm.getSsoSessionIdleTimeoutRememberMe()
|
? realm.getSsoSessionIdleTimeoutRememberMe()
|
||||||
: realm.getSsoSessionIdleTimeout());
|
: realm.getSsoSessionIdleTimeout());
|
||||||
|
|
||||||
long clientSessionIdleTimeout = realm.getClientSessionIdleTimeout();
|
long clientSessionIdleTimeout = realm.getClientSessionIdleTimeout();
|
||||||
|
|
||||||
if (clientSessionIdleTimeout > 0) {
|
if (clientSessionIdleTimeout > 0) {
|
||||||
long clientSessionIdleExpiration = entity.getLastSessionRefresh() + clientSessionIdleTimeout;
|
long clientSessionIdleExpiration = lastSessionRefresh + clientSessionIdleTimeout;
|
||||||
expiration = Math.min(expiration, clientSessionIdleExpiration);
|
expiration = Math.min(expiration, clientSessionIdleExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue