KEYCLOAK-1702 KEYCLOAK-1703 Remove mem user session provider
This commit is contained in:
parent
f32b38cdbc
commit
5d6cc61d4d
23 changed files with 16 additions and 1353 deletions
4
dependencies/server-all/pom.xml
vendored
4
dependencies/server-all/pom.xml
vendored
|
@ -40,10 +40,6 @@
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-model-file</artifactId>
|
<artifactId>keycloak-model-file</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-model-sessions-mem</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-model-sessions-jpa</artifactId>
|
<artifactId>keycloak-model-sessions-jpa</artifactId>
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<module xmlns="urn:jboss:module:1.3" name="org.keycloak.keycloak-model-sessions-mem">
|
|
||||||
<resources>
|
|
||||||
<artifact name="${org.keycloak:keycloak-model-sessions-mem}"/>
|
|
||||||
</resources>
|
|
||||||
<dependencies>
|
|
||||||
<module name="org.keycloak.keycloak-core"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-api"/>
|
|
||||||
<module name="org.jboss.logging"/>
|
|
||||||
<module name="javax.api"/>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</module>
|
|
|
@ -37,7 +37,6 @@
|
||||||
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mem" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-saml-protocol" services="import"/>
|
<module name="org.keycloak.keycloak-saml-protocol" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-services" export="true" services="import"/>
|
<module name="org.keycloak.keycloak-services" export="true" services="import"/>
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mem" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-saml-core" services="import"/>
|
<module name="org.keycloak.keycloak-saml-core" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-saml-protocol" services="import"/>
|
<module name="org.keycloak.keycloak-saml-protocol" services="import"/>
|
||||||
|
|
|
@ -189,10 +189,6 @@
|
||||||
<maven-resource group="org.keycloak" artifact="keycloak-model-jpa"/>
|
<maven-resource group="org.keycloak" artifact="keycloak-model-jpa"/>
|
||||||
</module-def>
|
</module-def>
|
||||||
|
|
||||||
<module-def name="org.keycloak.keycloak-model-sessions-mem">
|
|
||||||
<maven-resource group="org.keycloak" artifact="keycloak-model-sessions-mem"/>
|
|
||||||
</module-def>
|
|
||||||
|
|
||||||
<module-def name="org.keycloak.keycloak-model-sessions-jpa">
|
<module-def name="org.keycloak.keycloak-model-sessions-jpa">
|
||||||
<maven-resource group="org.keycloak" artifact="keycloak-model-sessions-jpa"/>
|
<maven-resource group="org.keycloak" artifact="keycloak-model-sessions-jpa"/>
|
||||||
</module-def>
|
</module-def>
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mem" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-saml-protocol" services="import"/>
|
<module name="org.keycloak.keycloak-saml-protocol" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-services" export="true" services="import"/>
|
<module name="org.keycloak.keycloak-services" export="true" services="import"/>
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-sessions-mem">
|
|
||||||
<resources>
|
|
||||||
<!-- Insert resources here -->
|
|
||||||
</resources>
|
|
||||||
<dependencies>
|
|
||||||
<module name="org.keycloak.keycloak-core"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-api"/>
|
|
||||||
<module name="org.jboss.logging"/>
|
|
||||||
<module name="javax.api"/>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</module>
|
|
|
@ -47,7 +47,6 @@
|
||||||
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
<module name="org.keycloak.keycloak-model-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mem" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
<module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
|
||||||
|
|
||||||
<module name="org.keycloak.keycloak-saml-core" services="import"/>
|
<module name="org.keycloak.keycloak-saml-core" services="import"/>
|
||||||
|
|
|
@ -79,6 +79,21 @@
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Version specific migration</title>
|
<title>Version specific migration</title>
|
||||||
|
<section>
|
||||||
|
<title>Migrating to 1.5.0.Final</title>
|
||||||
|
<simplesect>
|
||||||
|
<title>Infinispan set to default cache and user session providers</title>
|
||||||
|
<para>
|
||||||
|
Infinispan is now the default cache and user session provider.
|
||||||
|
</para>
|
||||||
|
</simplesect>
|
||||||
|
<simplesect>
|
||||||
|
<title>Mem user session provider</title>
|
||||||
|
<para>
|
||||||
|
The mem user session provider has been removed. Instead the Infinispan user session provider with a local cache should be used.
|
||||||
|
</para>
|
||||||
|
</simplesect>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<title>Migrating to 1.3.0.Final</title>
|
<title>Migrating to 1.3.0.Final</title>
|
||||||
<simplesect>
|
<simplesect>
|
||||||
|
|
|
@ -52,12 +52,6 @@
|
||||||
<artifactId>hibernate-entitymanager</artifactId>
|
<artifactId>hibernate-entitymanager</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-model-sessions-mem</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.resteasy</groupId>
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
<artifactId>resteasy-jaxrs</artifactId>
|
<artifactId>resteasy-jaxrs</artifactId>
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
<module>mongo</module>
|
<module>mongo</module>
|
||||||
<module>file</module>
|
<module>file</module>
|
||||||
<module>sessions-jpa</module>
|
<module>sessions-jpa</module>
|
||||||
<module>sessions-mem</module>
|
|
||||||
<module>sessions-mongo</module>
|
<module>sessions-mongo</module>
|
||||||
<module>sessions-infinispan</module>
|
<module>sessions-infinispan</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>keycloak-parent</artifactId>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<version>1.5.0.Final-SNAPSHOT</version>
|
|
||||||
<relativePath>../../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>keycloak-model-sessions-mem</artifactId>
|
|
||||||
<name>Keycloak Model Sessions Mem</name>
|
|
||||||
<description/>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-core</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-model-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,200 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem;
|
|
||||||
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.ClientSessionModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.ClientSessionEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UserSessionEntity;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class ClientSessionAdapter implements ClientSessionModel {
|
|
||||||
|
|
||||||
private KeycloakSession session;
|
|
||||||
private MemUserSessionProvider provider;
|
|
||||||
private RealmModel realm;
|
|
||||||
private ClientSessionEntity entity;
|
|
||||||
|
|
||||||
public ClientSessionAdapter(KeycloakSession session, MemUserSessionProvider provider, RealmModel realm, ClientSessionEntity entity) {
|
|
||||||
this.session = session;
|
|
||||||
this.provider = provider;
|
|
||||||
this.realm = realm;
|
|
||||||
this.entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return entity.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RealmModel getRealm() {
|
|
||||||
return session.realms().getRealm(entity.getRealmId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientSessionEntity getEntity() {
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientModel getClient() {
|
|
||||||
return realm.getClientById(entity.getClientId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserSessionModel getUserSession() {
|
|
||||||
if (entity.getSession() == null) return null;
|
|
||||||
return new UserSessionAdapter(session, provider, realm, entity.getSession());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUserSession(UserSessionModel userSession) {
|
|
||||||
if (userSession == null) {
|
|
||||||
if (entity.getSession() != null) {
|
|
||||||
entity.getSession().getClientSessions().remove(entity);
|
|
||||||
}
|
|
||||||
entity.setSession(null);
|
|
||||||
} else {
|
|
||||||
UserSessionAdapter adapter = (UserSessionAdapter) userSession;
|
|
||||||
UserSessionEntity userSessionEntity = adapter.getEntity();
|
|
||||||
entity.setSession(userSessionEntity);
|
|
||||||
userSessionEntity.getClientSessions().add(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRedirectUri(String uri) {
|
|
||||||
entity.setRedirectUri(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRoles(Set<String> roles) {
|
|
||||||
entity.setRoles(roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRedirectUri() {
|
|
||||||
return entity.getRedirectUri();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTimestamp() {
|
|
||||||
return entity.getTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTimestamp(int timestamp) {
|
|
||||||
entity.setTimestamp(timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAction() {
|
|
||||||
return entity.getAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAction(String action) {
|
|
||||||
entity.setAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getRoles() {
|
|
||||||
return entity.getRoles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getProtocolMappers() {
|
|
||||||
return entity.getProtocolMappers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
|
||||||
entity.setProtocolMappers(protocolMappers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNote(String name) {
|
|
||||||
return entity.getNotes().get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNote(String name, String value) {
|
|
||||||
entity.getNotes().put(name, value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeNote(String name) {
|
|
||||||
entity.getNotes().remove(name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getNotes() {
|
|
||||||
if (entity.getNotes() == null || entity.getNotes().isEmpty()) return Collections.emptyMap();
|
|
||||||
Map<String, String> copy = new HashMap<>();
|
|
||||||
copy.putAll(entity.getNotes());
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUserSessionNote(String name, String value) {
|
|
||||||
entity.getUserSessionNotes().put(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getUserSessionNotes() {
|
|
||||||
return entity.getUserSessionNotes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAuthMethod() {
|
|
||||||
return entity.getAuthMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAuthMethod(String method) {
|
|
||||||
entity.setAuthMethod(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, ExecutionStatus> getExecutionStatus() {
|
|
||||||
return entity.getAuthenticatorStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setExecutionStatus(String authenticator, ExecutionStatus status) {
|
|
||||||
entity.getAuthenticatorStatus().put(authenticator, status);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearExecutionStatus() {
|
|
||||||
entity.getAuthenticatorStatus().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearUserSessionNotes() {
|
|
||||||
entity.getUserSessionNotes().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getAuthenticatedUser() {
|
|
||||||
return entity.getAuthUserId() == null ? null : session.users().getUserById(entity.getAuthUserId(), realm); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAuthenticatedUser(UserModel user) {
|
|
||||||
if (user == null) entity.setAuthUserId(null);
|
|
||||||
else entity.setAuthUserId(user.getId());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,382 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem;
|
|
||||||
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.ClientSessionModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.UserSessionProvider;
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.ClientSessionEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UserSessionEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureKey;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
import org.keycloak.models.utils.RealmInfoUtil;
|
|
||||||
import org.keycloak.util.Time;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class MemUserSessionProvider implements UserSessionProvider {
|
|
||||||
|
|
||||||
private final KeycloakSession session;
|
|
||||||
private final ConcurrentHashMap<String, UserSessionEntity> userSessions;
|
|
||||||
private final ConcurrentHashMap<String, String> userSessionsByBrokerSessionId;
|
|
||||||
private final ConcurrentHashMap<String, Set<String>> userSessionsByBrokerUserId;
|
|
||||||
private final ConcurrentHashMap<String, ClientSessionEntity> clientSessions;
|
|
||||||
private final ConcurrentHashMap<UsernameLoginFailureKey, UsernameLoginFailureEntity> loginFailures;
|
|
||||||
|
|
||||||
public MemUserSessionProvider(KeycloakSession session, ConcurrentHashMap<String, UserSessionEntity> userSessions, ConcurrentHashMap<String, String> userSessionsByBrokerSessionId, ConcurrentHashMap<String, Set<String>> userSessionsByBrokerUserId, ConcurrentHashMap<String, ClientSessionEntity> clientSessions, ConcurrentHashMap<UsernameLoginFailureKey, UsernameLoginFailureEntity> loginFailures) {
|
|
||||||
this.session = session;
|
|
||||||
this.userSessions = userSessions;
|
|
||||||
this.clientSessions = clientSessions;
|
|
||||||
this.loginFailures = loginFailures;
|
|
||||||
this.userSessionsByBrokerSessionId = userSessionsByBrokerSessionId;
|
|
||||||
this.userSessionsByBrokerUserId = userSessionsByBrokerUserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientSessionModel createClientSession(RealmModel realm, ClientModel client) {
|
|
||||||
ClientSessionEntity entity = new ClientSessionEntity();
|
|
||||||
entity.setId(KeycloakModelUtils.generateId());
|
|
||||||
entity.setTimestamp(Time.currentTime());
|
|
||||||
entity.setClientId(client.getId());
|
|
||||||
entity.setRealmId(realm.getId());
|
|
||||||
clientSessions.put(entity.getId(), entity);
|
|
||||||
return new ClientSessionAdapter(session, this, realm, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeClientSession(RealmModel realm, ClientSessionModel clientSession) {
|
|
||||||
ClientSessionEntity entity = ((ClientSessionAdapter)clientSession).getEntity();
|
|
||||||
UserSessionModel userSession = clientSession.getUserSession();
|
|
||||||
if (userSession != null) {
|
|
||||||
UserSessionEntity userSessionEntity = ((UserSessionAdapter)userSession).getEntity();
|
|
||||||
userSessionEntity.getClientSessions().remove(entity);
|
|
||||||
}
|
|
||||||
clientSessions.remove(clientSession.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientSessionModel getClientSession(RealmModel realm, String id) {
|
|
||||||
ClientSessionEntity entity = clientSessions.get(id);
|
|
||||||
return entity != null ? new ClientSessionAdapter(session, this, realm, entity) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientSessionModel getClientSession(String id) {
|
|
||||||
ClientSessionEntity entity = clientSessions.get(id);
|
|
||||||
if (entity != null) {
|
|
||||||
RealmModel realm = session.realms().getRealm(entity.getRealmId());
|
|
||||||
return new ClientSessionAdapter(session, this, realm, entity);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserSessionModel createUserSession(RealmModel realm, UserModel user, String loginUsername, String ipAddress, String authMethod, boolean rememberMe, String brokerSessionId, String brokerUserId) {
|
|
||||||
String id = KeycloakModelUtils.generateId();
|
|
||||||
|
|
||||||
UserSessionEntity entity = new UserSessionEntity();
|
|
||||||
entity.setId(id);
|
|
||||||
entity.setRealm(realm.getId());
|
|
||||||
entity.setUser(user.getId());
|
|
||||||
entity.setLoginUsername(loginUsername);
|
|
||||||
entity.setIpAddress(ipAddress);
|
|
||||||
entity.setAuthMethod(authMethod);
|
|
||||||
entity.setRememberMe(rememberMe);
|
|
||||||
|
|
||||||
int currentTime = Time.currentTime();
|
|
||||||
|
|
||||||
entity.setStarted(currentTime);
|
|
||||||
entity.setLastSessionRefresh(currentTime);
|
|
||||||
entity.setBrokerSessionId(brokerSessionId);
|
|
||||||
entity.setBrokerUserId(brokerUserId);
|
|
||||||
|
|
||||||
userSessions.put(id, entity);
|
|
||||||
if (brokerSessionId != null) {
|
|
||||||
userSessionsByBrokerSessionId.put(brokerSessionId, id);
|
|
||||||
}
|
|
||||||
if (brokerUserId != null) {
|
|
||||||
while (true) { // while loop gets around a race condition when a user session is removed
|
|
||||||
Set<String> set = userSessionsByBrokerUserId.get(brokerUserId);
|
|
||||||
if (set == null) {
|
|
||||||
Set<String> value = new HashSet<>();
|
|
||||||
set = userSessionsByBrokerUserId.putIfAbsent(brokerUserId, value);
|
|
||||||
if (set == null) {
|
|
||||||
set = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
synchronized (set) {
|
|
||||||
set.add(id);
|
|
||||||
}
|
|
||||||
if (userSessionsByBrokerUserId.get(brokerUserId) == set) {
|
|
||||||
// we are ensured set isn't deleted before the new id is added
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UserSessionAdapter(session, this, realm, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserSessionModel> getUserSessionByBrokerUserId(RealmModel realm, String brokerUserId) {
|
|
||||||
Set<String> sessions = userSessionsByBrokerUserId.get(brokerUserId);
|
|
||||||
if (sessions == null) return Collections.emptyList();
|
|
||||||
List<UserSessionModel> userSessions = new LinkedList<UserSessionModel>();
|
|
||||||
for (String id : sessions) {
|
|
||||||
UserSessionModel userSession = getUserSession(realm, id);
|
|
||||||
if (userSession != null) userSessions.add(userSession);
|
|
||||||
}
|
|
||||||
return userSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserSessionModel getUserSessionByBrokerSessionId(RealmModel realm, String brokerSessionId) {
|
|
||||||
String id = userSessionsByBrokerSessionId.get(brokerSessionId);
|
|
||||||
if (id == null) return null;
|
|
||||||
return getUserSession(realm, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserSessionModel getUserSession(RealmModel realm, String id) {
|
|
||||||
UserSessionEntity entity = getUserSessionEntity(realm, id);
|
|
||||||
return entity != null ? new UserSessionAdapter(session, this, realm, entity) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
UserSessionEntity getUserSessionEntity(RealmModel realm, String id) {
|
|
||||||
UserSessionEntity entity = userSessions.get(id);
|
|
||||||
if (entity != null && entity.getRealm().equals(realm.getId())) {
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserSessionModel> getUserSessions(RealmModel realm, UserModel user) {
|
|
||||||
List<UserSessionModel> userSessions = new LinkedList<UserSessionModel>();
|
|
||||||
for (UserSessionEntity s : this.userSessions.values()) {
|
|
||||||
if (s.getRealm().equals(realm.getId()) && s.getUser().equals(user.getId())) {
|
|
||||||
userSessions.add(new UserSessionAdapter(session, this, realm, s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserSessionModel> getUserSessionsByNote(RealmModel realm, String noteName, String noteValue) {
|
|
||||||
List<UserSessionModel> userSessions = new LinkedList<UserSessionModel>();
|
|
||||||
for (UserSessionEntity s : this.userSessions.values()) {
|
|
||||||
if (s.getRealm().equals(realm.getId()) && noteValue.equals(s.getNotes().get(noteName))) {
|
|
||||||
userSessions.add(new UserSessionAdapter(session, this, realm, s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
|
|
||||||
List<UserSessionEntity> userSessionEntities = new LinkedList<UserSessionEntity>();
|
|
||||||
for (ClientSessionEntity s : clientSessions.values()) {
|
|
||||||
String realmId = realm.getId();
|
|
||||||
String clientId = client.getId();
|
|
||||||
if (s.getSession() != null && s.getSession().getRealm().equals(realmId) && s.getClientId().equals(clientId)) {
|
|
||||||
if (!userSessionEntities.contains(s.getSession())) {
|
|
||||||
userSessionEntities.add(s.getSession());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<UserSessionModel> userSessions = new LinkedList<UserSessionModel>();
|
|
||||||
for (UserSessionEntity e : userSessionEntities) {
|
|
||||||
userSessions.add(new UserSessionAdapter(session, this, realm, e));
|
|
||||||
}
|
|
||||||
Collections.sort(userSessions, new UserSessionSort());
|
|
||||||
return userSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client, int firstResult, int maxResults) {
|
|
||||||
List<UserSessionModel> userSessions = getUserSessions(realm, client);
|
|
||||||
if (firstResult > userSessions.size()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
int toIndex = (firstResult + maxResults) < userSessions.size() ? firstResult + maxResults : userSessions.size();
|
|
||||||
return userSessions.subList(firstResult, toIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getActiveUserSessions(RealmModel realm, ClientModel client) {
|
|
||||||
return getUserSessions(realm, client).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeUserSession(RealmModel realm, UserSessionModel session) {
|
|
||||||
UserSessionEntity entity = getUserSessionEntity(realm, session.getId());
|
|
||||||
if (entity != null) {
|
|
||||||
userSessions.remove(entity.getId());
|
|
||||||
remove(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeUserSessions(RealmModel realm, UserModel user) {
|
|
||||||
Iterator<UserSessionEntity> itr = userSessions.values().iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
UserSessionEntity s = itr.next();
|
|
||||||
if (s.getRealm().equals(realm.getId()) && s.getUser().equals(user.getId())) {
|
|
||||||
itr.remove();
|
|
||||||
remove(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void remove(UserSessionEntity s) {
|
|
||||||
if (s.getBrokerSessionId() != null) {
|
|
||||||
userSessionsByBrokerSessionId.remove(s.getBrokerSessionId());
|
|
||||||
}
|
|
||||||
if (s.getBrokerUserId() != null) {
|
|
||||||
Set<String> set = userSessionsByBrokerUserId.get(s.getBrokerUserId());
|
|
||||||
if (set != null) {
|
|
||||||
synchronized (set) {
|
|
||||||
set.remove(s.getId());
|
|
||||||
// this is a race condition :(
|
|
||||||
// Since it will be very rare for a user to have concurrent sessions, I'm hoping we never hit this
|
|
||||||
if (set.isEmpty()) userSessionsByBrokerUserId.remove(s.getBrokerUserId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ClientSessionEntity clientSession : s.getClientSessions()) {
|
|
||||||
clientSessions.remove(clientSession.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeExpiredUserSessions(RealmModel realm) {
|
|
||||||
Iterator<UserSessionEntity> itr = userSessions.values().iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
UserSessionEntity s = itr.next();
|
|
||||||
if (s.getRealm().equals(realm.getId()) && (s.getLastSessionRefresh() < Time.currentTime() - realm.getSsoSessionIdleTimeout() || s.getStarted() < Time.currentTime() - realm.getSsoSessionMaxLifespan())) {
|
|
||||||
itr.remove();
|
|
||||||
|
|
||||||
remove(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int expired = Time.currentTime() - RealmInfoUtil.getDettachedClientSessionLifespan(realm);
|
|
||||||
Iterator<ClientSessionEntity> citr = clientSessions.values().iterator();
|
|
||||||
while (citr.hasNext()) {
|
|
||||||
ClientSessionEntity c = citr.next();
|
|
||||||
if (c.getSession() == null && c.getRealmId().equals(realm.getId()) && c.getTimestamp() < expired) {
|
|
||||||
citr.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeUserSessions(RealmModel realm) {
|
|
||||||
Iterator<UserSessionEntity> itr = userSessions.values().iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
UserSessionEntity s = itr.next();
|
|
||||||
if (s.getRealm().equals(realm.getId())) {
|
|
||||||
itr.remove();
|
|
||||||
|
|
||||||
remove(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Iterator<ClientSessionEntity> citr = clientSessions.values().iterator();
|
|
||||||
while (citr.hasNext()) {
|
|
||||||
ClientSessionEntity c = citr.next();
|
|
||||||
if (c.getSession() == null && c.getRealmId().equals(realm.getId())) {
|
|
||||||
citr.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UsernameLoginFailureModel getUserLoginFailure(RealmModel realm, String username) {
|
|
||||||
UsernameLoginFailureEntity entity = loginFailures.get(new UsernameLoginFailureKey(realm.getId(), username));
|
|
||||||
return entity != null ? new UsernameLoginFailureAdapter(entity) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UsernameLoginFailureModel addUserLoginFailure(RealmModel realm, String username) {
|
|
||||||
UsernameLoginFailureKey key = new UsernameLoginFailureKey(realm.getId(), username);
|
|
||||||
UsernameLoginFailureEntity entity = new UsernameLoginFailureEntity(username, realm.getId());
|
|
||||||
if (loginFailures.putIfAbsent(key, entity) != null) {
|
|
||||||
throw new ModelDuplicateException();
|
|
||||||
}
|
|
||||||
return new UsernameLoginFailureAdapter(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeUserLoginFailure(RealmModel realm, String username) {
|
|
||||||
loginFailures.remove(new UsernameLoginFailureKey(realm.getId(), username));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeAllUserLoginFailures(RealmModel realm) {
|
|
||||||
Iterator<UsernameLoginFailureEntity> itr = loginFailures.values().iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
if (itr.next().getRealm().equals(realm.getId())) {
|
|
||||||
itr.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRealmRemoved(RealmModel realm) {
|
|
||||||
removeUserSessions(realm);
|
|
||||||
removeAllUserLoginFailures(realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClientRemoved(RealmModel realm, ClientModel client) {
|
|
||||||
for (ClientSessionEntity e : clientSessions.values()) {
|
|
||||||
if (e.getRealmId().equals(realm.getId()) && e.getClientId().equals(client.getId())) {
|
|
||||||
clientSessions.remove(e.getId());
|
|
||||||
e.getSession().removeClientSession(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUserRemoved(RealmModel realm, UserModel user) {
|
|
||||||
removeUserSessions(realm, user);
|
|
||||||
|
|
||||||
loginFailures.remove(new UsernameLoginFailureKey(realm.getId(), user.getUsername()));
|
|
||||||
loginFailures.remove(new UsernameLoginFailureKey(realm.getId(), user.getEmail()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UserSessionSort implements Comparator<UserSessionModel> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(UserSessionModel o1, UserSessionModel o2) {
|
|
||||||
int r = o1.getStarted() - o2.getStarted();
|
|
||||||
if (r == 0) {
|
|
||||||
return o1.getId().compareTo(o2.getId());
|
|
||||||
} else {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem;
|
|
||||||
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
import org.keycloak.models.UserSessionProvider;
|
|
||||||
import org.keycloak.models.UserSessionProviderFactory;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.ClientSessionEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UserSessionEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureKey;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class MemUserSessionProviderFactory implements UserSessionProviderFactory {
|
|
||||||
|
|
||||||
public static final String ID = "mem";
|
|
||||||
|
|
||||||
private ConcurrentHashMap<String, UserSessionEntity> userSessions = new ConcurrentHashMap<String, UserSessionEntity>();
|
|
||||||
|
|
||||||
private ConcurrentHashMap<String, ClientSessionEntity> clientSessions = new ConcurrentHashMap<String, ClientSessionEntity>();
|
|
||||||
|
|
||||||
private ConcurrentHashMap<UsernameLoginFailureKey, UsernameLoginFailureEntity> loginFailures = new ConcurrentHashMap<UsernameLoginFailureKey, UsernameLoginFailureEntity>();
|
|
||||||
private final ConcurrentHashMap<String, String> userSessionsByBrokerSessionId = new ConcurrentHashMap<>();
|
|
||||||
private final ConcurrentHashMap<String, Set<String>> userSessionsByBrokerUserId = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserSessionProvider create(KeycloakSession session) {
|
|
||||||
return new MemUserSessionProvider(session, userSessions, userSessionsByBrokerSessionId, userSessionsByBrokerUserId, clientSessions, loginFailures);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
userSessions.clear();
|
|
||||||
loginFailures.clear();
|
|
||||||
userSessionsByBrokerSessionId.clear();
|
|
||||||
userSessionsByBrokerUserId.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem;
|
|
||||||
|
|
||||||
import org.keycloak.models.ClientSessionModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.ClientSessionEntity;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UserSessionEntity;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class UserSessionAdapter implements UserSessionModel {
|
|
||||||
|
|
||||||
private final KeycloakSession session;
|
|
||||||
|
|
||||||
private MemUserSessionProvider provider;
|
|
||||||
private final RealmModel realm;
|
|
||||||
|
|
||||||
private final UserSessionEntity entity;
|
|
||||||
|
|
||||||
public UserSessionAdapter(KeycloakSession session, MemUserSessionProvider provider, RealmModel realm, UserSessionEntity entity) {
|
|
||||||
this.session = session;
|
|
||||||
this.provider = provider;
|
|
||||||
this.realm = realm;
|
|
||||||
this.entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSessionEntity getEntity() {
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return entity.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBrokerSessionId() {
|
|
||||||
return entity.getBrokerSessionId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBrokerUserId() {
|
|
||||||
return entity.getBrokerUserId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
entity.setId(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserModel getUser() {
|
|
||||||
return session.users().getUserById(entity.getUser(), realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(UserModel user) {
|
|
||||||
entity.setUser(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLoginUsername() {
|
|
||||||
return entity.getLoginUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIpAddress() {
|
|
||||||
return entity.getIpAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAuthMethod() {
|
|
||||||
return entity.getAuthMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRememberMe() {
|
|
||||||
return entity.isRememberMe();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStarted() {
|
|
||||||
return entity.getStarted();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastSessionRefresh() {
|
|
||||||
return entity.getLastSessionRefresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastSessionRefresh(int lastSessionRefresh) {
|
|
||||||
entity.setLastSessionRefresh(lastSessionRefresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State getState() {
|
|
||||||
return entity.getState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setState(State state) {
|
|
||||||
entity.setState(state);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ClientSessionModel> getClientSessions() {
|
|
||||||
List<ClientSessionModel> clientSessionModels = new LinkedList<ClientSessionModel>();
|
|
||||||
if (entity.getClientSessions() != null) {
|
|
||||||
for (ClientSessionEntity e : entity.getClientSessions()) {
|
|
||||||
clientSessionModels.add(new ClientSessionAdapter(session, provider, realm, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return clientSessionModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || !(o instanceof UserSessionModel)) return false;
|
|
||||||
|
|
||||||
UserSessionModel that = (UserSessionModel) o;
|
|
||||||
return that.getId().equals(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return getId().hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNote(String name) {
|
|
||||||
return entity.getNotes().get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNote(String name, String value) {
|
|
||||||
entity.getNotes().put(name, value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeNote(String name) {
|
|
||||||
entity.getNotes().remove(name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem;
|
|
||||||
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
|
||||||
import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class UsernameLoginFailureAdapter implements UsernameLoginFailureModel {
|
|
||||||
|
|
||||||
private final UsernameLoginFailureEntity entity;
|
|
||||||
|
|
||||||
public UsernameLoginFailureAdapter(UsernameLoginFailureEntity entity) {
|
|
||||||
this.entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsername() {
|
|
||||||
return entity.getUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRealm() {
|
|
||||||
return entity.getRealm();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getFailedLoginNotBefore() {
|
|
||||||
return entity.getFailedLoginNotBefore().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFailedLoginNotBefore(int notBefore) {
|
|
||||||
entity.getFailedLoginNotBefore().set(notBefore);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getNumFailures() {
|
|
||||||
return entity.getNumFailures().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void incrementFailures() {
|
|
||||||
entity.getNumFailures().incrementAndGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearFailures() {
|
|
||||||
entity.clearFailures();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLastFailure() {
|
|
||||||
return entity.getLastFailure().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLastFailure(long lastFailure) {
|
|
||||||
entity.getLastFailure().set(lastFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLastIPFailure() {
|
|
||||||
return entity.getLastIpFailure().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLastIPFailure(String ip) {
|
|
||||||
entity.getLastIpFailure().set(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem.entities;
|
|
||||||
|
|
||||||
import org.keycloak.models.ClientSessionModel;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class ClientSessionEntity {
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
private String clientId;
|
|
||||||
private String realmId;
|
|
||||||
private Map<String, ClientSessionModel.ExecutionStatus> authenticatorStatus = new HashMap<>();
|
|
||||||
private String authUserId;
|
|
||||||
|
|
||||||
private UserSessionEntity session;
|
|
||||||
|
|
||||||
private String redirectUri;
|
|
||||||
private String authMethod;
|
|
||||||
|
|
||||||
private int timestamp;
|
|
||||||
private String action;
|
|
||||||
private Set<String> roles;
|
|
||||||
private Set<String> protocolMappers;
|
|
||||||
private Map<String, String> notes = new HashMap<>();
|
|
||||||
private Map<String, String> userSessionNotes = new HashMap<>();
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientId() {
|
|
||||||
return clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
this.clientId = clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRealmId() {
|
|
||||||
return realmId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRealmId(String realmId) {
|
|
||||||
this.realmId = realmId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSessionEntity getSession() {
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSession(UserSessionEntity session) {
|
|
||||||
this.session = session;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRedirectUri() {
|
|
||||||
return redirectUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedirectUri(String redirectUri) {
|
|
||||||
this.redirectUri = redirectUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(int timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAction() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(String action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getRoles() {
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoles(Set<String> roles) {
|
|
||||||
this.roles = roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getProtocolMappers() {
|
|
||||||
return protocolMappers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
|
||||||
this.protocolMappers = protocolMappers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getNotes() {
|
|
||||||
return notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthMethod() {
|
|
||||||
return authMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthMethod(String authMethod) {
|
|
||||||
this.authMethod = authMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthUserId() {
|
|
||||||
return authUserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthUserId(String authUserId) {
|
|
||||||
this.authUserId = authUserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, ClientSessionModel.ExecutionStatus> getAuthenticatorStatus() {
|
|
||||||
return authenticatorStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthenticatorStatus(Map<String, ClientSessionModel.ExecutionStatus> authenticatorStatus) {
|
|
||||||
this.authenticatorStatus = authenticatorStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getUserSessionNotes() {
|
|
||||||
return userSessionNotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (!(o instanceof ClientSessionEntity)) return false;
|
|
||||||
|
|
||||||
ClientSessionEntity that = (ClientSessionEntity) o;
|
|
||||||
|
|
||||||
if (id != null ? !id.equals(that.id) : that.id != null) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return id != null ? id.hashCode() : 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem.entities;
|
|
||||||
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class UserSessionEntity {
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
private String brokerSessionId;
|
|
||||||
private String brokerUserId;
|
|
||||||
private String realm;
|
|
||||||
private String user;
|
|
||||||
private String loginUsername;
|
|
||||||
private String ipAddress;
|
|
||||||
private String authMethod;
|
|
||||||
private boolean rememberMe;
|
|
||||||
private int started;
|
|
||||||
private int lastSessionRefresh;
|
|
||||||
private UserSessionModel.State state;
|
|
||||||
private Map<String, String> notes = new HashMap<String, String>();
|
|
||||||
private List<ClientSessionEntity> clientSessions = Collections.synchronizedList(new LinkedList<ClientSessionEntity>());
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRealm() {
|
|
||||||
return realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRealm(String realm) {
|
|
||||||
this.realm = realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(String user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLoginUsername() {
|
|
||||||
return loginUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginUsername(String loginUsername) {
|
|
||||||
this.loginUsername = loginUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIpAddress() {
|
|
||||||
return ipAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIpAddress(String ipAddress) {
|
|
||||||
this.ipAddress = ipAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthMethod() {
|
|
||||||
return authMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthMethod(String authMethod) {
|
|
||||||
this.authMethod = authMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRememberMe() {
|
|
||||||
return rememberMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRememberMe(boolean rememberMe) {
|
|
||||||
this.rememberMe = rememberMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStarted() {
|
|
||||||
return started;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStarted(int started) {
|
|
||||||
this.started = started;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastSessionRefresh() {
|
|
||||||
return lastSessionRefresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastSessionRefresh(int lastSessionRefresh) {
|
|
||||||
this.lastSessionRefresh = lastSessionRefresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClientSession(ClientSessionEntity clientSession) {
|
|
||||||
if (clientSessions == null) {
|
|
||||||
clientSessions = new LinkedList<ClientSessionEntity>();
|
|
||||||
}
|
|
||||||
clientSessions.add(clientSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeClientSession(ClientSessionEntity clientSession) {
|
|
||||||
if (clientSessions != null) {
|
|
||||||
clientSessions.remove(clientSession);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ClientSessionEntity> getClientSessions() {
|
|
||||||
return clientSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getNotes() {
|
|
||||||
return notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSessionModel.State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(UserSessionModel.State state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBrokerSessionId() {
|
|
||||||
return brokerSessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrokerSessionId(String brokerSessionId) {
|
|
||||||
this.brokerSessionId = brokerSessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBrokerUserId() {
|
|
||||||
return brokerUserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrokerUserId(String brokerUserId) {
|
|
||||||
this.brokerUserId = brokerUserId;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem.entities;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class UsernameLoginFailureEntity {
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
private String realm;
|
|
||||||
|
|
||||||
private AtomicInteger failedLoginNotBefore = new AtomicInteger();
|
|
||||||
private AtomicInteger numFailures = new AtomicInteger();
|
|
||||||
private AtomicLong lastFailure = new AtomicLong();
|
|
||||||
private AtomicReference<String> lastIpFailure = new AtomicReference<String>();
|
|
||||||
|
|
||||||
public UsernameLoginFailureEntity(String username, String realm) {
|
|
||||||
this.username = username;
|
|
||||||
this.realm = realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRealm() {
|
|
||||||
return realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AtomicInteger getFailedLoginNotBefore() {
|
|
||||||
return failedLoginNotBefore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFailedLoginNotBefore(AtomicInteger failedLoginNotBefore) {
|
|
||||||
this.failedLoginNotBefore = failedLoginNotBefore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AtomicInteger getNumFailures() {
|
|
||||||
return numFailures;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumFailures(AtomicInteger numFailures) {
|
|
||||||
this.numFailures = numFailures;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AtomicLong getLastFailure() {
|
|
||||||
return lastFailure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastFailure(AtomicLong lastFailure) {
|
|
||||||
this.lastFailure = lastFailure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AtomicReference<String> getLastIpFailure() {
|
|
||||||
return lastIpFailure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastIpFailure(AtomicReference<String> lastIpFailure) {
|
|
||||||
this.lastIpFailure = lastIpFailure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearFailures() {
|
|
||||||
this.failedLoginNotBefore = new AtomicInteger();
|
|
||||||
this.lastFailure = new AtomicLong();
|
|
||||||
this.lastIpFailure = new AtomicReference<String>();
|
|
||||||
this.numFailures = new AtomicInteger();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package org.keycloak.models.sessions.mem.entities;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class UsernameLoginFailureKey {
|
|
||||||
|
|
||||||
private final String realm;
|
|
||||||
private final String username;
|
|
||||||
|
|
||||||
public UsernameLoginFailureKey(String realm, String username) {
|
|
||||||
this.realm = realm;
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
UsernameLoginFailureKey key = (UsernameLoginFailureKey) o;
|
|
||||||
|
|
||||||
if (realm != null ? !realm.equals(key.realm) : key.realm != null) return false;
|
|
||||||
if (username != null ? !username.equals(key.username) : key.username != null) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = realm != null ? realm.hashCode() : 0;
|
|
||||||
result = 31 * result + (username != null ? username.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
org.keycloak.models.sessions.mem.MemUserSessionProviderFactory
|
|
5
pom.xml
5
pom.xml
|
@ -950,11 +950,6 @@
|
||||||
<artifactId>keycloak-model-sessions-jpa</artifactId>
|
<artifactId>keycloak-model-sessions-jpa</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-model-sessions-mem</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-model-sessions-mongo</artifactId>
|
<artifactId>keycloak-model-sessions-mongo</artifactId>
|
||||||
|
|
Loading…
Reference in a new issue