diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/interceptor/RequestReaderInterceptor.java b/jans-config-api/server/src/main/java/io/jans/configapi/interceptor/RequestReaderInterceptor.java new file mode 100644 index 00000000000..308a89cbcc1 --- /dev/null +++ b/jans-config-api/server/src/main/java/io/jans/configapi/interceptor/RequestReaderInterceptor.java @@ -0,0 +1,262 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.interceptor; + +//import io.jans.as.common.model.common.User; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; + +import io.jans.configapi.core.interceptor.RequestInterceptor; +import io.jans.orm.PersistenceEntryManager; +import io.jans.configapi.core.rest.ProtectedApi; +import io.jans.configapi.core.util.DataUtil; +import io.jans.configapi.security.service.AuthorizationService; +import io.jans.configapi.util.ApiConstants; +import io.jans.configapi.util.DataProcessingUtil; +import io.jans.orm.PersistenceEntryManager; +import jakarta.annotation.Priority; +import jakarta.inject.Inject; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.ws.rs.Priorities; +import jakarta.ws.rs.ext.ReaderInterceptor; +import jakarta.ws.rs.ext.ReaderInterceptorContext; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.container.ResourceInfo; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriInfo; +import jakarta.ws.rs.ext.Provider; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.json.JSONException; +import org.json.JSONObject; +import java.util.Date; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.interceptor.AroundInvoke; +import jakarta.interceptor.Interceptor; +import jakarta.interceptor.InvocationContext; + +@Interceptor +@RequestInterceptor +@Priority(Interceptor.Priority.APPLICATION) +public class RequestReaderInterceptor { + + private static final Logger logger = LoggerFactory.getLogger(RequestReaderInterceptor.class); + private static final String[] IGNORE_METHODS = { "@jakarta.ws.rs.GET()", "@jakarta.ws.rs.DELETE()", "@jakarta.ws.rs.OPTIONS()", "@jakarta.ws.rs.PATCH()" }; + + @Inject + private Logger log; + + @Context + UriInfo info; + + @Context + HttpServletRequest request; + + @Context + private HttpHeaders httpHeaders; + + @Context + private ResourceInfo resourceInfo; + + @Inject + private DataProcessingUtil dataProcessingUtil; + + + @Inject + PersistenceEntryManager persistenceEntryManager; + + @SuppressWarnings({ "all" }) + @AroundInvoke + public Object aroundReadFrom(InvocationContext context) throws Exception { + System.out.println("\n\n\n RequestReaderInterceptor: entry - log=" + log + " logger=" + logger + + " , request:{} " + request + " info:{} " + info + ". resourceInfo=" + resourceInfo + + " , context:{} " + context + " , dataProcessingUtil = " + dataProcessingUtil+" , persistenceEntryManager"+persistenceEntryManager+" \n\n\n"); + try { + logger.error( + "======================= RequestReaderInterceptor Performing DataType Conversion ============================"); + + // context + logger.error( + "======ReaderInterceptorContext - context.getClass():{}, context.getConstructor(), context.getContextData():{}, context.getMethod():{}, context.getParameters():{}, context.getTarget():{}, context.getInputStream():{} ", + context.getClass(), context.getConstructor(), context.getContextData(), context.getMethod(), + context.getParameters(), context.getTarget()); + + //method + logger.error( + "======ReaderInterceptorContext - context.getMethod().getAnnotatedExceptionTypes().toString() :{}, context.getMethod().getAnnotatedParameterTypes().toString() :{}, context.getMethod().getAnnotatedReceiverType().toString() :{}, context.getMethod().getAnnotation(jakarta.ws.rs.GET.class):{}, context.getMethod().getAnnotations().toString() :{}., context.getMethod().getAnnotationsByType(jakarta.ws.rs.GET.class):{} ", + context.getMethod().getAnnotatedExceptionTypes().toString(), context.getMethod().getAnnotatedParameterTypes().toString(), context.getMethod().getAnnotatedReceiverType().toString(), context.getMethod().getAnnotation(jakarta.ws.rs.GET.class), + context.getMethod().getAnnotations().toString(), context.getMethod().getAnnotationsByType(jakarta.ws.rs.GET.class)); + + + boolean contains = isIgnoreMethod(context); + logger.error("====== context.getMethod():{} present in ignoreList contains:{}", context.getMethod(), + contains); + if (contains) { + logger.error("====== Exiting ReaderInterceptorContext as no action required for {} method. ======", + context.getMethod()); + return context.proceed(); + } + + processRequest(context); + + } catch (Exception ex) { + throw new WebApplicationException(ex); + } + return context.proceed(); + } + + private boolean isIgnoreMethod(InvocationContext context) { + logger.error("Checking if method to be ignored"); + if(context.getMethod().getAnnotations()==null || context.getMethod().getAnnotations().length<=0) { + return false; + } + + for(int i=0; i 0) { + for (int i = 0; i < clazzArray.length; i++) { + Class clazz = clazzArray[i]; + String propertyName = parameters[i].getName(); + logger.error("propertyName:{}, clazz:{} , clazz.isPrimitive():{} ", propertyName, clazz, + clazz.isPrimitive()); + + Object obj = ctxParameters[i]; + String jsonStr = null; + if (!clazz.isPrimitive()) { + + jsonStr = getJsonString(obj); + logger.error("RequestReaderInterceptor final - obj - jsonStr:{} ", jsonStr); + + //validate Json + //validateJson(jsonStr); + + performDataConversion(castObject(obj, clazz)); + + logger.error("RequestReaderInterceptor final - obj - obj:{} ", obj); + + } + } + } + } + + private T performDataConversion(T obj) { + try { + obj = dataProcessingUtil.encodeObjDataType(obj); + logger.error("RequestReaderInterceptor - Data after encoding - obj:{} , obj.getClass():{}", obj, + obj.getClass()); + } catch (Exception ex) { + logger.error("Exception while data conversion ", ex.getMessage()); + } + return obj; + } + + private String getJsonString(T obj) { + String jsonStr = null; + try { + jsonStr = dataProcessingUtil.getJsonString(obj); + logger.error("RequestReaderInterceptor - Object string - jsonStr:{}", jsonStr); + } catch (Exception ex) { + logger.error("Exception while data conversion ", ex.getMessage()); + } + return jsonStr; + } + + private T castObject(Object obj, Class clazz) { + T t = (T) clazz.cast(obj); + return t; + } + + private void validateJson(String jsonStr) throws JsonProcessingException { + logger.error("\n\n\n validateJson() - jsonStr:{} ", jsonStr); + JSONObject jsonObj = new JSONObject(jsonStr); + logger.error("\n\n\n validateJson() - jsonObj:{} ", jsonObj); + + Map jsonObjMap = jsonObj.toMap(); + logger.error("\n\n\n validateJson() - jsonObjMap:{} ", jsonObjMap); + + for (Map.Entry entry : jsonObjMap.entrySet()) { + logger.error("validateJson() - entry.getKey():{}, entry.getValue():{}", entry.getKey(), entry.getValue()); + + if ( entry.getValue() instanceof Date) { + logger.error("validateJson() - entry.getKey():{} is instanceof Date entry.getValue():{}", entry.getKey(), entry.getValue()); + + //encodeDate + logger.error("\n\n\n validateJson() - Encoding date \n\n\n\n"); + jsonObjMap.put(entry.getKey(), "31-12-2080"); + } + + if (entry.getKey().equalsIgnoreCase("createdAt")) { + logger.error("validateJson() - entry.getKey():{} is instanceof Date entry.getValue():{}", entry.getKey(), entry.getValue()); + + //encodeDate + logger.error("\n\n\n validateJson() - Encoding date \n\n\n\n"); + //logger.error("\n\n\n decodeTime(null, (String) entry.getValue():{} ", decodeTime(null, (Long) entry.getValue())); + //jsonObjMap.put(entry.getKey(), "31-12-2080"); + } + } + + + } + + public Date decodeTime(String baseDn, Long strDate) { + log.error("Decode date value - baseDn:{}, strDate:{} ", baseDn, strDate); + return persistenceEntryManager.decodeTime(baseDn, strDate.toString()); + } + +} diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/util/DataTypeConversionMapping.java b/jans-config-api/server/src/main/java/io/jans/configapi/util/DataTypeConversionMapping.java new file mode 100644 index 00000000000..a8ffec65655 --- /dev/null +++ b/jans-config-api/server/src/main/java/io/jans/configapi/util/DataTypeConversionMapping.java @@ -0,0 +1,80 @@ +package io.jans.configapi.core.util; + +import java.util.List; +import java.util.Map; + +public class DataTypeConversionMapping { + + /** + * Name of the class to be used for DataType conversion + */ + private String dataTypeConverterClassName; + + /** + * Accepatable dateFormat + */ + private String dateFormat; + + /** + * Map of DataType and method to invoke for encoding + */ + private Map encoder; + + /** + * Map of DataType and method to invoke for decoding + */ + private Map decoder; + + /** + * Map of Class and attribute to be ignored for conversion + */ + private Map> exclusion; + + + + public String getDataTypeConverterClassName() { + return dataTypeConverterClassName; + } + + public void setDataTypeConverterClassName(String dataTypeConverterClassName) { + this.dataTypeConverterClassName = dataTypeConverterClassName; + } + + public String getDateFormat() { + return dateFormat; + } + + public void setDateFormat(String dateFormat) { + this.dateFormat = dateFormat; + } + + public Map getEncoder() { + return encoder; + } + + public void setEncoder(Map encoder) { + this.encoder = encoder; + } + + public Map getDecoder() { + return decoder; + } + + public void setDecoder(Map decoder) { + this.decoder = decoder; + } + + public Map> getExclusion() { + return exclusion; + } + + public void setExclusion(Map> exclusion) { + this.exclusion = exclusion; + } + + @Override + public String toString() { + return "DataTypeConversionMapping [dataTypeConverterClassName=" + dataTypeConverterClassName + ", dateFormat=" + + dateFormat + ", encoder=" + encoder + ", decoder=" + decoder + ", exclusion=" + exclusion + "]"; + } +} \ No newline at end of file diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/interceptor/RequestInterceptor.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/interceptor/RequestInterceptor.java new file mode 100644 index 00000000000..a34a554555f --- /dev/null +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/interceptor/RequestInterceptor.java @@ -0,0 +1,20 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.core.interceptor; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.interceptor.InterceptorBinding; + +@InterceptorBinding +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.METHOD }) +public @interface RequestInterceptor { +} diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataTypeConverter.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataTypeConverter.java new file mode 100644 index 00000000000..ef5a072eb73 --- /dev/null +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/DataTypeConverter.java @@ -0,0 +1,60 @@ +package io.jans.configapi.core.util; + +import io.jans.orm.PersistenceEntryManager; +import io.jans.util.StringHelper; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import jakarta.annotation.Priority; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.inject.Named; + +import org.slf4j.Logger; + +@ApplicationScoped +@Priority(1) +@Named("dataTypeConverter") +public class DataTypeConverter { + + @Inject + Logger log; + + @Inject + PersistenceEntryManager persistenceEntryManager; + + + public Date validateDateFormat(String strDate, String format) throws ParseException { + log.error("Validate date value - strDate:{}, format:{} ", strDate, format); + Date formatedDate = null; + if (StringHelper.isEmpty(strDate) || StringHelper.isEmpty(format)) { + return formatedDate; + } + + SimpleDateFormat parser = new SimpleDateFormat(format); + return parser.parse(strDate); + } + + public Date decodeTime(String baseDn, String strDate) { + log.error("Decode date value - baseDn:{}, strDate:{} ", baseDn, strDate); + return persistenceEntryManager.decodeTime(baseDn, strDate); + } + + public String encodeTime(String baseDn, Date date) { + log.error("Encode Date value - baseDn:{}, date:{} ", baseDn, date); + return persistenceEntryManager.encodeTime(baseDn, date); + } + + public Boolean decodeBoolean(String strBoolean, boolean defaultValue) { + log.error("Decode boolean value - strBoolean:{} ", strBoolean); + return StringHelper.toBoolean(strBoolean, defaultValue); + } + + public String encodeBoolean(boolean booleanValue) { + log.error("Encode boolean value - booleanValue:{} ", booleanValue); + return Boolean.toString(booleanValue); + } + +}