diff options
| author | Thomas <> | 2023-05-31 09:05:19 +0200 | 
|---|---|---|
| committer | Thomas <> | 2023-05-31 09:05:19 +0200 | 
| commit | b8807c30b2ef988226573c6b5bf2f6b3de6aac4d (patch) | |
| tree | d3fb30b45db741aa19657f39cedabe7e353ada0b /eaaf_core/src | |
| parent | dc9595c7aea48583d4bd075b398b4ce68b626965 (diff) | |
| download | EAAF-Components-b8807c30b2ef988226573c6b5bf2f6b3de6aac4d.tar.gz EAAF-Components-b8807c30b2ef988226573c6b5bf2f6b3de6aac4d.tar.bz2 EAAF-Components-b8807c30b2ef988226573c6b5bf2f6b3de6aac4d.zip | |
refact(core): change some more internal representation to make it JSON serializable
Diffstat (limited to 'eaaf_core/src')
3 files changed, 201 insertions, 45 deletions
| diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java index 9d24eb8c..2c125cc0 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/builder/AbstractAuthenticationDataBuilder.java @@ -22,7 +22,9 @@ package at.gv.egiz.eaaf.core.impl.idp.auth.builder;  import java.io.ByteArrayInputStream;  import java.io.IOException;  import java.io.InputStream; +import java.io.Serializable;  import java.util.Collection; +import java.util.Collections;  import java.util.HashSet;  import java.util.Set; @@ -60,6 +62,9 @@ import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser;  import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor;  public abstract class AbstractAuthenticationDataBuilder implements IAuthenticationDataBuilder {    private static final Logger log = @@ -174,7 +179,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati      // includedToGenericAuthData =      // authProcessData.getGenericSessionDataStorage().keySet();      // else -    initializeThreadLocalVariable(authProcessData, new HashSet<>()); +    initializeThreadLocalVariable(authProcessData, new HashSet<String>());      // ####################################################      // set general authData info's @@ -224,23 +229,23 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati    }    /** -   * Initialize Thread-Local holder for generic attributes set in authenticated session. +   * Initialize Thread-Local holder for generic attributes set in authenticated +   * session.     *      * @param authProcessData Current authentication data holder -   * @param data {@link Collection} of generic attribute-names -   * @throws EaafAuthenticationException In case of an error  +   * @param set             Initial set of attributes of this holder +   * @throws EaafAuthenticationException In case of an error     */ -  protected void initializeThreadLocalVariable(@NonNull final IAuthProcessDataContainer authProcessData, -      Set<String> data)  +  protected void initializeThreadLocalVariable( +      @NonNull final IAuthProcessDataContainer authProcessData, Set<String> set)        throws EaafAuthenticationException {      try { -      authProcessData.setGenericDataToSession(GENERIC_ATTR_CONTAINER, data); +      authProcessData.setGenericDataToSession(GENERIC_ATTR_CONTAINER, new AttributeListHolder(set));      } catch (EaafStorageException e) {        throw new EaafAuthenticationException("builder.11", new Object[] { e.getMessage() }, e);      } -        }    /** @@ -248,9 +253,10 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati     *      * @param set {@link Collection} of generic attribute-names     */ -  @SuppressWarnings("unchecked")    protected Set<String> getThreadLocalVariable(@NonNull final IAuthProcessDataContainer authProcessData) { -    return authProcessData.getGenericDataFromSession(GENERIC_ATTR_CONTAINER, Set.class); +    AttributeListHolder holder = authProcessData.getGenericDataFromSession(GENERIC_ATTR_CONTAINER, +        AttributeListHolder.class); +    return holder != null ? holder.getProcessedAttributes() : Collections.emptySet();    } @@ -370,7 +376,7 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati        initializeThreadLocalVariable(authProcessData,             authProcessData.getGenericSessionDataStorage().keySet());            } else { -      initializeThreadLocalVariable(authProcessData, new HashSet<>()); +      initializeThreadLocalVariable(authProcessData, new HashSet<String>());      }      // #################################################### @@ -804,4 +810,14 @@ public abstract class AbstractAuthenticationDataBuilder implements IAuthenticati    } +  @Data +  @NoArgsConstructor +  @AllArgsConstructor +  private static class AttributeListHolder implements Serializable { +    private static final long serialVersionUID = -7767295315249087217L; + +    private Set<String> processedAttributes; + +  } +  } diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java index e76d0728..dc391902 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/data/AuthProcessDataWrapper.java @@ -19,9 +19,9 @@  package at.gv.egiz.eaaf.core.impl.idp.auth.data; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.io.Serializable;  import java.time.Instant; +import java.time.LocalDateTime;  import java.time.ZoneId;  import java.time.format.DateTimeFormatter;  import java.util.Date; @@ -33,19 +33,25 @@ import java.util.stream.Stream;  import javax.annotation.Nullable;  import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory;  import at.gv.egiz.eaaf.core.api.data.EaafConstants;  import at.gv.egiz.eaaf.core.api.idp.EaafAuthProcessDataConstants;  import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer;  import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException;  import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; - +import at.gv.egiz.eaaf.core.impl.utils.DefaultJsonMapper; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j  public class AuthProcessDataWrapper      implements IAuthProcessDataContainer, EaafAuthProcessDataConstants { -  private static final Logger log = LoggerFactory.getLogger(AuthProcessDataWrapper.class); +  public static final String GENERIC_DATA_PREFIX = "$GENERIC$_";    public static final String PATTERN_ISSUE_INSTANT = "yyyy-MM-dd'T'HH:mm:ss'Z'";    protected Map<String, Object> authProcessData; @@ -57,7 +63,7 @@ public class AuthProcessDataWrapper    @Override    public Instant getIssueInstant() { -    return wrapStoredObject(VALUE_ISSUEINSTANT, null, Instant.class); +    return buildDateTimeUtcDate(wrapStoredObject(VALUE_ISSUEINSTANT, null, String.class));    }    /* @@ -68,8 +74,7 @@ public class AuthProcessDataWrapper     */    @Override    public String getIssueInstantString() { -    return buildDateTimeUtcString( -        wrapStoredObject(VALUE_ISSUEINSTANT, null, Instant.class)); +    return wrapStoredObject(VALUE_ISSUEINSTANT, null, String.class);    }    /* @@ -81,9 +86,13 @@ public class AuthProcessDataWrapper     */    @Override    public void setIssueInstant(final String issueInstant) { -    authProcessData.put(VALUE_ISSUEINSTANT, -        buildDateTimeUtcDate(issueInstant)); +    if (buildDateTimeUtcDate(issueInstant) != null) { +      authProcessData.put(VALUE_ISSUEINSTANT, issueInstant); + +    } else if (StringUtils.isNotEmpty(issueInstant)) { +      log.warn("Can not parse IssueInstant of authentication: {}", issueInstant); +    }    }    /* @@ -95,7 +104,7 @@ public class AuthProcessDataWrapper     */    @Override    public void setIssueInstant(final Instant issueInstant) { -    authProcessData.put(VALUE_ISSUEINSTANT, issueInstant); +    authProcessData.put(VALUE_ISSUEINSTANT, buildDateTimeUtcString(issueInstant));    } @@ -257,8 +266,8 @@ public class AuthProcessDataWrapper     * at.gv.egovernment.moa.id.auth.data.IAuthenticationSession#getSessionCreated()     */    @Override -  public Date getSessionCreated() { -    return wrapStoredObject(EaafConstants.AUTH_DATA_CREATED, null, Date.class); +  public Instant getSessionCreated() { +    return buildDateTimeUtcDate(wrapStoredObject(EaafConstants.AUTH_DATA_CREATED, null, String.class));    }    /* @@ -271,6 +280,15 @@ public class AuthProcessDataWrapper    public Map<String, Object> getGenericSessionDataStorage() {          return authProcessData.entrySet().stream()          .filter(el -> el.getKey().startsWith(GENERIC_PREFIX)) +        .map(el -> { +          Object obj = el.getValue(); +          if (obj instanceof String && ((String) obj).startsWith(GENERIC_DATA_PREFIX)) { +            log.trace("Find generic JSON serialized data. Starting de-serialization ... "); +            el.setValue(objectSaveJsonDeserialization(obj)); + +          } +          return el; +        })          .collect(              Collectors.toMap(                  el -> el.getKey().substring(GENERIC_PREFIX.length()),  @@ -292,7 +310,8 @@ public class AuthProcessDataWrapper     */    @Override    public Object getGenericDataFromSession(final String key) { -    return authProcessData.get(GENERIC_PREFIX + key); +    return wrapStoredObject(GENERIC_PREFIX + key, null, Object.class); +    }    /* @@ -304,6 +323,7 @@ public class AuthProcessDataWrapper    @Override    public <T> T getGenericDataFromSession(final String key, final Class<T> clazz) {      return wrapStoredObject(GENERIC_PREFIX + key, null, clazz); +    }    /* @@ -315,7 +335,7 @@ public class AuthProcessDataWrapper    @Override    public void setGenericDataToSession(final String key, final Object object)        throws EaafStorageException { -    authProcessData.put(GENERIC_PREFIX + key, object); +    authProcessData.put(GENERIC_PREFIX + key, objectSaveJsonSerialization(object));    } @@ -323,19 +343,40 @@ public class AuthProcessDataWrapper        final Class<T> clazz) {      if (StringUtils.isNotEmpty(key)) {        final Object obj = authProcessData.get(key); -      if (obj != null && clazz.isInstance(obj)) { + +      // check if it is a generic container +      if (obj instanceof String && ((String) obj).startsWith(GENERIC_DATA_PREFIX)) { +        log.trace("Find generic JSON serialized data. Starting de-serialization ... "); +        return (T) objectSaveJsonDeserialization(obj); + +      // check if object is already of valid type +      } else if (obj != null && clazz.isInstance(obj)) {          return (T) obj; +        // check if byte[] was requested and object is of type String in that case it's +        // B64 content        } else if (obj instanceof String && clazz.equals(byte[].class)) { -        return (T) java.util.Base64.getDecoder().decode((String) obj); +        try { +          return (T) java.util.Base64.getDecoder().decode((String) obj); + +        } catch (IllegalArgumentException e) { +          log.warn("Can not decode session-object with key: {}", key, e); + +        } +      } else if (obj != null) { +        log.warn("Can not unwrap data object with key: {} because requires class: {} but  has: {}", +            key, clazz.getName(), obj.getClass().getName());        }      } +    // return default value if we get not other result      if (defaultValue == null) {        return null; +      } else if (clazz.isInstance(defaultValue)) {        return (T) defaultValue; +      } else {        log.error("DefaultValue: " + defaultValue.getClass().getName() + " is not of Type:"            + clazz.getName()); @@ -376,20 +417,70 @@ public class AuthProcessDataWrapper     */    @Nullable    public static Instant buildDateTimeUtcDate(@Nullable final String date) { -    final SimpleDateFormat f = new SimpleDateFormat(PATTERN_ISSUE_INSTANT); +    if (date != null) { +      DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(PATTERN_ISSUE_INSTANT); +      return LocalDateTime.parse(date, dateTimeFormatter).atZone(ZoneId.of("UTC")).toInstant(); + +    } + +    return null; + +  } +   +  private Object objectSaveJsonSerialization(Object object) throws EaafStorageException {      try { -      if (date != null) {         -        return f.parse(date).toInstant(); +      if (object == null || object instanceof String || object instanceof Boolean +          || object instanceof Integer) { +        return object; -      } +      } else { +        return GENERIC_DATA_PREFIX + DefaultJsonMapper.serialize(RawDataHolder.builder() +            .object(DefaultJsonMapper.serialize(object)) +            .clazzType(object.getClass().getName()) +            .build()); -    } catch (final ParseException e) { -      log.error("Can NOT parse Date from String: {}", date, null, e); +      } +    } catch (EaafJsonMapperException e) { +      throw new EaafStorageException("Can no serialize object to JSON", e);      } +  } +  private Object objectSaveJsonDeserialization(Object data) { +    try { +      if (data == null) { +        return null; + +      } else if (data instanceof String) { +        RawDataHolder holder = (RawDataHolder) DefaultJsonMapper.deserialize( +            ((String) data).substring(GENERIC_DATA_PREFIX.length()), RawDataHolder.class); +        Class<?> clz = Class.forName(holder.getClazzType()); +        return DefaultJsonMapper.deserialize(holder.getObject(), clz); + +      } else { +        log.error("Can not deserialize: {} because it's not of type String", data.getClass().getName()); + +      } +    } catch (final Exception e) { +      log.warn("Generic request-data object can not be casted to requested type", e); + +    }      return null;    } +  @Data +  @Builder +  @NoArgsConstructor +  @AllArgsConstructor +  private static class RawDataHolder implements Serializable { + +    private static final long serialVersionUID = -3827971372737399528L; + +    private String object; + +    private String clazzType; + +  } +  } diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java index eb32d03f..a4f60ddc 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java @@ -23,7 +23,7 @@ import java.io.Serializable;  import java.lang.reflect.InvocationTargetException;  import java.net.MalformedURLException;  import java.net.URL; -import java.util.Date; +import java.time.Instant;  import java.util.HashMap;  import java.util.Map;  import java.util.Map.Entry; @@ -49,12 +49,17 @@ import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;  import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;  import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;  import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException;  import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;  import at.gv.egiz.eaaf.core.impl.http.HttpUtils;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;  import at.gv.egiz.eaaf.core.impl.json.EscapedJsonDeserializer;  import at.gv.egiz.eaaf.core.impl.json.EscapedJsonSerializer; +import at.gv.egiz.eaaf.core.impl.utils.DefaultJsonMapper;  import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data;  import lombok.Getter;  import lombok.NoArgsConstructor;  import lombok.Setter; @@ -172,9 +177,9 @@ public abstract class RequestImpl implements IRequest, Serializable {        uniquePiiTransactionIdentifier = UUID.randomUUID().toString();      } -      // initialize session object -    genericDataStorage.put(EaafConstants.AUTH_DATA_CREATED, new Date()); +    genericDataStorage.put(EaafConstants.AUTH_DATA_CREATED, +        AuthProcessDataWrapper.buildDateTimeUtcString(Instant.now()));      // genericDataStorage.put(EAAFConstants.VALUE_SESSIONID,      // Random.nextLongRandom()); @@ -500,7 +505,7 @@ public abstract class RequestImpl implements IRequest, Serializable {    @Override    public final Object getRawData(final String key) {      if (StringUtils.isNotEmpty(key)) { -      return genericDataStorage.get(key); +      return objectSaveJsonDeserialization(genericDataStorage.get(key));      } @@ -515,19 +520,18 @@ public abstract class RequestImpl implements IRequest, Serializable {        if (data == null) {          return null; +        }        try { -        @SuppressWarnings("unchecked") -        final T test = (T) data; -        return test; +        Object deserializedObject = objectSaveJsonDeserialization(data); +        return deserializedObject != null ? (T) deserializedObject : null;        } catch (final Exception e) {          log.warn("Generic request-data object can not be casted to requested type", e);          return null;        } -      }      log.info("Can not load generic request-data with key='null'"); @@ -544,7 +548,6 @@ public abstract class RequestImpl implements IRequest, Serializable {            null);      } -      if (object != null && !Serializable.class.isInstance(object)) {        log.warn(            "Generic request-data can only store objects which implements the 'Seralizable' interface"); @@ -559,7 +562,7 @@ public abstract class RequestImpl implements IRequest, Serializable {        log.trace("Add generic request-data with key:" + key + " to session.");      } -    genericDataStorage.put(key, object); +    genericDataStorage.put(key, objectSaveJsonSerialization(object));    } @@ -580,4 +583,50 @@ public abstract class RequestImpl implements IRequest, Serializable {    } +  private String objectSaveJsonSerialization(Object object) throws EaafStorageException { +    try { +      return DefaultJsonMapper.serialize(RawDataHolder.builder() +          .object(DefaultJsonMapper.serialize(object)) +          .clazzzType(object.getClass().getName()) +          .build()); + +    } catch (EaafJsonMapperException e) { +      throw new EaafStorageException("Can no serialize object to JSON", e); + +    } +  } + +  private Object objectSaveJsonDeserialization(Object data) { +    try { +      if (data instanceof String) { +        RawDataHolder holder = (RawDataHolder) DefaultJsonMapper.deserialize( +            (String) data, RawDataHolder.class); +        Class<?> clz = Class.forName(holder.getClazzzType()); +        return DefaultJsonMapper.deserialize(holder.getObject(), clz); + +      } else { +        log.error("Can not deserialize: {} because it's not of type String", data.getClass().getName()); + +      } +    } catch (final Exception e) { +      log.warn("Generic request-data object can not be casted to requested type", e); + +    } +    return null; + +  } + +  @Data +  @Builder +  @NoArgsConstructor +  @AllArgsConstructor +  private static class RawDataHolder implements Serializable { +    private static final long serialVersionUID = -8127401393932687928L; + +    private String object; + +    private String clazzzType; + +  } +  } | 
