diff --git a/Dockerfile b/Dockerfile index 31a824b6..4a6484ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN curl -Ls https://github.com/Erudika/para/archive/master.tar.gz | tar -xz -C RUN cd /para/para-master && mvn -q install -DskipTests=true -DskipITs=true && \ cd /para/para-master/para-jar && mv target/para-[0-9]*.jar /para/ -FROM adoptopenjdk/openjdk11:alpine-jre +FROM eclipse-temurin:21-alpine ENV BOOT_SLEEP=0 \ JAVA_OPTS="-Dloader.path=lib" diff --git a/Dockerfile-base b/Dockerfile-base index c968ff17..dbc8e2a3 100644 --- a/Dockerfile-base +++ b/Dockerfile-base @@ -7,7 +7,7 @@ RUN curl -Ls https://github.com/Erudika/para/archive/master.tar.gz | tar -xz -C RUN cd /para/para-master && mvn -q install -DskipTests=true -DskipITs=true && \ cd /para/para-master/para-jar && mvn -q -Pbase clean package && mv target/para-[0-9]*.jar /para/ -FROM adoptopenjdk/openjdk11:alpine-jre +FROM eclipse-temurin:21-alpine ENV BOOT_SLEEP=0 \ JAVA_OPTS="-Dloader.path=lib" diff --git a/para-client/pom.xml b/para-client/pom.xml index 42d634a4..f5f712f1 100644 --- a/para-client/pom.xml +++ b/para-client/pom.xml @@ -75,7 +75,7 @@ - 11 + 17 ../para-core/src/main/javadoc/stylesheet.css public true diff --git a/para-client/src/main/java/com/erudika/para/client/ParaClient.java b/para-client/src/main/java/com/erudika/para/client/ParaClient.java index 32f843b2..ebb3d66b 100644 --- a/para-client/src/main/java/com/erudika/para/client/ParaClient.java +++ b/para-client/src/main/java/com/erudika/para/client/ParaClient.java @@ -36,6 +36,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.ws.rs.core.MultivaluedHashMap; +import jakarta.ws.rs.core.MultivaluedMap; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; @@ -55,8 +57,6 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; import nl.altindag.ssl.SSLFactory; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -1698,7 +1698,7 @@ public Map>> grantResourcePermission(String sub permission.add(App.AllowedMethods.GUEST); } subjectid = Utils.urlEncode(subjectid); - resourcePath = Utils.urlEncode(resourcePath); + resourcePath = Utils.base64encURL(resourcePath.getBytes()); return invokePut(Utils.formatMessage("_permissions/{0}/{1}", subjectid, resourcePath), permission, Map.class); } @@ -1713,7 +1713,7 @@ public Map>> revokeResourcePermission(String su return Collections.emptyMap(); } subjectid = Utils.urlEncode(subjectid); - resourcePath = Utils.urlEncode(resourcePath); + resourcePath = Utils.base64encURL(resourcePath.getBytes()); return invokeDelete(Utils.formatMessage("_permissions/{0}/{1}", subjectid, resourcePath), null, Map.class); } @@ -1742,7 +1742,7 @@ public boolean isAllowedTo(String subjectid, String resourcePath, String httpMet return false; } subjectid = Utils.urlEncode(subjectid); - resourcePath = Utils.urlEncode(resourcePath); + resourcePath = Utils.base64encURL(resourcePath.getBytes()); String url = Utils.formatMessage("_permissions/{0}/{1}/{2}", subjectid, resourcePath, httpMethod); Boolean result = invokeGet(url, null, Boolean.class); return result != null && result; diff --git a/para-core/pom.xml b/para-core/pom.xml index adec6f06..67d1d46d 100644 --- a/para-core/pom.xml +++ b/para-core/pom.xml @@ -12,7 +12,7 @@ para-core - 2.16.1 + 2.17.0 0.64.8 @@ -28,20 +28,20 @@ io.github.classgraph classgraph - 4.8.165 + 4.8.168 - javax.ws.rs - javax.ws.rs-api - 2.1.1 + jakarta.ws.rs + jakarta.ws.rs-api + 3.1.0 jakarta.inject jakarta.inject-api - 1.0.5 + 2.0.1 @@ -56,20 +56,20 @@ ${jacksonVer} - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base + com.fasterxml.jackson.jakarta.rs + jackson-jakarta-rs-base ${jacksonVer} - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider + com.fasterxml.jackson.jakarta.rs + jackson-jakarta-rs-json-provider ${jacksonVer} - + com.fasterxml.jackson.core @@ -136,7 +136,7 @@ ch.qos.logback logback-access - ${logbackVer} + 1.4.14 @@ -166,8 +166,7 @@ org.hibernate.validator hibernate-validator - - 6.2.5.Final + 8.0.1.Final org.apache.commons @@ -238,37 +237,37 @@ com.samskivert jmustache - 1.15 + 1.16 - javax.validation - validation-api - 2.0.1.Final + jakarta.validation + jakarta.validation-api + 3.0.2 - javax.el - javax.el-api - 3.0.1-b06 + jakarta.el + jakarta.el-api + 5.0.1 - + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.2 + + org.codehaus.woodstox stax2-api - 4.2.1 + 4.2.2 io.github.hakky54 sslcontext-kickstart - 7.4.11 + 8.3.3 @@ -278,7 +277,7 @@ org.codehaus.mojo templating-maven-plugin - 1.0.0 + 3.0.0 generate-verion-class @@ -295,7 +294,7 @@ org.codehaus.mojo buildnumber-maven-plugin - 3.0.0 + 3.2.0 UNKNOWN true @@ -317,7 +316,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.2 + 3.3.1 com.puppycrawl.tools @@ -348,7 +347,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.3.1 + 3.6.3 javadocs @@ -358,7 +357,7 @@ - 11 + 17 src/main/javadoc/stylesheet.css public true @@ -370,7 +369,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.2.0 + 3.3.0 diff --git a/para-core/src/main/java/com/erudika/para/core/Address.java b/para-core/src/main/java/com/erudika/para/core/Address.java index db7eb443..e921e943 100644 --- a/para-core/src/main/java/com/erudika/para/core/Address.java +++ b/para-core/src/main/java/com/erudika/para/core/Address.java @@ -17,17 +17,17 @@ */ package com.erudika.para.core; -import com.erudika.para.core.utils.CoreUtils; -import com.erudika.para.core.utils.ParaObjectUtils; import com.erudika.para.core.annotations.Locked; import com.erudika.para.core.annotations.Stored; +import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.utils.Pager; import com.erudika.para.core.utils.Para; +import com.erudika.para.core.utils.ParaObjectUtils; import com.erudika.para.core.utils.Utils; import java.util.List; import java.util.Objects; -import javax.validation.constraints.Size; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; /** * This class represents an address. It enables location based search queries. diff --git a/para-core/src/main/java/com/erudika/para/core/App.java b/para-core/src/main/java/com/erudika/para/core/App.java index 610d9fd6..814c3b7e 100644 --- a/para-core/src/main/java/com/erudika/para/core/App.java +++ b/para-core/src/main/java/com/erudika/para/core/App.java @@ -55,7 +55,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.apache.commons.collections.bidimap.DualHashBidiMap; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; diff --git a/para-core/src/main/java/com/erudika/para/core/Linker.java b/para-core/src/main/java/com/erudika/para/core/Linker.java index 78ae1a9e..c494d825 100644 --- a/para-core/src/main/java/com/erudika/para/core/Linker.java +++ b/para-core/src/main/java/com/erudika/para/core/Linker.java @@ -29,7 +29,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * This class represents a many-to-many relationship (link) between two objects. diff --git a/para-core/src/main/java/com/erudika/para/core/ParaObject.java b/para-core/src/main/java/com/erudika/para/core/ParaObject.java index 666e4e09..c8cce3a5 100644 --- a/para-core/src/main/java/com/erudika/para/core/ParaObject.java +++ b/para-core/src/main/java/com/erudika/para/core/ParaObject.java @@ -19,8 +19,8 @@ import java.io.Serializable; import java.util.List; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; /** * The core domain interface. All Para objects implement it. diff --git a/para-core/src/main/java/com/erudika/para/core/Tag.java b/para-core/src/main/java/com/erudika/para/core/Tag.java index 9c9603c1..c0c4cae0 100644 --- a/para-core/src/main/java/com/erudika/para/core/Tag.java +++ b/para-core/src/main/java/com/erudika/para/core/Tag.java @@ -24,8 +24,8 @@ import com.erudika.para.core.utils.Para; import com.erudika.para.core.utils.ParaObjectUtils; import com.erudika.para.core.utils.Utils; +import jakarta.validation.constraints.NotBlank; import java.util.List; -import javax.validation.constraints.NotBlank; import org.apache.commons.lang3.StringUtils; /** @@ -117,7 +117,10 @@ public String getTag() { * @param tag a tag. Must not be null or empty. */ public void setTag(String tag) { - this.tag = Utils.noSpaces(StringUtils.trimToEmpty(tag).toLowerCase().replaceAll("[^\\p{L}\\p{N}\\+\\#\\-\\.]+", " ").replaceAll("\\p{Z}+", " "), "-"); + this.tag = Utils.noSpaces(StringUtils.trimToEmpty(tag).toLowerCase(). + replaceAll("^[\\p{S}|\\p{P}|\\p{C}|\\-|\\+|\\p{Z}]*", ""). + replaceAll("[^\\p{L}\\p{N}\\+\\#\\-\\.]+", " "). + replaceAll("\\p{Z}+", " "), "-"); } /** diff --git a/para-core/src/main/java/com/erudika/para/core/Translation.java b/para-core/src/main/java/com/erudika/para/core/Translation.java index ecce93a5..4b9fe3b3 100644 --- a/para-core/src/main/java/com/erudika/para/core/Translation.java +++ b/para-core/src/main/java/com/erudika/para/core/Translation.java @@ -26,7 +26,7 @@ import com.erudika.para.core.utils.Utils; import java.util.List; import java.util.Objects; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * A translation is a key/value pair which holds a single translated string. diff --git a/para-core/src/main/java/com/erudika/para/core/User.java b/para-core/src/main/java/com/erudika/para/core/User.java index a738fabc..74b6cd12 100644 --- a/para-core/src/main/java/com/erudika/para/core/User.java +++ b/para-core/src/main/java/com/erudika/para/core/User.java @@ -34,7 +34,7 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; import javax.naming.LimitExceededException; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/Vote.java b/para-core/src/main/java/com/erudika/para/core/Vote.java index 81ff6c95..a4018ca5 100644 --- a/para-core/src/main/java/com/erudika/para/core/Vote.java +++ b/para-core/src/main/java/com/erudika/para/core/Vote.java @@ -29,9 +29,9 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.apache.commons.lang3.StringUtils; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; /** * When a user votes on an object the vote is saved as positive or negative. diff --git a/para-core/src/main/java/com/erudika/para/core/Webhook.java b/para-core/src/main/java/com/erudika/para/core/Webhook.java index 98adcaca..382efd01 100644 --- a/para-core/src/main/java/com/erudika/para/core/Webhook.java +++ b/para-core/src/main/java/com/erudika/para/core/Webhook.java @@ -28,7 +28,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.apache.commons.lang3.StringUtils; import org.hibernate.validator.constraints.URL; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/annotations/Email.java b/para-core/src/main/java/com/erudika/para/core/annotations/Email.java index c8622546..141155f2 100644 --- a/para-core/src/main/java/com/erudika/para/core/annotations/Email.java +++ b/para-core/src/main/java/com/erudika/para/core/annotations/Email.java @@ -23,16 +23,16 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; -import javax.validation.constraints.Pattern; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import jakarta.validation.constraints.Pattern; /** * Annotation for email validation. * * @author Alex Bogdanovski [alex@erudika.com] */ -@javax.validation.constraints.Email(message = "Please provide a valid email address") +@jakarta.validation.constraints.Email(message = "Please provide a valid email address") @Pattern(regexp = EMAIL_PATTERN, message = "Please provide a valid email address") @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) diff --git a/para-core/src/main/java/com/erudika/para/core/cache/MockCache.java b/para-core/src/main/java/com/erudika/para/core/cache/MockCache.java index 23695852..cf0bdd14 100644 --- a/para-core/src/main/java/com/erudika/para/core/cache/MockCache.java +++ b/para-core/src/main/java/com/erudika/para/core/cache/MockCache.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.LinkedHashMap; import java.util.concurrent.ConcurrentHashMap; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/listeners/WebhookIOListener.java b/para-core/src/main/java/com/erudika/para/core/listeners/WebhookIOListener.java index 097c7b96..1609d507 100644 --- a/para-core/src/main/java/com/erudika/para/core/listeners/WebhookIOListener.java +++ b/para-core/src/main/java/com/erudika/para/core/listeners/WebhookIOListener.java @@ -24,7 +24,7 @@ import com.erudika.para.core.utils.Utils; import java.lang.reflect.Method; import java.util.List; -import javax.inject.Singleton; +import jakarta.inject.Singleton; /** * Listens for IO events and forwards them to the registered webhooks, via a queue. diff --git a/para-core/src/main/java/com/erudika/para/core/persistence/MockDAO.java b/para-core/src/main/java/com/erudika/para/core/persistence/MockDAO.java index cdfdf4e0..25611208 100644 --- a/para-core/src/main/java/com/erudika/para/core/persistence/MockDAO.java +++ b/para-core/src/main/java/com/erudika/para/core/persistence/MockDAO.java @@ -30,7 +30,7 @@ import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/queue/MockQueue.java b/para-core/src/main/java/com/erudika/para/core/queue/MockQueue.java index 0a6ffd3b..f428f5f3 100644 --- a/para-core/src/main/java/com/erudika/para/core/queue/MockQueue.java +++ b/para-core/src/main/java/com/erudika/para/core/queue/MockQueue.java @@ -18,7 +18,7 @@ package com.erudika.para.core.queue; import java.util.concurrent.ConcurrentLinkedQueue; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/rest/CustomResourceHandler.java b/para-core/src/main/java/com/erudika/para/core/rest/CustomResourceHandler.java index c723f15c..73b3d49b 100644 --- a/para-core/src/main/java/com/erudika/para/core/rest/CustomResourceHandler.java +++ b/para-core/src/main/java/com/erudika/para/core/rest/CustomResourceHandler.java @@ -18,8 +18,8 @@ package com.erudika.para.core.rest; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.core.Response; /** * A custom API resource handler. Handles custom resources. diff --git a/para-core/src/main/java/com/erudika/para/core/rest/GenericExceptionMapper.java b/para-core/src/main/java/com/erudika/para/core/rest/GenericExceptionMapper.java index fd1a299b..3d5efe47 100644 --- a/para-core/src/main/java/com/erudika/para/core/rest/GenericExceptionMapper.java +++ b/para-core/src/main/java/com/erudika/para/core/rest/GenericExceptionMapper.java @@ -18,12 +18,12 @@ package com.erudika.para.core.rest; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.ext.ExceptionMapper; +import jakarta.ws.rs.ext.Provider; import java.util.LinkedHashMap; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.ExceptionMapper; -import javax.ws.rs.ext.Provider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/rest/Signer.java b/para-core/src/main/java/com/erudika/para/core/rest/Signer.java index d2d68978..1d910dc4 100644 --- a/para-core/src/main/java/com/erudika/para/core/rest/Signer.java +++ b/para-core/src/main/java/com/erudika/para/core/rest/Signer.java @@ -18,6 +18,7 @@ package com.erudika.para.core.rest; import com.erudika.para.core.utils.Config; +import jakarta.ws.rs.core.MultivaluedMap; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.time.Clock; @@ -32,7 +33,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import javax.ws.rs.core.MultivaluedMap; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/search/MockSearch.java b/para-core/src/main/java/com/erudika/para/core/search/MockSearch.java index 6822736f..20325b7c 100644 --- a/para-core/src/main/java/com/erudika/para/core/search/MockSearch.java +++ b/para-core/src/main/java/com/erudika/para/core/search/MockSearch.java @@ -23,7 +23,7 @@ import com.erudika.para.core.utils.Pager; import java.util.List; import java.util.Map; -import javax.inject.Singleton; +import jakarta.inject.Singleton; /** * diff --git a/para-core/src/main/java/com/erudika/para/core/utils/CoreUtils.java b/para-core/src/main/java/com/erudika/para/core/utils/CoreUtils.java index 30a0b8e0..a3800c5e 100644 --- a/para-core/src/main/java/com/erudika/para/core/utils/CoreUtils.java +++ b/para-core/src/main/java/com/erudika/para/core/utils/CoreUtils.java @@ -43,7 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.inject.Inject; +import jakarta.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-core/src/main/java/com/erudika/para/core/utils/Utils.java b/para-core/src/main/java/com/erudika/para/core/utils/Utils.java index 103f7e9e..96e89598 100644 --- a/para-core/src/main/java/com/erudika/para/core/utils/Utils.java +++ b/para-core/src/main/java/com/erudika/para/core/utils/Utils.java @@ -68,7 +68,7 @@ import java.util.regex.Pattern; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.LocaleUtils; import org.apache.commons.lang3.StringUtils; diff --git a/para-core/src/main/java/com/erudika/para/core/validation/Constraint.java b/para-core/src/main/java/com/erudika/para/core/validation/Constraint.java index d3882eb8..db1e453a 100644 --- a/para-core/src/main/java/com/erudika/para/core/validation/Constraint.java +++ b/para-core/src/main/java/com/erudika/para/core/validation/Constraint.java @@ -26,21 +26,21 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import javax.validation.constraints.AssertFalse; -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.Digits; -import javax.validation.constraints.Future; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Past; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.AssertFalse; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Past; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import org.hibernate.validator.constraints.URL; /** diff --git a/para-core/src/main/java/com/erudika/para/core/validation/ValidationUtils.java b/para-core/src/main/java/com/erudika/para/core/validation/ValidationUtils.java index 9cbeed13..3ff4458c 100644 --- a/para-core/src/main/java/com/erudika/para/core/validation/ValidationUtils.java +++ b/para-core/src/main/java/com/erudika/para/core/validation/ValidationUtils.java @@ -47,18 +47,18 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.constraints.AssertFalse; -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.Digits; -import javax.validation.constraints.Future; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.Past; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.constraints.AssertFalse; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Past; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; diff --git a/para-jar/pom.xml b/para-jar/pom.xml index 355ca984..74e79323 100644 --- a/para-jar/pom.xml +++ b/para-jar/pom.xml @@ -17,6 +17,11 @@ para-server ${project.version} + + jakarta.inject + jakarta.inject-api + 2.0.1 + @@ -65,7 +70,7 @@ - 11 + 17 ../para-core/src/main/javadoc/stylesheet.css false public diff --git a/para-server/pom.xml b/para-server/pom.xml index 840e35a8..7922f09a 100644 --- a/para-server/pom.xml +++ b/para-server/pom.xml @@ -12,8 +12,8 @@ para-server - 5.8.11 - 2.4.1 + 6.2.2 + 3.2.2 @@ -104,12 +104,6 @@ org.springframework.boot spring-boot-starter-jetty ${springBootVer} - - - org.eclipse.jetty.websocket - * - - org.springframework.boot @@ -142,8 +136,22 @@ com.fasterxml.woodstox woodstox-core - 6.5.1 + 6.6.1 + + + org.apache.felix + org.apache.felix.http.wrappers + 1.1.2 + compile + + + javax.servlet + javax.servlet-api + 4.0.1 + compile + + @@ -206,7 +214,7 @@ com.google.inject guice - 5.1.0 + 7.0.0 @@ -242,10 +250,10 @@ 2.2 - javax.servlet - javax.servlet-api - 4.0.1 - + jakarta.servlet + jakarta.servlet-api + 6.0.0 + provided org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-inmemory @@ -327,18 +335,6 @@ - - com.vmlens - concurrent-junit - 1.0.2 - test - - - org.apache.commons - commons-lang3 - - - + com.jcabi jcabi-dynamodb-maven-plugin @@ -397,7 +401,7 @@ maven-dependency-plugin - 3.1.2 + 3.6.1 unpack-dynamodb-local @@ -425,7 +429,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.2 + 3.3.1 com.puppycrawl.tools @@ -455,7 +459,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.3.1 + 3.6.3 javadocs @@ -465,7 +469,7 @@ - 11 + 17 ../para-core/src/main/javadoc/stylesheet.css public true @@ -477,7 +481,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.2.0 + 3.3.0 diff --git a/para-server/src/main/java/com/erudika/para/server/ParaServer.java b/para-server/src/main/java/com/erudika/para/server/ParaServer.java index 6401ad39..3c965be8 100644 --- a/para-server/src/main/java/com/erudika/para/server/ParaServer.java +++ b/para-server/src/main/java/com/erudika/para/server/ParaServer.java @@ -41,6 +41,7 @@ import com.google.inject.Module; import com.google.inject.Stage; import com.google.inject.util.Modules; +import jakarta.annotation.PreDestroy; import java.io.File; import java.time.Duration; import java.util.ArrayList; @@ -52,7 +53,6 @@ import java.util.Map; import java.util.ServiceLoader; import java.util.concurrent.TimeUnit; -import javax.annotation.PreDestroy; import org.apache.commons.lang3.StringUtils; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; @@ -311,14 +311,16 @@ public ServletWebServerFactory jettyConfigBean() { if (Para.getConfig().inProduction()) { ForwardedRequestCustomizer frc = new ForwardedRequestCustomizer() { public void customize(Connector connector, HttpConfiguration config, Request request) { - super.customize(connector, config, request); - String cfProto = request.getHeader("CloudFront-Forwarded-Proto"); + //super.customize(connector, config, request); + String cfProto = request.getHeaders().get("CloudFront-Forwarded-Proto"); if (StringUtils.isBlank(cfProto)) { - cfProto = request.getHeader("X-Forwarded-Proto"); + cfProto = request.getHeaders().get("X-Forwarded-Proto"); } if (StringUtils.equalsIgnoreCase(cfProto, config.getSecureScheme())) { - request.setScheme(cfProto); - request.setSecure(true); + setForwardedProtoHeader(cfProto); + setSslIsSecure(true); + //request.setScheme(cfProto); + //request.setSecure(true); } } }; diff --git a/para-server/src/main/java/com/erudika/para/server/aop/IndexAndCacheAspect.java b/para-server/src/main/java/com/erudika/para/server/aop/IndexAndCacheAspect.java index 0d29c3af..0cb6ddce 100644 --- a/para-server/src/main/java/com/erudika/para/server/aop/IndexAndCacheAspect.java +++ b/para-server/src/main/java/com/erudika/para/server/aop/IndexAndCacheAspect.java @@ -38,7 +38,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import javax.inject.Inject; +import jakarta.inject.Inject; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.slf4j.Logger; diff --git a/para-server/src/main/java/com/erudika/para/server/cache/CaffeineCache.java b/para-server/src/main/java/com/erudika/para/server/cache/CaffeineCache.java index d4115975..4628c150 100644 --- a/para-server/src/main/java/com/erudika/para/server/cache/CaffeineCache.java +++ b/para-server/src/main/java/com/erudika/para/server/cache/CaffeineCache.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/email/AWSEmailer.java b/para-server/src/main/java/com/erudika/para/server/email/AWSEmailer.java index 54cf973d..aca74ad0 100644 --- a/para-server/src/main/java/com/erudika/para/server/email/AWSEmailer.java +++ b/para-server/src/main/java/com/erudika/para/server/email/AWSEmailer.java @@ -19,21 +19,21 @@ import com.erudika.para.core.email.Emailer; import com.erudika.para.core.utils.Para; +import jakarta.activation.DataHandler; +import jakarta.inject.Singleton; +import jakarta.mail.Session; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.InternetHeaders; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMessage.RecipientType; +import jakarta.mail.internet.MimeMultipart; +import jakarta.mail.util.ByteArrayDataSource; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.Iterator; import java.util.List; import java.util.Properties; -import javax.activation.DataHandler; -import javax.inject.Singleton; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.InternetHeaders; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMessage.RecipientType; -import javax.mail.internet.MimeMultipart; -import javax.mail.util.ByteArrayDataSource; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/email/JavaMailEmailer.java b/para-server/src/main/java/com/erudika/para/server/email/JavaMailEmailer.java index 5bdb3ba5..cb467437 100644 --- a/para-server/src/main/java/com/erudika/para/server/email/JavaMailEmailer.java +++ b/para-server/src/main/java/com/erudika/para/server/email/JavaMailEmailer.java @@ -26,8 +26,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; -import javax.mail.internet.MimeMessage; -import javax.mail.util.ByteArrayDataSource; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.util.ByteArrayDataSource; import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/persistence/AWSDynamoDAO.java b/para-server/src/main/java/com/erudika/para/server/persistence/AWSDynamoDAO.java index 957bd209..af7fbb6b 100644 --- a/para-server/src/main/java/com/erudika/para/server/persistence/AWSDynamoDAO.java +++ b/para-server/src/main/java/com/erudika/para/server/persistence/AWSDynamoDAO.java @@ -48,7 +48,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/queue/AWSQueue.java b/para-server/src/main/java/com/erudika/para/server/queue/AWSQueue.java index f69a7874..51e8f1a0 100644 --- a/para-server/src/main/java/com/erudika/para/server/queue/AWSQueue.java +++ b/para-server/src/main/java/com/erudika/para/server/queue/AWSQueue.java @@ -21,7 +21,7 @@ import com.erudika.para.core.utils.Para; import java.util.Collections; import java.util.List; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; /** diff --git a/para-server/src/main/java/com/erudika/para/server/queue/LocalQueue.java b/para-server/src/main/java/com/erudika/para/server/queue/LocalQueue.java index 803e1cfe..b317fd41 100644 --- a/para-server/src/main/java/com/erudika/para/server/queue/LocalQueue.java +++ b/para-server/src/main/java/com/erudika/para/server/queue/LocalQueue.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Future; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/queue/River.java b/para-server/src/main/java/com/erudika/para/server/queue/River.java index f739e4df..6680354e 100644 --- a/para-server/src/main/java/com/erudika/para/server/queue/River.java +++ b/para-server/src/main/java/com/erudika/para/server/queue/River.java @@ -28,6 +28,7 @@ import com.erudika.para.core.utils.Utils; import com.erudika.para.server.utils.HealthUtils; import com.fasterxml.jackson.databind.ObjectReader; +import jakarta.ws.rs.core.HttpHeaders; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; @@ -39,7 +40,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.IntStream; -import javax.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.hc.client5.http.classic.methods.HttpPost; @@ -213,11 +213,13 @@ protected int processWebhookPayload(String appid, String id, Map return "OK"; }); } catch (Exception e) { + updateFailureCount(appid, id); logger.info("Webhook {} not delivered! {} isn't responding. {}", id, targetUrl, status); } }); return 1; } catch (Exception e) { + updateFailureCount(appid, id); logger.error("Webhook payload was not delivered:", e); } return 0; diff --git a/para-server/src/main/java/com/erudika/para/server/rest/Api1.java b/para-server/src/main/java/com/erudika/para/server/rest/Api1.java index fcd05bc5..d4c684d9 100644 --- a/para-server/src/main/java/com/erudika/para/server/rest/Api1.java +++ b/para-server/src/main/java/com/erudika/para/server/rest/Api1.java @@ -63,8 +63,16 @@ import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.json.JsonMapper; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import com.nimbusds.jwt.SignedJWT; +import jakarta.ws.rs.HttpMethod; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.StreamingOutput; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; @@ -85,14 +93,6 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; -import javax.ws.rs.HttpMethod; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.glassfish.jersey.process.Inflector; @@ -354,7 +354,7 @@ private Inflector introHandler() { return new Inflector() { public Response apply(ContainerRequestContext ctx) { Map info = new TreeMap<>(); - info.put("info", "Para - the backend for busy developers."); + info.put("info", "Para - the backend for busy developers.!"); if (Para.getConfig().versionBannerEnabled()) { info.put("version", StringUtils.replace(getVersion(), "-SNAPSHOT", "")); } @@ -634,7 +634,7 @@ public static Inflector checkPermitHandler(fi public Response apply(ContainerRequestContext ctx) { App app = (a != null) ? a : getPrincipalApp(); String subjectid = pathParam("subjectid", ctx); - String resourcePath = pathParam(Config._TYPE, ctx); + String resourcePath = Utils.base64dec(pathParam(Config._TYPE, ctx)); String httpMethod = pathParam("method", ctx); if (app != null) { return Response.ok(app.isAllowedTo(subjectid, resourcePath, httpMethod), @@ -655,7 +655,7 @@ public static Inflector grantPermitHandler(fi public Response apply(ContainerRequestContext ctx) { App app = (a != null) ? a : getPrincipalApp(); String subjectid = pathParam("subjectid", ctx); - String resourcePath = pathParam(Config._TYPE, ctx); + String resourcePath = Utils.base64dec(pathParam(Config._TYPE, ctx)); if (app != null) { Response resp = getEntity(ctx.getEntityStream(), List.class); if (resp.getStatusInfo() == Response.Status.OK) { @@ -695,11 +695,11 @@ public static Inflector revokePermitHandler(f public Response apply(ContainerRequestContext ctx) { App app = (a != null) ? a : getPrincipalApp(); String subjectid = pathParam("subjectid", ctx); - String type = pathParam(Config._TYPE, ctx); + String resourcePath = Utils.base64dec(pathParam(Config._TYPE, ctx)); if (app != null) { boolean revoked; - if (type != null) { - revoked = app.revokeResourcePermission(subjectid, type); + if (!StringUtils.isBlank(resourcePath)) { + revoked = app.revokeResourcePermission(subjectid, resourcePath); } else { revoked = app.revokeAllResourcePermissions(subjectid); } diff --git a/para-server/src/main/java/com/erudika/para/server/rest/RestUtils.java b/para-server/src/main/java/com/erudika/para/server/rest/RestUtils.java index 4cd7760a..202ef99f 100644 --- a/para-server/src/main/java/com/erudika/para/server/rest/RestUtils.java +++ b/para-server/src/main/java/com/erudika/para/server/rest/RestUtils.java @@ -39,6 +39,14 @@ import static com.erudika.para.server.security.SecurityUtils.isNotAnApp; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.core.Response; import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -52,14 +60,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; diff --git a/para-server/src/main/java/com/erudika/para/server/security/AjaxRequestMatcher.java b/para-server/src/main/java/com/erudika/para/server/security/AjaxRequestMatcher.java index 4830bcc0..37a6a686 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/AjaxRequestMatcher.java +++ b/para-server/src/main/java/com/erudika/para/server/security/AjaxRequestMatcher.java @@ -19,8 +19,8 @@ import com.erudika.para.server.utils.HttpUtils; import com.erudika.para.core.utils.Utils; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.ws.rs.core.HttpHeaders; import org.springframework.security.web.util.matcher.RequestMatcher; /** diff --git a/para-server/src/main/java/com/erudika/para/server/security/CachedCsrfTokenRepository.java b/para-server/src/main/java/com/erudika/para/server/security/CachedCsrfTokenRepository.java index c9f09718..9a7986a0 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/CachedCsrfTokenRepository.java +++ b/para-server/src/main/java/com/erudika/para/server/security/CachedCsrfTokenRepository.java @@ -23,10 +23,10 @@ import com.erudika.para.server.utils.HttpUtils; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.inject.Inject; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.inject.Inject; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/security/CsrfProtectionRequestMatcher.java b/para-server/src/main/java/com/erudika/para/server/security/CsrfProtectionRequestMatcher.java index f76e2f08..4fdd9c59 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/CsrfProtectionRequestMatcher.java +++ b/para-server/src/main/java/com/erudika/para/server/security/CsrfProtectionRequestMatcher.java @@ -18,7 +18,7 @@ package com.erudika.para.server.security; import java.util.regex.Pattern; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.web.util.matcher.RegexRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; diff --git a/para-server/src/main/java/com/erudika/para/server/security/IgnoredRequestMatcher.java b/para-server/src/main/java/com/erudika/para/server/security/IgnoredRequestMatcher.java index c0a27f43..c97b3bda 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/IgnoredRequestMatcher.java +++ b/para-server/src/main/java/com/erudika/para/server/security/IgnoredRequestMatcher.java @@ -20,9 +20,9 @@ import com.erudika.para.core.utils.Para; import com.typesafe.config.ConfigList; import com.typesafe.config.ConfigValue; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; -import javax.servlet.http.HttpServletRequest; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; diff --git a/para-server/src/main/java/com/erudika/para/server/security/JWTRestfulAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/JWTRestfulAuthFilter.java index 02c5d34d..d5cf3873 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/JWTRestfulAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/JWTRestfulAuthFilter.java @@ -38,20 +38,20 @@ import com.erudika.para.server.security.filters.SlackAuthFilter; import com.erudika.para.server.security.filters.TwitterAuthFilter; import com.nimbusds.jwt.SignedJWT; +import jakarta.inject.Inject; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.HttpMethod; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; import java.io.IOException; import java.text.ParseException; import java.util.HashMap; import java.util.Map; -import javax.inject.Inject; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.HttpMethod; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/security/RestAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/RestAuthFilter.java index 15ad7b6c..5f4366a8 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/RestAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/RestAuthFilter.java @@ -24,19 +24,19 @@ import com.erudika.para.core.utils.Utils; import com.erudika.para.server.rest.RestUtils; import com.erudika.para.server.utils.BufferedRequestWrapper; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import static jakarta.ws.rs.HttpMethod.DELETE; +import static jakarta.ws.rs.HttpMethod.GET; +import static jakarta.ws.rs.HttpMethod.PATCH; +import static jakarta.ws.rs.HttpMethod.POST; +import static jakarta.ws.rs.HttpMethod.PUT; import java.io.IOException; import java.util.Date; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import static javax.ws.rs.HttpMethod.DELETE; -import static javax.ws.rs.HttpMethod.GET; -import static javax.ws.rs.HttpMethod.PATCH; -import static javax.ws.rs.HttpMethod.POST; -import static javax.ws.rs.HttpMethod.PUT; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/security/RestRequestMatcher.java b/para-server/src/main/java/com/erudika/para/server/security/RestRequestMatcher.java index f5f75e0b..6c56f929 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/RestRequestMatcher.java +++ b/para-server/src/main/java/com/erudika/para/server/security/RestRequestMatcher.java @@ -17,7 +17,7 @@ */ package com.erudika.para.server.security; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.web.util.matcher.RegexRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; diff --git a/para-server/src/main/java/com/erudika/para/server/security/SecurityConfig.java b/para-server/src/main/java/com/erudika/para/server/security/SecurityConfig.java index 9e2b617d..3c7ebd45 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SecurityConfig.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SecurityConfig.java @@ -22,9 +22,9 @@ import com.typesafe.config.ConfigList; import com.typesafe.config.ConfigObject; import com.typesafe.config.ConfigValue; +import jakarta.annotation.security.DeclareRoles; import java.util.HashSet; import java.util.LinkedList; -import javax.annotation.security.DeclareRoles; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; @@ -88,32 +88,33 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { String signoutSuccessPath = Para.getConfig().signoutSuccessPath(); ConfigObject protectedResources = Para.getConfig().protectedPaths(); - http.authorizeHttpRequests().requestMatchers(IgnoredRequestMatcher.INSTANCE).permitAll(); - http.authorizeHttpRequests().requestMatchers(RestRequestMatcher.INSTANCE).authenticated(); + http.authorizeHttpRequests((authorize) -> authorize.requestMatchers("/**").permitAll()); + http.authorizeHttpRequests((authorize) -> authorize.requestMatchers(IgnoredRequestMatcher.INSTANCE).permitAll()); + http.authorizeHttpRequests((authorize) -> authorize.requestMatchers(RestRequestMatcher.INSTANCE).authenticated()); parseProtectedResources(http, protectedResources); if (Para.getConfig().csrfProtectionEnabled()) { - http.csrf().requireCsrfProtectionMatcher(CsrfProtectionRequestMatcher.INSTANCE). - csrfTokenRepository(csrfTokenRepository); + http.csrf((csrf) -> csrf.requireCsrfProtectionMatcher(CsrfProtectionRequestMatcher.INSTANCE). + csrfTokenRepository(csrfTokenRepository)); } else { - http.csrf().disable(); + http.csrf((csrf) -> csrf.disable()); } - http.sessionManagement().enableSessionUrlRewriting(false); - http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER); - http.sessionManagement().sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy()); - http.exceptionHandling().authenticationEntryPoint(new SimpleAuthenticationEntryPoint(signinPath)); - http.exceptionHandling().accessDeniedHandler(new SimpleAccessDeniedHandler(accessDeniedPath)); - http.requestCache().requestCache(new SimpleRequestCache()); - http.logout().deleteCookies(Para.getConfig().authCookieName()).invalidateHttpSession(true). - logoutUrl(signoutPath).logoutSuccessUrl(signoutSuccessPath); - http.rememberMe().disable(); + http.sessionManagement((session) -> session.enableSessionUrlRewriting(false)); + http.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.NEVER)); + http.sessionManagement((session) -> session.sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy())); + http.exceptionHandling((session) -> session.authenticationEntryPoint(new SimpleAuthenticationEntryPoint(signinPath))); + http.exceptionHandling((session) -> session.accessDeniedHandler(new SimpleAccessDeniedHandler(accessDeniedPath))); + http.requestCache((cache) -> cache.requestCache(new SimpleRequestCache())); + http.logout((logout) -> logout.deleteCookies(Para.getConfig().authCookieName()).invalidateHttpSession(true). + logoutUrl(signoutPath).logoutSuccessUrl(signoutSuccessPath)); + http.rememberMe((rme) -> rme.disable()); http.authenticationProvider(new JWTAuthenticationProvider()); http.authenticationProvider(new LDAPAuthenticationProvider()); - http.apply(new JwtConfigurer()); + http.with(new JwtConfigurer(), (c) -> { }); return http.build(); } @@ -133,7 +134,7 @@ private void parseProtectedResources(HttpSecurity http, ConfigObject protectedRe for (ConfigValue role : (ConfigList) configValue) { String r = ((String) role.unwrapped()).toUpperCase().trim(); // check if any HTTP methods appear here - HttpMethod m = HttpMethod.resolve(r); + HttpMethod m = HttpMethod.valueOf(r); if (m != null) { methods.add(m); } else { @@ -147,13 +148,13 @@ private void parseProtectedResources(HttpSecurity http, ConfigObject protectedRe logger.error("Invalid config syntax for protected resource: {}.", configValue.render(), e); } } - String[] rolz = (roles.isEmpty()) ? DEFAULT_ROLES : roles.toArray(new String[0]); - String[] patternz = patterns.toArray(new String[0]); + String[] rolz = (roles.isEmpty()) ? DEFAULT_ROLES : roles.toArray(String[]::new); + String[] patternz = patterns.toArray(String[]::new); if (methods.isEmpty()) { - http.authorizeHttpRequests().requestMatchers(patternz).hasAnyRole(rolz); + http.authorizeHttpRequests((authorize) -> authorize.requestMatchers(patternz).hasAnyRole(rolz)); } else { for (HttpMethod method : methods) { - http.authorizeHttpRequests().requestMatchers(method, patternz).hasAnyRole(rolz); + http.authorizeHttpRequests((authorize) -> authorize.requestMatchers(method, patternz).hasAnyRole(rolz)); } } } diff --git a/para-server/src/main/java/com/erudika/para/server/security/SecurityUtils.java b/para-server/src/main/java/com/erudika/para/server/security/SecurityUtils.java index 84fb6954..af56f83e 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SecurityUtils.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SecurityUtils.java @@ -52,9 +52,9 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; diff --git a/para-server/src/main/java/com/erudika/para/server/security/SimpleAccessDeniedHandler.java b/para-server/src/main/java/com/erudika/para/server/security/SimpleAccessDeniedHandler.java index f0ebbd40..728965bb 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SimpleAccessDeniedHandler.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SimpleAccessDeniedHandler.java @@ -18,10 +18,10 @@ package com.erudika.para.server.security; import com.erudika.para.server.rest.RestUtils; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandlerImpl; diff --git a/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationEntryPoint.java b/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationEntryPoint.java index 25036f79..cac9159f 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationEntryPoint.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationEntryPoint.java @@ -18,11 +18,11 @@ package com.erudika.para.server.security; import com.erudika.para.server.rest.RestUtils; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.HttpMethod; import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.HttpMethod; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; diff --git a/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationFailureHandler.java b/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationFailureHandler.java index 1962055a..e1834be7 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationFailureHandler.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationFailureHandler.java @@ -22,9 +22,9 @@ import com.erudika.para.server.rest.RestUtils; import java.io.IOException; import java.util.Set; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.DefaultRedirectStrategy; diff --git a/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationSuccessHandler.java b/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationSuccessHandler.java index f36af317..331d9f34 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationSuccessHandler.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SimpleAuthenticationSuccessHandler.java @@ -26,9 +26,9 @@ import com.nimbusds.jwt.SignedJWT; import java.io.IOException; import java.util.Set; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.security.core.Authentication; import org.springframework.security.web.DefaultRedirectStrategy; diff --git a/para-server/src/main/java/com/erudika/para/server/security/SimpleRequestCache.java b/para-server/src/main/java/com/erudika/para/server/security/SimpleRequestCache.java index 5490fccc..fd0307f9 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/SimpleRequestCache.java +++ b/para-server/src/main/java/com/erudika/para/server/security/SimpleRequestCache.java @@ -20,8 +20,8 @@ import com.erudika.para.core.utils.Para; import com.erudika.para.server.utils.HttpUtils; import com.erudika.para.core.utils.Utils; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.web.PortResolver; import org.springframework.security.web.PortResolverImpl; import org.springframework.security.web.savedrequest.DefaultSavedRequest; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/AmazonAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/AmazonAuthFilter.java index 848a279d..f13a4395 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/AmazonAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/AmazonAuthFilter.java @@ -31,9 +31,9 @@ import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/FacebookAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/FacebookAuthFilter.java index 5e73b874..bd48fbac 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/FacebookAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/FacebookAuthFilter.java @@ -31,8 +31,8 @@ import java.io.IOException; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.config.RequestConfig; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/GenericOAuth2Filter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/GenericOAuth2Filter.java index 50ccc92c..89be6fda 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/GenericOAuth2Filter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/GenericOAuth2Filter.java @@ -28,15 +28,15 @@ import com.erudika.para.server.security.UserAuthentication; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectReader; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import java.io.IOException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; @@ -481,7 +481,7 @@ private String getEmailFromProfile(Map profile, String emailPara JsonNode profileTree = ParaObjectUtils.getJsonMapper().valueToTree(profile); JsonNode nodeAtPath = profileTree.at(emailParam); if (!nodeAtPath.isMissingNode()) { - email = nodeAtPath.asText(email); + email = nodeAtPath.asText(); } } if (StringUtils.isBlank(email)) { @@ -505,7 +505,7 @@ private String getPictureFromProfile(Map profile, String picture JsonNode profileTree = ParaObjectUtils.getJsonMapper().valueToTree(profile); JsonNode nodeAtPath = profileTree.at(pictureParam); if (!nodeAtPath.isMissingNode()) { - pic = nodeAtPath.asText(pic); + pic = nodeAtPath.asText(); } } return pic; @@ -518,7 +518,7 @@ private String getNameFromProfile(Map profile, String nameParam) JsonNode profileTree = ParaObjectUtils.getJsonMapper().valueToTree(profile); JsonNode nodeAtPath = profileTree.at(nameParam); if (!nodeAtPath.isMissingNode()) { - name = nodeAtPath.asText(name); + name = nodeAtPath.asText(); } } return name; @@ -531,7 +531,7 @@ private String getGivenNameFromProfile(Map profile, String gnPar JsonNode profileTree = ParaObjectUtils.getJsonMapper().valueToTree(profile); JsonNode nodeAtPath = profileTree.at(gnParam); if (!nodeAtPath.isMissingNode()) { - gname = nodeAtPath.asText(gname); + gname = nodeAtPath.asText(); } } return gname; @@ -544,7 +544,7 @@ private String getFirstNameFromProfile(Map profile, String fnPar JsonNode profileTree = ParaObjectUtils.getJsonMapper().valueToTree(profile); JsonNode nodeAtPath = profileTree.at(fnParam); if (!nodeAtPath.isMissingNode()) { - fname = nodeAtPath.asText(fname); + fname = nodeAtPath.asText(); } } return fname; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/GitHubAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/GitHubAuthFilter.java index 293e4d1f..08a602b2 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/GitHubAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/GitHubAuthFilter.java @@ -32,9 +32,9 @@ import java.io.InputStream; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/GoogleAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/GoogleAuthFilter.java index 582499a6..aad08ef8 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/GoogleAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/GoogleAuthFilter.java @@ -30,9 +30,9 @@ import java.io.IOException; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/LdapAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/LdapAuthFilter.java index 3d308cd1..4fb2a5f0 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/LdapAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/LdapAuthFilter.java @@ -31,8 +31,8 @@ import java.util.Collections; import java.util.Optional; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/LinkedInAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/LinkedInAuthFilter.java index 83229a05..090f8f10 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/LinkedInAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/LinkedInAuthFilter.java @@ -32,9 +32,9 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/MicrosoftAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/MicrosoftAuthFilter.java index 29746040..a7881c32 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/MicrosoftAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/MicrosoftAuthFilter.java @@ -31,9 +31,9 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordAuthFilter.java index 7895b988..a2d14d36 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordAuthFilter.java @@ -23,11 +23,11 @@ import com.erudika.para.server.security.AuthenticatedUserDetails; import com.erudika.para.server.security.SecurityUtils; import com.erudika.para.server.security.UserAuthentication; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import javax.naming.LimitExceededException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.security.authentication.LockedException; import org.springframework.security.core.Authentication; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordlessAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordlessAuthFilter.java index 13a36d9c..c4f79f08 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordlessAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/PasswordlessAuthFilter.java @@ -28,9 +28,9 @@ import com.nimbusds.jwt.SignedJWT; import java.io.IOException; import java.text.ParseException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLAuthFilter.java index 34c1ccd7..25bea77e 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLAuthFilter.java @@ -50,6 +50,8 @@ import static com.onelogin.saml2.settings.SettingsBuilder.SP_X509CERT_PROPERTY_KEY; import static com.onelogin.saml2.settings.SettingsBuilder.STRICT_PROPERTY_KEY; import com.onelogin.saml2.util.Constants; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URL; import java.security.spec.InvalidKeySpecException; @@ -57,9 +59,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; +import org.apache.felix.http.javaxwrappers.HttpServletRequestWrapper; +import org.apache.felix.http.javaxwrappers.HttpServletResponseWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationServiceException; @@ -128,7 +130,7 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ Saml2Settings settings = builder.fromValues(samlSettings).build(); - Auth auth = new Auth(settings, request, response); + Auth auth = new Auth(settings, new HttpServletRequestWrapper(request), new HttpServletResponseWrapper(response)); samlSettingsLoaded = true; if (request.getParameter("SAMLResponse") != null) { diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLMetadataFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLMetadataFilter.java index cdff0467..9dfb25e4 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLMetadataFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/SAMLMetadataFilter.java @@ -25,15 +25,15 @@ import com.onelogin.saml2.settings.SettingsBuilder; import java.io.IOException; import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_OK; -import javax.ws.rs.core.MediaType; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_OK; +import jakarta.ws.rs.core.MediaType; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/SlackAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/SlackAuthFilter.java index d52b8c8e..d237aa70 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/SlackAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/SlackAuthFilter.java @@ -32,9 +32,9 @@ import java.util.Collections; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/security/filters/TwitterAuthFilter.java b/para-server/src/main/java/com/erudika/para/server/security/filters/TwitterAuthFilter.java index 33f398bf..dec40b9f 100644 --- a/para-server/src/main/java/com/erudika/para/server/security/filters/TwitterAuthFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/security/filters/TwitterAuthFilter.java @@ -33,9 +33,9 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/para-server/src/main/java/com/erudika/para/server/storage/AWSFileStore.java b/para-server/src/main/java/com/erudika/para/server/storage/AWSFileStore.java index 77408754..1b2afc52 100644 --- a/para-server/src/main/java/com/erudika/para/server/storage/AWSFileStore.java +++ b/para-server/src/main/java/com/erudika/para/server/storage/AWSFileStore.java @@ -24,7 +24,7 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; -import javax.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.HttpHeaders; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/utils/BufferedRequestWrapper.java b/para-server/src/main/java/com/erudika/para/server/utils/BufferedRequestWrapper.java index 9e905bbc..53117809 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/BufferedRequestWrapper.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/BufferedRequestWrapper.java @@ -17,13 +17,13 @@ */ package com.erudika.para.server.utils; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; import org.slf4j.LoggerFactory; /** diff --git a/para-server/src/main/java/com/erudika/para/server/utils/BufferedServletInputStream.java b/para-server/src/main/java/com/erudika/para/server/utils/BufferedServletInputStream.java index 3c052e3c..61bca576 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/BufferedServletInputStream.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/BufferedServletInputStream.java @@ -19,8 +19,8 @@ import java.io.ByteArrayInputStream; import java.io.IOException; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; /** * Servlet Input Stream. diff --git a/para-server/src/main/java/com/erudika/para/server/utils/GZipResponseUtil.java b/para-server/src/main/java/com/erudika/para/server/utils/GZipResponseUtil.java index c54248c9..d6283609 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/GZipResponseUtil.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/GZipResponseUtil.java @@ -17,12 +17,12 @@ */ package com.erudika.para.server.utils; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Collection; -import javax.servlet.ServletException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * A collection of response processing utilities, which are shared between 2 or more filters. @@ -69,9 +69,9 @@ public static boolean shouldGzippedBodyBeZero(byte[] compressedBytes, HttpServle /** * Performs a number of checks to ensure response saneness according to the rules of RFC2616: *
    - *
  1. If the response code is {@link javax.servlet.http.HttpServletResponse#SC_NO_CONTENT} then it is illegal for + *
  2. If the response code is {@link jakarta.servlet.http.HttpServletResponse#SC_NO_CONTENT} then it is illegal for * the body to contain anything. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5 - *
  3. If the response code is {@link javax.servlet.http.HttpServletResponse#SC_NOT_MODIFIED} then it is illegal for + *
  4. If the response code is {@link jakarta.servlet.http.HttpServletResponse#SC_NOT_MODIFIED} then it is illegal for * the body to contain anything. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 *
* @param request the client HTTP request @@ -106,7 +106,7 @@ public static boolean shouldBodyBeZero(HttpServletRequest request, int responseS * @param response the response which will have a header added to it. I.e this method changes its parameter * @throws ServletException Either the response is committed or we were called using the * include method from a - * {@link javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} + * {@link jakarta.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, jakarta.servlet.ServletResponse)} * method and the set header is ignored. */ public static void addGzipHeader(final HttpServletResponse response) throws ServletException { diff --git a/para-server/src/main/java/com/erudika/para/server/utils/GZipServletOutputStream.java b/para-server/src/main/java/com/erudika/para/server/utils/GZipServletOutputStream.java index f44d82d1..83a6bac5 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/GZipServletOutputStream.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/GZipServletOutputStream.java @@ -17,13 +17,13 @@ */ package com.erudika.para.server.utils; -import javax.servlet.ServletOutputStream; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; import java.io.IOException; import java.io.OutputStream; -import javax.servlet.WriteListener; /** - * A custom {@link javax.servlet.ServletOutputStream} for use by our filters. + * A custom {@link jakarta.servlet.ServletOutputStream} for use by our filters. * @version $Id: FilterServletOutputStream.java 744 2008-08-16 20:10:49Z gregluck $ * @author Greg Luck */ diff --git a/para-server/src/main/java/com/erudika/para/server/utils/GZipServletResponseWrapper.java b/para-server/src/main/java/com/erudika/para/server/utils/GZipServletResponseWrapper.java index fb4437cf..7157c2f0 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/GZipServletResponseWrapper.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/GZipServletResponseWrapper.java @@ -17,16 +17,16 @@ */ package com.erudika.para.server.utils; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.zip.GZIPOutputStream; /** - * Provides a wrapper for {@link javax.servlet.http.HttpServletResponseWrapper}. + * Provides a wrapper for {@link jakarta.servlet.http.HttpServletResponseWrapper}. * It is used to wrap the real Response so that we can modify it after * that the target of the request has delivered its response. * It uses the Wrapper pattern. diff --git a/para-server/src/main/java/com/erudika/para/server/utils/HttpUtils.java b/para-server/src/main/java/com/erudika/para/server/utils/HttpUtils.java index bc976249..bc76a2e2 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/HttpUtils.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/HttpUtils.java @@ -19,10 +19,11 @@ import com.erudika.para.core.utils.Para; import com.erudika.para.server.security.SecurityUtils; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.ws.rs.core.HttpHeaders; import java.util.TimeZone; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; @@ -184,6 +185,6 @@ public static void setAuthCookie(String name, String value, boolean httpOnly, in if (!StringUtils.isBlank(sameSite)) { sb.append("SameSite=").append(sameSite); } - response.addHeader(javax.ws.rs.core.HttpHeaders.SET_COOKIE, sb.toString()); + response.addHeader(HttpHeaders.SET_COOKIE, sb.toString()); } } diff --git a/para-server/src/main/java/com/erudika/para/server/utils/filters/CORSFilter.java b/para-server/src/main/java/com/erudika/para/server/utils/filters/CORSFilter.java index 07d344d1..5eec62ca 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/filters/CORSFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/filters/CORSFilter.java @@ -12,6 +12,14 @@ */ package com.erudika.para.server.utils.filters; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -21,15 +29,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; /** diff --git a/para-server/src/main/java/com/erudika/para/server/utils/filters/CachingHttpHeadersFilter.java b/para-server/src/main/java/com/erudika/para/server/utils/filters/CachingHttpHeadersFilter.java index 88571a95..cba27e90 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/filters/CachingHttpHeadersFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/filters/CachingHttpHeadersFilter.java @@ -17,15 +17,15 @@ */ package com.erudika.para.server.utils.filters; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.TimeUnit; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; /** * This filter is used in production, to put HTTP cache headers with a long (1 month) expiration time. diff --git a/para-server/src/main/java/com/erudika/para/server/utils/filters/ErrorFilter.java b/para-server/src/main/java/com/erudika/para/server/utils/filters/ErrorFilter.java index e906d586..4ae4d656 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/filters/ErrorFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/filters/ErrorFilter.java @@ -19,15 +19,15 @@ package com.erudika.para.server.utils.filters; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; diff --git a/para-server/src/main/java/com/erudika/para/server/utils/filters/FieldFilter.java b/para-server/src/main/java/com/erudika/para/server/utils/filters/FieldFilter.java index bd92865e..0423e5a6 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/filters/FieldFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/filters/FieldFilter.java @@ -27,12 +27,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerResponseContext; -import javax.ws.rs.container.ContainerResponseFilter; -import javax.ws.rs.core.Context; -import javax.ws.rs.ext.Provider; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerResponseContext; +import jakarta.ws.rs.container.ContainerResponseFilter; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.ext.Provider; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; diff --git a/para-server/src/main/java/com/erudika/para/server/utils/filters/GZipServletFilter.java b/para-server/src/main/java/com/erudika/para/server/utils/filters/GZipServletFilter.java index 24d8d9c2..787536bf 100644 --- a/para-server/src/main/java/com/erudika/para/server/utils/filters/GZipServletFilter.java +++ b/para-server/src/main/java/com/erudika/para/server/utils/filters/GZipServletFilter.java @@ -19,19 +19,19 @@ import com.erudika.para.server.utils.GZipResponseUtil; import com.erudika.para.server.utils.GZipServletResponseWrapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Provides GZIP compression of responses. diff --git a/para-server/src/main/resources/logback.xml b/para-server/src/main/resources/logback.xml index 93b317ae..9a8952c0 100644 --- a/para-server/src/main/resources/logback.xml +++ b/para-server/src/main/resources/logback.xml @@ -23,7 +23,7 @@ %-26(%d [%-5level]) %logger{35} - %msg%n - + ${para.file_logger_level:-INFO} diff --git a/para-server/src/test/java/com/erudika/para/client/ConcurrentParaClientIT.java b/para-server/src/test/java/com/erudika/para/client/ConcurrentParaClientIT.java index 4d406d01..70b72529 100644 --- a/para-server/src/test/java/com/erudika/para/client/ConcurrentParaClientIT.java +++ b/para-server/src/test/java/com/erudika/para/client/ConcurrentParaClientIT.java @@ -17,25 +17,27 @@ */ package com.erudika.para.client; -import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner; -import com.anarsoft.vmlens.concurrent.junit.ThreadCount; -import com.erudika.para.client.ParaClient; -import com.erudika.para.core.utils.Para; -import com.erudika.para.server.ParaServer; import com.erudika.para.core.App; import com.erudika.para.core.ParaObject; import com.erudika.para.core.Sysprop; +import com.erudika.para.core.utils.Para; +import com.erudika.para.server.ParaServer; import java.io.IOException; import java.util.ArrayList; +import java.util.Deque; import java.util.List; import java.util.Map; -import org.junit.After; -import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +45,6 @@ * * @author Alex Bogdanovski [alex@erudika.com] */ -@RunWith(ConcurrentTestRunner.class) public class ConcurrentParaClientIT { private static final Logger logger = LoggerFactory.getLogger(ConcurrentParaClientIT.class); @@ -55,13 +56,13 @@ public class ConcurrentParaClientIT { private static final int TOTAL = TOTAL_THREADS * BATCH_SIZE; private static ParaClient pc; - @BeforeClass + @BeforeAll public static void setUpClass() throws InterruptedException, IOException { System.setProperty("para.env", "embedded"); System.setProperty("para.print_logo", "false"); System.setProperty("para.app_name", ROOT_APP_NAME); System.setProperty("para.search", "LuceneSearch"); - System.setProperty("server.port", "8181"); + System.setProperty("para.port", "8181"); String endpoint = "http://localhost:8181"; ParaServer.main(new String[0]); @@ -83,28 +84,34 @@ public static void setUpClass() throws InterruptedException, IOException { } @Test - @ThreadCount(TOTAL_THREADS) public void testBatchWrite() throws InterruptedException { - ArrayList cats = new ArrayList(); - for (int i = 0; i < BATCH_SIZE; i++) { - Sysprop s = new Sysprop(); - s.setType(catsType); - s.addProperty("createTime", System.currentTimeMillis()); - cats.add(s); + ExecutorService executorService = Executors.newFixedThreadPool(TOTAL_THREADS); + List> futures = new ArrayList<>(); + for (int j = 0; j < TOTAL_THREADS; j++) { + futures.add(CompletableFuture.runAsync(() -> { + Deque cats = new ConcurrentLinkedDeque(); + for (int i = 0; i < BATCH_SIZE; i++) { + Sysprop s = new Sysprop(); + s.setType(catsType); + s.addProperty("createTime", System.currentTimeMillis()); + cats.add(s); + } + List created = pc.createAll(cats.stream().collect(Collectors.toList())); + logger.info("Created {} objects from thread {}.", created.size(), Thread.currentThread().getName()); + }, executorService)); } - - List created = pc.createAll(cats); - logger.info("Created {} objects from thread {}.", created.size(), Thread.currentThread().getId()); + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + executorService.shutdown(); } - @After + @AfterEach public void tearDown() { int total = pc.getCount(catsType).intValue(); assertEquals(TOTAL, total); logger.info("Total concurrently created objects: {}", total); } - @AfterClass + @AfterAll public static void tearDownClass() throws InterruptedException { System.setProperty("server.port", "8080"); new App(TEST_APP_NAME).delete(); diff --git a/para-server/src/test/java/com/erudika/para/client/ParaClientIT.java b/para-server/src/test/java/com/erudika/para/client/ParaClientIT.java deleted file mode 100644 index a9899aeb..00000000 --- a/para-server/src/test/java/com/erudika/para/client/ParaClientIT.java +++ /dev/null @@ -1,1094 +0,0 @@ -/* - * Copyright 2013-2022 Erudika. https://erudika.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For issues and patches go to: https://github.com/erudika - */ -package com.erudika.para.client; - -import com.erudika.para.core.Address; -import com.erudika.para.core.App; -import com.erudika.para.core.App.AllowedMethods; -import static com.erudika.para.core.App.AllowedMethods.GET; -import static com.erudika.para.core.App.AllowedMethods.OWN; -import static com.erudika.para.core.App.AllowedMethods.PATCH; -import static com.erudika.para.core.App.AllowedMethods.POST; -import static com.erudika.para.core.App.AllowedMethods.PUT; -import static com.erudika.para.core.App.AllowedMethods.READ; -import static com.erudika.para.core.App.AllowedMethods.READ_AND_WRITE; -import static com.erudika.para.core.App.AllowedMethods.READ_WRITE; -import static com.erudika.para.core.App.AllowedMethods.WRITE; -import com.erudika.para.core.ParaObject; -import com.erudika.para.core.Sysprop; -import com.erudika.para.core.Tag; -import com.erudika.para.core.User; -import com.erudika.para.core.Votable; -import com.erudika.para.core.Vote; -import com.erudika.para.core.utils.Config; -import com.erudika.para.core.utils.CoreUtils; -import com.erudika.para.core.utils.HumanTime; -import com.erudika.para.core.utils.Pager; -import com.erudika.para.core.utils.Para; -import com.erudika.para.core.utils.Utils; -import static com.erudika.para.core.validation.Constraint.*; -import com.erudika.para.server.ParaServer; -import com.erudika.para.server.security.AuthenticatedUserDetails; -import com.erudika.para.server.security.SecurityModule; -import com.erudika.para.server.security.UserAuthentication; -import com.erudika.para.server.security.filters.FacebookAuthFilter; -import com.google.inject.util.Modules; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import org.junit.AfterClass; -import static org.junit.Assert.*; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.Banner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; - -/** - * - * @author Alex Bogdanovski [alex@erudika.com] - */ -public class ParaClientIT { - - private static final Logger logger = LoggerFactory.getLogger(ParaClientIT.class); - private static ParaClient pc; - private static ParaClient pc2; - private static ParaClient pcc; - private static final String catsType = "cat"; - private static final String dogsType = "dog"; - private static final String batsType = "bat"; - private static final String APP_NAME = "para-test"; - private static final String APP_NAME_CHILD = "para-test-child"; - - protected static Sysprop u; - protected static Sysprop u1; - protected static Sysprop u2; - protected static Tag t; - protected static Sysprop s1; - protected static Sysprop s2; - protected static Sysprop s3; - protected static Address a1; - protected static Address a2; - protected static User fbUser; - - @BeforeClass - public static void setUpClass() throws InterruptedException, IOException { - System.setProperty("para.env", "embedded"); - System.setProperty("para.print_logo", "false"); - System.setProperty("para.app_name", APP_NAME); - System.setProperty("para.cluster_name", "para-test"); - System.setProperty("para.search", "LuceneSearch"); - String endpoint = "http://localhost:8080"; - - fbUser = new User("fbUser_1"); - fbUser.setEmail("test@user.com"); - fbUser.setIdentifier("fb:1234"); - fbUser.setGroups("users"); - fbUser.setActive(true); - fbUser.setAppid(APP_NAME); - - UserAuthentication ua = new UserAuthentication(new AuthenticatedUserDetails(fbUser)); - SpringApplication app = new SpringApplication(ParaServer.class); - app.setWebApplicationType(WebApplicationType.SERVLET); - app.setBannerMode(Banner.Mode.OFF); - SecurityModule secMod = new SecurityModule(); - FacebookAuthFilter fbaf = new FacebookAuthFilter("/"); - fbaf = spy(fbaf); - when(fbaf.getOrCreateUser((App) any(), anyString())).thenReturn(ua); - secMod.setFacebookFilter(fbaf); - ParaServer.initialize(Modules.override(ParaServer.getCoreModules()).with(secMod)); - app.run(); - - CoreUtils.getInstance().setDao(Para.getDAO()); - CoreUtils.getInstance().setSearch(Para.getSearch()); - - ParaClient temp = new ParaClient("x", "x"); - temp.setEndpoint(endpoint); - - assertNull(temp.me()); - assertTrue(temp.newId().isEmpty()); - - App rootApp = Para.getDAO().read(App.id(APP_NAME)); - if (rootApp == null) { - rootApp = new App(APP_NAME); - rootApp.setName(APP_NAME); - rootApp.setSharingIndex(false); - rootApp.create(); - } else { - rootApp.resetSecret(); - rootApp.create(); - } - - Map creds = Para.newApp(APP_NAME_CHILD, "Child app with routing", false, false); - - pc = new ParaClient(App.id(APP_NAME), rootApp.getSecret()); - pc.setEndpoint(endpoint); - pc2 = new ParaClient(App.id(APP_NAME), rootApp.getSecret()); - pc2.setEndpoint(endpoint); - pcc = new ParaClient(App.id(APP_NAME_CHILD), creds.get("secretKey")); - pcc.setEndpoint(endpoint); - logger.info("accessKey: {}, secretKey: {}", rootApp.getId(), rootApp.getSecret()); - - u = new Sysprop("c111"); - u.setName("John Doe"); - u.setTimestamp(Utils.timestamp()); - u.setTags(CoreUtils.getInstance().addTags(u.getTags(), "one", "two", "three")); - - u1 = new Sysprop("c222"); - u1.setName("Joe Black"); - u1.setTimestamp(Utils.timestamp()); - u1.setTags(CoreUtils.getInstance().addTags(u1.getTags(), "two", "four", "three")); - - u2 = new Sysprop("c333"); - u2.setName("Ann Smith"); - u2.setTimestamp(Utils.timestamp()); - u2.setTags(CoreUtils.getInstance().addTags(u2.getTags(), "four", "five", "three")); - - t = new Tag("test"); - t.setCount(3); - t.setTimestamp(Utils.timestamp()); - - a1 = new Address("adr1"); - a1.setName("Place 1"); - a1.setAddress("NYC"); - a1.setCountry("US"); - a1.setLatlng("40.67,-73.94"); - a1.setParentid(u.getId()); - a1.setCreatorid(u.getId()); - - a2 = new Address("adr2"); - a2.setName("Place 2"); - a2.setAddress("NYC"); - a2.setCountry("US"); - a2.setLatlng("40.69,-73.95"); - a2.setParentid(t.getId()); - a2.setCreatorid(t.getId()); - - s1 = new Sysprop("s1"); - s1.addProperty("text", "This is a little test sentence. Testing, one, two, three."); - s1.setTimestamp(Utils.timestamp()); - - s2 = new Sysprop("s2"); - s2.addProperty("text", "We are testing this thing. This sentence is a test. One, two."); - s2.setTimestamp(Utils.timestamp()); - - s3 = new Sysprop("уникод"); - s3.setType("тип"); - s3.setTimestamp(Utils.timestamp()); - - assertNotNull(fbUser.create()); - pc.createAll(Arrays.asList(u, u1, u2, t, s1, s2, s3, a1, a2)); -// Thread.sleep(1000); - } - - @AfterClass - public static void tearDownClass() { - Para.getDAO().delete(new App(APP_NAME_CHILD)); - Para.getDAO().delete(new App(APP_NAME)); - Para.getDAO().deleteAll(Arrays.asList(u, u1, u2, t, s1, s2, a1, a2, fbUser)); - Para.destroy(); - } - - @Test - public void testCRUD() { - assertNull(pc.create(null)); - - Tag tag1 = new Tag("test1"); - tag1.setVersion(1L); // enable optimistic locking - Tag t1 = pc.create(tag1); - User ux = null; - try { - // validation fails - ux = pc.create(new User("u1")); - } catch (Exception e) {} - - assertNotNull(t1); - assertNull(ux); - - assertNull(pc.read(null, null)); - assertNull(pc.read("", "")); - - Tag trID = pc.read(t1.getId()); - assertNotNull(trID); - assertNotNull(trID.getTimestamp()); - assertEquals(t1.getTag(), trID.getTag()); - - Tag tr = pc.read(t1.getType(), t1.getId()); - assertNotNull(tr); - assertNotNull(tr.getTimestamp()); - assertEquals(t1.getTag(), tr.getTag()); - assertEquals(t1.getVersion(), tr.getVersion()); - - // Not all DAOs support this, therefore we skip these tests -// tr.setCount(15); -// tr.setVersion(-1L); -// Tag tu = pc.update(tr); -// assertNotNull(tu); -// assertNotEquals(Long.valueOf(-1), tu.getVersion()); -// tr.setVersion(5L); -// tu = pc.update(tr); -// assertNotEquals(Long.valueOf(5), tu.getVersion()); - -// assertNull(pc.update(new Tag("null"))); -// assertEquals(tu.getCount(), tr.getCount()); -// assertNotNull(tu.getUpdated()); -// -// tu.setVersion(0L); // disable optimistic locking -// assertEquals(Long.valueOf(0L), pc.create(tu).getVersion()); // overwrite to disable locking - - Sysprop s = new Sysprop(); - s.setType(dogsType); - s.addProperty("foo", "bark!"); - s = pc.create(s); - - Sysprop dog = pc.read(dogsType, s.getId()); - assertTrue(dog.hasProperty("foo")); - assertEquals("bark!", dog.getProperty("foo")); - - pc.delete(t1); - pc.delete(dog); - assertNull(pc.read(tr.getType(), tr.getId())); - - // app must not overwrite itself - assertNull(pc.create(new App(APP_NAME))); - // app can read itself - assertNotNull(pc.read(Utils.type(App.class), APP_NAME)); - } - - @Test - public void testBatchCRUD() throws InterruptedException { - ArrayList dogs = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - Sysprop s = new Sysprop(); - s.setType(dogsType); - s.addProperty("foo", "bark!"); - dogs.add(s); - } - - assertTrue(pc.createAll(null).isEmpty()); - List l1 = pc.createAll(dogs); - assertEquals(3, l1.size()); - assertNotNull(l1.get(0).getId()); - - assertTrue(pc.readAll(null).isEmpty()); - ArrayList nl = new ArrayList<>(3); - assertTrue(pc.readAll(nl).isEmpty()); - nl.add(l1.get(0).getId()); - nl.add(l1.get(1).getId()); - nl.add(l1.get(2).getId()); - List l2 = pc.readAll(nl); - assertEquals(3, l2.size()); - assertEquals(l1.get(0).getId(), l2.get(0).getId()); - assertEquals(l1.get(1).getId(), l2.get(1).getId()); - assertTrue(l2.get(0).hasProperty("foo")); - assertEquals("bark!", l2.get(0).getProperty("foo")); - - assertTrue(pc.updateAll(null).isEmpty()); - - Sysprop part1 = new Sysprop(l1.get(0).getId()); - Sysprop part2 = new Sysprop(l1.get(1).getId()); - Sysprop part3 = new Sysprop(l1.get(2).getId()); - part1.setType(dogsType); - part2.setType(dogsType); - part3.setType(dogsType); - - part1.addProperty("custom", "prop"); - part1.setName("NewName1"); - part2.setName("NewName2"); - part3.setName("NewName3"); - - List l3 = pc.updateAll(Arrays.asList(part1, part2, part3)); - - assertTrue(l3.get(0).hasProperty("custom")); - assertEquals(dogsType, l3.get(0).getType()); - assertEquals(dogsType, l3.get(1).getType()); - assertEquals(dogsType, l3.get(2).getType()); - - assertEquals(part1.getName(), l3.get(0).getName()); - assertEquals(part2.getName(), l3.get(1).getName()); - assertEquals(part3.getName(), l3.get(2).getName()); - - pc.deleteAll(nl); -// Thread.sleep(1000); - - List l4 = pc.list(dogsType); - assertTrue(l4.isEmpty()); - - assertTrue(pc.getApp().getDatatypes().containsValue(dogsType)); - } - - @Test - public void testBatchCRUDForChildApp() throws InterruptedException { - ArrayList articles = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - Sysprop s = new Sysprop(); - s.setType("article"); - // DO NOT SET appid, must be always set automatically on the server - // depending on which app is currently in context (i.e. making the requests) - s.addProperty("text", "a b c"); - articles.add(s); - } - pcc.signOut(); - Para.getDAO().deleteAll(pcc.findQuery("article", "*")); - List l1 = pcc.createAll(articles); - assertEquals(3, l1.size()); - assertNotNull(l1.get(0).getId()); - assertNotNull(l1.get(1).getId()); - assertNotNull(l1.get(2).getId()); - assertTrue(l1.get(0).hasProperty("text")); - assertEquals("a b c", l1.get(0).getProperty("text")); - - assertEquals(APP_NAME_CHILD, l1.get(0).getAppid()); - assertEquals(APP_NAME_CHILD, l1.get(1).getAppid()); - assertEquals(APP_NAME_CHILD, l1.get(2).getAppid()); - - // test if appid is set on partial update - // test if old data is not lost on partial update - // test if new custom properties are merged with old ones in case of partial update - Sysprop part1 = new Sysprop(l1.get(0).getId()); - Sysprop part2 = new Sysprop(l1.get(1).getId()); - Sysprop part3 = new Sysprop(l1.get(2).getId()); - // DO NOT SET appid - should work without it in partial updateAll() - part1.setType("update_must_not_change_type"); - part2.setType("update_must_not_change_type"); - part3.setType("update_must_not_change_type"); - - part1.addProperty("text2", "d e f"); - part2.addProperty("text2", "d e f"); - part2.setName("NewName2"); - part3.setName("NewName3"); - - List lu = pcc.updateAll(Arrays.asList(part1, part2, part3)); - assertEquals(3, lu.size()); - List l2 = pcc.readAll(Arrays.asList(part1.getId(), part2.getId(), part3.getId())); - assertEquals(3, l2.size()); - assertTrue(l2.get(0).hasProperty("text")); - assertTrue(l2.get(1).hasProperty("text")); - assertTrue(l2.get(2).hasProperty("text")); - assertTrue(l2.get(0).hasProperty("text2")); - assertTrue(l2.get(1).hasProperty("text2")); - assertEquals(2, l2.get(0).getProperties().size()); - assertEquals("a b c", l2.get(0).getProperty("text")); - assertEquals(part2.getName(), l2.get(1).getName()); - assertEquals(part3.getName(), l2.get(2).getName()); - assertEquals("article", l2.get(0).getType()); - assertEquals("article", l2.get(1).getType()); - assertEquals("article", l2.get(2).getType()); - assertEquals(APP_NAME_CHILD, l2.get(0).getAppid()); - assertEquals(APP_NAME_CHILD, l2.get(1).getAppid()); - assertEquals(APP_NAME_CHILD, l2.get(2).getAppid()); - - // test if objects are validated on updateAll() - pcc.addValidationConstraint("article", "text", required()); - part1.addProperty("text", ""); - part2.addProperty("text", ""); - List lu2 = pcc.updateAll(Arrays.asList(part1, part2)); - assertTrue(lu2.isEmpty()); - Para.getDAO().deleteAll(l1); - pcc.deleteAll(Arrays.asList(part1.getId(), part2.getId(), part3.getId())); - } - - @Test - public void testCRUDWithNonStandardIDs() throws InterruptedException { - String id1 = "test/123/file.txt"; - String id2 = "file.txt?/!./=-+)))(*&^%+$#@><`~±_|'"; - String type1 = "type?/!./=-+)))(*&^%+$#@><`~±_|'"; // # should be removed - String type2 = "___ type 123 +__"; - Sysprop so1 = new Sysprop(id1); - Sysprop so2 = new Sysprop(id2); - so1.setType(type1); - so2.setType(type2); - Sysprop obj1 = pc.create(so1); - Sysprop obj2 = pc.create(so2); - assertNotNull(obj1); - assertNotNull(obj2); - Sysprop sr1 = pc.read(so1.getId()); - Sysprop sr2 = pc.read(so2.getId()); - assertNotNull(sr1); - assertNotNull(sr2); - assertNotNull(sr1.getTimestamp()); - assertNotNull(sr2.getTimestamp()); - assertEquals(id1, sr1.getId()); - assertEquals(id2, sr2.getId()); - assertNotNull(pc.read(obj1.getType(), obj1.getId())); - assertNotNull(pc.read(obj2.getType(), obj2.getId())); - so1.setName("test name"); - Sysprop su = pc.update(so1); - assertNotNull(su); - assertEquals(so1.getName(), su.getName()); - assertNotNull(su.getUpdated()); - pc.delete(so1); - pc.delete(so2); - assertNull(pc.read(so1.getId())); - assertNull(pc.read(so2.getId())); - assertNull(pc.read(so1.getType(), so1.getId())); - assertNull(pc.read(so2.getType(), so2.getId())); - - pc.createAll(Arrays.asList(sr1, sr2)); - List srl = pc.readAll(Arrays.asList(id1, id2)); - assertEquals(2, srl.size()); - assertEquals(id1, srl.get(0).getId()); - assertEquals(id2, srl.get(1).getId()); - pc.deleteAll(Arrays.asList(id1, id2)); - assertTrue(pc.readAll(Arrays.asList(id1, id2)).isEmpty()); - - // test unicode ids - assertNotNull(pc.read(s3.getId())); - s3.addProperty("text", "текст"); - pc.update(s3); - assertEquals("текст", ((Sysprop) pc.read(s3.getId())).getProperty("text")); - - pc.link(s3, t.getId()); - assertTrue(pc.isLinked(s3, t.getType(), t.getId())); - assertEquals(1, pc.countLinks(s3, t.getType()).intValue()); - pc.unlink(s3, t.getType(), t.getId()); - assertTrue(pc.getLinkedObjects(s3, t.getType()).isEmpty()); - assertTrue(pc.voteUp(s3, u1.getId())); - - pc.delete(s3); - assertNull(pc.read(s3.getId())); - } - - @Test - public void testList() throws InterruptedException { - ArrayList cats = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - Sysprop s = new Sysprop(catsType + i); - s.setType(catsType); - cats.add(s); - } - pc.createAll(cats); -// Thread.sleep(1000); - - assertTrue(pc.list(null).isEmpty()); - assertTrue(pc.list("").isEmpty()); - - List list1 = pc.list(catsType); - assertFalse(list1.isEmpty()); - assertEquals(3, list1.size()); - assertEquals(Sysprop.class, list1.get(0).getClass()); - - List list2 = pc.list(catsType, new Pager(2)); - assertFalse(list2.isEmpty()); - assertEquals(2, list2.size()); - - ArrayList nl = new ArrayList<>(3); - nl.add(cats.get(0).getId()); - nl.add(cats.get(1).getId()); - nl.add(cats.get(2).getId()); - pc.deleteAll(nl); - - assertTrue(pc.getApp().getDatatypes().containsValue(catsType)); - } - - - @Test - public void testSearch() throws InterruptedException { - assertNull(pc.findById(null)); - assertNull(pc.findById("")); - assertNotNull(pc.findById(u.getId())); - assertNotNull(pc.findById(t.getId())); - - assertTrue(pc.findByIds(null).isEmpty()); - List res1 = pc.findByIds(Arrays.asList(u.getId(), u1.getId(), u2.getId())); - assertEquals(3, res1.size()); - - Sysprop withRouting1 = new Sysprop("routed_object1"); - Sysprop withRouting2 = new Sysprop("routed_object2"); - Para.getDAO().deleteAll(Arrays.asList(withRouting1, withRouting2)); - withRouting1.setAppid(APP_NAME_CHILD); - withRouting2.setAppid(APP_NAME_CHILD); - pcc.createAll(Arrays.asList(withRouting1, withRouting2)); - -// Thread.sleep(1000); - - assertEquals(2, pcc.findByIds(Arrays.asList(withRouting1.getId(), withRouting2.getId())).size()); - Para.getDAO().deleteAll(APP_NAME_CHILD, Arrays.asList(withRouting1, withRouting2)); - - assertTrue(pc.findNearby(null, null, 100, 1, 1).isEmpty()); - assertFalse(pc.findNearby(u.getType(), "*", 10, 40.60, -73.90).isEmpty()); - assertFalse(pc.findNearby(t.getType(), "*", 10, 40.62, -73.91).isEmpty()); - - assertTrue(pc.findPrefix(null, null, "").isEmpty()); - assertTrue(pc.findPrefix("", "null", "xx").isEmpty()); - assertFalse(pc.findPrefix(u.getType(), Config._NAME, "Ann").isEmpty()); - - assertFalse(pc.findQuery(null, null).isEmpty()); - assertFalse(pc.findQuery("", "*").isEmpty()); - assertEquals(2, pc.findQuery(a1.getType(), "country:US").size()); - //assertFalse(pc.findQuery(u.getType(), "Ann*").isEmpty()); - assertTrue(pc.findQuery(null, "*").size() > 4); - - Pager p = new Pager(); - assertEquals(0, p.getCount()); - List res = pc.findQuery(u.getType(), "*", p); - assertEquals(res.size(), p.getCount()); - assertTrue(p.getCount() > 0); - - assertTrue(pc.findSimilar(t.getType(), "", null, null).isEmpty()); - assertTrue(pc.findSimilar(t.getType(), "", new String[0], "").isEmpty()); - res = pc.findSimilar(s1.getType(), s1.getId(), new String[]{"properties.text"}, (String) s1.getProperty("text")); - assertFalse(res.isEmpty()); - assertEquals(s2, res.get(0)); - - int i0 = pc.findTagged(u.getType(), null).size(); - int i1 = pc.findTagged(u.getType(), new String[]{"two"}).size(); - int i2 = pc.findTagged(u.getType(), new String[]{"one", "two"}).size(); - int i3 = pc.findTagged(u.getType(), new String[]{"three"}).size(); - int i4 = pc.findTagged(u.getType(), new String[]{"four", "three"}).size(); - int i5 = pc.findTagged(u.getType(), new String[]{"five", "three"}).size(); - int i6 = pc.findTagged(t.getType(), new String[]{"four", "three"}).size(); - - assertEquals(0, i0); - assertEquals(2, i1); - assertEquals(1, i2); - assertEquals(3, i3); - assertEquals(2, i4); - assertEquals(1, i5); - assertEquals(0, i6); - - assertFalse(pc.findTags(null).isEmpty()); - assertFalse(pc.findTags("").isEmpty()); - assertTrue(pc.findTags("unknown").isEmpty()); - assertTrue(pc.findTags(t.getTag()).size() >= 1); - - assertEquals(3, pc.findTermInList(u.getType(), Config._ID, - Arrays.asList(u.getId(), u1.getId(), u2.getId(), "xxx", "yyy")).size()); - - // many terms - Map terms = new HashMap<>(); -// terms.put(Config._TYPE, u.getType()); - terms.put(Config._ID, u.getId()); - - Map terms1 = new HashMap<>(); - terms1.put(Config._TYPE, null); - terms1.put(Config._ID, " "); - - Map terms2 = new HashMap<>(); - terms2.put(" ", "bad"); - terms2.put("", ""); - - assertEquals(1, pc.findTerms(u.getType(), terms, true).size()); - assertTrue(pc.findTerms(u.getType(), terms1, true).isEmpty()); - assertTrue(pc.findTerms(u.getType(), terms2, true).isEmpty()); - - // single term - assertTrue(pc.findTerms(null, null, true).isEmpty()); - assertTrue(pc.findTerms(u.getType(), Collections.singletonMap("", null), true).isEmpty()); - assertTrue(pc.findTerms(u.getType(), Collections.singletonMap("", ""), true).isEmpty()); - assertTrue(pc.findTerms(u.getType(), Collections.singletonMap("term", null), true).isEmpty()); - assertTrue(pc.findTerms(u.getType(), Collections.singletonMap(Config._TYPE, u.getType()), true).size() >= 2); - assertTrue(pc.findTerms(u.getType(), Collections.singletonMap(Config._NAME, "Ann Smith"), true).size() >= 1); - // "name" field is not analyzed, see https://github.com/Erudika/para/issues/13 - assertTrue(pc.findTerms(u.getType(), Collections.singletonMap(Config._NAME, "ann smith"), true).isEmpty()); -// assertFalse(pc.findQuery(u.getType(), "\"Ann Smith\"").isEmpty()); - - assertTrue(pc.findWildcard(u.getType(), null, null).isEmpty()); - assertTrue(pc.findWildcard(u.getType(), "", "").isEmpty()); - assertFalse(pc.findWildcard(u.getType(), Config._NAME, "An*").isEmpty()); - - assertTrue(pc.getCount(null).intValue() > 4); - assertNotEquals(0, pc.getCount("").intValue()); - assertEquals(0, pc.getCount("test").intValue()); - assertTrue(pc.getCount(u.getType()).intValue() >= 3); - - assertEquals(0L, pc.getCount(null, null).intValue()); - assertEquals(0L, pc.getCount(u.getType(), Collections.singletonMap(Config._ID, " ")).intValue()); - assertEquals(1L, pc.getCount(u.getType(), Collections.singletonMap(Config._ID, u.getId())).intValue()); - assertTrue(pc.getCount(null, Collections.singletonMap(Config._TYPE, u.getType())).intValue() > 1); - } - - @Test - public void testLinks() throws InterruptedException { - assertNotNull(pc.link(u, t.getId())); - assertNotNull(pc.link(u, u2.getId())); - - assertFalse(pc.isLinked(u, null)); - assertTrue(pc.isLinked(u, t)); - assertTrue(pc.isLinked(u, u2)); - -// Thread.sleep(1000); - - assertEquals(1, pc.getLinkedObjects(u, Utils.type(Tag.class)).size()); - assertEquals(1, pc.getLinkedObjects(u, Utils.type(Sysprop.class)).size()); - - assertEquals(0, pc.countLinks(u, null).intValue()); - assertEquals(1, pc.countLinks(u, Utils.type(Tag.class)).intValue()); - assertEquals(1, pc.countLinks(u, Utils.type(Sysprop.class)).intValue()); - - pc.unlinkAll(u); - - assertFalse(pc.isLinked(u, t)); - assertFalse(pc.isLinked(u, u2)); - - Sysprop second1 = new Sysprop("secondLink1"); - Sysprop second2 = new Sysprop("secondLink2"); - Sysprop second3 = new Sysprop("secondLink3"); - second1.addProperty("text", "hello from the other side"); - second2.addProperty("text", "hello kitty"); - second3.setName("gordon"); - - Sysprop child1 = new Sysprop("child1"); - Sysprop child2 = new Sysprop("child2"); - Sysprop child3 = new Sysprop("child3"); - child1.setParentid(u.getId()); - child2.setParentid(u.getId()); - child3.setParentid(u.getId()); - child1.addProperty("text", "hello from the other side"); - child2.addProperty("text", "hello kitty"); - child3.setName("gordon"); - - pc.createAll(Arrays.asList(second1, second2, second3, child1, child2, child3)); - -// Thread.sleep(1000); - - assertNotNull(pc.link(u, second1.getId())); - assertNotNull(pc.link(u, second2.getId())); - assertNotNull(pc.link(u, second3.getId())); - -// Thread.sleep(1000); - - // test linked objects search - assertTrue(pc.findLinkedObjects(u, second1.getType(), Config._NAME, null).size() >= 3); - - List found1 = pc.findLinkedObjects(u, second1.getType(), Config._NAME, "gord*"); - assertFalse(found1.isEmpty()); - assertTrue(found1.get(0).getId().equals(second3.getId())); - - List found2 = pc.findLinkedObjects(u, second1.getType(), "properties.text", "kitt*"); - assertFalse(found2.isEmpty()); - assertTrue(found2.get(0).getId().equals(second2.getId())); - - List found3 = pc.findLinkedObjects(u, second1.getType(), "properties.text", "hello"); - assertEquals(2, found3.size()); - assertTrue(found3.get(0).getId().equals(second1.getId()) || found3.get(1).getId().equals(second1.getId())); - assertTrue(found3.get(0).getId().equals(second2.getId()) || found3.get(1).getId().equals(second2.getId())); - - // test children search - assertEquals(3, pc.findChildren(u, child1.getType(), null).size()); - - List result1 = pc.findChildren(u, child1.getType(), "gord*"); - assertFalse(result1.isEmpty()); - assertTrue(result1.get(0).getId().equals(child3.getId())); - - List result2 = pc.findChildren(u, child1.getType(), "kitt*"); - assertFalse(result2.isEmpty()); - assertTrue(result2.get(0).getId().equals(child2.getId())); - - List result3 = pc.findChildren(u, child1.getType(), "hello"); - assertEquals(2, result3.size()); - assertTrue(result3.get(0).getId().equals(child1.getId()) || result3.get(1).getId().equals(child1.getId())); - assertTrue(result3.get(0).getId().equals(child2.getId()) || result3.get(1).getId().equals(child2.getId())); - - pc.unlinkAll(u); - pc.deleteAll(Arrays.asList(second1.getId(), second2.getId(), second3.getId(), - child1.getId(), child2.getId(), child3.getId())); - } - - @Test - public void testUtils() { - String id1 = pc.newId(); - String id2 = pc.newId(); - assertNotNull(id1); - assertFalse(id1.isEmpty()); - assertNotEquals(id1, id2); - - final Long ts = pc.getTimestamp(); - assertNotNull(ts); - assertNotEquals(0, ts.intValue()); - - String date1 = pc.formatDate("MM dd yyyy", Locale.US); - String date2 = Utils.formatDate("MM dd yyyy", Locale.US); - assertEquals(date1, date2); - - String ns1 = pc.noSpaces(" test 123 test ", ""); - String ns2 = Utils.noSpaces(" test 123 test ", ""); - assertEquals(ns1, ns2); - - String st1 = pc.stripAndTrim(" %^&*( cool ) @!"); - String st2 = Utils.stripAndTrim(" %^&*( cool ) @!"); - assertEquals(st1, st2); - - String md1 = pc.markdownToHtml("**test** #hello"); - String md2 = Utils.markdownToHtml("**test** #hello"); - assertEquals(md1, md2); - - String ht1 = pc.approximately(15000); - String ht2 = HumanTime.approximately(15000); - assertEquals(ht1, ht2); - } - - @Test - public void testMisc() { - Map types = pc.types(); - assertNotNull(types); - assertFalse(types.isEmpty()); - assertTrue(types.containsKey(new User().getPlural())); - - assertEquals(App.id(APP_NAME), pc.me().getId()); - } - - @Test - public void testValidationConstraints() { - // Validations - String kittenType = "kitten"; - Map constraints = pc.validationConstraints(); - assertNotNull(constraints); - assertFalse(constraints.isEmpty()); - assertTrue(constraints.containsKey("app")); - assertTrue(constraints.containsKey("user")); - - Map>>> constraint = pc.validationConstraints("app"); - assertFalse(constraint.isEmpty()); - assertTrue(constraint.containsKey("app")); - assertEquals(1, constraint.size()); - - pc.addValidationConstraint(kittenType, "paws", required()); - constraint = pc.validationConstraints(kittenType); - assertNotNull(constraint); - assertNotNull(constraint.get(kittenType)); - assertTrue(constraint.get(kittenType).containsKey("paws")); - - Sysprop ct = new Sysprop("felix"); - pc.delete(ct); - pc.delete(new Vote(u.getId(), ct.getId(), Votable.VoteValue.UP)); - pc.delete(new Vote(u.getId(), ct.getId(), Votable.VoteValue.DOWN)); - ct.setType(kittenType); - Sysprop ct2 = null; - try { - // validation fails - ct2 = pc.create(ct); - } catch (Exception e) {} - - assertNull(ct2); - ct.addProperty("paws", "4"); - assertNotNull(pc.create(ct)); - - pc.removeValidationConstraint(kittenType, "paws", "required"); - constraint = pc.validationConstraints(kittenType); - assertFalse(constraint.containsKey(kittenType)); - - Integer votes = ct.getVotes() + 1; - assertTrue(pc.voteUp(ct, u.getId())); - assertEquals(votes, pc.read(ct.getId()).getVotes()); - assertFalse(pc.voteUp(ct, u.getId())); - votes -= 1; - assertTrue(pc.voteDown(ct, u.getId())); - assertEquals(votes, pc.read(ct.getId()).getVotes()); - votes -= 1; - assertTrue(pc.voteDown(ct, u.getId())); - assertFalse(pc.voteDown(ct, u.getId())); - assertEquals(votes, pc.read(ct.getId()).getVotes()); - Para.getDAO().delete(ct); - Para.getDAO().delete(new Vote(u.getId(), ct.getId(), Votable.VoteValue.UP)); - } - - @Test - public void testResourcePermissions() { - // Permissions - Map>> permits = pcc.resourcePermissions(); - assertNotNull(permits); - - assertTrue(pcc.grantResourcePermission(null, dogsType, EnumSet.noneOf(AllowedMethods.class)).isEmpty()); - assertTrue(pcc.grantResourcePermission(" ", "", EnumSet.noneOf(AllowedMethods.class)).isEmpty()); - - pcc.grantResourcePermission(u1.getId(), dogsType, READ); - permits = pcc.resourcePermissions(u1.getId()); - assertTrue(permits.containsKey(u1.getId())); - assertTrue(permits.get(u1.getId()).containsKey(dogsType)); - assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); - assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, POST.toString())); - - permits = pcc.resourcePermissions(); - assertTrue(permits.containsKey(u1.getId())); - assertTrue(permits.get(u1.getId()).containsKey(dogsType)); - - pcc.revokeResourcePermission(u1.getId(), dogsType); - permits = pcc.resourcePermissions(u1.getId()); - assertFalse(permits.get(u1.getId()).containsKey(dogsType)); - assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); - assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, POST.toString())); - - pcc.grantResourcePermission(u2.getId(), App.ALLOW_ALL, WRITE); - assertTrue(pcc.isAllowedTo(u2.getId(), dogsType, PUT.toString())); - assertTrue(pcc.isAllowedTo(u2.getId(), dogsType, PATCH.toString())); - - pcc.revokeAllResourcePermissions(u2.getId()); - permits = pcc.resourcePermissions(); - assertFalse(pcc.isAllowedTo(u2.getId(), dogsType, PUT.toString())); - assertFalse(permits.containsKey(u2.getId())); -// assertTrue(permits.get(u2.getId()).isEmpty()); - - pcc.grantResourcePermission(u1.getId(), dogsType, WRITE); - pcc.grantResourcePermission(App.ALLOW_ALL, catsType, WRITE); - pcc.grantResourcePermission(App.ALLOW_ALL, App.ALLOW_ALL, READ); - // user-specific permissions are in effect - assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, PUT.toString())); - assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), catsType, PUT.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), catsType, GET.toString())); - - pcc.revokeAllResourcePermissions(u1.getId()); - // user-specific permissions not found so check wildcard - assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, PUT.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), catsType, PUT.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), catsType, GET.toString())); - - pcc.revokeResourcePermission(App.ALLOW_ALL, catsType); - // resource-specific permissions not found so check wildcard - assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, PUT.toString())); - assertFalse(pcc.isAllowedTo(u1.getId(), catsType, PUT.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); - assertTrue(pcc.isAllowedTo(u1.getId(), catsType, GET.toString())); - assertTrue(pcc.isAllowedTo(u2.getId(), dogsType, GET.toString())); - assertTrue(pcc.isAllowedTo(u2.getId(), catsType, GET.toString())); - - pcc.revokeAllResourcePermissions(App.ALLOW_ALL); - pcc.revokeAllResourcePermissions(u1.getId()); - } - - @Test - public void testAppSettings() { - Map settings = pc.appSettings(); - assertNotNull(settings); - assertTrue(settings.isEmpty()); - - pc.addAppSetting("", null); - pc.addAppSetting(" ", " "); - pc.addAppSetting(null, " "); - pc.addAppSetting("prop1", 1); - pc.addAppSetting("prop2", true); - pc.addAppSetting("prop3", "string"); - - settings = pc.appSettings(); - assertEquals(3, settings.size()); - assertEquals(settings, pc.appSettings(null)); - assertEquals(1, settings.get("prop1")); - assertEquals(true, settings.get("prop2")); - assertEquals("string", settings.get("prop3")); - - pc.removeAppSetting("prop3"); - pc.removeAppSetting(" "); - pc.removeAppSetting(null); - - settings = pc.appSettings(); - assertFalse(settings.containsKey("prop3")); - assertEquals(2, settings.size()); - pc.removeAppSetting("prop2"); - pc.removeAppSetting("prop1"); - - pc.addAppSetting("propZ", 1); - Map newSettings = new HashMap<>(); - newSettings.put("propX", "X"); - newSettings.put("propY", "Y"); - pc.setAppSettings(newSettings); - settings = pc.appSettings(); - assertEquals(2, settings.size()); - assertFalse(settings.containsKey("propZ")); - assertTrue(settings.containsKey("propX")); - assertTrue(settings.containsKey("propY")); - newSettings.clear(); - pc.setAppSettings(newSettings); - settings = pc.appSettings(); - assertTrue(settings.isEmpty()); - } - - @Test - public void testAccessTokens() throws IOException, InterruptedException { - assertNotNull(fbUser); - assertNull(pc2.getAccessToken()); - - // fails with google+ - service not mocked - User failsNotMocked = pc2.signIn("google", "test_token"); - assertNull(failsNotMocked); - - // should fail to create user for root app -// System.setProperty("para.clients_can_access_root_app", "false"); - User notSignedIn = pc2.signIn("facebook", "test_token"); - logger.info(pc2.getAccessToken()); - assertNull(notSignedIn); - assertNull(pc2.getAccessToken()); - - // then allow clients to modify root app -// System.setProperty("para.clients_can_access_root_app", "true"); - User signedIn = pc2.signIn("facebook", "test_token"); - logger.info(pc2.getAccessToken()); - assertNull(signedIn); - assertNull(pc2.getAccessToken()); - - // test without permissions - signed in but you can't access anything yet - signedIn = pcc.signIn("facebook", "test_token"); - pcc.revokeAllResourcePermissions(fbUser.getId()); - ParaObject me = pcc.me(); - assertNotNull(me); - assertEquals("user", me.getType()); - assertTrue(pcc.newId().isEmpty()); - assertTrue(pcc.getTimestamp() == 0L); - - // test with permissions - logout first to use app credentials (full access) - pcc.signOut(); - pcc.grantResourcePermission(fbUser.getId(), App.ALLOW_ALL, READ_AND_WRITE); - signedIn = pcc.signIn("facebook", "test_token"); - logger.info(pcc.getAccessToken()); - assertNotNull(signedIn); - assertNotNull(pcc.getAccessToken()); - me = pcc.me(); - assertNotNull(me); - assertFalse(pcc.newId().isEmpty()); - assertEquals(signedIn.getName(), me.getName()); - - // now switch back to App access - pcc.signOut(); - assertNull(pcc.getAccessToken()); - me = pcc.me(); // app - assertNotNull(me); - assertEquals("app", me.getType()); - assertFalse(pcc.newId().isEmpty()); - signedIn = pcc.signIn("facebook", "test_token"); - logger.info(pcc.getAccessToken()); - me = pcc.me(); // user - assertNotNull(me); - assertEquals("user", me.getType()); - assertEquals(signedIn.getId(), me.getId()); - - assertNull(pcc.newKeys()); // users can't change API keys! - - // test revoke tokens - pcc.revokeAllTokens(); - assertTrue(pcc.newId().isEmpty()); - assertTrue(pcc.getTimestamp() == 0L); - assertNull(pcc.me()); - - pcc.signOut(); - - // test anonymous permissions - String utilsPath = "utils/timestamp"; - ParaClient guest = new ParaClient(App.id(APP_NAME_CHILD), null); - guest.setEndpoint(pcc.getEndpoint()); - assertFalse(guest.getTimestamp() > 0); - assertFalse(guest.isAllowedTo(App.ALLOW_ALL, utilsPath, GET.toString())); - pcc.grantResourcePermission(App.ALLOW_ALL, utilsPath, READ, true); - assertTrue(guest.getTimestamp() > 0); - } - - @Test - public void testOwnersPermissions() throws InterruptedException { - // test user should be able to login twice - first time the object is created, second time password is checked - String emailInactive = "test2@user.com"; - String emailPassFail = emailInactive + "::12345678"; - String emailPassPass = "test3@user.com::12345678"; - String emailPassPass2 = "test4@user.com::12345678"; - assertNull(pcc.signIn("password", emailPassFail)); // unverified email - user is created but not active - List failed = pcc.findTerms(fbUser.getType(), Collections.singletonMap(Config._EMAIL, emailInactive), true); - assertFalse(failed.isEmpty()); - assertEquals(emailInactive, failed.get(0).getEmail()); - pcc.delete(failed.get(0)); - - System.setProperty("para.security.allow_unverified_emails", "true"); // allow it - User newUser = pcc.signIn("password", emailPassPass); - User newUser2 = pcc.signIn("password", emailPassPass2); - assertNotNull(newUser); - assertNotNull(newUser2); - pcc.signOut(); - assertNotNull(pcc.signIn("password", emailPassPass)); - pcc.signOut(); - - // test permissions with/without signed in user - assertTrue(pcc.isAllowedTo(newUser.getId(), newUser.getObjectURI(), GET.toString())); - assertNotNull(pcc.signIn("password", emailPassPass)); - assertTrue(pcc.isAllowedTo(newUser.getId(), newUser.getObjectURI(), GET.toString())); - assertFalse(pcc.isAllowedTo(newUser.getId(), newUser.getObjectURI() + "x", GET.toString())); - assertNotNull(pcc.read(newUser.getId())); // can read self - pcc.signOut(); - - // test implicit user permissions - read/update/delete own object (children) - assertFalse(pcc.isAllowedTo(newUser.getId(), "todo", POST.toString())); // can't create yet - pcc.grantResourcePermission(newUser.getId(), "todo", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs - pcc.grantResourcePermission(newUser.getId(), "todo/*", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs - pcc.signIn("password", emailPassPass); - assertTrue(pcc.isAllowedTo(newUser.getId(), "todo", POST.toString())); - Sysprop todo = new Sysprop("todo_id"); - todo.setType("todo"); - // test if creatorid is set correctly - todo.setCreatorid("invalid_user_id"); // must be corrected by the server - todo.setName("[] buy milk"); - todo = pcc.create(todo); -// Thread.sleep(1000); - assertNotNull(todo); - assertFalse(todo.getId().equals("todo_id")); - assertNotNull(pcc.read(todo.getType(), todo.getId())); - assertEquals(1, pcc.findQuery("todo", "*").size()); // user only sees own TODO - assertEquals(newUser.getId(), todo.getCreatorid()); - pcc.signOut(); - - // one user must not be able to overwrite another user's TODOs (custom ids) - pcc.grantResourcePermission(newUser2.getId(), "todo", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs - pcc.grantResourcePermission(newUser2.getId(), "todo/*", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs - pcc.signIn("password", emailPassPass2); - assertTrue(pcc.list("todo").isEmpty()); - assertNull(pcc.read(todo.getId())); - Sysprop todo2 = new Sysprop("todo_id2"); - todo2.setType("todo"); - todo2.setName("[] buy eggs"); - todo2 = pcc.create(todo2); - assertNotNull(todo2); - assertFalse(todo2.getId().equals("todo_id2")); - assertNotNull(pcc.read(todo2.getType(), todo2.getId())); - assertEquals(1, pcc.findQuery("todo", "*").size()); - assertEquals(newUser2.getId(), todo2.getCreatorid()); - pcc.signOut(); - // app can see all TODOs - assertEquals(2, pcc.list("todo").size()); - - pc.delete(todo); - pc.delete(todo2); - pc.delete(newUser); - pc.delete(newUser2); - - // an app should be able to update and delete itself - String appId = "para-child-app-test"; - Map creds = Para.newApp(appId, "Child app", false, false); - ParaClient pclient = new ParaClient(App.id(appId), creds.get("secretKey")); - pclient.setEndpoint(pc.getEndpoint()); - - App app = pclient.me(); - assertNotNull(app); - assertEquals(appId, app.getAppIdentifier()); - - app.setName("Child application"); - pclient.update(app); - app = pclient.me(); - assertEquals("Child application", app.getName()); - - pclient.delete(app); - assertNull(pclient.read(App.id(appId))); - } -} diff --git a/para-server/src/test/java/com/erudika/para/client/ParaIntegrationsIT.java b/para-server/src/test/java/com/erudika/para/client/ParaIntegrationsIT.java new file mode 100644 index 00000000..0fbdd934 --- /dev/null +++ b/para-server/src/test/java/com/erudika/para/client/ParaIntegrationsIT.java @@ -0,0 +1,1110 @@ +/* + * Copyright 2013-2022 Erudika. https://erudika.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For issues and patches go to: https://github.com/erudika + */ +package com.erudika.para.client; + +import com.erudika.para.core.Address; +import com.erudika.para.core.App; +import com.erudika.para.core.App.AllowedMethods; +import static com.erudika.para.core.App.AllowedMethods.GET; +import static com.erudika.para.core.App.AllowedMethods.OWN; +import static com.erudika.para.core.App.AllowedMethods.PATCH; +import static com.erudika.para.core.App.AllowedMethods.POST; +import static com.erudika.para.core.App.AllowedMethods.PUT; +import static com.erudika.para.core.App.AllowedMethods.READ; +import static com.erudika.para.core.App.AllowedMethods.READ_AND_WRITE; +import static com.erudika.para.core.App.AllowedMethods.READ_WRITE; +import static com.erudika.para.core.App.AllowedMethods.WRITE; +import com.erudika.para.core.ParaObject; +import com.erudika.para.core.Sysprop; +import com.erudika.para.core.Tag; +import com.erudika.para.core.User; +import com.erudika.para.core.Votable; +import com.erudika.para.core.Vote; +import com.erudika.para.core.utils.Config; +import com.erudika.para.core.utils.CoreUtils; +import com.erudika.para.core.utils.HumanTime; +import com.erudika.para.core.utils.Pager; +import com.erudika.para.core.utils.Para; +import com.erudika.para.core.utils.Utils; +import static com.erudika.para.core.validation.Constraint.*; +import com.erudika.para.server.ParaServer; +import com.erudika.para.server.persistence.AWSDynamoUtils; +import com.erudika.para.server.security.AuthenticatedUserDetails; +import com.erudika.para.server.security.SecurityModule; +import com.erudika.para.server.security.UserAuthentication; +import com.erudika.para.server.security.filters.FacebookAuthFilter; +import com.google.inject.util.Modules; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.ClassOrderer; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestClassOrder; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.Banner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; + +/** + * Integration tests for ParaClient & AWSDynamoDBDAO + * @author Alex Bogdanovski [alex@erudika.com] + */ +@TestClassOrder(ClassOrderer.OrderAnnotation.class) +class ParaIntegrationsIT { + + @Nested + @Order(1) + class ParaClientIT { + + private static final Logger logger = LoggerFactory.getLogger(ParaClientIT.class); + private static ParaClient pc; + private static ParaClient pc2; + private static ParaClient pcc; + private static final String catsType = "cat"; + private static final String dogsType = "dog"; + private static final String batsType = "bat"; + private static final String APP_NAME = "para-test"; + private static final String APP_NAME_CHILD = "para-test-child"; + + protected static Sysprop u; + protected static Sysprop u1; + protected static Sysprop u2; + protected static Tag t; + protected static Sysprop s1; + protected static Sysprop s2; + protected static Sysprop s3; + protected static Address a1; + protected static Address a2; + protected static User fbUser; + + @BeforeAll + public static void setUpClass() throws InterruptedException, IOException { + System.setProperty("para.env", "embedded"); + System.setProperty("para.print_logo", "false"); + System.setProperty("para.app_name", APP_NAME); + System.setProperty("para.cluster_name", "para-test"); + System.setProperty("para.search", "LuceneSearch"); + System.setProperty("para.dynamodb.provisioned_mode_enabled", "true"); + String endpoint = "http://localhost:8080"; + + fbUser = new User("fbUser_1"); + fbUser.setEmail("test@user.com"); + fbUser.setIdentifier("fb:1234"); + fbUser.setGroups("users"); + fbUser.setActive(true); + fbUser.setAppid(APP_NAME); + + AWSDynamoUtils.createTable(APP_NAME, 1, 1); + AWSDynamoUtils.createTable(APP_NAME_CHILD, 1, 1); + + UserAuthentication ua = new UserAuthentication(new AuthenticatedUserDetails(fbUser)); + SpringApplication app = new SpringApplication(ParaServer.class); + app.setWebApplicationType(WebApplicationType.SERVLET); + app.setBannerMode(Banner.Mode.OFF); + SecurityModule secMod = new SecurityModule(); + FacebookAuthFilter fbaf = new FacebookAuthFilter("/"); + fbaf = spy(fbaf); + when(fbaf.getOrCreateUser((App) any(), anyString())).thenReturn(ua); + secMod.setFacebookFilter(fbaf); + ParaServer.initialize(Modules.override(ParaServer.getCoreModules()).with(secMod)); + app.run(); + + CoreUtils.getInstance().setDao(Para.getDAO()); + CoreUtils.getInstance().setSearch(Para.getSearch()); + + ParaClient temp = new ParaClient("x", "x"); + temp.setEndpoint(endpoint); + + assertNull(temp.me()); + assertTrue(temp.newId().isEmpty()); + + App rootApp = Para.getDAO().read(App.id(APP_NAME)); + if (rootApp == null) { + rootApp = new App(APP_NAME); + rootApp.setName(APP_NAME); + rootApp.setSharingIndex(false); + rootApp.create(); + } else { + rootApp.resetSecret(); + rootApp.create(); + } + + Map creds = Para.newApp(APP_NAME_CHILD, "Child app with routing", false, false); + + pc = new ParaClient(App.id(APP_NAME), rootApp.getSecret()); + pc.setEndpoint(endpoint); + pc2 = new ParaClient(App.id(APP_NAME), rootApp.getSecret()); + pc2.setEndpoint(endpoint); + pcc = new ParaClient(App.id(APP_NAME_CHILD), creds.get("secretKey")); + pcc.setEndpoint(endpoint); + logger.info("accessKey: {}, secretKey: {}", rootApp.getId(), rootApp.getSecret()); + + u = new Sysprop("c111"); + u.setName("John Doe"); + u.setTimestamp(Utils.timestamp()); + u.setTags(CoreUtils.getInstance().addTags(u.getTags(), "one", "two", "three")); + + u1 = new Sysprop("c222"); + u1.setName("Joe Black"); + u1.setTimestamp(Utils.timestamp()); + u1.setTags(CoreUtils.getInstance().addTags(u1.getTags(), "two", "four", "three")); + + u2 = new Sysprop("c333"); + u2.setName("Ann Smith"); + u2.setTimestamp(Utils.timestamp()); + u2.setTags(CoreUtils.getInstance().addTags(u2.getTags(), "four", "five", "three")); + + t = new Tag("test"); + t.setCount(3); + t.setTimestamp(Utils.timestamp()); + + a1 = new Address("adr1"); + a1.setName("Place 1"); + a1.setAddress("NYC"); + a1.setCountry("US"); + a1.setLatlng("40.67,-73.94"); + a1.setParentid(u.getId()); + a1.setCreatorid(u.getId()); + + a2 = new Address("adr2"); + a2.setName("Place 2"); + a2.setAddress("NYC"); + a2.setCountry("US"); + a2.setLatlng("40.69,-73.95"); + a2.setParentid(t.getId()); + a2.setCreatorid(t.getId()); + + s1 = new Sysprop("s1"); + s1.addProperty("text", "This is a little test sentence. Testing, one, two, three."); + s1.setTimestamp(Utils.timestamp()); + + s2 = new Sysprop("s2"); + s2.addProperty("text", "We are testing this thing. This sentence is a test. One, two."); + s2.setTimestamp(Utils.timestamp()); + + s3 = new Sysprop("уникод"); + s3.setType("тип"); + s3.setTimestamp(Utils.timestamp()); + + assertNotNull(fbUser.create()); + pc.createAll(Arrays.asList(u, u1, u2, t, s1, s2, s3, a1, a2)); + } + + @AfterAll + public static void tearDownClass() { + Para.getDAO().deleteAll(Arrays.asList(u, u1, u2, t, s1, s2, a1, a2, fbUser)); + Para.getDAO().delete(new App(APP_NAME_CHILD)); + Para.getDAO().delete(new App(APP_NAME)); + AWSDynamoUtils.deleteTable(APP_NAME); + AWSDynamoUtils.deleteTable(APP_NAME_CHILD); + Para.destroy(); + } + + @Test + public void testCRUD() { + assertNull(pc.create(null)); + + Tag tag1 = new Tag("test1"); + tag1.setVersion(1L); // enable optimistic locking + Tag t1 = pc.create(tag1); + User ux = null; + try { + // validation fails + ux = pc.create(new User("u1")); + } catch (Exception e) { + } + + assertNotNull(t1); + assertNull(ux); + + assertNull(pc.read(null, null)); + assertNull(pc.read("", "")); + + Tag trID = pc.read(t1.getId()); + assertNotNull(trID); + assertNotNull(trID.getTimestamp()); + assertEquals(t1.getTag(), trID.getTag()); + + Tag tr = pc.read(t1.getType(), t1.getId()); + assertNotNull(tr); + assertNotNull(tr.getTimestamp()); + assertEquals(t1.getTag(), tr.getTag()); + assertEquals(t1.getVersion(), tr.getVersion()); + + // Not all DAOs support this, therefore we skip these tests + // tr.setCount(15); + // tr.setVersion(-1L); + // Tag tu = pc.update(tr); + // assertNotNull(tu); + // assertNotEquals(Long.valueOf(-1), tu.getVersion()); + // tr.setVersion(5L); + // tu = pc.update(tr); + // assertNotEquals(Long.valueOf(5), tu.getVersion()); + // assertNull(pc.update(new Tag("null"))); + // assertEquals(tu.getCount(), tr.getCount()); + // assertNotNull(tu.getUpdated()); + // + // tu.setVersion(0L); // disable optimistic locking + // assertEquals(Long.valueOf(0L), pc.create(tu).getVersion()); // overwrite to disable locking + Sysprop s = new Sysprop(); + s.setType(dogsType); + s.addProperty("foo", "bark!"); + s = pc.create(s); + + Sysprop dog = pc.read(dogsType, s.getId()); + assertTrue(dog.hasProperty("foo")); + assertEquals("bark!", dog.getProperty("foo")); + + pc.delete(t1); + pc.delete(dog); + assertNull(pc.read(tr.getType(), tr.getId())); + + // app must not overwrite itself + assertNull(pc.create(new App(APP_NAME))); + // app can read itself + assertNotNull(pc.read(Utils.type(App.class), APP_NAME)); + } + + @Test + public void testBatchCRUD() throws InterruptedException { + ArrayList dogs = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + Sysprop s = new Sysprop(); + s.setType(dogsType); + s.addProperty("foo", "bark!"); + dogs.add(s); + } + + assertTrue(pc.createAll(null).isEmpty()); + List l1 = pc.createAll(dogs); + assertEquals(3, l1.size()); + assertNotNull(l1.get(0).getId()); + + assertTrue(pc.readAll(null).isEmpty()); + ArrayList nl = new ArrayList<>(3); + assertTrue(pc.readAll(nl).isEmpty()); + nl.add(l1.get(0).getId()); + nl.add(l1.get(1).getId()); + nl.add(l1.get(2).getId()); + List l2 = pc.readAll(nl); + assertEquals(3, l2.size()); + assertEquals(l1.get(0).getId(), l2.get(0).getId()); + assertEquals(l1.get(1).getId(), l2.get(1).getId()); + assertTrue(l2.get(0).hasProperty("foo")); + assertEquals("bark!", l2.get(0).getProperty("foo")); + + assertTrue(pc.updateAll(null).isEmpty()); + + Sysprop part1 = new Sysprop(l1.get(0).getId()); + Sysprop part2 = new Sysprop(l1.get(1).getId()); + Sysprop part3 = new Sysprop(l1.get(2).getId()); + part1.setType(dogsType); + part2.setType(dogsType); + part3.setType(dogsType); + + part1.addProperty("custom", "prop"); + part1.setName("NewName1"); + part2.setName("NewName2"); + part3.setName("NewName3"); + + List l3 = pc.updateAll(Arrays.asList(part1, part2, part3)); + + assertTrue(l3.get(0).hasProperty("custom")); + assertEquals(dogsType, l3.get(0).getType()); + assertEquals(dogsType, l3.get(1).getType()); + assertEquals(dogsType, l3.get(2).getType()); + + assertEquals(part1.getName(), l3.get(0).getName()); + assertEquals(part2.getName(), l3.get(1).getName()); + assertEquals(part3.getName(), l3.get(2).getName()); + + pc.deleteAll(nl); + // Thread.sleep(1000); + + List l4 = pc.list(dogsType); + assertTrue(l4.isEmpty()); + + assertTrue(pc.getApp().getDatatypes().containsValue(dogsType)); + } + + @Test + public void testBatchCRUDForChildApp() throws InterruptedException { + ArrayList articles = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + Sysprop s = new Sysprop(); + s.setType("article"); + // DO NOT SET appid, must be always set automatically on the server + // depending on which app is currently in context (i.e. making the requests) + s.addProperty("text", "a b c"); + articles.add(s); + } + pcc.signOut(); + Para.getDAO().deleteAll(pcc.findQuery("article", "*")); + List l1 = pcc.createAll(articles); + assertEquals(3, l1.size()); + assertNotNull(l1.get(0).getId()); + assertNotNull(l1.get(1).getId()); + assertNotNull(l1.get(2).getId()); + assertTrue(l1.get(0).hasProperty("text")); + assertEquals("a b c", l1.get(0).getProperty("text")); + + assertEquals(APP_NAME_CHILD, l1.get(0).getAppid()); + assertEquals(APP_NAME_CHILD, l1.get(1).getAppid()); + assertEquals(APP_NAME_CHILD, l1.get(2).getAppid()); + + // test if appid is set on partial update + // test if old data is not lost on partial update + // test if new custom properties are merged with old ones in case of partial update + Sysprop part1 = new Sysprop(l1.get(0).getId()); + Sysprop part2 = new Sysprop(l1.get(1).getId()); + Sysprop part3 = new Sysprop(l1.get(2).getId()); + // DO NOT SET appid - should work without it in partial updateAll() + part1.setType("update_must_not_change_type"); + part2.setType("update_must_not_change_type"); + part3.setType("update_must_not_change_type"); + + part1.addProperty("text2", "d e f"); + part2.addProperty("text2", "d e f"); + part2.setName("NewName2"); + part3.setName("NewName3"); + + List lu = pcc.updateAll(Arrays.asList(part1, part2, part3)); + assertEquals(3, lu.size()); + List l2 = pcc.readAll(Arrays.asList(part1.getId(), part2.getId(), part3.getId())); + assertEquals(3, l2.size()); + assertTrue(l2.get(0).hasProperty("text")); + assertTrue(l2.get(1).hasProperty("text")); + assertTrue(l2.get(2).hasProperty("text")); + assertTrue(l2.get(0).hasProperty("text2")); + assertTrue(l2.get(1).hasProperty("text2")); + assertEquals(2, l2.get(0).getProperties().size()); + assertEquals("a b c", l2.get(0).getProperty("text")); + assertEquals(part2.getName(), l2.get(1).getName()); + assertEquals(part3.getName(), l2.get(2).getName()); + assertEquals("article", l2.get(0).getType()); + assertEquals("article", l2.get(1).getType()); + assertEquals("article", l2.get(2).getType()); + assertEquals(APP_NAME_CHILD, l2.get(0).getAppid()); + assertEquals(APP_NAME_CHILD, l2.get(1).getAppid()); + assertEquals(APP_NAME_CHILD, l2.get(2).getAppid()); + + // test if objects are validated on updateAll() + pcc.addValidationConstraint("article", "text", required()); + part1.addProperty("text", ""); + part2.addProperty("text", ""); + List lu2 = pcc.updateAll(Arrays.asList(part1, part2)); + assertTrue(lu2.isEmpty()); + Para.getDAO().deleteAll(l1); + pcc.deleteAll(Arrays.asList(part1.getId(), part2.getId(), part3.getId())); + } + + @Test + public void testCRUDWithNonStandardIDs() throws InterruptedException { + // String id1 = "test/123/file.txt"; + // String id2 = "file.txt?/!./=-+)))(*&^%+$#@><`~±_|'"; + // String type1 = "type?/!./=-+)))(*&^%+$#@><`~±_|'"; // # should be removed + // String type2 = "___ type 123 +__"; + String id1 = "test123file.txt"; + String id2 = "file.txt-^><±_|'"; + String type1 = "type?=-+^><_|'"; + String type2 = "___ type 123 +__"; + Sysprop so1 = new Sysprop(id1); + Sysprop so2 = new Sysprop(id2); + so1.setType(type1); + so2.setType(type2); + Sysprop obj1 = pc.create(so1); + Sysprop obj2 = pc.create(so2); + assertNotNull(obj1); + assertNotNull(obj2); + Sysprop sr1 = pc.read(so1.getId()); + Sysprop sr2 = pc.read(so2.getId()); + assertNotNull(sr1); + assertNotNull(sr2); + assertNotNull(sr1.getTimestamp()); + assertNotNull(sr2.getTimestamp()); + assertEquals(id1, sr1.getId()); + assertEquals(id2, sr2.getId()); + assertNotNull(pc.read(obj1.getType(), obj1.getId())); + assertNotNull(pc.read(obj2.getType(), obj2.getId())); + so1.setName("test name"); + Sysprop su = pc.update(so1); + assertNotNull(su); + assertEquals(so1.getName(), su.getName()); + assertNotNull(su.getUpdated()); + pc.delete(so1); + pc.delete(so2); + assertNull(pc.read(so1.getId())); + assertNull(pc.read(so2.getId())); + assertNull(pc.read(so1.getType(), so1.getId())); + assertNull(pc.read(so2.getType(), so2.getId())); + + pc.createAll(Arrays.asList(sr1, sr2)); + List srl = pc.readAll(Arrays.asList(id1, id2)); + assertEquals(2, srl.size()); + assertEquals(id1, srl.get(0).getId()); + assertEquals(id2, srl.get(1).getId()); + pc.deleteAll(Arrays.asList(id1, id2)); + assertTrue(pc.readAll(Arrays.asList(id1, id2)).isEmpty()); + + // test unicode ids + assertNotNull(pc.read(s3.getId())); + s3.addProperty("text", "текст"); + pc.update(s3); + assertEquals("текст", ((Sysprop) pc.read(s3.getId())).getProperty("text")); + + pc.link(s3, t.getId()); + assertTrue(pc.isLinked(s3, t.getType(), t.getId())); + assertEquals(1, pc.countLinks(s3, t.getType()).intValue()); + pc.unlink(s3, t.getType(), t.getId()); + assertTrue(pc.getLinkedObjects(s3, t.getType()).isEmpty()); + assertTrue(pc.voteUp(s3, u1.getId())); + + pc.delete(s3); + assertNull(pc.read(s3.getId())); + } + + @Test + public void testList() throws InterruptedException { + ArrayList cats = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + Sysprop s = new Sysprop(catsType + i); + s.setType(catsType); + cats.add(s); + } + pc.createAll(cats); + + assertTrue(pc.list(null).isEmpty()); + assertTrue(pc.list("").isEmpty()); + + List list1 = pc.list(catsType); + assertFalse(list1.isEmpty()); + assertEquals(3, list1.size()); + assertEquals(Sysprop.class, list1.get(0).getClass()); + + List list2 = pc.list(catsType, new Pager(2)); + assertFalse(list2.isEmpty()); + assertEquals(2, list2.size()); + + ArrayList nl = new ArrayList<>(3); + nl.add(cats.get(0).getId()); + nl.add(cats.get(1).getId()); + nl.add(cats.get(2).getId()); + pc.deleteAll(nl); + + assertTrue(pc.getApp().getDatatypes().containsValue(catsType)); + } + + @Test + public void testSearch() throws InterruptedException { + assertNull(pc.findById(null)); + assertNull(pc.findById("")); + assertNotNull(pc.findById(u.getId())); + assertNotNull(pc.findById(t.getId())); + + assertTrue(pc.findByIds(null).isEmpty()); + List res1 = pc.findByIds(Arrays.asList(u.getId(), u1.getId(), u2.getId())); + assertEquals(3, res1.size()); + + Sysprop withRouting1 = new Sysprop("routed_object1"); + Sysprop withRouting2 = new Sysprop("routed_object2"); + Para.getDAO().deleteAll(Arrays.asList(withRouting1, withRouting2)); + withRouting1.setAppid(APP_NAME_CHILD); + withRouting2.setAppid(APP_NAME_CHILD); + pcc.createAll(Arrays.asList(withRouting1, withRouting2)); + + assertEquals(2, pcc.findByIds(Arrays.asList(withRouting1.getId(), withRouting2.getId())).size()); + Para.getDAO().deleteAll(APP_NAME_CHILD, Arrays.asList(withRouting1, withRouting2)); + + assertTrue(pc.findNearby(null, null, 100, 1, 1).isEmpty()); + assertFalse(pc.findNearby(u.getType(), "*", 10, 40.60, -73.90).isEmpty()); + assertFalse(pc.findNearby(t.getType(), "*", 10, 40.62, -73.91).isEmpty()); + + assertTrue(pc.findPrefix(null, null, "").isEmpty()); + assertTrue(pc.findPrefix("", "null", "xx").isEmpty()); + assertFalse(pc.findPrefix(u.getType(), Config._NAME, "Ann").isEmpty()); + + assertFalse(pc.findQuery(null, null).isEmpty()); + assertFalse(pc.findQuery("", "*").isEmpty()); + assertEquals(2, pc.findQuery(a1.getType(), "country:US").size()); + //assertFalse(pc.findQuery(u.getType(), "Ann*").isEmpty()); + assertTrue(pc.findQuery(null, "*").size() > 4); + + Pager p = new Pager(); + assertEquals(0, p.getCount()); + List res = pc.findQuery(u.getType(), "*", p); + assertEquals(res.size(), p.getCount()); + assertTrue(p.getCount() > 0); + + assertTrue(pc.findSimilar(t.getType(), "", null, null).isEmpty()); + assertTrue(pc.findSimilar(t.getType(), "", new String[0], "").isEmpty()); + res = pc.findSimilar(s1.getType(), s1.getId(), new String[]{"properties.text"}, (String) s1.getProperty("text")); + assertFalse(res.isEmpty()); + assertEquals(s2, res.get(0)); + + int i0 = pc.findTagged(u.getType(), null).size(); + int i1 = pc.findTagged(u.getType(), new String[]{"two"}).size(); + int i2 = pc.findTagged(u.getType(), new String[]{"one", "two"}).size(); + int i3 = pc.findTagged(u.getType(), new String[]{"three"}).size(); + int i4 = pc.findTagged(u.getType(), new String[]{"four", "three"}).size(); + int i5 = pc.findTagged(u.getType(), new String[]{"five", "three"}).size(); + int i6 = pc.findTagged(t.getType(), new String[]{"four", "three"}).size(); + + assertEquals(0, i0); + assertEquals(2, i1); + assertEquals(1, i2); + assertEquals(3, i3); + assertEquals(2, i4); + assertEquals(1, i5); + assertEquals(0, i6); + + assertFalse(pc.findTags(null).isEmpty()); + assertFalse(pc.findTags("").isEmpty()); + assertTrue(pc.findTags("unknown").isEmpty()); + assertTrue(pc.findTags(t.getTag()).size() >= 1); + + assertEquals(3, pc.findTermInList(u.getType(), Config._ID, + Arrays.asList(u.getId(), u1.getId(), u2.getId(), "xxx", "yyy")).size()); + + // many terms + Map terms = new HashMap<>(); + // terms.put(Config._TYPE, u.getType()); + terms.put(Config._ID, u.getId()); + + Map terms1 = new HashMap<>(); + terms1.put(Config._TYPE, null); + terms1.put(Config._ID, " "); + + Map terms2 = new HashMap<>(); + terms2.put(" ", "bad"); + terms2.put("", ""); + + assertEquals(1, pc.findTerms(u.getType(), terms, true).size()); + assertTrue(pc.findTerms(u.getType(), terms1, true).isEmpty()); + assertTrue(pc.findTerms(u.getType(), terms2, true).isEmpty()); + + // single term + assertTrue(pc.findTerms(null, null, true).isEmpty()); + assertTrue(pc.findTerms(u.getType(), Collections.singletonMap("", null), true).isEmpty()); + assertTrue(pc.findTerms(u.getType(), Collections.singletonMap("", ""), true).isEmpty()); + assertTrue(pc.findTerms(u.getType(), Collections.singletonMap("term", null), true).isEmpty()); + assertTrue(pc.findTerms(u.getType(), Collections.singletonMap(Config._TYPE, u.getType()), true).size() >= 2); + assertTrue(pc.findTerms(u.getType(), Collections.singletonMap(Config._NAME, "Ann Smith"), true).size() >= 1); + // "name" field is not analyzed, see https://github.com/Erudika/para/issues/13 + assertTrue(pc.findTerms(u.getType(), Collections.singletonMap(Config._NAME, "ann smith"), true).isEmpty()); + // assertFalse(pc.findQuery(u.getType(), "\"Ann Smith\"").isEmpty()); + + assertTrue(pc.findWildcard(u.getType(), null, null).isEmpty()); + assertTrue(pc.findWildcard(u.getType(), "", "").isEmpty()); + assertFalse(pc.findWildcard(u.getType(), Config._NAME, "An*").isEmpty()); + + assertTrue(pc.getCount(null).intValue() > 4); + assertNotEquals(0, pc.getCount("").intValue()); + assertEquals(0, pc.getCount("test").intValue()); + assertTrue(pc.getCount(u.getType()).intValue() >= 3); + + assertEquals(0L, pc.getCount(null, null).intValue()); + assertEquals(0L, pc.getCount(u.getType(), Collections.singletonMap(Config._ID, " ")).intValue()); + assertEquals(1L, pc.getCount(u.getType(), Collections.singletonMap(Config._ID, u.getId())).intValue()); + assertTrue(pc.getCount(null, Collections.singletonMap(Config._TYPE, u.getType())).intValue() > 1); + } + + @Test + public void testLinks() throws InterruptedException { + assertNotNull(pc.link(u, t.getId())); + assertNotNull(pc.link(u, u2.getId())); + + assertFalse(pc.isLinked(u, null)); + assertTrue(pc.isLinked(u, t)); + assertTrue(pc.isLinked(u, u2)); + + assertEquals(1, pc.getLinkedObjects(u, Utils.type(Tag.class)).size()); + assertEquals(1, pc.getLinkedObjects(u, Utils.type(Sysprop.class)).size()); + + assertEquals(0, pc.countLinks(u, null).intValue()); + assertEquals(1, pc.countLinks(u, Utils.type(Tag.class)).intValue()); + assertEquals(1, pc.countLinks(u, Utils.type(Sysprop.class)).intValue()); + + pc.unlinkAll(u); + + assertFalse(pc.isLinked(u, t)); + assertFalse(pc.isLinked(u, u2)); + + Sysprop second1 = new Sysprop("secondLink1"); + Sysprop second2 = new Sysprop("secondLink2"); + Sysprop second3 = new Sysprop("secondLink3"); + second1.addProperty("text", "hello from the other side"); + second2.addProperty("text", "hello kitty"); + second3.setName("gordon"); + + Sysprop child1 = new Sysprop("child1"); + Sysprop child2 = new Sysprop("child2"); + Sysprop child3 = new Sysprop("child3"); + child1.setParentid(u.getId()); + child2.setParentid(u.getId()); + child3.setParentid(u.getId()); + child1.addProperty("text", "hello from the other side"); + child2.addProperty("text", "hello kitty"); + child3.setName("gordon"); + + pc.createAll(Arrays.asList(second1, second2, second3, child1, child2, child3)); + + assertNotNull(pc.link(u, second1.getId())); + assertNotNull(pc.link(u, second2.getId())); + assertNotNull(pc.link(u, second3.getId())); + + // test linked objects search + assertTrue(pc.findLinkedObjects(u, second1.getType(), Config._NAME, null).size() >= 3); + + List found1 = pc.findLinkedObjects(u, second1.getType(), Config._NAME, "gord*"); + assertFalse(found1.isEmpty()); + assertTrue(found1.get(0).getId().equals(second3.getId())); + + List found2 = pc.findLinkedObjects(u, second1.getType(), "properties.text", "kitt*"); + assertFalse(found2.isEmpty()); + assertTrue(found2.get(0).getId().equals(second2.getId())); + + List found3 = pc.findLinkedObjects(u, second1.getType(), "properties.text", "hello"); + assertEquals(2, found3.size()); + assertTrue(found3.get(0).getId().equals(second1.getId()) || found3.get(1).getId().equals(second1.getId())); + assertTrue(found3.get(0).getId().equals(second2.getId()) || found3.get(1).getId().equals(second2.getId())); + + // test children search + assertEquals(3, pc.findChildren(u, child1.getType(), null).size()); + + List result1 = pc.findChildren(u, child1.getType(), "gord*"); + assertFalse(result1.isEmpty()); + assertTrue(result1.get(0).getId().equals(child3.getId())); + + List result2 = pc.findChildren(u, child1.getType(), "kitt*"); + assertFalse(result2.isEmpty()); + assertTrue(result2.get(0).getId().equals(child2.getId())); + + List result3 = pc.findChildren(u, child1.getType(), "hello"); + assertEquals(2, result3.size()); + assertTrue(result3.get(0).getId().equals(child1.getId()) || result3.get(1).getId().equals(child1.getId())); + assertTrue(result3.get(0).getId().equals(child2.getId()) || result3.get(1).getId().equals(child2.getId())); + + pc.unlinkAll(u); + pc.deleteAll(Arrays.asList(second1.getId(), second2.getId(), second3.getId(), + child1.getId(), child2.getId(), child3.getId())); + } + + @Test + public void testUtils() { + String id1 = pc.newId(); + String id2 = pc.newId(); + assertNotNull(id1); + assertFalse(id1.isEmpty()); + assertNotEquals(id1, id2); + + final Long ts = pc.getTimestamp(); + assertNotNull(ts); + assertNotEquals(0, ts.intValue()); + + String date1 = pc.formatDate("MM dd yyyy", Locale.US); + String date2 = Utils.formatDate("MM dd yyyy", Locale.US); + assertEquals(date1, date2); + + String ns1 = pc.noSpaces(" test 123 test ", ""); + String ns2 = Utils.noSpaces(" test 123 test ", ""); + assertEquals(ns1, ns2); + + String st1 = pc.stripAndTrim(" %^&*( cool ) @!"); + String st2 = Utils.stripAndTrim(" %^&*( cool ) @!"); + assertEquals(st1, st2); + + String md1 = pc.markdownToHtml("**test** #hello"); + String md2 = Utils.markdownToHtml("**test** #hello"); + assertEquals(md1, md2); + + String ht1 = pc.approximately(15000); + String ht2 = HumanTime.approximately(15000); + assertEquals(ht1, ht2); + } + + @Test + public void testMisc() { + Map types = pc.types(); + assertNotNull(types); + assertFalse(types.isEmpty()); + assertTrue(types.containsKey(new User().getPlural())); + + assertEquals(App.id(APP_NAME), pc.me().getId()); + } + + @Test + public void testValidationConstraints() { + // Validations + String kittenType = "kitten"; + Map constraints = pc.validationConstraints(); + assertNotNull(constraints); + assertFalse(constraints.isEmpty()); + assertTrue(constraints.containsKey("app")); + assertTrue(constraints.containsKey("user")); + + Map>>> constraint = pc.validationConstraints("app"); + assertFalse(constraint.isEmpty()); + assertTrue(constraint.containsKey("app")); + assertEquals(1, constraint.size()); + + pc.addValidationConstraint(kittenType, "paws", required()); + constraint = pc.validationConstraints(kittenType); + assertNotNull(constraint); + assertNotNull(constraint.get(kittenType)); + assertTrue(constraint.get(kittenType).containsKey("paws")); + + Sysprop ct = new Sysprop("felix"); + pc.delete(ct); + pc.delete(new Vote(u.getId(), ct.getId(), Votable.VoteValue.UP)); + pc.delete(new Vote(u.getId(), ct.getId(), Votable.VoteValue.DOWN)); + ct.setType(kittenType); + Sysprop ct2 = null; + try { + // validation fails + ct2 = pc.create(ct); + } catch (Exception e) { + } + + assertNull(ct2); + ct.addProperty("paws", "4"); + assertNotNull(pc.create(ct)); + + pc.removeValidationConstraint(kittenType, "paws", "required"); + constraint = pc.validationConstraints(kittenType); + assertFalse(constraint.containsKey(kittenType)); + + Integer votes = ct.getVotes() + 1; + assertTrue(pc.voteUp(ct, u.getId())); + assertEquals(votes, pc.read(ct.getId()).getVotes()); + assertFalse(pc.voteUp(ct, u.getId())); + votes -= 1; + assertTrue(pc.voteDown(ct, u.getId())); + assertEquals(votes, pc.read(ct.getId()).getVotes()); + votes -= 1; + assertTrue(pc.voteDown(ct, u.getId())); + assertFalse(pc.voteDown(ct, u.getId())); + assertEquals(votes, pc.read(ct.getId()).getVotes()); + Para.getDAO().delete(ct); + Para.getDAO().delete(new Vote(u.getId(), ct.getId(), Votable.VoteValue.UP)); + } + + @Test + public void testResourcePermissions() { + // Permissions + Map>> permits = pcc.resourcePermissions(); + assertNotNull(permits); + + assertTrue(pcc.grantResourcePermission(null, dogsType, EnumSet.noneOf(AllowedMethods.class)).isEmpty()); + assertTrue(pcc.grantResourcePermission(" ", "", EnumSet.noneOf(AllowedMethods.class)).isEmpty()); + + pcc.grantResourcePermission(u1.getId(), dogsType, READ); + permits = pcc.resourcePermissions(u1.getId()); + assertTrue(permits.containsKey(u1.getId())); + assertTrue(permits.get(u1.getId()).containsKey(dogsType)); + assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); + assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, POST.toString())); + + permits = pcc.resourcePermissions(); + assertTrue(permits.containsKey(u1.getId())); + assertTrue(permits.get(u1.getId()).containsKey(dogsType)); + + pcc.revokeResourcePermission(u1.getId(), dogsType); + permits = pcc.resourcePermissions(u1.getId()); + assertFalse(permits.get(u1.getId()).containsKey(dogsType)); + assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); + assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, POST.toString())); + + pcc.grantResourcePermission(u2.getId(), App.ALLOW_ALL, WRITE); + assertTrue(pcc.isAllowedTo(u2.getId(), dogsType, PUT.toString())); + assertTrue(pcc.isAllowedTo(u2.getId(), dogsType, PATCH.toString())); + + pcc.revokeAllResourcePermissions(u2.getId()); + permits = pcc.resourcePermissions(); + assertFalse(pcc.isAllowedTo(u2.getId(), dogsType, PUT.toString())); + assertFalse(permits.containsKey(u2.getId())); + // assertTrue(permits.get(u2.getId()).isEmpty()); + + pcc.grantResourcePermission(u1.getId(), dogsType, WRITE); + pcc.grantResourcePermission(App.ALLOW_ALL, catsType, WRITE); + pcc.grantResourcePermission(App.ALLOW_ALL, App.ALLOW_ALL, READ); + // user-specific permissions are in effect + assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, PUT.toString())); + assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), catsType, PUT.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), catsType, GET.toString())); + + pcc.revokeAllResourcePermissions(u1.getId()); + // user-specific permissions not found so check wildcard + assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, PUT.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), catsType, PUT.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), catsType, GET.toString())); + + pcc.revokeResourcePermission(App.ALLOW_ALL, catsType); + // resource-specific permissions not found so check wildcard + assertFalse(pcc.isAllowedTo(u1.getId(), dogsType, PUT.toString())); + assertFalse(pcc.isAllowedTo(u1.getId(), catsType, PUT.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), dogsType, GET.toString())); + assertTrue(pcc.isAllowedTo(u1.getId(), catsType, GET.toString())); + assertTrue(pcc.isAllowedTo(u2.getId(), dogsType, GET.toString())); + assertTrue(pcc.isAllowedTo(u2.getId(), catsType, GET.toString())); + + pcc.revokeAllResourcePermissions(App.ALLOW_ALL); + pcc.revokeAllResourcePermissions(u1.getId()); + } + + @Test + public void testAppSettings() { + Map settings = pc.appSettings(); + assertNotNull(settings); + assertTrue(settings.isEmpty()); + + pc.addAppSetting("", null); + pc.addAppSetting(" ", " "); + pc.addAppSetting(null, " "); + pc.addAppSetting("prop1", 1); + pc.addAppSetting("prop2", true); + pc.addAppSetting("prop3", "string"); + + settings = pc.appSettings(); + assertEquals(3, settings.size()); + assertEquals(settings, pc.appSettings(null)); + assertEquals(1, settings.get("prop1")); + assertEquals(true, settings.get("prop2")); + assertEquals("string", settings.get("prop3")); + + pc.removeAppSetting("prop3"); + pc.removeAppSetting(" "); + pc.removeAppSetting(null); + + settings = pc.appSettings(); + assertFalse(settings.containsKey("prop3")); + assertEquals(2, settings.size()); + pc.removeAppSetting("prop2"); + pc.removeAppSetting("prop1"); + + pc.addAppSetting("propZ", 1); + Map newSettings = new HashMap<>(); + newSettings.put("propX", "X"); + newSettings.put("propY", "Y"); + pc.setAppSettings(newSettings); + settings = pc.appSettings(); + assertEquals(2, settings.size()); + assertFalse(settings.containsKey("propZ")); + assertTrue(settings.containsKey("propX")); + assertTrue(settings.containsKey("propY")); + newSettings.clear(); + pc.setAppSettings(newSettings); + settings = pc.appSettings(); + assertTrue(settings.isEmpty()); + } + + @Test + public void testAccessTokens() throws IOException, InterruptedException { + assertNotNull(fbUser); + assertNull(pc2.getAccessToken()); + + // fails with google+ - service not mocked + User failsNotMocked = pc2.signIn("google", "test_token"); + assertNull(failsNotMocked); + + // should fail to create user for root app + // System.setProperty("para.clients_can_access_root_app", "false"); + User notSignedIn = pc2.signIn("facebook", "test_token"); + logger.info(pc2.getAccessToken()); + assertNull(notSignedIn); + assertNull(pc2.getAccessToken()); + + // then allow clients to modify root app + // System.setProperty("para.clients_can_access_root_app", "true"); + User signedIn = pc2.signIn("facebook", "test_token"); + logger.info(pc2.getAccessToken()); + assertNull(signedIn); + assertNull(pc2.getAccessToken()); + + // test without permissions - signed in but you can't access anything yet + signedIn = pcc.signIn("facebook", "test_token"); + pcc.revokeAllResourcePermissions(fbUser.getId()); + ParaObject me = pcc.me(); + assertNotNull(me); + assertEquals("user", me.getType()); + assertTrue(pcc.newId().isEmpty()); + assertTrue(pcc.getTimestamp() == 0L); + + // test with permissions - logout first to use app credentials (full access) + pcc.signOut(); + pcc.grantResourcePermission(fbUser.getId(), App.ALLOW_ALL, READ_AND_WRITE); + signedIn = pcc.signIn("facebook", "test_token"); + logger.info(pcc.getAccessToken()); + assertNotNull(signedIn); + assertNotNull(pcc.getAccessToken()); + me = pcc.me(); + assertNotNull(me); + assertFalse(pcc.newId().isEmpty()); + assertEquals(signedIn.getName(), me.getName()); + + // now switch back to App access + pcc.signOut(); + assertNull(pcc.getAccessToken()); + me = pcc.me(); // app + assertNotNull(me); + assertEquals("app", me.getType()); + assertFalse(pcc.newId().isEmpty()); + signedIn = pcc.signIn("facebook", "test_token"); + logger.info(pcc.getAccessToken()); + me = pcc.me(); // user + assertNotNull(me); + assertEquals("user", me.getType()); + assertEquals(signedIn.getId(), me.getId()); + + assertNull(pcc.newKeys()); // users can't change API keys! + + // test revoke tokens + pcc.revokeAllTokens(); + assertTrue(pcc.newId().isEmpty()); + assertTrue(pcc.getTimestamp() == 0L); + assertNull(pcc.me()); + + pcc.signOut(); + + // test anonymous permissions + String utilsPath = "utils/timestamp"; + ParaClient guest = new ParaClient(App.id(APP_NAME_CHILD), null); + guest.setEndpoint(pcc.getEndpoint()); + assertFalse(guest.getTimestamp() > 0); + assertFalse(guest.isAllowedTo(App.ALLOW_ALL, utilsPath, GET.toString())); + pcc.grantResourcePermission(App.ALLOW_ALL, utilsPath, READ, true); + assertTrue(guest.getTimestamp() > 0); + } + + @Test + public void testOwnersPermissions() throws InterruptedException { + // test user should be able to login twice - first time the object is created, second time password is checked + String emailInactive = "test2@user.com"; + String emailPassFail = emailInactive + "::12345678"; + String emailPassPass = "test3@user.com::12345678"; + String emailPassPass2 = "test4@user.com::12345678"; + assertNull(pcc.signIn("password", emailPassFail)); // unverified email - user is created but not active + List failed = pcc.findTerms(fbUser.getType(), Collections.singletonMap(Config._EMAIL, emailInactive), true); + assertFalse(failed.isEmpty()); + assertEquals(emailInactive, failed.get(0).getEmail()); + pcc.delete(failed.get(0)); + + System.setProperty("para.security.allow_unverified_emails", "true"); // allow it + User newUser = pcc.signIn("password", emailPassPass); + User newUser2 = pcc.signIn("password", emailPassPass2); + assertNotNull(newUser); + assertNotNull(newUser2); + pcc.signOut(); + assertNotNull(pcc.signIn("password", emailPassPass)); + pcc.signOut(); + + // test permissions with/without signed in user + assertTrue(pcc.isAllowedTo(newUser.getId(), newUser.getObjectURI(), GET.toString())); + assertNotNull(pcc.signIn("password", emailPassPass)); + assertTrue(pcc.isAllowedTo(newUser.getId(), newUser.getObjectURI(), GET.toString())); + assertFalse(pcc.isAllowedTo(newUser.getId(), newUser.getObjectURI() + "x", GET.toString())); + assertNotNull(pcc.read(newUser.getId())); // can read self + pcc.signOut(); + + // test implicit user permissions - read/update/delete own object (children) + assertFalse(pcc.isAllowedTo(newUser.getId(), "todo", POST.toString())); // can't create yet + pcc.grantResourcePermission(newUser.getId(), "todo", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs + pcc.grantResourcePermission(newUser.getId(), "todo/*", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs + pcc.signIn("password", emailPassPass); + assertTrue(pcc.isAllowedTo(newUser.getId(), "todo", POST.toString())); + Sysprop todo = new Sysprop("todo_id"); + todo.setType("todo"); + // test if creatorid is set correctly + todo.setCreatorid("invalid_user_id"); // must be corrected by the server + todo.setName("[] buy milk"); + todo = pcc.create(todo); + + assertNotNull(todo); + assertFalse(todo.getId().equals("todo_id")); + assertNotNull(pcc.read(todo.getType(), todo.getId())); + assertEquals(1, pcc.findQuery("todo", "*").size()); // user only sees own TODO + assertEquals(newUser.getId(), todo.getCreatorid()); + pcc.signOut(); + + // one user must not be able to overwrite another user's TODOs (custom ids) + pcc.grantResourcePermission(newUser2.getId(), "todo", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs + pcc.grantResourcePermission(newUser2.getId(), "todo/*", EnumSet.of(READ_WRITE, OWN)); // can only manage own TODOs + pcc.signIn("password", emailPassPass2); + assertTrue(pcc.list("todo").isEmpty()); + assertNull(pcc.read(todo.getId())); + Sysprop todo2 = new Sysprop("todo_id2"); + todo2.setType("todo"); + todo2.setName("[] buy eggs"); + todo2 = pcc.create(todo2); + assertNotNull(todo2); + assertFalse(todo2.getId().equals("todo_id2")); + assertNotNull(pcc.read(todo2.getType(), todo2.getId())); + assertEquals(1, pcc.findQuery("todo", "*").size()); + assertEquals(newUser2.getId(), todo2.getCreatorid()); + pcc.signOut(); + // app can see all TODOs + assertEquals(2, pcc.list("todo").size()); + + pc.delete(todo); + pc.delete(todo2); + pc.delete(newUser); + pc.delete(newUser2); + pc.deleteAll(List.of(emailPassPass, emailPassPass2)); + + // an app should be able to update and delete itself + String appId = "para-child-app-test"; + Map creds = Para.newApp(appId, "Child app", false, false); + ParaClient pclient = new ParaClient(App.id(appId), creds.get("secretKey")); + pclient.setEndpoint(pc.getEndpoint()); + + App app = pclient.me(); + assertNotNull(app); + assertEquals(appId, app.getAppIdentifier()); + + app.setName("Child application"); + pclient.update(app); + app = pclient.me(); + assertEquals("Child application", app.getName()); + + pclient.delete(app); + assertNull(pclient.read(App.id(appId))); + } + } +} diff --git a/para-server/src/test/java/com/erudika/para/core/AddressTest.java b/para-server/src/test/java/com/erudika/para/core/AddressTest.java index e4fac28b..324ad9a6 100644 --- a/para-server/src/test/java/com/erudika/para/core/AddressTest.java +++ b/para-server/src/test/java/com/erudika/para/core/AddressTest.java @@ -17,8 +17,11 @@ */ package com.erudika.para.core; -import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + /** * diff --git a/para-server/src/test/java/com/erudika/para/core/AppTest.java b/para-server/src/test/java/com/erudika/para/core/AppTest.java index 2e31444a..b009b244 100644 --- a/para-server/src/test/java/com/erudika/para/core/AppTest.java +++ b/para-server/src/test/java/com/erudika/para/core/AppTest.java @@ -41,8 +41,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static org.junit.Assert.*; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/core/LinkerTest.java b/para-server/src/test/java/com/erudika/para/core/LinkerTest.java index e76e5c57..9c9a0277 100644 --- a/para-server/src/test/java/com/erudika/para/core/LinkerTest.java +++ b/para-server/src/test/java/com/erudika/para/core/LinkerTest.java @@ -18,8 +18,9 @@ package com.erudika.para.core; import com.erudika.para.core.utils.Utils; -import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/core/NestedITs.java b/para-server/src/test/java/com/erudika/para/core/NestedITs.java new file mode 100644 index 00000000..bd351734 --- /dev/null +++ b/para-server/src/test/java/com/erudika/para/core/NestedITs.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2024 Erudika. http://erudika.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * For issues and patches go to: https://github.com/erudika + */ +package com.erudika.para.core; + +import org.junit.jupiter.api.ClassOrderer; +import org.junit.jupiter.api.TestClassOrder; + +/** + * Integration tests for ParaClient & AWSDynamoDBDAO + * @author Alex Bogdanovski [alex@erudika.com] + */ +@TestClassOrder(ClassOrderer.OrderAnnotation.class) +public interface NestedITs { + +} diff --git a/para-server/src/test/java/com/erudika/para/core/ParaObjectTest.java b/para-server/src/test/java/com/erudika/para/core/ParaObjectTest.java index 58f0db6a..91cd533f 100644 --- a/para-server/src/test/java/com/erudika/para/core/ParaObjectTest.java +++ b/para-server/src/test/java/com/erudika/para/core/ParaObjectTest.java @@ -17,18 +17,26 @@ */ package com.erudika.para.core; -import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.persistence.DAO; import com.erudika.para.core.persistence.MockDAO; import com.erudika.para.core.search.Search; +import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.utils.Utils; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import org.junit.Test; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * diff --git a/para-server/src/test/java/com/erudika/para/core/ParaObjectUtilsTest.java b/para-server/src/test/java/com/erudika/para/core/ParaObjectUtilsTest.java index feae4fa9..503c1cf1 100644 --- a/para-server/src/test/java/com/erudika/para/core/ParaObjectUtilsTest.java +++ b/para-server/src/test/java/com/erudika/para/core/ParaObjectUtilsTest.java @@ -18,13 +18,13 @@ package com.erudika.para.core; import com.erudika.para.core.annotations.Stored; +import com.erudika.para.core.utils.Cat; +import com.erudika.para.core.utils.CatDeserializer; +import com.erudika.para.core.utils.CatSerializer; import static com.erudika.para.core.utils.ParaObjectUtils.getAnnotatedFields; import static com.erudika.para.core.utils.ParaObjectUtils.getAppidFromAuthHeader; import static com.erudika.para.core.utils.ParaObjectUtils.getCoreTypes; import static com.erudika.para.core.utils.ParaObjectUtils.setAnnotatedFields; -import com.erudika.para.core.utils.Cat; -import com.erudika.para.core.utils.CatDeserializer; -import com.erudika.para.core.utils.CatSerializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.net.URI; @@ -34,14 +34,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /** * TODO! @@ -52,11 +52,11 @@ public class ParaObjectUtilsTest { public ParaObjectUtilsTest() { } - @BeforeClass + @BeforeAll public static void setUpClass() { } - @AfterClass + @AfterAll public static void tearDownClass() { } diff --git a/para-server/src/test/java/com/erudika/para/core/SyspropTest.java b/para-server/src/test/java/com/erudika/para/core/SyspropTest.java index 0029903e..1bb1f62b 100644 --- a/para-server/src/test/java/com/erudika/para/core/SyspropTest.java +++ b/para-server/src/test/java/com/erudika/para/core/SyspropTest.java @@ -17,10 +17,12 @@ */ package com.erudika.para.core; -import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.persistence.DAO; -import org.junit.Test; -import static org.junit.Assert.*; +import com.erudika.para.core.utils.CoreUtils; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/core/TagTest.java b/para-server/src/test/java/com/erudika/para/core/TagTest.java index 2e61045f..b9c13ee4 100644 --- a/para-server/src/test/java/com/erudika/para/core/TagTest.java +++ b/para-server/src/test/java/com/erudika/para/core/TagTest.java @@ -19,9 +19,11 @@ import com.erudika.para.core.persistence.DAO; import com.erudika.para.core.persistence.MockDAO; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * @@ -32,7 +34,7 @@ public class TagTest { private DAO dao; private Tag t; - @Before + @BeforeEach public void setUp() { dao = new MockDAO(); t = new Tag("test"); @@ -63,6 +65,12 @@ public void testId() { assertEquals("tag:d--", t.getId()); t.setId("A123"); assertEquals("tag:a123", t.getId()); + t.setId("+-#-+971507107546-#abortio"); + assertEquals("tag:971507107546-#abortio", t.getId()); + t.setId("#-+971507107546-#abortio+"); + assertEquals("tag:971507107546-#abortio+", t.getId()); + t.setId("# +971507107546 #abortio+"); + assertEquals("tag:971507107546-#abortio+", t.getId()); t.setId("tag:tag-test1"); assertEquals("tag:tag-test1", t.getId()); diff --git a/para-server/src/test/java/com/erudika/para/core/UserTest.java b/para-server/src/test/java/com/erudika/para/core/UserTest.java index 440335bb..c2a341f6 100644 --- a/para-server/src/test/java/com/erudika/para/core/UserTest.java +++ b/para-server/src/test/java/com/erudika/para/core/UserTest.java @@ -32,10 +32,16 @@ import java.util.HashMap; import java.util.Map; import javax.naming.LimitExceededException; -import org.junit.After; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import static org.mockito.Mockito.*; /** @@ -58,13 +64,13 @@ private static DAO dao() { return CoreUtils.getInstance().getDao(); //new MockDAO(); } - @Before + @BeforeEach public void setUp() { System.setProperty("para.min_password_length", "6"); CoreUtils.getInstance().setSearch(mock(Search.class)); } - @After + @AfterEach public void tearDown() { } diff --git a/para-server/src/test/java/com/erudika/para/core/VoteTest.java b/para-server/src/test/java/com/erudika/para/core/VoteTest.java index e071e61a..94d40499 100644 --- a/para-server/src/test/java/com/erudika/para/core/VoteTest.java +++ b/para-server/src/test/java/com/erudika/para/core/VoteTest.java @@ -17,10 +17,10 @@ */ package com.erudika.para.core; -import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.persistence.DAO; -import org.junit.Test; -import static org.junit.Assert.*; +import com.erudika.para.core.utils.CoreUtils; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/core/utils/ConfigTest.java b/para-server/src/test/java/com/erudika/para/core/utils/ConfigTest.java index c11df926..d3cde542 100644 --- a/para-server/src/test/java/com/erudika/para/core/utils/ConfigTest.java +++ b/para-server/src/test/java/com/erudika/para/core/utils/ConfigTest.java @@ -17,8 +17,11 @@ */ package com.erudika.para.core.utils; -import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + /** * diff --git a/para-server/src/test/java/com/erudika/para/core/utils/HumanTimeTest.java b/para-server/src/test/java/com/erudika/para/core/utils/HumanTimeTest.java index e37fe17a..436bdce4 100644 --- a/para-server/src/test/java/com/erudika/para/core/utils/HumanTimeTest.java +++ b/para-server/src/test/java/com/erudika/para/core/utils/HumanTimeTest.java @@ -21,14 +21,15 @@ */ package com.erudika.para.core.utils; -import com.erudika.para.core.utils.HumanTime; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; - -import junit.framework.TestCase; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * Test case for {@link HumanTime}. @@ -38,26 +39,21 @@ * @see Date * Formatting and Parsing for Humans in Java with HumanTime */ -public class HumanTimeTest extends TestCase { - - public HumanTimeTest() { - super(); - } - - public HumanTimeTest(String name) { - super(name); - } +public class HumanTimeTest { + @Test public void testD() { assertEquals("2 d", new HumanTime().d().d().getExactly()); assertEquals("2 d", new HumanTime().d().h(-24).getExactly()); } + @Test public void testY() { assertEquals("1 y", HumanTime.eval("-1Y").toString()); assertEquals("320 y", HumanTime.eval("- 4 319 y Y").y().toString()); } + @Test public void testS() { assertEquals("2 s", HumanTime.eval("1 s s").s().toString()); assertEquals("4 s", HumanTime.eval("2 s s").s().s().toString()); @@ -66,6 +62,7 @@ public void testS() { /** * Test method for {@link com.eaio.util.text.HumanTime#eval(java.lang.CharSequence)}. */ + @Test public void testEval() { assertEquals("2 m", HumanTime.eval("2 m").getExactly()); assertEquals("8 d 2 h 6 m", HumanTime.eval("2m8d2h4m").getExactly()); @@ -80,11 +77,13 @@ public void testEval() { /** * Test method for {@link com.eaio.util.text.HumanTime#exactly(long)}. */ + @Test public void testExactlyLong() { assertEquals("42 ms", HumanTime.exactly(42)); assertEquals("1 s 42 ms", HumanTime.exactly(1042)); } + @Test public void testApproximately() { assertEquals("42ms", HumanTime.approximately(42)); assertEquals("1s", HumanTime.approximately(1042)); @@ -114,12 +113,14 @@ public void testApproximately() { assertEquals("1d", HumanTime.approximately("23 h 1h 10 s")); } + @Test public void testEquals() { assertEquals(HumanTime.eval("4d20m1s"), HumanTime.eval(" 4 d20 m 1 s ")); assertFalse(HumanTime.eval("4d20m2s").equals(HumanTime.eval(" 4 d20 m 1 s "))); assertFalse(HumanTime.eval("4d20m1s").equals(HumanTime.eval(" 4 d20 m 1 d "))); } + @Test public void testGetStateChar() { assertEquals(HumanTime.State.IGNORED, HumanTime.getState(' ')); assertEquals(HumanTime.State.IGNORED, HumanTime.getState('a')); @@ -129,11 +130,13 @@ public void testGetStateChar() { assertEquals(HumanTime.State.UNIT, HumanTime.getState('d')); } + @Test public void testHashCode() throws CloneNotSupportedException { assertEquals(0, new HumanTime(0L).hashCode()); assertTrue(HumanTime.eval("42 s").hashCode() != 0); } + @Test public void testSerialization() throws IOException, ClassNotFoundException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream oOut = new ObjectOutputStream(bOut); diff --git a/para-server/src/test/java/com/erudika/para/core/utils/IdGenTest.java b/para-server/src/test/java/com/erudika/para/core/utils/IdGenTest.java index 28ae7791..9a1fcb93 100644 --- a/para-server/src/test/java/com/erudika/para/core/utils/IdGenTest.java +++ b/para-server/src/test/java/com/erudika/para/core/utils/IdGenTest.java @@ -17,41 +17,39 @@ */ package com.erudika.para.core.utils; -import com.erudika.para.core.utils.Utils; -import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner; -import com.anarsoft.vmlens.concurrent.junit.ThreadCount; import java.util.ArrayList; import java.util.HashSet; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; /** * Concurrency test for ID generation in Para. * @author Alex Bogdanovski [alex@erudika.com] */ -@RunWith(ConcurrentTestRunner.class) +@Execution(ExecutionMode.CONCURRENT) public class IdGenTest { final ArrayList ids = new ArrayList(); - @Before + @BeforeEach public void setup() throws Exception { } @Test - @ThreadCount(16) +// @ThreadCount(16) public void testGetNewId() { ids.add(Utils.getNewId()); } - @After + @AfterEach public void tearDown() { HashSet uniqueIds = new HashSet(ids.size()); for (String id : ids) { if (uniqueIds.contains(id)) { - Assert.fail("Duplicate ID generated: " + id); + fail("Duplicate ID generated: " + id); } uniqueIds.add(id); } diff --git a/para-server/src/test/java/com/erudika/para/core/utils/OAuth1HmacSignerTest.java b/para-server/src/test/java/com/erudika/para/core/utils/OAuth1HmacSignerTest.java index d35f716d..01d7b47f 100644 --- a/para-server/src/test/java/com/erudika/para/core/utils/OAuth1HmacSignerTest.java +++ b/para-server/src/test/java/com/erudika/para/core/utils/OAuth1HmacSignerTest.java @@ -17,18 +17,17 @@ */ package com.erudika.para.core.utils; -import com.erudika.para.core.utils.Utils; import com.erudika.para.server.security.OAuth1HmacSigner; import java.util.Collections; import java.util.Map; import java.util.TreeMap; -import org.junit.After; -import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * @@ -36,19 +35,19 @@ */ public class OAuth1HmacSignerTest { - @BeforeClass + @BeforeAll public static void setUpClass() { } - @AfterClass + @AfterAll public static void tearDownClass() { } - @Before + @BeforeEach public void setUp() { } - @After + @AfterEach public void tearDown() { } diff --git a/para-server/src/test/java/com/erudika/para/core/utils/UtilsTest.java b/para-server/src/test/java/com/erudika/para/core/utils/UtilsTest.java index 38e667c9..89500076 100644 --- a/para-server/src/test/java/com/erudika/para/core/utils/UtilsTest.java +++ b/para-server/src/test/java/com/erudika/para/core/utils/UtilsTest.java @@ -36,10 +36,15 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.commons.lang3.StringUtils; import org.joda.time.Instant; -import static org.junit.Assert.*; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import org.junit.jupiter.api.Test; /** * @@ -366,7 +371,7 @@ public void testSetAnnotatedFields() { assertEquals(map.get(Config._NAME), obj2.getName()); assertEquals(map.get(Config._EMAIL), obj2.getEmail()); assertEquals(timestamp, obj2.getTimestamp().longValue()); - assertEquals(true, obj2.getActive()); + assertEquals(true, obj2.getActive().booleanValue()); // complex nested objects coming from Jackson Map map1 = new HashMap<>(); diff --git a/para-server/src/test/java/com/erudika/para/core/utils/ValidationUtilsTest.java b/para-server/src/test/java/com/erudika/para/core/utils/ValidationUtilsTest.java index 89327677..e9f16b21 100644 --- a/para-server/src/test/java/com/erudika/para/core/utils/ValidationUtilsTest.java +++ b/para-server/src/test/java/com/erudika/para/core/utils/ValidationUtilsTest.java @@ -28,8 +28,11 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; -import static org.junit.Assert.*; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/email/EmailerTest.java b/para-server/src/test/java/com/erudika/para/email/EmailerTest.java index 1bedd6fb..45ad70a6 100644 --- a/para-server/src/test/java/com/erudika/para/email/EmailerTest.java +++ b/para-server/src/test/java/com/erudika/para/email/EmailerTest.java @@ -20,15 +20,16 @@ import com.erudika.para.core.email.Emailer; import java.util.ArrayList; import java.util.Collections; -import static org.junit.Assert.*; -import org.junit.Ignore; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** * * @author Alex Bogdanovski [alex@erudika.com] */ -@Ignore +@Disabled public abstract class EmailerTest { protected Emailer e; diff --git a/para-server/src/test/java/com/erudika/para/i18n/CurrencyUtilsTest.java b/para-server/src/test/java/com/erudika/para/i18n/CurrencyUtilsTest.java index 810eaf7a..1d813652 100644 --- a/para-server/src/test/java/com/erudika/para/i18n/CurrencyUtilsTest.java +++ b/para-server/src/test/java/com/erudika/para/i18n/CurrencyUtilsTest.java @@ -19,8 +19,12 @@ import com.erudika.para.core.i18n.CurrencyUtils; import java.util.Locale; -import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/rest/RestUtilsTest.java b/para-server/src/test/java/com/erudika/para/rest/RestUtilsTest.java index 7d19ae06..4f744dae 100644 --- a/para-server/src/test/java/com/erudika/para/rest/RestUtilsTest.java +++ b/para-server/src/test/java/com/erudika/para/rest/RestUtilsTest.java @@ -36,18 +36,20 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.google.inject.Binder; import com.google.inject.Module; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response.Status; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.HashMap; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response.Status; -import org.junit.AfterClass; -import static org.junit.Assert.*; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; /** * @@ -58,7 +60,7 @@ public class RestUtilsTest { public RestUtilsTest() { } - @BeforeClass + @BeforeAll public static void setUpClass() { System.setProperty("para.env", "embedded"); System.setProperty("para.app_name", "para-test"); @@ -75,7 +77,7 @@ public void configure(Binder binder) { }); } - @AfterClass + @AfterAll public static void tearDownClass() { Para.destroy(); } diff --git a/para-server/src/test/java/com/erudika/para/search/SearchTest.java b/para-server/src/test/java/com/erudika/para/search/SearchTest.java index 0e99dc69..641a5d28 100644 --- a/para-server/src/test/java/com/erudika/para/search/SearchTest.java +++ b/para-server/src/test/java/com/erudika/para/search/SearchTest.java @@ -17,16 +17,16 @@ */ package com.erudika.para.search; -import com.erudika.para.core.search.Search; import com.erudika.para.core.Address; import com.erudika.para.core.App; import com.erudika.para.core.Linker; import com.erudika.para.core.ParaObject; -import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.Sysprop; import com.erudika.para.core.Tag; import com.erudika.para.core.User; +import com.erudika.para.core.search.Search; import com.erudika.para.core.utils.Config; +import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.utils.Pager; import com.erudika.para.core.utils.Utils; import java.util.ArrayList; @@ -35,15 +35,20 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Ignore; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** * * @author Alex Bogdanovski [alex@erudika.com] */ -@Ignore +@Disabled public abstract class SearchTest { protected static Search s; diff --git a/para-server/src/test/java/com/erudika/para/security/LdapAuthTest.java b/para-server/src/test/java/com/erudika/para/security/LdapAuthTest.java index 6efb4967..9607bdc7 100644 --- a/para-server/src/test/java/com/erudika/para/security/LdapAuthTest.java +++ b/para-server/src/test/java/com/erudika/para/security/LdapAuthTest.java @@ -24,11 +24,11 @@ import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; import com.unboundid.ldap.listener.InMemoryListenerConfig; import java.util.Map; -import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextOperations; @@ -42,30 +42,35 @@ */ public class LdapAuthTest { - private static LDAPAuthenticator bindAuthenticator; - private static LDAPAuthenticator passComparingAuthenticator; - private static InMemoryDirectoryServer server; - private static Authentication bob = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); - private static Authentication ben = new UsernamePasswordAuthenticationToken("ben", "benspassword"); + static LDAPAuthenticator bindAuthenticator; + static LDAPAuthenticator passComparingAuthenticator; + static InMemoryDirectoryServer server; + static Authentication bob = new UsernamePasswordAuthenticationToken("bob", "bobspassword"); + static Authentication ben = new UsernamePasswordAuthenticationToken("ben", "benspassword"); - @BeforeClass - public static void setUpClass() throws Exception { - InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=springframework,dc=org"); - config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", 8389)); - config.addAdditionalBindCredentials("uid=admin,ou=system", "secret"); - server = new InMemoryDirectoryServer(config); - server.startListening(); + @BeforeAll + public static void setUpClass() { + try { + System.out.println("-----------"); + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=springframework,dc=org"); + config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", 8389)); + config.addAdditionalBindCredentials("uid=admin,ou=system", "secret"); + server = new InMemoryDirectoryServer(config); + server.startListening(); - LdapTestUtils.loadLdif(server, new ClassPathResource("test-server.ldif")); - Map defaultSettings = Para.getConfig().getLdapSettingsForApp(new App("test")); - defaultSettings.put("security.ldap.user_dn_pattern", "uid={0},ou=people"); - bindAuthenticator = new LDAPAuthenticator(defaultSettings); - defaultSettings.put("security.ldap.compare_passwords", "true"); - passComparingAuthenticator = new LDAPAuthenticator(defaultSettings); + LdapTestUtils.loadLdif(server, new ClassPathResource("test-server.ldif")); + Map defaultSettings = Para.getConfig().getLdapSettingsForApp(new App("test")); + defaultSettings.put("security.ldap.user_dn_pattern", "uid={0},ou=people"); + bindAuthenticator = new LDAPAuthenticator(defaultSettings); + defaultSettings.put("security.ldap.compare_passwords", "true"); + passComparingAuthenticator = new LDAPAuthenticator(defaultSettings); + } catch (Exception e) { + e.printStackTrace(); + } } - @AfterClass - public static void tearDownClass() throws Exception { + @AfterAll + public static void tearDownClass() { server.shutDown("LDAP", true); } diff --git a/para-server/src/test/java/com/erudika/para/server/aop/AOPUtilsTest.java b/para-server/src/test/java/com/erudika/para/server/aop/AOPUtilsTest.java index 11ed269b..a2d45736 100644 --- a/para-server/src/test/java/com/erudika/para/server/aop/AOPUtilsTest.java +++ b/para-server/src/test/java/com/erudika/para/server/aop/AOPUtilsTest.java @@ -23,12 +23,17 @@ import com.erudika.para.core.persistence.DAO; import com.erudika.para.core.persistence.MockDAO; import com.erudika.para.core.search.Search; +import com.erudika.para.core.utils.Utils; +import static com.erudika.para.server.aop.AOPUtils.*; import java.util.ArrayList; import java.util.List; -import static com.erudika.para.server.aop.AOPUtils.*; -import com.erudika.para.core.utils.Utils; -import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; diff --git a/para-server/src/test/java/com/erudika/para/server/aop/AspectsIT.java b/para-server/src/test/java/com/erudika/para/server/aop/AspectsIT.java index 8ad2cb7b..65558812 100644 --- a/para-server/src/test/java/com/erudika/para/server/aop/AspectsIT.java +++ b/para-server/src/test/java/com/erudika/para/server/aop/AspectsIT.java @@ -17,18 +17,18 @@ */ package com.erudika.para.server.aop; -import com.erudika.para.core.utils.Para; -import com.erudika.para.server.ParaServer; -import com.erudika.para.core.cache.Cache; -import com.erudika.para.core.cache.MockCache; -import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.Sysprop; import com.erudika.para.core.Tag; import com.erudika.para.core.User; +import com.erudika.para.core.cache.Cache; +import com.erudika.para.core.cache.MockCache; import com.erudika.para.core.persistence.DAO; import com.erudika.para.core.persistence.MockDAO; import com.erudika.para.core.search.Search; +import com.erudika.para.core.utils.CoreUtils; +import com.erudika.para.core.utils.Para; import com.erudika.para.core.utils.Utils; +import com.erudika.para.server.ParaServer; import com.erudika.para.server.search.LuceneSearch; import com.google.inject.Binder; import com.google.inject.Module; @@ -38,10 +38,14 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import org.junit.AfterClass; -import static org.junit.Assert.*; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,7 +60,7 @@ public class AspectsIT { private static Sysprop s1; private static Sysprop s2; - @BeforeClass + @BeforeAll public static void setUpClass() throws Exception { System.setProperty("para.env", "embedded"); System.setProperty("para.print_logo", "false"); @@ -93,7 +97,7 @@ public void configure(Binder binder) { CoreUtils.getInstance().setSearch(Para.getSearch()); } - @AfterClass + @AfterAll public static void tearDownClass() throws Exception { Para.getDAO().deleteAll(Arrays.asList(s0, s1, s2)); Para.destroy(); diff --git a/para-server/src/test/java/com/erudika/para/server/cache/CacheTest.java b/para-server/src/test/java/com/erudika/para/server/cache/CacheTest.java index b4ab0e2a..c4a57db8 100644 --- a/para-server/src/test/java/com/erudika/para/server/cache/CacheTest.java +++ b/para-server/src/test/java/com/erudika/para/server/cache/CacheTest.java @@ -17,21 +17,24 @@ */ package com.erudika.para.server.cache; -import com.erudika.para.core.cache.Cache; import com.erudika.para.core.User; +import com.erudika.para.core.cache.Cache; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Ignore; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** * * @author Alex Bogdanovski [alex@erudika.com] */ -@Ignore +@Disabled public abstract class CacheTest { private final Cache c; @@ -42,7 +45,7 @@ public CacheTest(Cache c) { this.c = c; } - @Before + @BeforeEach public void setUp() { c.removeAll(); } diff --git a/para-server/src/test/java/com/erudika/para/server/cache/CaffeineCacheTest.java b/para-server/src/test/java/com/erudika/para/server/cache/CaffeineCacheTest.java index bd014e3a..69bea21f 100644 --- a/para-server/src/test/java/com/erudika/para/server/cache/CaffeineCacheTest.java +++ b/para-server/src/test/java/com/erudika/para/server/cache/CaffeineCacheTest.java @@ -17,13 +17,12 @@ */ package com.erudika.para.server.cache; -import com.erudika.para.server.cache.CaffeineCache; import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Expiry; import java.util.concurrent.TimeUnit; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; /** * diff --git a/para-server/src/test/java/com/erudika/para/server/persistence/AWSDynamoDAOIT.java b/para-server/src/test/java/com/erudika/para/server/persistence/AWSDynamoDAOIT.java deleted file mode 100644 index 2306670c..00000000 --- a/para-server/src/test/java/com/erudika/para/server/persistence/AWSDynamoDAOIT.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2013-2022 Erudika. https://erudika.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * For issues and patches go to: https://github.com/erudika - */ -package com.erudika.para.server.persistence; - -import com.erudika.para.core.App; -import com.erudika.para.core.Sysprop; -import com.erudika.para.core.utils.Pager; -import com.erudika.para.core.utils.Para; -import com.erudika.para.core.utils.Utils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; -import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * DynamoDB integration test. - * @author Alex Bogdanovski [alex@erudika.com] - */ -public class AWSDynamoDAOIT extends DAOTest { - - private static final String ROOT_APP_NAME = "para-test"; - - public AWSDynamoDAOIT() { - super(new AWSDynamoDAO()); - } - - @BeforeClass - public static void setUpClass() throws InterruptedException { - System.setProperty("para.prepend_shared_appids_with_space", "true"); - System.setProperty("para.dynamodb.provisioned_mode_enabled", "true"); - System.setProperty("para.app_name", ROOT_APP_NAME); - AWSDynamoUtils.createTable(Para.getConfig().getRootAppIdentifier()); - AWSDynamoUtils.createTable(appid1); - AWSDynamoUtils.createTable(appid2); - AWSDynamoUtils.createTable(appid3); - AWSDynamoUtils.createSharedTable(1, 1); - } - - @AfterClass - public static void tearDownClass() { - AWSDynamoUtils.deleteTable(Para.getConfig().getRootAppIdentifier()); - AWSDynamoUtils.deleteTable(appid1); - AWSDynamoUtils.deleteTable(appid2); - AWSDynamoUtils.deleteTable(appid3); - AWSDynamoUtils.deleteTable(Para.getConfig().sharedTableName()); - AWSDynamoUtils.shutdownClient(); - System.setProperty("para.prepend_shared_appids_with_space", "false"); - } - - @Test - public void testCreateDeleteExistsTable() throws InterruptedException { - String testappid1 = "test-index"; - String badAppid = "test index 123"; - - AWSDynamoUtils.createTable(""); - assertFalse(AWSDynamoUtils.existsTable("")); - - AWSDynamoUtils.createTable(testappid1); - assertTrue(AWSDynamoUtils.existsTable(testappid1)); - - AWSDynamoUtils.deleteTable(testappid1); - assertFalse(AWSDynamoUtils.existsTable(testappid1)); - - assertFalse(AWSDynamoUtils.createTable(badAppid)); - assertFalse(AWSDynamoUtils.existsTable(badAppid)); - assertFalse(AWSDynamoUtils.deleteTable(badAppid)); - } - - @Test - public void testCRUDSharedTable() { - assertTrue(AWSDynamoUtils.existsTable(Para.getConfig().sharedTableName())); - - App app = new App("shared-app1"); - App app2 = new App("shared-app2"); - app.setSharingTable(true); - app2.setSharingTable(true); - - Sysprop s = new Sysprop("sharedobj1"); - s.setAppid(app.getAppIdentifier()); - assertNotNull(dao().create(app.getAppIdentifier(), s)); - - assertNull(dao().read(app2.getAppIdentifier(), s.getId())); - - Sysprop sr = dao().read(s.getAppid(), s.getId()); - assertNull(dao().read(s.getId())); // not in root table - assertFalse(AWSDynamoUtils.existsTable(s.getAppid().trim())); - assertNotNull(sr); - assertEquals(s.getId(), sr.getId()); - - s.setName("I'm shared"); - dao().update(s.getAppid(), s); - sr = dao().read(s.getAppid(), s.getId()); - assertNotNull(sr); - assertNull(dao().read(s.getId())); // not in root table - assertEquals("I'm shared", sr.getName()); - - dao().delete(sr); // no effect - different App (root appid) - assertNotNull(dao().read(s.getAppid(), s.getId())); // not in root table - dao().delete(s.getAppid(), s); - assertNull(dao().read(s.getAppid(), s.getId())); - } - - @Test - public void testBatchCRUDSharedTable() { - Sysprop t1 = new Sysprop("sps1"); - Sysprop t2 = new Sysprop("sps2"); - Sysprop t3 = new Sysprop("sps3"); - Sysprop t4 = new Sysprop("sps4"); - App app1 = new App("batch-shared-app1"); - app1.setSharingTable(true); - App app2 = new App("batch-shared-app2"); - app2.setSharingTable(true); - - t1.setAppid(app1.getAppIdentifier()); - t2.setAppid(app1.getAppIdentifier()); - t3.setAppid(app2.getAppIdentifier()); - t4.setAppid(app2.getAppIdentifier()); - - // multi app support - dao().createAll(app1.getAppIdentifier(), Arrays.asList(t1, t2)); - dao().createAll(app2.getAppIdentifier(), Arrays.asList(t3, t4)); - Sysprop s = dao().read(app1.getAppIdentifier(), t2.getId()); - assertNotNull(s); - assertEquals(app1.getAppIdentifier(), s.getAppid()); - assertNull(dao().read(t2.getId())); - assertNull(dao().read(app2.getAppIdentifier(), t2.getId())); - - assertNotNull(dao().read(app2.getAppIdentifier(), t3.getId())); - assertNotNull(dao().read(app2.getAppIdentifier(), t4.getId())); - - // app1 must not see app2's objects, and vice versa - Map m1 = dao().readAll(app1.getAppIdentifier(), Arrays.asList(t3.getId(), t4.getId()), true); - Map m2 = dao().readAll(app2.getAppIdentifier(), Arrays.asList(t1.getId(), t2.getId()), true); - assertNull(m1.get(t3.getId())); - assertNull(m1.get(t4.getId())); - assertNull(m2.get(t1.getId())); - assertNull(m2.get(t2.getId())); - - Map props = dao().readAll(app1.getAppIdentifier(), Arrays.asList(t1.getId(), t2.getId()), true); - assertFalse(props.isEmpty()); - assertTrue(props.containsKey(t1.getId())); - assertTrue(props.containsKey(t2.getId())); - assertFalse(props.containsKey(t3.getId())); - assertTrue(t1.equals(props.get(t1.getId()))); - assertTrue(t2.equals(props.get(t2.getId()))); - - t1.setName("Name 1"); - t2.setName("Name 2"); - t3.setName("Name 3"); - // these should go through (custom types support) - t1.setType("type1"); - t2.setType("type2"); - t3.setType("type3"); - - dao().updateAll(app1.getAppIdentifier(), Arrays.asList(t1, t2)); - Sysprop tr1 = dao().read(app1.getAppIdentifier(), t1.getId()); - Sysprop tr2 = dao().read(app1.getAppIdentifier(), t2.getId()); - assertNull(dao().read(app1.getAppIdentifier(), t3.getId())); - - assertNotNull(tr1); - assertNotNull(tr2); - - assertEquals(t1.getId(), tr1.getId()); - assertEquals(t2.getId(), tr2.getId()); - assertEquals(Utils.type(Sysprop.class), tr1.getType()); - assertEquals(Utils.type(Sysprop.class), tr2.getType()); - assertEquals(t1.getName(), tr1.getName()); - assertEquals(t2.getName(), tr2.getName()); - assertNotNull(t1.getUpdated()); - assertNotNull(t2.getUpdated()); - - dao().deleteAll(null); - dao().deleteAll(app1.getAppIdentifier(), Arrays.asList(t1, t2, t3)); - - assertNull(dao().read(app1.getAppIdentifier(), t1.getId())); - assertNull(dao().read(app1.getAppIdentifier(), t2.getId())); - assertNotNull(dao().read(app2.getAppIdentifier(), t3.getId())); - dao().deleteAll(app2.getAppIdentifier(), Arrays.asList(t3, t4)); - assertNull(dao().read(app2.getAppIdentifier(), t1.getId())); - assertNull(dao().read(app2.getAppIdentifier(), t2.getId())); - - // update locked field test - Sysprop ts4 = new Sysprop(); - ts4.setParentid("123"); - dao().create(app1.getAppIdentifier(), ts4); - ts4.setParentid("321"); - ts4.setType("type4"); - dao().update(app1.getAppIdentifier(), ts4); - Sysprop tr4 = dao().read(app1.getAppIdentifier(), ts4.getId()); - assertEquals(ts4.getId(), tr4.getId()); - assertEquals(Utils.type(Sysprop.class), tr4.getType()); - assertEquals("123", tr4.getParentid()); - } - - @Test - public void testReadPageSharedTable() { - App app3 = new App("shared-app3"); - App app4 = new App("shared-app4"); - app3.setSharingTable(true); - app4.setSharingTable(true); - - ArrayList list = new ArrayList<>(); - for (int i = 0; i < 22; i++) { - Sysprop s = new Sysprop("id_" + i); - s.addProperty("prop" + i, i); - s.setAppid(app3.getAppIdentifier()); - list.add(s); - } - dao().createAll(app3.getAppIdentifier(), list); - - Sysprop s = new Sysprop("sharedobj2"); - assertNotNull(dao().create(app4.getAppIdentifier(), s)); - dao().create(app4.getAppIdentifier(), s); - - Pager p = new Pager(10); - assertTrue(dao().readPage(null, null).isEmpty()); - assertFalse(dao().readPage(app3.getAppIdentifier(), null).isEmpty()); - assertEquals(10, dao().readPage(app3.getAppIdentifier(), p).size()); // page 1 - assertEquals(10, dao().readPage(app3.getAppIdentifier(), p).size()); // page 2 - assertEquals(2, dao().readPage(app3.getAppIdentifier(), p).size()); // page 3 - assertTrue(dao().readPage(app3.getAppIdentifier(), p).isEmpty()); // end - assertEquals(22, p.getCount()); - - assertEquals(1, dao().readPage(app4.getAppIdentifier(), null).size()); - - // test deleteAllFromSharedTable() - AWSDynamoUtils.deleteAllFromSharedTable(app3.getAppIdentifier()); - assertEquals(0, dao().readPage(app3.getAppIdentifier(), null).size()); - assertEquals(1, dao().readPage(app4.getAppIdentifier(), null).size()); - } - - @Test - public void testReadAllPartial() { - Sysprop s1 = new Sysprop("read-partially1"); - Sysprop s2 = new Sysprop("read-partially2"); - s1.setType("customtype"); - s2.setType("customtype"); - - dao().create(ROOT_APP_NAME, s1); - dao().create(ROOT_APP_NAME, s2); - - Map res = dao().readAll(ROOT_APP_NAME, Arrays.asList(s1.getId(), s2.getId()), false); - assertFalse(res.isEmpty()); - assertNotNull(res.get(s1.getId())); - assertNotNull(res.get(s2.getId())); - assertEquals(s1.getType(), res.get(s1.getId()).getType()); - assertEquals(s1.getType(), res.get(s2.getId()).getType()); - dao().deleteAll(ROOT_APP_NAME, Arrays.asList(s1, s2)); - } - - @Test - public void testOptimisticLockingOnUpdate() { - Sysprop s1 = new Sysprop("conditional-update1"); - s1.setVersion(1L); // enable optimistic locking on object - dao().create(s1); - assertEquals(Long.valueOf(1L), s1.getVersion()); - Sysprop sr1 = dao().read(s1.getId()); - assertEquals(Long.valueOf(1L), sr1.getVersion()); - sr1.setName("Updated"); - dao().update(sr1); - assertEquals(Long.valueOf(2L), sr1.getVersion()); - s1.setName("FAIL"); - dao().update(s1); - assertEquals(Long.valueOf(-1L), s1.getVersion()); // failed update - Sysprop sr2 = dao().read(s1.getId()); - sr2.setName("SUCCESS"); - dao().update(sr2); - assertEquals(Long.valueOf(3L), sr2.getVersion()); // successful update - Sysprop sr3 = dao().read(s1.getId()); - assertEquals("SUCCESS", sr3.getName()); - - sr3.setVersion(null); // disable optimistic locking - dao().update(sr3); - assertEquals(Long.valueOf(0L), sr3.getVersion()); - s1.setName("Disabled"); - dao().update(s1); - Sysprop sr4 = dao().read(s1.getId()); - assertEquals("Disabled", sr4.getName()); - } -} diff --git a/para-server/src/test/java/com/erudika/para/server/persistence/DAOTest.java b/para-server/src/test/java/com/erudika/para/server/persistence/DAOTest.java index 34d8a1e3..6fb294d3 100644 --- a/para-server/src/test/java/com/erudika/para/server/persistence/DAOTest.java +++ b/para-server/src/test/java/com/erudika/para/server/persistence/DAOTest.java @@ -17,28 +17,32 @@ */ package com.erudika.para.server.persistence; -import com.erudika.para.core.persistence.DAO; import com.erudika.para.core.App; import com.erudika.para.core.Sysprop; import com.erudika.para.core.Tag; import com.erudika.para.core.User; -import com.erudika.para.core.utils.CoreUtils; +import com.erudika.para.core.persistence.DAO; import com.erudika.para.core.search.Search; +import com.erudika.para.core.utils.CoreUtils; import com.erudika.para.core.utils.Pager; import com.erudika.para.core.utils.Utils; import java.util.ArrayList; import java.util.Arrays; import java.util.Map; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import static org.mockito.Mockito.*; /** * * @author Alex Bogdanovski [alex@erudika.com] */ -@Ignore +@Disabled public abstract class DAOTest { private final DAO dao; @@ -70,7 +74,7 @@ private static Tag t() { return t; } - @Before + @BeforeEach public void setUp() { CoreUtils.getInstance().setDao(dao); CoreUtils.getInstance().setSearch(mock(Search.class)); diff --git a/para-server/src/test/java/com/erudika/para/server/queue/AWSQueueIT.java b/para-server/src/test/java/com/erudika/para/server/queue/AWSQueueIT.java index 8d44bfea..2e055d63 100644 --- a/para-server/src/test/java/com/erudika/para/server/queue/AWSQueueIT.java +++ b/para-server/src/test/java/com/erudika/para/server/queue/AWSQueueIT.java @@ -22,12 +22,12 @@ import java.util.List; import org.elasticmq.rest.sqs.SQSRestServer; import org.elasticmq.rest.sqs.SQSRestServerBuilder; -import org.junit.AfterClass; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; /** * @@ -37,14 +37,14 @@ public class AWSQueueIT extends QueueTest { private static SQSRestServer sqsServer; - @BeforeClass + @BeforeAll public static void setUpClass() throws InterruptedException { sqsServer = SQSRestServerBuilder.start(); Thread.sleep(1000); q = new AWSQueue("testq"); } - @AfterClass + @AfterAll public static void tearDownClass() { sqsServer.stopAndWait(); } diff --git a/para-server/src/test/java/com/erudika/para/server/queue/QueueTest.java b/para-server/src/test/java/com/erudika/para/server/queue/QueueTest.java index 9bc0b4d6..f2ac97fc 100644 --- a/para-server/src/test/java/com/erudika/para/server/queue/QueueTest.java +++ b/para-server/src/test/java/com/erudika/para/server/queue/QueueTest.java @@ -18,15 +18,15 @@ package com.erudika.para.server.queue; import com.erudika.para.core.queue.Queue; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Ignore; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; /** * * @author Alex Bogdanovski [alex@erudika.com] */ -@Ignore +@Disabled public abstract class QueueTest { protected static Queue q; diff --git a/para-server/src/test/java/com/erudika/para/utils/filters/CORSFilterTest.java b/para-server/src/test/java/com/erudika/para/utils/filters/CORSFilterTest.java index c9ed5165..7b39282f 100644 --- a/para-server/src/test/java/com/erudika/para/utils/filters/CORSFilterTest.java +++ b/para-server/src/test/java/com/erudika/para/utils/filters/CORSFilterTest.java @@ -16,1403 +16,1398 @@ package com.erudika.para.utils.filters; import com.erudika.para.server.utils.filters.CORSFilter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.LinkedHashSet; import java.util.Set; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; public class CORSFilterTest { - private FilterChain filterChain = new MockFilterChain(); - - /** - * Tests if a GET request is treated as simple request. - * - * @See http://www.w3.org/TR/cors/#simple-method - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimpleGET() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("GET"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "https://www.apache.org")); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Tests if a POST request is treated as simple request. - * - * @See http://www.w3.org/TR/cors/#simple-method - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimplePOST() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setContentType("text/plain"); - request.setMethod("POST"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "https://www.apache.org")); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Tests if a HEAD request is treated as simple request. - * - * @See http://www.w3.org/TR/cors/#simple-method - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimpleHEAD() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("HEAD"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "https://www.apache.org")); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Test the presence of specific origin in response, when '*' is not used. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimpleSpecificHeader() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("POST"); - request.setContentType("text/plain"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Tests the prsence of the origin (and not '*') in the response, when - * supports credentials is enabled alongwith any origin, '*'. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimpleAnyOriginAndSupportsCredentials() - throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("GET"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getFilterConfigAnyOriginAndSupportsCredentials()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS) - .equals( - "true")); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Tests the prsence of the origin (and not '*') in the response, when - * supports credentials is enabled alongwith any origin, '*'. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimpleAnyOriginAndSupportsCredentialsDisabled() - throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("GET"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getFilterConfigAnyOriginAndSupportsCredentialsDisabled()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.ANY_ORIGIN)); - Assert.assertNull(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Tests the presence of exposed headers in response, if configured. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterSimpleWithExposedHeaders() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("POST"); - request.setContentType("text/plain"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getFilterConfigWithExposedHeaders()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "https://www.apache.org")); - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS) - .equals(TestConfigs.EXPOSED_HEADERS)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - /** - * Checks if an OPTIONS request is processed as pre-flight. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterPreflight() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( - "Content-Type")); - } - - /** - * Checks if an OPTIONS request is processed as pre-flight where any origin - * is enabled. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterPreflightAnyOrigin() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( - "Content-Type")); - } - - /** - * Checks if an OPTIONS request is processed as pre-flight. - * - * @throws IOException - * @throws ServletException - */ - @Test - public void testDoFilterPreflightInvalidOrigin() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://www.example.com"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertEquals(response.getStatus(), - HttpServletResponse.SC_FORBIDDEN); - } - - @Test - public void testDoFilterPreflightNegativeMaxAge() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfigNegativeMaxAge()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertNull(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_MAX_AGE)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( - "Content-Type")); - } - - @Test - public void testDoFilterPreflightWithCredentials() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSecureFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS) - .equals("true")); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( - "Content-Type")); - } - - @Test - public void testDoFilterPreflightWithoutCredentialsAndSpecificOrigin() - throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getFilterConfigSpecificOriginAndSupportsCredentialsDisabled()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertNull(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( - "Content-Type")); - } - - /** - * Negative test, when a CORS request arrives, with a null origin. - */ - @Test - public void testDoFilterNullOrigin() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - - request.setMethod("POST"); - request.setContentType("text/plain"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.NOT_CORS, requestType); - - corsFilter.doFilter(request, response, filterChain); - - Assert.assertFalse((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - } - - @Test - public void testDoFilterInvalidCORSOriginNotAllowed() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "www.google.com"); - request.setMethod("POST"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - @Test(expected = ServletException.class) - public void testDoFilterNullRequestNullResponse() throws IOException, - ServletException { - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.doFilter(null, null, filterChain); - } - - @Test(expected = ServletException.class) - public void testDoFilterNullRequestResponse() throws IOException, - ServletException { - MockHttpServletResponse response = new MockHttpServletResponse(); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.doFilter(null, response, filterChain); - } - - @Test(expected = ServletException.class) - public void testDoFilterRequestNullResponse() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.doFilter(request, null, filterChain); - } - - @Test - public void testInitDefaultFilterConfig() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("GET"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(null); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "https://www.apache.org")); - Assert.assertTrue((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( - TestConfigs.HTTPS_WWW_APACHE_ORG)); - Assert.assertTrue(request.getAttribute( - CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( - CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); - } - - @Test(expected = ServletException.class) - public void testInitInvalidFilterConfig() throws IOException, - ServletException { - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getFilterConfigInvalidMaxPreflightAge()); - // If we don't get an exception at this point, then all mocked objects - // worked as expected. - } - - /** - * Tests if a non-simple request is given to simple request handler. - * - * @throws IOException - * @throws ServletException - */ - @Test(expected = IllegalArgumentException.class) - public void testNotSimple() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - corsFilter.handleSimpleCORS(request, response, filterChain); - } - - /** - * When a non-preflight request is given to a pre-flight requets handler. - * - * @throws IOException - * @throws ServletException - */ - @Test(expected = IllegalArgumentException.class) - public void testNotPreflight() throws IOException, ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("GET"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getDefaultFilterConfig()); - corsFilter.handlePreflightCORS(request, response, filterChain); - } - - @Test(expected = IllegalArgumentException.class) - public void testDecorateCORSPropertiesNullRequestNullCORSRequestType() { - CORSFilter.decorateCORSProperties(null, null); - } - - @Test(expected = IllegalArgumentException.class) - public void testDecorateCORSPropertiesNullRequestValidCORSRequestType() { - CORSFilter.decorateCORSProperties(null, - CORSFilter.CORSRequestType.SIMPLE); - } - - @Test(expected = IllegalArgumentException.class) - public void testDecorateCORSPropertiesValidRequestNullRequestType() { - MockHttpServletRequest request = new MockHttpServletRequest(); - CORSFilter.decorateCORSProperties(request, null); - } - - @Test - public void testDecorateCORSPropertiesCORSRequestTypeNotCORS() { - MockHttpServletRequest request = new MockHttpServletRequest(); - CORSFilter.decorateCORSProperties(request, - CORSFilter.CORSRequestType.NOT_CORS); - Assert.assertFalse((Boolean) request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - } - - @Test - public void testDecorateCORSPropertiesCORSRequestTypeInvalidCORS() { - MockHttpServletRequest request = new MockHttpServletRequest(); - CORSFilter - .decorateCORSProperties(request, - CORSFilter.CORSRequestType.INVALID_CORS); - Assert.assertNull(request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - } - - @Test - public void testCheckSimpleRequestTypeAnyOrigin() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://www.w3.org"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.SIMPLE, requestType); - } - - /** - * Happy path test, when a valid CORS Simple request arrives. - * - * @throws ServletException - */ - @Test - public void testCheckSimpleRequestType() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.SIMPLE, requestType); - } - - /** - * Happy path test, when a valid CORS Simple request arrives. - * - * @throws ServletException - */ - @Test - public void testCheckActualRequestType() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setMethod("PUT"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.ACTUAL, requestType); - } - - /** - * Happy path test, when a valid CORS Simple request arrives. - * - * @throws ServletException - */ - @Test - public void testCheckActualRequestTypeMethodPOSTNotSimpleHeaders() - throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setMethod("POST"); - request.setContentType("application/json"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.ACTUAL, requestType); - } - - /** - * Happy path test, when a valid CORS Pre-flight request arrives. - * - * @throws ServletException - */ - @Test - public void testCheckPreFlightRequestType() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Content-Type"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.PRE_FLIGHT, requestType); - } - - /** - * when a valid CORS Pre-flight request arrives, with no - * Access-Control-Request-Method - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckPreFlightRequestTypeNoACRM() throws ServletException, - IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.ACTUAL, requestType); - } - - /** - * when a valid CORS Pre-flight request arrives, with empty - * Access-Control-Request-Method - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckPreFlightRequestTypeEmptyACRM() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - ""); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - /** - * Happy path test, when a valid CORS Pre-flight request arrives. - * - * @throws ServletException - */ - @Test - public void testCheckPreFlightRequestTypeNoHeaders() - throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "PUT"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.PRE_FLIGHT, requestType); - } - - /** - * Section 6.2.3 - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckPreFlightRequestTypeInvalidRequestMethod() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "POLITE"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * Section Section 6.2.5 - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckPreFlightRequestTypeUnsupportedRequestMethod() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "TRACE"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * Section Section 6.2.6 - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckPreFlightRequestTypeUnsupportedRequestHeaders() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "X-ANSWER"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSecureFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * Section Section 6.2.7 - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckPreFlightRequestTypeAnyOriginNoWithCredentials() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - "Origin"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getFilterConfigAnyOriginAndSupportsCredentialsDisabled()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "*")); - Assert.assertNull(response - .getHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); - } - - @Test - public void testCheckPreFlightRequestTypeOriginNotAllowed() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "www.ebay.com"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "PUT"); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSecureFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * Happy path test, when a valid CORS Pre-flight request arrives. - * - * @throws ServletException - */ - @Test - public void testCheckPreFlightRequestTypeEmptyHeaders() - throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTP_TOMCAT_APACHE_ORG); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, - "PUT"); - request.setHeader( - CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, - ""); - request.setMethod("OPTIONS"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.PRE_FLIGHT, requestType); - } - - /** - * Negative test, when a CORS request arrives, with an empty origin. - * - * @throws ServletException - */ - @Test - public void testCheckNotCORSRequestTypeEmptyOrigin() - throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - ""); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - /** - * Tests for failure, when a different domain is used, that's not in the - * allowed list of origins. - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckInvalidOrigin() throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "www.example.com"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * Tests for failure, when a different sub-domain is used, that's not in the - * allowed list of origins. - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckInvalidOriginNotAllowedSubdomain() - throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://commons.apache.org"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * PUT is not an allowed request method. - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckInvalidRequestMethod() throws ServletException, - IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://tomcat.apache.org"); - request.setMethod("PUT"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * When requestMethod is null - * - * @throws ServletException - */ - @Test - public void testCheckNullRequestMethod() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://tomcat.apache.org"); - request.setMethod(null); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - /** - * "http://tomcat.apache.org" is an allowed origin and - * "https://tomcat.apache.org" is not, because scheme doesn't match - * - * @throws ServletException - */ - @Test - public void testCheckForSchemeVariance() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "https://tomcat.apache.org"); - request.setMethod("POST"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - /** - * "http://tomcat.apache.org" is an allowed origin and - * "http://tomcat.apache.org:8080" is not, because ports doesn't match - * - * @throws ServletException - * @throws IOException - */ - @Test - public void testCheckForPortVariance() throws ServletException, IOException { - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://tomcat.apache.org:8080"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getSpecificOriginFilterConfig()); - corsFilter.doFilter(request, response, filterChain); - Assert.assertEquals(HttpServletResponse.SC_FORBIDDEN, - response.getStatus()); - } - - /** - * Tests for failure, when an invalid {@link HttpServletRequest} is - * encountered. - * - * @throws ServletException - */ - @Test(expected = IllegalArgumentException.class) - public void testCheckRequestTypeNull() throws ServletException { - HttpServletRequest request = null; - CORSFilter corsFilter = new CORSFilter(); - corsFilter.checkRequestType(request); - } - - @Test - public void testJoin() { - Set elements = new LinkedHashSet<>(); - String separator = ","; - elements.add("world"); - elements.add("peace"); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue("world,peace".equals(join)); - } - - @Test - public void testJoinSingleElement() { - Set elements = new LinkedHashSet<>(); - String separator = ","; - elements.add("world"); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue("world".equals(join)); - } - - @Test - public void testJoinSepNull() { - Set elements = new LinkedHashSet<>(); - String separator = null; - elements.add("world"); - elements.add("peace"); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue("world,peace".equals(join)); - } - - @Test - public void testJoinElementsNull() { - Set elements = null; - String separator = ","; - String join = CORSFilter.join(elements, separator); - - Assert.assertNull(join); - } - - @Test - public void testJoinOneNullElement() { - Set elements = new LinkedHashSet<>(); - String separator = ","; - elements.add(null); - elements.add("peace"); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue(",peace".equals(join)); - } - - @Test - public void testJoinAllNullElements() { - Set elements = new LinkedHashSet<>(); - String separator = ","; - elements.add(null); - elements.add(null); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue("".equals(join)); - } - - @Test - public void testJoinAllEmptyElements() { - Set elements = new LinkedHashSet<>(); - String separator = ","; - elements.add(""); - elements.add(""); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue("".equals(join)); - } - - @Test - public void testJoinPipeSeparator() { - Set elements = new LinkedHashSet<>(); - String separator = "|"; - elements.add("world"); - elements.add("peace"); - String join = CORSFilter.join(elements, separator); - Assert.assertTrue("world|peace".equals(join)); - } - - @Test - public void testWithFilterConfig() throws ServletException { - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - Assert.assertTrue(corsFilter.getAllowedHttpHeaders().size() == 6); - Assert.assertTrue(corsFilter.getAllowedHttpMethods().size() == 4); - Assert.assertTrue(corsFilter.getAllowedOrigins().size() == 0); - Assert.assertTrue(corsFilter.isAnyOriginAllowed()); - Assert.assertTrue(corsFilter.getExposedHeaders().size() == 0); - Assert.assertTrue(corsFilter.isSupportsCredentials()); - Assert.assertTrue(corsFilter.getPreflightMaxAge() == 1800); - Assert.assertTrue(!corsFilter.isLoggingEnabled()); - } - - @Test(expected = ServletException.class) - public void testWithFilterConfigInvalidPreflightAge() - throws ServletException { - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getFilterConfigInvalidMaxPreflightAge()); - } - - @Test - public void testWithStringParserEmpty() throws ServletException { - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getEmptyFilterConfig()); - Assert.assertTrue(corsFilter.getAllowedHttpHeaders().size() == 0); - Assert.assertTrue(corsFilter.getAllowedHttpMethods().size() == 0); - Assert.assertTrue(corsFilter.getAllowedOrigins().size() == 0); - Assert.assertTrue(corsFilter.getExposedHeaders().size() == 0); - Assert.assertFalse(corsFilter.isSupportsCredentials()); - Assert.assertTrue(corsFilter.getPreflightMaxAge() == 0); - Assert.assertTrue(!corsFilter.isLoggingEnabled()); - } - - /** - * If an init param is null, it's default value will be used. - * - * @throws ServletException - */ - @Test - public void testWithStringParserNull() throws ServletException { - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getNullFilterConfig()); - Assert.assertTrue(corsFilter.getAllowedHttpHeaders().size() == 6); - Assert.assertTrue(corsFilter.getAllowedHttpMethods().size() == 4); - Assert.assertTrue(corsFilter.getAllowedOrigins().size() == 0); - Assert.assertTrue(corsFilter.isAnyOriginAllowed()); - Assert.assertTrue(corsFilter.getExposedHeaders().size() == 0); - Assert.assertTrue(corsFilter.isSupportsCredentials()); - Assert.assertTrue(corsFilter.getPreflightMaxAge() == 1800); - Assert.assertTrue(!corsFilter.isLoggingEnabled()); - } - - @Test - public void testValidOrigin() { - Assert.assertTrue(CORSFilter.isValidOrigin("http://www.w3.org")); - } - - @Test - public void testInValidOriginCRLF() { - Assert.assertFalse(CORSFilter.isValidOrigin("http://www.w3.org\r\n")); - } - - @Test - public void testInValidOriginEncodedCRLF1() { - Assert.assertFalse(CORSFilter.isValidOrigin("http://www.w3.org%0d%0a")); - } - - @Test - public void testInValidOriginEncodedCRLF2() { - Assert.assertFalse(CORSFilter.isValidOrigin("http://www.w3.org%0D%0A")); - } - - @Test - public void testInValidOriginEncodedCRLF3() { - Assert.assertFalse(CORSFilter - .isValidOrigin("http://www.w3.org%0%0d%0ad%0%0d%0aa")); - } - - @Test - public void testCheckInvalidCRLF1() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://www.w3.org\r\n"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - @Test - public void testCheckInvalidCRLF2() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://www.w3.org\r\n"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - @Test - public void testCheckInvalidCRLF3() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://www.w3.org%0d%0a"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - @Test - public void testCheckInvalidCRLF4() throws ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - "http://www.w3.org%0D%0A"); - request.setMethod("GET"); - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs - .getDefaultFilterConfig()); - CORSFilter.CORSRequestType requestType = - corsFilter.checkRequestType(request); - Assert.assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, - requestType); - } - - @Test - public void testDecorateRequestDisabled() throws IOException, - ServletException { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, - TestConfigs.HTTPS_WWW_APACHE_ORG); - request.setMethod("GET"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - CORSFilter corsFilter = new CORSFilter(); - corsFilter.init(TestConfigs.getFilterConfigDecorateRequestDisabled()); - corsFilter.doFilter(request, response, filterChain); - - Assert.assertTrue(response.getHeader( - CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( - "https://www.apache.org")); - Assert.assertNull(request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); - Assert.assertNull(request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN)); - Assert.assertNull(request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS)); - Assert.assertNull(request - .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE)); - } - - @Test - public void testDestroy() { - // Nothing to test. - // NO-OP - } + + private FilterChain filterChain = new MockFilterChain(); + + /** + * Tests if a GET request is treated as simple request. + * + * @See http://www.w3.org/TR/cors/#simple-method + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimpleGET() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("GET"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "https://www.apache.org")); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Tests if a POST request is treated as simple request. + * + * @See http://www.w3.org/TR/cors/#simple-method + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimplePOST() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setContentType("text/plain"); + request.setMethod("POST"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "https://www.apache.org")); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Tests if a HEAD request is treated as simple request. + * + * @See http://www.w3.org/TR/cors/#simple-method + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimpleHEAD() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("HEAD"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "https://www.apache.org")); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Test the presence of specific origin in response, when '*' is not used. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimpleSpecificHeader() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("POST"); + request.setContentType("text/plain"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Tests the prsence of the origin (and not '*') in the response, when supports credentials is enabled alongwith any + * origin, '*'. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimpleAnyOriginAndSupportsCredentials() + throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("GET"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getFilterConfigAnyOriginAndSupportsCredentials()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS) + .equals( + "true")); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Tests the prsence of the origin (and not '*') in the response, when supports credentials is enabled alongwith any + * origin, '*'. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimpleAnyOriginAndSupportsCredentialsDisabled() + throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("GET"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getFilterConfigAnyOriginAndSupportsCredentialsDisabled()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.ANY_ORIGIN)); + assertNull(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Tests the presence of exposed headers in response, if configured. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterSimpleWithExposedHeaders() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("POST"); + request.setContentType("text/plain"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getFilterConfigWithExposedHeaders()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "https://www.apache.org")); + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS) + .equals(TestConfigs.EXPOSED_HEADERS)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + /** + * Checks if an OPTIONS request is processed as pre-flight. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterPreflight() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( + "Content-Type")); + } + + /** + * Checks if an OPTIONS request is processed as pre-flight where any origin is enabled. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterPreflightAnyOrigin() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( + "Content-Type")); + } + + /** + * Checks if an OPTIONS request is processed as pre-flight. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testDoFilterPreflightInvalidOrigin() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://www.example.com"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertEquals(response.getStatus(), + HttpServletResponse.SC_FORBIDDEN); + } + + @Test + public void testDoFilterPreflightNegativeMaxAge() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfigNegativeMaxAge()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertNull(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_MAX_AGE)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( + "Content-Type")); + } + + @Test + public void testDoFilterPreflightWithCredentials() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSecureFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS) + .equals("true")); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( + "Content-Type")); + } + + @Test + public void testDoFilterPreflightWithoutCredentialsAndSpecificOrigin() + throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getFilterConfigSpecificOriginAndSupportsCredentialsDisabled()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertNull(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.PRE_FLIGHT.name().toLowerCase())); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS).equals( + "Content-Type")); + } + + /** + * Negative test, when a CORS request arrives, with a null origin. + */ + @Test + public void testDoFilterNullOrigin() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + + request.setMethod("POST"); + request.setContentType("text/plain"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.NOT_CORS, requestType); + + corsFilter.doFilter(request, response, filterChain); + + assertFalse((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + } + + @Test + public void testDoFilterInvalidCORSOriginNotAllowed() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "www.google.com"); + request.setMethod("POST"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + @Test + public void testDoFilterNullRequestNullResponse() throws IOException, + ServletException { + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + Assertions.assertThrows(ServletException.class, () -> corsFilter.doFilter(null, null, filterChain)); + } + + @Test + public void testDoFilterNullRequestResponse() throws IOException, + ServletException { + MockHttpServletResponse response = new MockHttpServletResponse(); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + Assertions.assertThrows(ServletException.class, () -> corsFilter.doFilter(null, response, filterChain)); + } + + @Test + public void testDoFilterRequestNullResponse() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + Assertions.assertThrows(ServletException.class, () -> corsFilter.doFilter(request, null, filterChain)); + } + + @Test + public void testInitDefaultFilterConfig() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("GET"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(null); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "https://www.apache.org")); + assertTrue((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN).equals( + TestConfigs.HTTPS_WWW_APACHE_ORG)); + assertTrue(request.getAttribute( + CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE).equals( + CORSFilter.CORSRequestType.SIMPLE.name().toLowerCase())); + } + + @Test + public void testInitInvalidFilterConfig() throws IOException, + ServletException { + CORSFilter corsFilter = new CORSFilter(); + Assertions.assertThrows(ServletException.class, () -> corsFilter.init(TestConfigs.getFilterConfigInvalidMaxPreflightAge())); + // If we don't get an exception at this point, then all mocked objects + // worked as expected. + } + + /** + * Tests if a non-simple request is given to simple request handler. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testNotSimple() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + Assertions.assertThrows(IllegalArgumentException.class, () -> corsFilter.handleSimpleCORS(request, response, filterChain)); + } + + /** + * When a non-preflight request is given to a pre-flight requets handler. + * + * @throws IOException + * @throws ServletException + */ + @Test + public void testNotPreflight() throws IOException, ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("GET"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getDefaultFilterConfig()); + Assertions.assertThrows(IllegalArgumentException.class, () -> corsFilter.handlePreflightCORS(request, response, filterChain)); + } + + @Test + public void testDecorateCORSPropertiesNullRequestNullCORSRequestType() { + Assertions.assertThrows(IllegalArgumentException.class, () -> CORSFilter.decorateCORSProperties(null, null)); + } + + @Test + public void testDecorateCORSPropertiesNullRequestValidCORSRequestType() { + Assertions.assertThrows(IllegalArgumentException.class, () -> CORSFilter.decorateCORSProperties(null, CORSFilter.CORSRequestType.SIMPLE)); + } + + @Test + public void testDecorateCORSPropertiesValidRequestNullRequestType() { + MockHttpServletRequest request = new MockHttpServletRequest(); + Assertions.assertThrows(IllegalArgumentException.class, () -> CORSFilter.decorateCORSProperties(request, null)); + } + + @Test + public void testDecorateCORSPropertiesCORSRequestTypeNotCORS() { + MockHttpServletRequest request = new MockHttpServletRequest(); + CORSFilter.decorateCORSProperties(request, + CORSFilter.CORSRequestType.NOT_CORS); + assertFalse((Boolean) request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + } + + @Test + public void testDecorateCORSPropertiesCORSRequestTypeInvalidCORS() { + MockHttpServletRequest request = new MockHttpServletRequest(); + CORSFilter + .decorateCORSProperties(request, + CORSFilter.CORSRequestType.INVALID_CORS); + assertNull(request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + } + + @Test + public void testCheckSimpleRequestTypeAnyOrigin() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://www.w3.org"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.SIMPLE, requestType); + } + + /** + * Happy path test, when a valid CORS Simple request arrives. + * + * @throws ServletException + */ + @Test + public void testCheckSimpleRequestType() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.SIMPLE, requestType); + } + + /** + * Happy path test, when a valid CORS Simple request arrives. + * + * @throws ServletException + */ + @Test + public void testCheckActualRequestType() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setMethod("PUT"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.ACTUAL, requestType); + } + + /** + * Happy path test, when a valid CORS Simple request arrives. + * + * @throws ServletException + */ + @Test + public void testCheckActualRequestTypeMethodPOSTNotSimpleHeaders() + throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setMethod("POST"); + request.setContentType("application/json"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.ACTUAL, requestType); + } + + /** + * Happy path test, when a valid CORS Pre-flight request arrives. + * + * @throws ServletException + */ + @Test + public void testCheckPreFlightRequestType() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Content-Type"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.PRE_FLIGHT, requestType); + } + + /** + * when a valid CORS Pre-flight request arrives, with no Access-Control-Request-Method + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckPreFlightRequestTypeNoACRM() throws ServletException, + IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.ACTUAL, requestType); + } + + /** + * when a valid CORS Pre-flight request arrives, with empty Access-Control-Request-Method + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckPreFlightRequestTypeEmptyACRM() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + ""); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + /** + * Happy path test, when a valid CORS Pre-flight request arrives. + * + * @throws ServletException + */ + @Test + public void testCheckPreFlightRequestTypeNoHeaders() + throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "PUT"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.PRE_FLIGHT, requestType); + } + + /** + * Section 6.2.3 + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckPreFlightRequestTypeInvalidRequestMethod() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "POLITE"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * Section Section 6.2.5 + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckPreFlightRequestTypeUnsupportedRequestMethod() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "TRACE"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * Section Section 6.2.6 + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckPreFlightRequestTypeUnsupportedRequestHeaders() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "X-ANSWER"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSecureFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * Section Section 6.2.7 + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckPreFlightRequestTypeAnyOriginNoWithCredentials() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + "Origin"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getFilterConfigAnyOriginAndSupportsCredentialsDisabled()); + corsFilter.doFilter(request, response, filterChain); + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "*")); + assertNull(response + .getHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)); + } + + @Test + public void testCheckPreFlightRequestTypeOriginNotAllowed() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "www.ebay.com"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "PUT"); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSecureFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * Happy path test, when a valid CORS Pre-flight request arrives. + * + * @throws ServletException + */ + @Test + public void testCheckPreFlightRequestTypeEmptyHeaders() + throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTP_TOMCAT_APACHE_ORG); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD, + "PUT"); + request.setHeader( + CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS, + ""); + request.setMethod("OPTIONS"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.PRE_FLIGHT, requestType); + } + + /** + * Negative test, when a CORS request arrives, with an empty origin. + * + * @throws ServletException + */ + @Test + public void testCheckNotCORSRequestTypeEmptyOrigin() + throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + ""); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + /** + * Tests for failure, when a different domain is used, that's not in the allowed list of origins. + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckInvalidOrigin() throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "www.example.com"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * Tests for failure, when a different sub-domain is used, that's not in the allowed list of origins. + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckInvalidOriginNotAllowedSubdomain() + throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://commons.apache.org"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * PUT is not an allowed request method. + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckInvalidRequestMethod() throws ServletException, + IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://tomcat.apache.org"); + request.setMethod("PUT"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * When requestMethod is null + * + * @throws ServletException + */ + @Test + public void testCheckNullRequestMethod() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://tomcat.apache.org"); + request.setMethod(null); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + /** + * "http://tomcat.apache.org" is an allowed origin and "https://tomcat.apache.org" is not, because scheme doesn't + * match + * + * @throws ServletException + */ + @Test + public void testCheckForSchemeVariance() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "https://tomcat.apache.org"); + request.setMethod("POST"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + /** + * "http://tomcat.apache.org" is an allowed origin and "http://tomcat.apache.org:8080" is not, because ports doesn't + * match + * + * @throws ServletException + * @throws IOException + */ + @Test + public void testCheckForPortVariance() throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://tomcat.apache.org:8080"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getSpecificOriginFilterConfig()); + corsFilter.doFilter(request, response, filterChain); + assertEquals(HttpServletResponse.SC_FORBIDDEN, + response.getStatus()); + } + + /** + * Tests for failure, when an invalid {@link HttpServletRequest} is encountered. + * + * @throws ServletException + */ + @Test + public void testCheckRequestTypeNull() throws ServletException { + HttpServletRequest request = null; + CORSFilter corsFilter = new CORSFilter(); + Assertions.assertThrows(IllegalArgumentException.class, () -> corsFilter.checkRequestType(request)); + } + + @Test + public void testJoin() { + Set elements = new LinkedHashSet<>(); + String separator = ","; + elements.add("world"); + elements.add("peace"); + String join = CORSFilter.join(elements, separator); + assertTrue("world,peace".equals(join)); + } + + @Test + public void testJoinSingleElement() { + Set elements = new LinkedHashSet<>(); + String separator = ","; + elements.add("world"); + String join = CORSFilter.join(elements, separator); + assertTrue("world".equals(join)); + } + + @Test + public void testJoinSepNull() { + Set elements = new LinkedHashSet<>(); + String separator = null; + elements.add("world"); + elements.add("peace"); + String join = CORSFilter.join(elements, separator); + assertTrue("world,peace".equals(join)); + } + + @Test + public void testJoinElementsNull() { + Set elements = null; + String separator = ","; + String join = CORSFilter.join(elements, separator); + + assertNull(join); + } + + @Test + public void testJoinOneNullElement() { + Set elements = new LinkedHashSet<>(); + String separator = ","; + elements.add(null); + elements.add("peace"); + String join = CORSFilter.join(elements, separator); + assertTrue(",peace".equals(join)); + } + + @Test + public void testJoinAllNullElements() { + Set elements = new LinkedHashSet<>(); + String separator = ","; + elements.add(null); + elements.add(null); + String join = CORSFilter.join(elements, separator); + assertTrue("".equals(join)); + } + + @Test + public void testJoinAllEmptyElements() { + Set elements = new LinkedHashSet<>(); + String separator = ","; + elements.add(""); + elements.add(""); + String join = CORSFilter.join(elements, separator); + assertTrue("".equals(join)); + } + + @Test + public void testJoinPipeSeparator() { + Set elements = new LinkedHashSet<>(); + String separator = "|"; + elements.add("world"); + elements.add("peace"); + String join = CORSFilter.join(elements, separator); + assertTrue("world|peace".equals(join)); + } + + @Test + public void testWithFilterConfig() throws ServletException { + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + assertTrue(corsFilter.getAllowedHttpHeaders().size() == 6); + assertTrue(corsFilter.getAllowedHttpMethods().size() == 4); + assertTrue(corsFilter.getAllowedOrigins().size() == 0); + assertTrue(corsFilter.isAnyOriginAllowed()); + assertTrue(corsFilter.getExposedHeaders().size() == 0); + assertTrue(corsFilter.isSupportsCredentials()); + assertTrue(corsFilter.getPreflightMaxAge() == 1800); + assertTrue(!corsFilter.isLoggingEnabled()); + } + + @Test + public void testWithFilterConfigInvalidPreflightAge() + throws ServletException { + CORSFilter corsFilter = new CORSFilter(); + Assertions.assertThrows(ServletException.class, () -> corsFilter.init(TestConfigs.getFilterConfigInvalidMaxPreflightAge())); + } + + @Test + public void testWithStringParserEmpty() throws ServletException { + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getEmptyFilterConfig()); + assertTrue(corsFilter.getAllowedHttpHeaders().size() == 0); + assertTrue(corsFilter.getAllowedHttpMethods().size() == 0); + assertTrue(corsFilter.getAllowedOrigins().size() == 0); + assertTrue(corsFilter.getExposedHeaders().size() == 0); + assertFalse(corsFilter.isSupportsCredentials()); + assertTrue(corsFilter.getPreflightMaxAge() == 0); + assertTrue(!corsFilter.isLoggingEnabled()); + } + + /** + * If an init param is null, it's default value will be used. + * + * @throws ServletException + */ + @Test + public void testWithStringParserNull() throws ServletException { + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getNullFilterConfig()); + assertTrue(corsFilter.getAllowedHttpHeaders().size() == 6); + assertTrue(corsFilter.getAllowedHttpMethods().size() == 4); + assertTrue(corsFilter.getAllowedOrigins().size() == 0); + assertTrue(corsFilter.isAnyOriginAllowed()); + assertTrue(corsFilter.getExposedHeaders().size() == 0); + assertTrue(corsFilter.isSupportsCredentials()); + assertTrue(corsFilter.getPreflightMaxAge() == 1800); + assertTrue(!corsFilter.isLoggingEnabled()); + } + + @Test + public void testValidOrigin() { + assertTrue(CORSFilter.isValidOrigin("http://www.w3.org")); + } + + @Test + public void testInValidOriginCRLF() { + assertFalse(CORSFilter.isValidOrigin("http://www.w3.org\r\n")); + } + + @Test + public void testInValidOriginEncodedCRLF1() { + assertFalse(CORSFilter.isValidOrigin("http://www.w3.org%0d%0a")); + } + + @Test + public void testInValidOriginEncodedCRLF2() { + assertFalse(CORSFilter.isValidOrigin("http://www.w3.org%0D%0A")); + } + + @Test + public void testInValidOriginEncodedCRLF3() { + assertFalse(CORSFilter + .isValidOrigin("http://www.w3.org%0%0d%0ad%0%0d%0aa")); + } + + @Test + public void testCheckInvalidCRLF1() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://www.w3.org\r\n"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + @Test + public void testCheckInvalidCRLF2() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://www.w3.org\r\n"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + @Test + public void testCheckInvalidCRLF3() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://www.w3.org%0d%0a"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + @Test + public void testCheckInvalidCRLF4() throws ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + "http://www.w3.org%0D%0A"); + request.setMethod("GET"); + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs + .getDefaultFilterConfig()); + CORSFilter.CORSRequestType requestType + = corsFilter.checkRequestType(request); + assertEquals(CORSFilter.CORSRequestType.INVALID_CORS, + requestType); + } + + @Test + public void testDecorateRequestDisabled() throws IOException, + ServletException { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setHeader(CORSFilter.REQUEST_HEADER_ORIGIN, + TestConfigs.HTTPS_WWW_APACHE_ORG); + request.setMethod("GET"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + CORSFilter corsFilter = new CORSFilter(); + corsFilter.init(TestConfigs.getFilterConfigDecorateRequestDisabled()); + corsFilter.doFilter(request, response, filterChain); + + assertTrue(response.getHeader( + CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN).equals( + "https://www.apache.org")); + assertNull(request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)); + assertNull(request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN)); + assertNull(request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_HEADERS)); + assertNull(request + .getAttribute(CORSFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE)); + } + + @Test + public void testDestroy() { + // Nothing to test. + // NO-OP + } } diff --git a/para-server/src/test/java/com/erudika/para/utils/filters/MockFilterChain.java b/para-server/src/test/java/com/erudika/para/utils/filters/MockFilterChain.java index 98fdf32d..ab5b860c 100644 --- a/para-server/src/test/java/com/erudika/para/utils/filters/MockFilterChain.java +++ b/para-server/src/test/java/com/erudika/para/utils/filters/MockFilterChain.java @@ -17,10 +17,10 @@ import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; public class MockFilterChain implements FilterChain { diff --git a/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletRequest.java b/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletRequest.java index 87bd1adc..7272d65a 100644 --- a/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletRequest.java +++ b/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletRequest.java @@ -16,6 +16,21 @@ package com.erudika.para.utils.filters; import com.erudika.para.server.utils.filters.CORSFilter; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletConnection; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpUpgradeHandler; +import jakarta.servlet.http.Part; import java.io.BufferedReader; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -29,21 +44,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpUpgradeHandler; -import javax.servlet.http.Part; @SuppressWarnings("unchecked") public class MockHttpServletRequest implements HttpServletRequest { @@ -411,4 +411,19 @@ public DispatcherType getDispatcherType() { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public String getRequestId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getProtocolRequestId() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ServletConnection getServletConnection() { + throw new UnsupportedOperationException("Not supported yet."); + } + } diff --git a/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletResponse.java b/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletResponse.java index 01decfb8..455ae0c2 100644 --- a/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletResponse.java +++ b/para-server/src/test/java/com/erudika/para/utils/filters/MockHttpServletResponse.java @@ -23,9 +23,9 @@ import java.util.List; import java.util.Locale; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; @SuppressWarnings("unchecked") public class MockHttpServletResponse implements HttpServletResponse { diff --git a/para-server/src/test/java/com/erudika/para/utils/filters/MockServletContext.java b/para-server/src/test/java/com/erudika/para/utils/filters/MockServletContext.java index 3a5c6f1d..f824270e 100644 --- a/para-server/src/test/java/com/erudika/para/utils/filters/MockServletContext.java +++ b/para-server/src/test/java/com/erudika/para/utils/filters/MockServletContext.java @@ -22,17 +22,17 @@ import java.util.EventListener; import java.util.Map; import java.util.Set; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.descriptor.JspConfigDescriptor; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterRegistration; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.SessionCookieConfig; +import jakarta.servlet.SessionTrackingMode; +import jakarta.servlet.descriptor.JspConfigDescriptor; @SuppressWarnings("unchecked") public class MockServletContext implements ServletContext { diff --git a/para-server/src/test/java/com/erudika/para/utils/filters/TestConfigs.java b/para-server/src/test/java/com/erudika/para/utils/filters/TestConfigs.java index ebd20e8d..5d40a264 100644 --- a/para-server/src/test/java/com/erudika/para/utils/filters/TestConfigs.java +++ b/para-server/src/test/java/com/erudika/para/utils/filters/TestConfigs.java @@ -18,8 +18,8 @@ import com.erudika.para.server.utils.filters.CORSFilter; import java.util.Enumeration; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; @SuppressWarnings("unchecked") public class TestConfigs { diff --git a/para-server/src/test/resources/logback-test.xml b/para-server/src/test/resources/logback-test.xml index 566b554a..4f43a572 100644 --- a/para-server/src/test/resources/logback-test.xml +++ b/para-server/src/test/resources/logback-test.xml @@ -16,8 +16,7 @@ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - + diff --git a/pom.xml b/pom.xml index ebcf2d61..a76a9388 100644 --- a/pom.xml +++ b/pom.xml @@ -78,17 +78,19 @@ ${skipTests} ${skipTests} 3.1.1 - 1.7.36 - 1.2.13 + 2.0.12 + 1.5.3 [2.21.23,) - 2.41 - 2.7.18 + 3.1.6 + 3.2.4 4.2.25 5.3.1 5.2.4 1.16.0 1.47.0 1.47.0 + 5.10.2 + 1.10.2 @@ -96,33 +98,45 @@ org.mockito mockito-core - 4.8.1 + 5.11.0 test - + org.junit.jupiter junit-jupiter-api - 5.9.2 + ${junitVer} test org.junit.jupiter junit-jupiter-engine - 5.9.2 + ${junitVer} test - + + + @@ -130,7 +144,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.0.0 + 3.2.5 @@ -151,11 +165,21 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0 + 3.2.5 + + + org.apache.maven.surefire + surefire-junit-platform + 3.2.5 + + + ${skipUTs} - 1.5C + 2C