From bb3c76a9d99914282f5d87d8a33f0da528d383df Mon Sep 17 00:00:00 2001 From: Hynek Mlnarik Date: Tue, 20 Mar 2018 12:16:28 +0100 Subject: [PATCH] KEYCLOAK-6929 Externalizers for AuthenticationSessionEntity --- .../entities/AuthenticationSessionEntity.java | 115 ++++++++++++++++++ .../RootAuthenticationSessionEntity.java | 56 +++++++++ 2 files changed, 171 insertions(+) diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java index 8dcac436d4..be21ef6c2b 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java @@ -17,6 +17,7 @@ package org.keycloak.models.sessions.infinispan.entities; +import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil; import java.io.Serializable; import java.util.Map; import java.util.Set; @@ -24,10 +25,18 @@ import java.util.concurrent.ConcurrentHashMap; import org.infinispan.util.concurrent.ConcurrentHashSet; import org.keycloak.sessions.AuthenticationSessionModel; +import org.keycloak.sessions.CommonClientSessionModel.ExecutionStatus; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import org.infinispan.commons.marshall.Externalizer; +import org.infinispan.commons.marshall.MarshallUtil; +import org.infinispan.commons.marshall.SerializeWith; /** * @author Marek Posolda */ +@SerializeWith(AuthenticationSessionEntity.ExternalizerImpl.class) public class AuthenticationSessionEntity implements Serializable { private String clientUUID; @@ -47,6 +56,33 @@ public class AuthenticationSessionEntity implements Serializable { private Set requiredActions = new ConcurrentHashSet<>(); private Map userSessionNotes; + public AuthenticationSessionEntity() { + } + + public AuthenticationSessionEntity( + String clientUUID, + String authUserId, + String redirectUri, String action, Set roles, Set protocolMappers, + Map executionStatus, String protocol, + Map clientNotes, Map authNotes, Set requiredActions, Map userSessionNotes) { + this.clientUUID = clientUUID; + + this.authUserId = authUserId; + + this.redirectUri = redirectUri; + this.action = action; + this.roles = roles; + this.protocolMappers = protocolMappers; + + this.executionStatus = executionStatus; + this.protocol = protocol; + + this.clientNotes = clientNotes; + this.authNotes = authNotes; + this.requiredActions = requiredActions; + this.userSessionNotes = userSessionNotes; + } + public String getClientUUID() { return clientUUID; } @@ -143,4 +179,83 @@ public class AuthenticationSessionEntity implements Serializable { this.authNotes = authNotes; } + public static class ExternalizerImpl implements Externalizer { + + private static final int VERSION_1 = 1; + + public static final ExternalizerImpl INSTANCE = new ExternalizerImpl(); + + private static AuthenticationSessionModel.ExecutionStatus fromOrdinal(int ordinal) { + ExecutionStatus[] values = AuthenticationSessionModel.ExecutionStatus.values(); + return (ordinal < 0 || ordinal >= values.length) + ? null + : values[ordinal]; + } + + public static final Externalizer EXECUTION_STATUS_EXT = new Externalizer() { + + @Override + public void writeObject(ObjectOutput output, AuthenticationSessionModel.ExecutionStatus e) throws IOException { + MarshallUtil.marshallEnum(e, output); + } + + @Override + public AuthenticationSessionModel.ExecutionStatus readObject(ObjectInput input) throws IOException, ClassNotFoundException { + return MarshallUtil.unmarshallEnum(input, ExternalizerImpl::fromOrdinal); + } + }; + + @Override + public void writeObject(ObjectOutput output, AuthenticationSessionEntity value) throws IOException { + output.writeByte(VERSION_1); + + MarshallUtil.marshallString(value.clientUUID, output); + + MarshallUtil.marshallString(value.authUserId, output); + + MarshallUtil.marshallString(value.redirectUri, output); + MarshallUtil.marshallString(value.action, output); + KeycloakMarshallUtil.writeCollection(value.roles, KeycloakMarshallUtil.STRING_EXT, output); + KeycloakMarshallUtil.writeCollection(value.protocolMappers, KeycloakMarshallUtil.STRING_EXT, output); + + KeycloakMarshallUtil.writeMap(value.executionStatus, KeycloakMarshallUtil.STRING_EXT, EXECUTION_STATUS_EXT, output); + MarshallUtil.marshallString(value.protocol, output); + + KeycloakMarshallUtil.writeMap(value.clientNotes, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, output); + KeycloakMarshallUtil.writeMap(value.authNotes, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, output); + KeycloakMarshallUtil.writeCollection(value.requiredActions, KeycloakMarshallUtil.STRING_EXT, output); + KeycloakMarshallUtil.writeMap(value.userSessionNotes, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, output); + } + + @Override + public AuthenticationSessionEntity readObject(ObjectInput input) throws IOException, ClassNotFoundException { + switch (input.readByte()) { + case VERSION_1: + return readObjectVersion1(input); + default: + throw new IOException("Unknown version"); + } + } + + public AuthenticationSessionEntity readObjectVersion1(ObjectInput input) throws IOException, ClassNotFoundException { + return new AuthenticationSessionEntity( + MarshallUtil.unmarshallString(input), // clientUUID + + MarshallUtil.unmarshallString(input), // authUserId + + MarshallUtil.unmarshallString(input), // redirectUri + MarshallUtil.unmarshallString(input), // action + KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // roles + KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // protocolMappers + + KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, EXECUTION_STATUS_EXT, size -> new ConcurrentHashMap<>(size)), // executionStatus + MarshallUtil.unmarshallString(input), // protocol + + KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashMap<>(size)), // clientNotes + KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashMap<>(size)), // authNotes + KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // requiredActions + KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashMap<>(size)) // userSessionNotes + ); + } + } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/RootAuthenticationSessionEntity.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/RootAuthenticationSessionEntity.java index 751b6f0d58..dd9cbcc6bd 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/RootAuthenticationSessionEntity.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/RootAuthenticationSessionEntity.java @@ -17,18 +17,36 @@ package org.keycloak.models.sessions.infinispan.entities; +import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.infinispan.commons.marshall.Externalizer; +import org.infinispan.commons.marshall.MarshallUtil; +import org.infinispan.commons.marshall.SerializeWith; /** * @author Marek Posolda */ +@SerializeWith(RootAuthenticationSessionEntity.ExternalizerImpl.class) public class RootAuthenticationSessionEntity extends SessionEntity { private String id; private int timestamp; private Map authenticationSessions = new ConcurrentHashMap<>(); + public RootAuthenticationSessionEntity() { + } + + protected RootAuthenticationSessionEntity(String realmId, String id, int timestamp, Map authenticationSessions) { + super(realmId); + this.id = id; + this.timestamp = timestamp; + this.authenticationSessions = authenticationSessions; + } + public String getId() { return id; } @@ -74,4 +92,42 @@ public class RootAuthenticationSessionEntity extends SessionEntity { public String toString() { return String.format("RootAuthenticationSessionEntity [ id=%s, realm=%s ]", getId(), getRealmId()); } + + public static class ExternalizerImpl implements Externalizer { + + private static final int VERSION_1 = 1; + + @Override + public void writeObject(ObjectOutput output, RootAuthenticationSessionEntity value) throws IOException { + output.writeByte(VERSION_1); + + MarshallUtil.marshallString(value.getRealmId(), output); + + MarshallUtil.marshallString(value.id, output); + output.writeInt(value.timestamp); + + KeycloakMarshallUtil.writeMap(value.authenticationSessions, KeycloakMarshallUtil.STRING_EXT, AuthenticationSessionEntity.ExternalizerImpl.INSTANCE, output); + } + + @Override + public RootAuthenticationSessionEntity readObject(ObjectInput input) throws IOException, ClassNotFoundException { + switch (input.readByte()) { + case VERSION_1: + return readObjectVersion1(input); + default: + throw new IOException("Unknown version"); + } + } + + public RootAuthenticationSessionEntity readObjectVersion1(ObjectInput input) throws IOException, ClassNotFoundException { + return new RootAuthenticationSessionEntity( + MarshallUtil.unmarshallString(input), // realmId + + MarshallUtil.unmarshallString(input), // id + input.readInt(), // timestamp + + KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, AuthenticationSessionEntity.ExternalizerImpl.INSTANCE, size -> new ConcurrentHashMap<>(size)) // authenticationSessions + ); + } + } }