From b9756f4a3db1b3c511ae863df3fe9ac2059c1158 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 13:46:06 -0600 Subject: [PATCH 01/18] Update gradle scripts Signed-off-by: montesm --- app/gradle.properties | 2 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 62076 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 11 ++++++----- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/gradle.properties b/app/gradle.properties index 34d10c06..c9de9c7a 100644 --- a/app/gradle.properties +++ b/app/gradle.properties @@ -11,4 +11,4 @@ # 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. -micronautVersion=3.9.6 +micronautVersion=4.0.0 diff --git a/gradle.properties b/gradle.properties index 34d10c06..c9de9c7a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ # 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. -micronautVersion=3.9.6 +micronautVersion=4.0.0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 13895 zcmZ8|Wmp``)-~=Hdu)0n3Y-8OvyK$p9^s9MM|Aj$miotNhy-{udLczZyd9uWtD)X_{|!LhIEF9y8(e*Z zW>^w$u&x|i9OjL=#6Nl~*ERulzX>8C-}o;iSMRYdfCU5d`~U{V4>HCg0HG4Xg2uP;fn!>S9+>LbuWbc0bETMQfo9~h}yI*TSv;Oikl~t-+xqI-`P$Rj@yi{mr2zC~s1snMT3!OPBdJ%IDnPXq+pl*Z>=+?qo${lkCSKmwTlVjfb3thU6B8yFjr!tphOs*G6 zwL`RyVAUXj4p=9&@PpWK)m+REuvHaq838TEhY^7W+JAp$ zZ^y;8`Z*@VqJ{sFFj?<|7SKS@G`$Yi)gx%nOi@Lr zCv0IJlFz0bP(eDIW(uWNq?;8zEAb+uGgnkLk;y!4XhA6=Eoa<`+|;6mOq>z`%ir@z$4)Mkd3 zF=hFo zyd{*bRQ4YUe^bU*Y`__)Uhu5NIjVJ~a}{lHp-_7wI?#EB11XcqmdY>pk`JJ) zW9Rt!tK=N>fZ!UDomwMnb`0EOvTjcNl=yW@$c!OAg*=l()GjZwSyJ+o^;Zi#I5*uP z$6qeih8&g8E(pNSneK>93A(8*%gvwv!0V|SqGcj55Y7`=N*@pJx_ig3uVuf-G~LJbm`7nxNcZ>Jgqy(LTHu_C2e>STp^Pm{}f&^)XU}vzuU`UV&>e& zqsXNXSs;Wri|?NhCq0vXC5$>9Cag$adyWz^x@NCiy2${9Dc)Y;J8k1Z933W$3$H}g zCQFU1XwzGm_WUheXvnDisH_%BdzMgNwk2^mHcQu*x>U%iN*B^8U(eVz1~(%`kV1Vb z=9T0xmN?bQMyrrd?u}jer}zV&sCK6zSm!zV8A8dP6THF=4*V{_K*E*K<)I(Q^(eV!m!vu##-2g|G z{RB;{gJB_X-w{ANq?ft_n!@=O8_gj6FxW&zO$7L3@NjWt@R{NxMbpHLk6;=2$0P5P=kKc1_85inX z#s$&s0zhV1cz>nRb#|D#N8Z-=Tphm)sGH>9cz3K3I)6XpimJW0(6$GtLzN(YPu9%R zdFXG9|30AZME4r@joC0IdvBBe08mF@+5Dd97p$h=n|pi80Cn2n{ev!S$llPGLqHva zZ3*OmW%!Qj>C$F!Ffafl7#I_1(gz!aa)b{ebU*=yH%^kr=~N?|2&2Df2o9X=2B?U!#R#+Cj45=f@=EcQx+9J z=X3~A=zbX29Fqn23m3dm}0Voj^Q9BjI=MiG+NZ)YCYn@r^qv(xE3=)&i z=(ML301=rNTptvUt2tnsPb1~G*DWFWoZfv)wV|uNW%?!)jju`jN(K-0$JYi!ofNup z9K%_ucHwutbZsl~vDQ!Jtj8uI6WA6K--@?8+_=t>g|kgUeC=w`IP9m&*fuoO3#A;t z&3@=3;J0>yjM89?h5MG$S`wW+=vyYOWQGhIP`^vScM8^JL{mGan5uTJPvAg$0z}8; z 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 J*WbtZ{{Z#P!zlm& delta 13442 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 50832291..37aef8d3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68d..aeb74cbb 100755 --- a/gradlew +++ b/gradlew @@ -85,9 +85,6 @@ done APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +141,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +149,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in From 3ab58a75a60bf7feeb6ed2f30c60f08df1355b85 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 13:47:52 -0600 Subject: [PATCH 02/18] Update build.gradle Signed-off-by: montesm --- app/build.gradle | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3ffe69e1..fa8f94da 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,11 +20,12 @@ buildscript { } } plugins { - id("com.github.johnrengelman.shadow") version "7.1.2" + id("com.github.johnrengelman.shadow") version "8.1.1" id("jacoco") - id("com.gorylenko.gradle-git-properties") version "2.3.2" - id("io.micronaut.application") version "3.7.10" - id("io.micronaut.test-resources") version "3.7.10" + id("com.gorylenko.gradle-git-properties") version "2.4.1" + id("io.micronaut.application") version "4.0.0" + id("io.micronaut.test-resources") version "4.0.0" + id("io.micronaut.aot") version "4.0.0" } version = "0.1" @@ -37,10 +38,12 @@ repositories { dependencies { annotationProcessor("io.micronaut.data:micronaut-data-processor") - annotationProcessor("io.micronaut:micronaut-http-validation") annotationProcessor("io.micronaut.openapi:micronaut-openapi") annotationProcessor("io.micronaut.security:micronaut-security-annotations") + annotationProcessor("io.micronaut.validation:micronaut-validation-processor") + annotationProcessor("io.micronaut.serde:micronaut-serde-processor") annotationProcessor("io.micronaut:micronaut-graal") + implementation("io.micronaut.serde:micronaut-serde-jackson") implementation("io.micronaut:micronaut-http-client") implementation("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut:micronaut-management") @@ -51,18 +54,23 @@ dependencies { implementation("io.micronaut.sql:micronaut-jdbc-hikari") implementation("io.swagger.core.v3:swagger-annotations") implementation("jakarta.annotation:jakarta.annotation-api") + implementation("io.micronaut.validation:micronaut-validation") + implementation("io.micronaut:micronaut-websocket") runtimeOnly("ch.qos.logback:logback-classic") - implementation("io.micronaut:micronaut-validation") + implementation("org.bouncycastle:bcprov-jdk18on:1.72") implementation("org.bouncycastle:bcpkix-jdk18on:1.72") - implementation("org.bouncycastle:bcmail-jdk18on:1.72") +// implementation("org.bouncycastle:bcmail-jdk18on:1.72") + implementation("org.bouncycastle:bcjmail-jdk18on:1.72") implementation("io.micronaut.email:micronaut-email-javamail") + implementation("jakarta.xml.bind:jakarta.xml.bind-api:4.0.1") implementation("io.micronaut.views:micronaut-views-freemarker") implementation("io.micronaut.gcp:micronaut-gcp-secret-manager") implementation("com.google.cloud:google-cloud-secretmanager:2.12.0") + runtimeOnly("org.yaml:snakeyaml") // nativeImageCompileOnly("com.google.cloud:native-image-support") String databaseSelection = System.getenv("DPM_DATABASE_DEPENDENCY") @@ -85,8 +93,8 @@ application { mainClass.set("io.unityfoundation.dds.permissions.manager.RunApplication") } java { - sourceCompatibility = JavaVersion.toVersion("11") - targetCompatibility = JavaVersion.toVersion("11") + sourceCompatibility = JavaVersion.toVersion("17") + targetCompatibility = JavaVersion.toVersion("17") } graalvmNative.toolchainDetection = false From 63d632dea4f1a04156b7367b185fb097a2b1de57 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 13:50:33 -0600 Subject: [PATCH 03/18] Update known necessary changes for logback and cookie config Signed-off-by: montesm --- app/src/main/resources/application.yml | 5 ++--- app/src/main/resources/logback.xml | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/resources/application.yml b/app/src/main/resources/application.yml index b6b1bd80..985baf09 100644 --- a/app/src/main/resources/application.yml +++ b/app/src/main/resources/application.yml @@ -32,9 +32,8 @@ micronaut: cookie: cookie-path: / cookie-max-age: 1d - jwt: - cookie: - cookie-max-age: 1h + cookie: + cookie-max-age: 1h authentication: cookie oauth2: login-uri: "/api/oauth/login{/provider}" diff --git a/app/src/main/resources/logback.xml b/app/src/main/resources/logback.xml index e1d2af93..46c8fec0 100644 --- a/app/src/main/resources/logback.xml +++ b/app/src/main/resources/logback.xml @@ -16,7 +16,6 @@ limitations under the License. - true From 7ec9e6d939af0e6f0b36437efbde973ccee4424c Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:01:38 -0600 Subject: [PATCH 04/18] Use Serdable and use correct tags per property Signed-off-by: montesm --- ...TOConstraintViolationExceptionHandler.java | 8 ++++---- .../manager/model/action/dto/ActionDTO.java | 7 ++----- .../model/action/dto/CreateActionDTO.java | 7 +++---- .../model/action/dto/UpdateActionDTO.java | 6 +++--- .../actioninterval/dto/ActionIntervalDTO.java | 20 ++++++++----------- .../dto/CreateActionIntervalDTO.java | 13 +++++------- .../model/application/ApplicationDTO.java | 13 +++++------- .../applicationgrant/dto/CreateGrantDTO.java | 11 +++++----- .../dto/DetailedGrantDTO.java | 5 ++--- .../model/applicationgrant/dto/GrantDTO.java | 4 ++-- .../applicationgrant/dto/UpdateGrantDTO.java | 11 +++++----- .../AccessPermissionBodyDTO.java | 4 ++-- .../AccessPermissionDTO.java | 4 ++-- .../dto/CreateGrantDurationDTO.java | 10 ++++++---- .../grantduration/dto/GrantDurationDTO.java | 16 +++++++-------- .../manager/model/group/DetailedGroupDTO.java | 4 ++-- .../manager/model/group/SimpleGroupDTO.java | 9 ++++----- .../manager/model/groupuser/GroupUserDTO.java | 11 +++++----- .../model/groupuser/GroupUserResponseDTO.java | 4 ++-- .../manager/model/topic/TopicDTO.java | 15 +++++--------- .../model/topicset/dto/CreateTopicSetDTO.java | 11 +++++----- .../model/topicset/dto/TopicSetDTO.java | 7 ++----- .../model/topicset/dto/UpdateTopicSetDTO.java | 9 ++++----- .../manager/model/user/AdminDTO.java | 17 +++++++++++----- .../manager/search/SearchResponseDTO.java | 4 ++-- 25 files changed, 105 insertions(+), 125 deletions(-) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DTOConstraintViolationExceptionHandler.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DTOConstraintViolationExceptionHandler.java index 7faebc17..a06bbd19 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DTOConstraintViolationExceptionHandler.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DTOConstraintViolationExceptionHandler.java @@ -23,13 +23,13 @@ import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; import io.unityfoundation.dds.permissions.manager.security.PassphraseGenerator; import jakarta.inject.Singleton; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.constraints.*; +import jakarta.validation.metadata.ConstraintDescriptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; -import javax.validation.constraints.*; -import javax.validation.metadata.ConstraintDescriptor; import java.util.List; import java.util.Set; import java.util.stream.Collectors; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/ActionDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/ActionDTO.java index 80f9f37d..8c608c5a 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/ActionDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/ActionDTO.java @@ -13,8 +13,7 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.action.dto; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import java.time.Instant; @@ -22,7 +21,7 @@ import java.util.Map; import java.util.Set; -@Introspected +@Serdeable public class ActionDTO implements EntityDTO { private Long id; @@ -34,10 +33,8 @@ public class ActionDTO implements EntityDTO { Set partitions = new HashSet<>(); private Boolean isPublishAction; - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateCreated; - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateUpdated; public ActionDTO() { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/CreateActionDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/CreateActionDTO.java index f1b035f3..66f04aac 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/CreateActionDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/CreateActionDTO.java @@ -13,11 +13,10 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.action.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; - -@Introspected +@Serdeable public class CreateActionDTO extends UpdateActionDTO { @NotNull diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/UpdateActionDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/UpdateActionDTO.java index f6fe20f4..3033bc3f 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/UpdateActionDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/dto/UpdateActionDTO.java @@ -13,13 +13,13 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.action.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.util.HashSet; import java.util.Set; -@Introspected +@Serdeable public class UpdateActionDTO { @NotNull diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/ActionIntervalDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/ActionIntervalDTO.java index c41e2fd9..d39cd207 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/ActionIntervalDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/ActionIntervalDTO.java @@ -13,25 +13,23 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.actioninterval.dto; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; -import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionInterval; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.time.Instant; import java.util.List; -@Introspected +@Serdeable public class ActionIntervalDTO implements EntityDTO { - @NotBlank - @Size(min = 3) + @NotNull private Long id; - @NotNull + @NotBlank + @Size(min = 3) private String name; private Long groupId; private String groupName; @@ -39,11 +37,9 @@ public class ActionIntervalDTO implements EntityDTO { private Integer actionCount; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant startDate; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant endDate; public ActionIntervalDTO() { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/CreateActionIntervalDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/CreateActionIntervalDTO.java index a9f3fe7c..5a1383be 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/CreateActionIntervalDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/dto/CreateActionIntervalDTO.java @@ -13,17 +13,16 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.actioninterval.dto; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionInterval; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.time.Instant; -@Introspected +@Serdeable public class CreateActionIntervalDTO implements EntityDTO { @NotBlank @@ -34,11 +33,9 @@ public class CreateActionIntervalDTO implements EntityDTO { private Long groupId; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant startDate; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant endDate; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationDTO.java index 0d838554..98042e5f 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationDTO.java @@ -13,17 +13,16 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.application; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.time.Instant; import java.util.List; -@Introspected +@Serdeable public class ApplicationDTO implements EntityDTO { private Long id; @@ -37,10 +36,8 @@ public class ApplicationDTO implements EntityDTO { private Long group; private String groupName; - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateCreated; - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateUpdated; private List admins; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/CreateGrantDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/CreateGrantDTO.java index 621f7b9c..90aadb54 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/CreateGrantDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/CreateGrantDTO.java @@ -13,14 +13,13 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -@Introspected +@Serdeable public class CreateGrantDTO implements EntityDTO { @NotBlank @Size(min = 3) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/DetailedGrantDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/DetailedGrantDTO.java index a928874c..a08df830 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/DetailedGrantDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/DetailedGrantDTO.java @@ -13,13 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto; -import io.micronaut.core.annotation.Introspected; -import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.action.dto.ActionDTO; import java.util.List; -@Introspected +@Serdeable public class DetailedGrantDTO extends GrantDTO { List actions; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/GrantDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/GrantDTO.java index a52c7127..be642551 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/GrantDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/GrantDTO.java @@ -13,12 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import java.util.List; -@Introspected +@Serdeable public class GrantDTO implements EntityDTO { private final Long id; private final String name; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/UpdateGrantDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/UpdateGrantDTO.java index 6dae2f58..a914a3b2 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/UpdateGrantDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/dto/UpdateGrantDTO.java @@ -13,14 +13,13 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -@Introspected +@Serdeable public class UpdateGrantDTO implements EntityDTO { @NotBlank @Size(min = 3) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionBodyDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionBodyDTO.java index 69cb3d07..3dc82aa5 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionBodyDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionBodyDTO.java @@ -13,12 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationpermission; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import java.util.Set; -@Introspected +@Serdeable public class AccessPermissionBodyDTO implements EntityDTO { private boolean read; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionDTO.java index d3cab7b1..4378dd74 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/AccessPermissionDTO.java @@ -13,12 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationpermission; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import java.util.Set; -@Introspected +@Serdeable public class AccessPermissionDTO implements EntityDTO { private final Long topicId; private final String topicName; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/CreateGrantDurationDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/CreateGrantDurationDTO.java index 20664121..72125744 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/CreateGrantDurationDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/CreateGrantDurationDTO.java @@ -13,13 +13,15 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.grantduration.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.*; - -@Introspected +@Serdeable public class CreateGrantDurationDTO implements EntityDTO { @NotBlank diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/GrantDurationDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/GrantDurationDTO.java index 3d456aeb..8a063c8c 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/GrantDurationDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/dto/GrantDurationDTO.java @@ -13,22 +13,22 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.grantduration.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.util.List; -@Introspected +@Serdeable public class GrantDurationDTO implements EntityDTO { - @NotBlank - @Size(min = 3) + @NotNull private Long id; - @NotNull + @NotBlank + @Size(min = 3) private String name; private Long groupId; private String groupName; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/DetailedGroupDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/DetailedGroupDTO.java index 1b70ab18..501a23a9 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/DetailedGroupDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/DetailedGroupDTO.java @@ -13,12 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.group; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import java.util.Set; -@Introspected +@Serdeable public class DetailedGroupDTO implements EntityDTO { private Long id; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/SimpleGroupDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/SimpleGroupDTO.java index c082864c..ff5b95ee 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/SimpleGroupDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/SimpleGroupDTO.java @@ -13,13 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.group; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - -@Introspected +@Serdeable public class SimpleGroupDTO implements EntityDTO { private Long id; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserDTO.java index 53c78137..4e5f9a56 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserDTO.java @@ -13,13 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.groupuser; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - -@Introspected +@Serdeable public class GroupUserDTO { private Long id; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserResponseDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserResponseDTO.java index 0d6dc147..849521b4 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserResponseDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserResponseDTO.java @@ -13,9 +13,9 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.groupuser; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; -@Introspected +@Serdeable public class GroupUserResponseDTO { private Long id; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicDTO.java index 01d41448..fc714bb2 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicDTO.java @@ -13,18 +13,17 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.topic; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.micronaut.core.annotation.Introspected; import io.micronaut.core.annotation.Nullable; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.time.Instant; import java.util.List; -@Introspected +@Serdeable public class TopicDTO implements EntityDTO { private Long id; @@ -40,11 +39,7 @@ public class TopicDTO implements EntityDTO { private String groupName; private String canonicalName; private List admins; - - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateCreated; - - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateUpdated; public TopicDTO() { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/CreateTopicSetDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/CreateTopicSetDTO.java index 7542258e..2ea52d2c 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/CreateTopicSetDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/CreateTopicSetDTO.java @@ -13,15 +13,14 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.topicset.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -@Introspected +@Serdeable public class CreateTopicSetDTO implements EntityDTO { @NotBlank diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/TopicSetDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/TopicSetDTO.java index bc032e4d..7b89482a 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/TopicSetDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/TopicSetDTO.java @@ -13,8 +13,7 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.topicset.dto; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import java.time.Instant; @@ -22,7 +21,7 @@ import java.util.Map; import java.util.Set; -@Introspected +@Serdeable public class TopicSetDTO implements EntityDTO { private Long id; @@ -32,10 +31,8 @@ public class TopicSetDTO implements EntityDTO { private Set> topics; private List admins; - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateCreated; - @JsonFormat(shape = JsonFormat.Shape.STRING) private Instant dateUpdated; public TopicSetDTO(Long id, String name, Long groupId, String groupName, Set> topics, Instant dateCreated, Instant dateUpdated) { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/UpdateTopicSetDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/UpdateTopicSetDTO.java index ba7023d6..a6b26d29 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/UpdateTopicSetDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/dto/UpdateTopicSetDTO.java @@ -13,14 +13,13 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.topicset.dto; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - -@Introspected +@Serdeable public class UpdateTopicSetDTO implements EntityDTO { @NotBlank diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/AdminDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/AdminDTO.java index 954c91c0..241cfacc 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/AdminDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/AdminDTO.java @@ -13,12 +13,11 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.user; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; - -@Introspected +@Serdeable public class AdminDTO { private Long id; @NotBlank @@ -38,7 +37,15 @@ public Long getId() { return id; } + public void setId(Long id) { + this.id = id; + } + public String getEmail() { return email; } + + public void setEmail(String email) { + this.email = email; + } } diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/SearchResponseDTO.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/SearchResponseDTO.java index 1ab4ad8a..dceb7a25 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/SearchResponseDTO.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/SearchResponseDTO.java @@ -13,12 +13,12 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.search; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; import io.unityfoundation.dds.permissions.manager.model.DPMEntity; import io.unityfoundation.dds.permissions.manager.model.EntityDTO; -@Introspected +@Serdeable public class SearchResponseDTO { private DPMEntity type; From b580071de0a202ff82275358f446cd3df947a56b Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:06:39 -0600 Subject: [PATCH 05/18] Refactor tests and optimize imports Signed-off-by: montesm --- .../permissions/manager/ActionApiTest.java | 70 +-- .../manager/ActionIntervalApiTest.java | 113 +++-- .../dds/permissions/manager/AdminApiTest.java | 44 +- .../manager/ApplicationApiTest.java | 473 +++++++++--------- .../manager/ApplicationGrantApiTest.java | 114 +++-- .../manager/ApplicationPermissionApiTest.java | 51 +- .../manager/GrantDurationApiTest.java | 128 ++--- .../dds/permissions/manager/GroupApiTest.java | 85 ++-- .../manager/GroupMembershipApiTest.java | 446 ++++++++++------- .../manager/SecurityServiceReplacement.java | 6 +- .../manager/TemplateServiceTest.java | 6 +- .../dds/permissions/manager/TopicApiTest.java | 456 +++++++++-------- .../permissions/manager/TopicSetApiTest.java | 143 +++--- .../manager/UniversalSearchApiTest.java | 2 +- .../permissions/manager/WebSocketTests.java | 24 +- .../permissions/manager/XMLEscaperTest.java | 2 +- .../manager/testing/util/DbCleanup.java | 5 +- 17 files changed, 1200 insertions(+), 968 deletions(-) diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionApiTest.java index c0dc1044..961459f9 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionApiTest.java @@ -26,6 +26,7 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.action.ActionPartition; import io.unityfoundation.dds.permissions.manager.model.action.ActionPartitionRepository; import io.unityfoundation.dds.permissions.manager.model.action.dto.ActionDTO; @@ -141,10 +142,11 @@ void cannotCreateOnItsOwnWithoutAGrantAssociation() { blockingClient.exchange(finalRequest, ActionDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_REQUIRES_APPLICATION_GRANT_ASSOCIATION.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_REQUIRES_APPLICATION_GRANT_ASSOCIATION.equals(dpmErrorResponse.getCode()))); // without action interval create.setActionIntervalId(null); @@ -154,10 +156,11 @@ void cannotCreateOnItsOwnWithoutAGrantAssociation() { blockingClient.exchange(finalRequest1, ActionDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_REQUIRES_INTERVAL_ASSOCIATION.equals(map.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_REQUIRES_INTERVAL_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -788,10 +791,11 @@ void cannotCreate(){ entityUtil.createAction(applicationGrant.getId(), actionInterval.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // update @@ -832,10 +836,11 @@ void cannotUpdate(){ blockingClient.exchange(request, ActionDTO.class); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -873,10 +878,11 @@ void cannotDelete(){ blockingClient.exchange(request); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -978,10 +984,11 @@ void cannotShowActionIfItBelongsToAGroupIAmNotAMemberOf(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // list @@ -1146,10 +1153,11 @@ void cannotCreateAction(){ entityUtil.createAction(applicationGrant.getId(), actionInterval.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1184,11 +1192,12 @@ void cannotDeleteAction(){ HttpClientResponseException exception = assertThrowsExactly(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest); }); - assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + assertEquals(UNAUTHORIZED, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1223,10 +1232,11 @@ void cannotShowAction(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionIntervalApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionIntervalApiTest.java index c1f3b3db..24c059a7 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionIntervalApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ActionIntervalApiTest.java @@ -26,6 +26,7 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.action.dto.ActionDTO; import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.ActionIntervalDTO; import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.CreateActionIntervalDTO; @@ -122,10 +123,11 @@ void cannotCreateOnItsOwnWithoutAGroupAssociation() { blockingClient.exchange(request, ActionIntervalDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_INTERVAL_REQUIRES_GROUP_ASSOCIATION.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -245,10 +247,11 @@ public void cannotCreateWithNullNorWhitespace() { blockingClient.exchange(finalRequest, ActionIntervalDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_INTERVAL_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); actionIntervalDTO.setName(" "); request = HttpRequest.POST("/action_intervals", actionIntervalDTO); @@ -257,10 +260,11 @@ public void cannotCreateWithNullNorWhitespace() { blockingClient.exchange(finalRequest1, ActionIntervalDTO.class); }); assertEquals(BAD_REQUEST, exception1.getStatus()); - bodyOptional = exception1.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_INTERVAL_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); } @Test @@ -277,10 +281,11 @@ public void cannotCreateWithNameLessThanThreeCharacters() { entityUtil.createActionInterval("A", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_INTERVAL_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -327,14 +332,15 @@ public void cannotUpdateGroupAssociation() { abcActionInterval.setGroupId(zeta.getId()); request = HttpRequest.PUT("/action_intervals/"+abcActionInterval.getId(), abcActionInterval); HttpRequest finalRequest = request; - HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { + HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - Optional bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_INTERVAL_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(map.get("code")))); + assertEquals(BAD_REQUEST, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -358,10 +364,13 @@ public void canUpdateNameAndDates() { // with different name and dates savedActionInterval.setName("NewName123"); + Instant updateStartInstant = Instant.now().plus(2, ChronoUnit.DAYS); savedActionInterval.setStartDate(updateStartInstant); + Instant updateEndInstant = Instant.now().plus(5, ChronoUnit.DAYS); savedActionInterval.setEndDate(updateEndInstant); + request = HttpRequest.PUT("/action_intervals/"+savedActionInterval.getId(), savedActionInterval); response = blockingClient.exchange(request, ActionIntervalDTO.class); assertEquals(OK, response.getStatus()); @@ -407,10 +416,11 @@ public void cannotCreateActionIntervalWithSameNameInGroup() { entityUtil.createActionInterval("Abc123", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.ACTION_INTERVAL_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } //show @@ -849,10 +859,11 @@ void cannotDeleteActionIntervalIfAssociatedToAnAction(){ blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.ACTION_INTERVAL_HAS_ONE_OR_MORE_ACTION_ASSOCIATIONS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.ACTION_INTERVAL_HAS_ONE_OR_MORE_ACTION_ASSOCIATIONS.equals(dpmErrorResponse.getCode()))); } } @@ -901,10 +912,11 @@ void cannotCreateActionInterval(){ entityUtil.createActionInterval("Abc123", theta.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -941,10 +953,11 @@ void cannotDeleteActionInterval(){ blockingClient.exchange(request2); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1049,10 +1062,11 @@ void cannotShowActionIntervalIfActionIntervalBelongsToAGroupIAmNotAMemberOf(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // list @@ -1294,10 +1308,11 @@ void cannotCreateActionInterval(){ entityUtil.createActionInterval("Abc123", theta.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1332,10 +1347,11 @@ void cannotDeleteActionInterval(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1378,10 +1394,11 @@ void cannotShowActionIntervalWithAssociatedGroup(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminApiTest.java index 09cbde58..bcd0dda0 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminApiTest.java @@ -26,7 +26,8 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; -import io.unityfoundation.dds.permissions.manager.model.group.Group; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; +import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; import io.unityfoundation.dds.permissions.manager.model.user.AdminDTO; import io.unityfoundation.dds.permissions.manager.model.user.User; @@ -106,11 +107,12 @@ void canAddAdmin(){ @Test void canEscalateExistingMembersPrivilegeToAdmin(){ // group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); String bobEmail = "bob.builder@test.test"; @@ -138,27 +140,29 @@ void canEscalateExistingMembersPrivilegeToAdmin(){ @Test public void userWithInvalidEmailFormatShallNotPersist() { - HttpRequest request = HttpRequest.POST("/admins/save", new User("pparker@.test.test", true)); + HttpRequest request = HttpRequest.POST("/admins/save", new AdminDTO("pparker@.test.test")); HttpRequest finalRequest = request; - HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { + HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - Optional bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.INVALID_EMAIL_FORMAT.equals(map.get("code")))); - - request = HttpRequest.POST("/admins/save", new User("pparker@unityfoundation", true)); + assertEquals(BAD_REQUEST, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.INVALID_EMAIL_FORMAT.equals(dpmErrorResponse.getCode()))); + + request = HttpRequest.POST("/admins/save", new AdminDTO("pparker@unityfoundation")); HttpRequest finalRequest1 = request; - thrown = assertThrows(HttpClientResponseException.class, () -> { + exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest1); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.INVALID_EMAIL_FORMAT.equals(map.get("code")))); + assertEquals(BAD_REQUEST, exception.getStatus()); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.INVALID_EMAIL_FORMAT.equals(dpmErrorResponse.getCode()))); } // update @@ -230,7 +234,7 @@ void canRemoveAdmin(){ HttpRequest request = HttpRequest.POST("/admins/save", justin); HttpResponse response = blockingClient.exchange(request, AdminDTO.class); assertEquals(OK, response.getStatus()); - Optional jjones = response.getBody(User.class); + Optional jjones = response.getBody(AdminDTO.class); assertTrue(jjones.isPresent()); request = HttpRequest.PUT("/admins/remove_admin/"+jjones.get().getId(), Map.of()); diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java index 6ff37b01..abae94e8 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java @@ -28,12 +28,12 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.action.dto.ActionDTO; import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.ActionIntervalDTO; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.GrantDTO; import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.GrantDurationDTO; -import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; @@ -124,10 +124,11 @@ public void cannotCreateWithoutGroupSpecified() { entityUtil.createApplication("TestApplication", null); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_REQUIRES_GROUP_ASSOCIATION.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -137,9 +138,9 @@ public void canCreateApplicationWithGroupSpecified() { // create group response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -155,9 +156,9 @@ public void cannotCreateApplicationWithSameNameAsAnotherInSameGroup() { // create group response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -169,10 +170,11 @@ public void cannotCreateApplicationWithSameNameAsAnotherInSameGroup() { entityUtil.createApplication("TestApplication", primaryGroup.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -182,15 +184,15 @@ public void canCreateApplicationWithSameNameInAnotherGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create application response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -209,29 +211,31 @@ public void cannotCreateApplicationWithNullNorWhitespace() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // null HttpClientResponseException exception = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createApplication(null, primaryGroup.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); // space exception = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createApplication(" ", primaryGroup.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(group.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); } @Test @@ -240,18 +244,19 @@ public void cannotCreateWithNameLessThanThreeCharacters() { response = entityUtil.createGroup("Theta"); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); HttpClientResponseException exception = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createApplication("a", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -261,9 +266,9 @@ public void createShouldTrimWhitespace() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication(" Abc123 ", primaryGroup.getId()); @@ -281,9 +286,9 @@ public void cannotCreateApplicationWithSameNameInGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("Abc123", primaryGroup.getId()); @@ -297,10 +302,11 @@ public void cannotCreateApplicationWithSameNameInGroup() { entityUtil.createApplication("Abc123", primaryGroup.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -310,9 +316,9 @@ public void createWithDescriptionAndDenyIfDescriptionIsMoreThanFourThousandChars // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -336,10 +342,11 @@ public void createWithDescriptionAndDenyIfDescriptionIsMoreThanFourThousandChars blockingClient.exchange(finalRequest, ApplicationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.APPLICATION_DESCRIPTION_CANNOT_BE_MORE_THAN_FOUR_THOUSAND_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_DESCRIPTION_CANNOT_BE_MORE_THAN_FOUR_THOUSAND_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -349,9 +356,9 @@ public void createWithDescriptionWithFourThousandChars() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -388,9 +395,9 @@ public void createWithPublicGroup() { request = HttpRequest.POST("/groups/save", group); response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional betaOptional = response.getBody(Group.class); + Optional betaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(betaOptional.isPresent()); - Group beta = betaOptional.get(); + SimpleGroupDTO beta = betaOptional.get(); // create private application allowed ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -437,9 +444,9 @@ public void createWithPrivateGroup() { // create private group response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); // create private application (allowed) ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -462,10 +469,11 @@ public void createWithPrivateGroup() { blockingClient.exchange(finalRequest, ApplicationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(dpmErrorResponse.getCode()))); // create public application (not allowed) ApplicationDTO publicApplicationDTO = new ApplicationDTO(); @@ -478,10 +486,11 @@ public void createWithPrivateGroup() { blockingClient.exchange(finalRequest1, ApplicationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(group.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(dpmErrorResponse.getCode()))); } @Test @@ -492,15 +501,15 @@ public void canViewAllApplications() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -527,9 +536,9 @@ public void canViewPublic() { request = HttpRequest.POST("/groups/save", group); response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -563,15 +572,15 @@ void canListAllApplicationsWithFilter(){ // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create applications response = entityUtil.createApplication("Xyz789", primaryGroup.getId(), "xyzdesc"); @@ -631,15 +640,15 @@ void canListApplicationsWithGroupId(){ // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create applications response = entityUtil.createApplication("Xyz789", primaryGroup.getId()); @@ -687,15 +696,15 @@ void canListAllApplicationsNameInAscendingOrderByDefault(){ // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create applications response = entityUtil.createApplication("Xyz789", primaryGroup.getId()); @@ -743,15 +752,15 @@ void canListAllApplicationsNameInDescendingOrder(){ // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create applications response = entityUtil.createApplication("Xyz789", primaryGroup.getId()); @@ -786,9 +795,9 @@ public void canUpdateApplication() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -823,9 +832,9 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -870,15 +879,15 @@ public void cannotUpdateApplicationGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); - Group secondaryGroup = secondaryOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -894,10 +903,11 @@ public void cannotUpdateApplicationGroup() { blockingClient.exchange(request); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -908,9 +918,9 @@ public void cannotUpdateApplicationNameIfOneAlreadyExistsInSameGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -932,10 +942,11 @@ public void cannotUpdateApplicationNameIfOneAlreadyExistsInSameGroup() { blockingClient.exchange(request, ApplicationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -946,9 +957,9 @@ public void canDeleteFromGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -971,9 +982,9 @@ void canGeneratePassphraseAndVerify() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -1024,9 +1035,9 @@ void canGenerateApplicationGrantToken() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -1051,9 +1062,9 @@ void cannotGenerateApplicationGrantTokenForApplicationThatDoesNotExist() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -1069,10 +1080,11 @@ void cannotGenerateApplicationGrantTokenForApplicationThatDoesNotExist() { blockingClient.exchange(finalRequest, ApplicationDTO.class); }); assertEquals(NOT_FOUND, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_NOT_FOUND.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_NOT_FOUND.equals(dpmErrorResponse.getCode()))); } } @@ -1102,10 +1114,11 @@ public void cannotCreateWithoutGroupSpecified() { entityUtil.createApplication("TestApplication", null); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_REQUIRES_GROUP_ASSOCIATION.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -1117,9 +1130,9 @@ public void cannotCreateIfNotMemberOfGroup() { // save group without members response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryGroupOptional = response.getBody(Group.class); + Optional primaryGroupOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryGroupOptional.isPresent()); - Group primaryGroup = primaryGroupOptional.get(); + SimpleGroupDTO primaryGroup = primaryGroupOptional.get(); loginAsNonAdmin(); @@ -1127,10 +1140,11 @@ public void cannotCreateIfNotMemberOfGroup() { entityUtil.createApplication("TestApplication", primaryGroup.getId()); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1144,9 +1158,9 @@ public void canCreate() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1178,9 +1192,9 @@ public void cannotCreateIfNonApplicationAdminMemberOfGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // get user User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1201,10 +1215,11 @@ public void cannotCreateIfNonApplicationAdminMemberOfGroup() { entityUtil.createApplication("TestApplication", primaryGroup.getId()); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @@ -1221,13 +1236,13 @@ public void canViewGroupApplicationsAsMember() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryGroupOptional = response.getBody(Group.class); + Optional secondaryGroupOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryGroupOptional.isPresent()); // get user @@ -1280,9 +1295,9 @@ public void canViewPublic() { request = HttpRequest.POST("/groups/save", group); response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -1319,13 +1334,13 @@ void canListApplicationsWithFilterLimitedToGroupMembership(){ // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryGroupOptional = response.getBody(Group.class); + Optional secondaryGroupOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryGroupOptional.isPresent()); // get user @@ -1418,13 +1433,13 @@ void canListApplicationsWithGroupParameterLimitedToGroupMembership(){ // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryGroupOptional = response.getBody(Group.class); + Optional secondaryGroupOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryGroupOptional.isPresent()); // get user @@ -1491,9 +1506,9 @@ public void canUpdateApplicationName() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // get user User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1537,11 +1552,11 @@ public void cannotUpdateApplicationGroupIfTargetGroupApplicationAdmin() { // create two groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Group primaryGroup = response.getBody(Group.class).get(); + SimpleGroupDTO primaryGroup = response.getBody(SimpleGroupDTO.class).get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Group secondaryGroup = response.getBody(Group.class).get(); + SimpleGroupDTO secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); // get user User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1576,10 +1591,11 @@ public void cannotUpdateApplicationGroupIfTargetGroupApplicationAdmin() { blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -1592,11 +1608,11 @@ public void cannotUpdateApplicationGroupIfNotApplicationAdminOfTargetGroup() { // create two groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Group primaryGroup = response.getBody(Group.class).get(); + SimpleGroupDTO primaryGroup = response.getBody(SimpleGroupDTO.class).get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Group secondaryGroup = response.getBody(Group.class).get(); + SimpleGroupDTO secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); // get user User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1633,10 +1649,11 @@ public void cannotUpdateApplicationGroupIfNotApplicationAdminOfTargetGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1649,7 +1666,7 @@ public void canDeleteFromGroup() { // create group response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Group primaryGroup = response.getBody(Group.class).get(); + SimpleGroupDTO primaryGroup = response.getBody(SimpleGroupDTO.class).get(); // get user User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1687,9 +1704,9 @@ void canGenerateApplicationGrantToken() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // get user User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -1747,10 +1764,11 @@ public void cannotCreateWithoutGroupSpecified() { entityUtil.createApplication("TestApplication", null); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_REQUIRES_GROUP_ASSOCIATION.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -1764,9 +1782,9 @@ public void cannotCreateApplicationWithGroupSpecified() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); loginAsNonAdmin(); @@ -1774,10 +1792,11 @@ public void cannotCreateApplicationWithGroupSpecified() { entityUtil.createApplication("TestApplication", primaryGroup.getId()); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1792,9 +1811,9 @@ public void cannotCreateApplicationWithSameNameAsAnotherInSameGroup() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -1811,10 +1830,11 @@ public void cannotCreateApplicationWithSameNameAsAnotherInSameGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1829,9 +1849,9 @@ public void cannotViewApplicationDetails() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -1848,10 +1868,11 @@ public void cannotViewApplicationDetails() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1871,9 +1892,9 @@ public void canViewPublic() { request = HttpRequest.POST("/groups/save", group); response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications ApplicationDTO applicationDTO = new ApplicationDTO(); @@ -1906,9 +1927,9 @@ public void cannotUpdateApplicationName() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", primaryGroup.getId()); @@ -1926,10 +1947,11 @@ public void cannotUpdateApplicationName() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1942,9 +1964,9 @@ public void cannotUpdateApplicationNameIfOneAlreadyExistsInSameGroup() { // create group response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -1968,10 +1990,11 @@ public void cannotUpdateApplicationNameIfOneAlreadyExistsInSameGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1984,9 +2007,9 @@ public void cannotDeleteFromGroup() { // create group response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationDelete", primaryGroup.getId()); @@ -2003,10 +2026,11 @@ public void cannotDeleteFromGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -2020,9 +2044,9 @@ void canGenerateApplicationGrantToken() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -2040,10 +2064,11 @@ void canGenerateApplicationGrantToken() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.UNAUTHORIZED.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } @@ -2080,9 +2105,9 @@ void canDownloadFiles() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -2277,9 +2302,9 @@ void downloadFileRequestShouldReturnNotModifiedIfRequestEtagIsTheSameAsCachedFil // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -2337,9 +2362,9 @@ void downloadFileRequestShouldReturnUpdatedFileIfRequestEtagIsDifferentThanCache // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -2493,9 +2518,9 @@ void canRetrieveClientCertAndPrivateKey() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -2531,10 +2556,11 @@ void canRetrieveClientCertAndPrivateKey() { blockingClient.exchange(finalRequest, Map.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.INVALID_NONCE_FORMAT.equals(group.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.INVALID_NONCE_FORMAT.equals(dpmErrorResponse.getCode()))); request = HttpRequest.GET("/applications/key_pair?nonce=unity"); response = blockingClient.exchange(request, Map.class); @@ -2554,9 +2580,9 @@ void canRetrievePermissions() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("ApplicationOne", primaryGroup.getId()); @@ -2593,10 +2619,11 @@ void canRetrievePermissions() { blockingClient.exchange(finalRequest, Map.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.INVALID_NONCE_FORMAT.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.INVALID_NONCE_FORMAT.equals(dpmErrorResponse.getCode()))); request = HttpRequest.GET("/applications/permissions.xml.p7s?nonce=unity"); response = blockingClient.exchange(request, String.class); diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantApiTest.java index dd0464b3..62f549d6 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantApiTest.java @@ -29,6 +29,7 @@ import io.micronaut.security.token.jwt.generator.claims.JWTClaimsSetGenerator; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationRepository; @@ -40,6 +41,7 @@ import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.GrantDurationDTO; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; +import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUser; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserRepository; @@ -162,9 +164,9 @@ public void grantIsDeletedPostApplicationDeletion() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("Application123", primaryGroup.getId()); @@ -252,7 +254,7 @@ public void canUpdateApplicationGrant() { HashMap responseMap = blockingClient.retrieve(request, HashMap.class); assertNotNull(responseMap); List content = (List) responseMap.get("content"); - assertNull(content); + assertTrue(content.isEmpty()); } @Test @@ -263,9 +265,9 @@ public void attemptToAssociateApplicationWithInvalidApplicationJwtToken() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("Application123", primaryGroup.getId()); @@ -299,9 +301,9 @@ public void tokenWithInvalidSignatureSecretShouldFail() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("Application123", primaryGroup.getId()); @@ -343,9 +345,9 @@ public void canDeleteApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("Application123", primaryGroup.getId()); @@ -390,9 +392,9 @@ public void cannotCreateDuplicateEntries() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = entityUtil.createApplication("Application123", primaryGroup.getId()); @@ -427,10 +429,11 @@ public void cannotCreateDuplicateEntries() { entityUtil.createApplicationGrant(applicationGrantToken, primaryGroup.getId(), "MyGrant", durationOptional.get().getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - List list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_GRANT_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_GRANT_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -536,10 +539,11 @@ public void attemptToCreateWithInvalidData() { null, durationOptional.get().getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - List list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_GRANT_NAME_CANNOT_BE_BLANK_OR_NULL.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_GRANT_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); // name less than three characters exception = assertThrowsExactly(HttpClientResponseException.class, () -> { @@ -547,30 +551,33 @@ public void attemptToCreateWithInvalidData() { " ", durationOptional.get().getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_GRANT_NAME_CANNOT_BE_BLANK_OR_NULL.equals(group.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_GRANT_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); // requires group exception = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createApplicationGrant(applicationGrantToken, null, "MyGrant", durationOptional.get().getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_GRANT_REQUIRES_GROUP_ASSOCIATION.equals(group.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_GRANT_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); // requires duration exception = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createApplicationGrant(applicationGrantToken, applicationOne.getPermissionsGroup().getId(), "MyGrant", null); }); assertEquals(BAD_REQUEST, exception.getStatus()); - body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_GRANT_REQUIRES_DURATION_ASSOCIATION.equals(group.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_GRANT_REQUIRES_DURATION_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -599,10 +606,11 @@ public void cannotCreateWithADurationFromAnotherGroup() { entityUtil.createApplicationGrant(finalApplicationGrantToken, testGroup.getId(), "CreateGrantAttempt-Fail", durationOptional.get().getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - List list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_GRANT_GRANT_DURATION_DOES_NOT_BELONG_TO_SAME_GROUP.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_GRANT_GRANT_DURATION_DOES_NOT_BELONG_TO_SAME_GROUP.equals(dpmErrorResponse.getCode()))); // attempt to create a grant under publicGroup with group B duration - pass request = HttpRequest.GET("/applications/generate_grant_token/" + applicationOne.getId()); @@ -664,9 +672,9 @@ public void canCreateApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -717,9 +725,9 @@ public void canUpdateApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -781,9 +789,9 @@ public void canDeleteApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -876,15 +884,15 @@ public void canDeleteApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryGroupOptional = response.getBody(Group.class); + Optional secondaryGroupOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryGroupOptional.isPresent()); - Group secondaryGroup = secondaryGroupOptional.get(); + SimpleGroupDTO secondaryGroup = secondaryGroupOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -974,9 +982,9 @@ public void canViewApplicationGrants() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -1049,9 +1057,9 @@ public void cannotCreateApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -1104,9 +1112,9 @@ public void cannotUpdateApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -1175,9 +1183,9 @@ public void cannotDeleteApplicationGrant() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionApiTest.java index 5163fe22..35b60735 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionApiTest.java @@ -29,12 +29,14 @@ import io.micronaut.security.token.jwt.generator.claims.JWTClaimsSetGenerator; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationRepository; import io.unityfoundation.dds.permissions.manager.model.applicationpermission.*; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; +import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUser; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserRepository; @@ -164,9 +166,9 @@ public void permissionIsDeletedPostTopicDeletion() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = createApplication("Application123", primaryGroup.getId()); @@ -228,9 +230,9 @@ public void permissionIsDeletedPostApplicationDeletion() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = createApplication("Application123", primaryGroup.getId()); @@ -302,7 +304,7 @@ public void canUpdatePermissions() { responseMap = blockingClient.retrieve(request, HashMap.class); assertNotNull(responseMap); content = (List) responseMap.get("content"); - assertNull(content); + assertTrue(content.isEmpty()); } @Test @@ -458,9 +460,9 @@ public void attemptToAssociateApplicationWithInvalidApplicationJwtToken() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = createApplication("Application123", primaryGroup.getId()); @@ -498,9 +500,9 @@ public void tokenWithInvalidSignatureSecretShouldFail() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = createApplication("Application123", primaryGroup.getId()); @@ -542,9 +544,9 @@ public void canDeleteApplicationPermission() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = createApplication("Application123", primaryGroup.getId()); @@ -592,9 +594,9 @@ public void cannotCreateDuplicateEntries() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); // create application response = createApplication("Application123", primaryGroup.getId()); @@ -629,10 +631,11 @@ public void cannotCreateDuplicateEntries() { createApplicationPermission(applicationGrantToken, topicOptional.get().getId(), false, true); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional body = exception.getResponse().getBody(List.class); - assertTrue(body.isPresent()); - List list = body.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.APPLICATION_PERMISSION_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.APPLICATION_PERMISSION_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -885,9 +888,9 @@ public void canDeleteApplicationPermission() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -1022,9 +1025,9 @@ public void canDeleteApplicationPermission() { // create groups response = createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); - Group primaryGroup = primaryOptional.get(); + SimpleGroupDTO primaryGroup = primaryOptional.get(); User justin = userRepository.findByEmail("jjones@test.test").get(); // add user to group as an application admin @@ -1210,10 +1213,10 @@ public void cannotDeleteApplicationPermission() { } private HttpResponse createGroup(String groupName) { - Group group = new Group(groupName); + SimpleGroupDTO group = new SimpleGroupDTO(); + group.setName(groupName); HttpRequest request = HttpRequest.POST("/groups/save", group); - HttpResponse response; - return blockingClient.exchange(request, Group.class); + return blockingClient.exchange(request, SimpleGroupDTO.class); } private HttpResponse createApplication(String applicationName, Long groupId) { diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/GrantDurationApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/GrantDurationApiTest.java index a70ec56c..bd856308 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/GrantDurationApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/GrantDurationApiTest.java @@ -26,6 +26,7 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.GrantDTO; import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.CreateGrantDurationDTO; @@ -118,10 +119,11 @@ void cannotCreateOnItsOwnWithoutAGroupAssociation() { blockingClient.exchange(request, GrantDurationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_REQUIRES_GROUP_ASSOCIATION.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -219,10 +221,11 @@ public void cannotCreateWithNullNorWhitespace() { blockingClient.exchange(finalRequest, GrantDurationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); grantDurationDTO.setName(" "); request = HttpRequest.POST("/grant_durations", grantDurationDTO); @@ -231,10 +234,11 @@ public void cannotCreateWithNullNorWhitespace() { blockingClient.exchange(finalRequest1, GrantDurationDTO.class); }); assertEquals(BAD_REQUEST, exception1.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); } @Test @@ -261,10 +265,11 @@ public void cannotCreateWithWithAValueLessThanZeroOrNull() { blockingClient.exchange(finalRequest, GrantDurationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_DURATION_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_DURATION_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); // negative case grantDurationDTO.setDurationInMilliseconds(-2000L); @@ -274,10 +279,11 @@ public void cannotCreateWithWithAValueLessThanZeroOrNull() { blockingClient.exchange(finalRequest1, GrantDurationDTO.class); }); assertEquals(BAD_REQUEST, exception1.getStatus()); - Optional negativeOptional = exception1.getResponse().getBody(List.class); - assertTrue(negativeOptional.isPresent()); - List negativeList = negativeOptional.get(); - assertTrue(negativeList.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_DURATION_CANNOT_BE_A_NEGATIVE_VALUE.equals(map.get("code")))); + listOptional = exception1.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_DURATION_CANNOT_BE_A_NEGATIVE_VALUE.equals(dpmErrorResponse.getCode()))); } @Test @@ -294,10 +300,11 @@ public void cannotCreateWithNameLessThanThreeCharacters() { entityUtil.createGrantDuration("A", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -344,14 +351,15 @@ public void cannotUpdateGroupAssociation() { abcGrantDuration.setGroupId(zeta.getId()); request = HttpRequest.PUT("/grant_durations/"+abcGrantDuration.getId(), abcGrantDuration); HttpRequest finalRequest = request; - HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { + HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - Optional bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(map.get("code")))); + assertEquals(BAD_REQUEST, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_CANNOT_UPDATE_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -428,10 +436,11 @@ public void cannotCreateGrantDurationWithSameNameInGroup() { entityUtil.createGrantDuration("Abc123", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.GRANT_DURATION_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } //show @@ -858,10 +867,11 @@ void cannotDeleteGrantDurationIfAssociatedToAGrant(){ blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GRANT_DURATION_HAS_ONE_OR_MORE_GRANT_ASSOCIATIONS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GRANT_DURATION_HAS_ONE_OR_MORE_GRANT_ASSOCIATIONS.equals(dpmErrorResponse.getCode()))); } } @@ -910,10 +920,11 @@ void cannotCreateGrantDuration(){ entityUtil.createGrantDuration("Abc123", theta.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -950,10 +961,11 @@ void cannotDeleteGrantDuration(){ blockingClient.exchange(request2); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1058,10 +1070,11 @@ void cannotShowGrantDurationIfGrantDurationBelongsToAGroupIAmNotAMemberOf(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // list @@ -1303,10 +1316,11 @@ void cannotCreateGrantDuration(){ entityUtil.createGrantDuration("Abc123", theta.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1341,10 +1355,11 @@ void cannotDeleteGrantDuration(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1387,10 +1402,11 @@ void cannotShowGrantDurationWithAssociatedGroup(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupApiTest.java index 5e2fa33c..075d10b0 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupApiTest.java @@ -27,12 +27,15 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationRepository; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrant; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrantRepository; -import io.unityfoundation.dds.permissions.manager.model.applicationpermission.*; +import io.unityfoundation.dds.permissions.manager.model.applicationpermission.AccessPermissionDTO; +import io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermission; +import io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermissionRepository; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDurationRepository; import io.unityfoundation.dds.permissions.manager.model.group.Group; @@ -181,18 +184,19 @@ void canCreateGroup(){ @Test public void cannotCreateGroupWithSameNameAsAnExistingGroup() { HttpResponse response = entityUtil.createGroup("Theta"); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); HttpClientResponseException exception = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createGroup("Theta"); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.GROUP_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -201,28 +205,30 @@ public void cannotCreateGroupWithNullNorWhitespace() { entityUtil.createGroup(null); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); HttpClientResponseException exception1 = assertThrowsExactly(HttpClientResponseException.class, () -> { entityUtil.createGroup(" "); }); assertEquals(BAD_REQUEST, exception1.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); } @Test public void createShouldTrimWhitespace() { HttpResponse response = entityUtil.createGroup(" Theta "); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); assertEquals("Theta", theta.getName()); } @@ -232,10 +238,11 @@ public void cannotCreateWithNameLessThanThreeCharacters() { entityUtil.createGroup("g"); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -258,10 +265,11 @@ public void createWithDescriptionAndDenyIfDescriptionIsMoreThanFourThousandChars blockingClient.exchange(finalRequest, SimpleGroupDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_DESCRIPTION_CANNOT_BE_MORE_THAN_FOUR_THOUSAND_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_DESCRIPTION_CANNOT_BE_MORE_THAN_FOUR_THOUSAND_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -344,9 +352,9 @@ public void cannotUpdateGroupWithSameNameAsAnExistingGroup() { response = entityUtil.createGroup("Beta"); assertEquals(OK, response.getStatus()); - Optional betaOptional = response.getBody(Group.class); + Optional betaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(betaOptional.isPresent()); - Group beta = betaOptional.get(); + SimpleGroupDTO beta = betaOptional.get(); beta.setName("Theta"); request = HttpRequest.POST("/groups/save", beta); @@ -605,9 +613,9 @@ void listGroupsWithCounts() { @Test void canDeleteGroup(){ HttpResponse response = entityUtil.createGroup("Beta"); - Optional betaOptional = response.getBody(Group.class); + Optional betaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(betaOptional.isPresent()); - Group beta = betaOptional.get(); + SimpleGroupDTO beta = betaOptional.get(); HttpRequest request = HttpRequest.DELETE("/groups/"+beta.getId(), Map.of()); response = blockingClient.exchange(request); @@ -642,9 +650,9 @@ void deleteCascades() { // create group response = entityUtil.createGroup("CascadeTestTheta"); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); // create member - non-admin and only membership response = createNonAdminGroupMembership("cascade-user@test.test", theta.getId()); @@ -761,12 +769,12 @@ void cannotDeleteGroup() { response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); loginAsNonAdmin(); - Group group = primaryOptional.get(); + SimpleGroupDTO group = primaryOptional.get(); request = HttpRequest.DELETE("/groups/"+group.getId(), Map.of()); HttpClientResponseException exception = assertThrowsExactly(HttpClientResponseException.class, () -> { blockingClient.exchange(request); @@ -785,12 +793,12 @@ void canSearchAndShouldYieldOnlyGroupsWhereGroupAdmin() { // create groups response = entityUtil.createGroup("PrimaryGroup"); assertEquals(OK, response.getStatus()); - Optional primaryOptional = response.getBody(Group.class); + Optional primaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(primaryOptional.isPresent()); response = entityUtil.createGroup("SecondaryGroup"); assertEquals(OK, response.getStatus()); - Optional secondaryOptional = response.getBody(Group.class); + Optional secondaryOptional = response.getBody(SimpleGroupDTO.class); assertTrue(secondaryOptional.isPresent()); // add membership @@ -838,11 +846,12 @@ void cannotDeleteAnApplication(){ mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupMembershipApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupMembershipApiTest.java index 1126d635..77eb552a 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupMembershipApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/GroupMembershipApiTest.java @@ -28,8 +28,9 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; -import io.unityfoundation.dds.permissions.manager.model.group.Group; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; +import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserResponseDTO; import io.unityfoundation.dds.permissions.manager.model.user.User; @@ -102,11 +103,12 @@ void setup() { // create @Test public void canCreate() { - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -119,17 +121,19 @@ public void canCreate() { @Test public void canCreateWithSameEmailDifferentGroup() { // group creation - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); // perform test GroupUserDTO dto = new GroupUserDTO(); @@ -143,17 +147,17 @@ public void canCreateWithSameEmailDifferentGroup() { request = HttpRequest.POST("/group_membership", dto); response = blockingClient.exchange(request); assertEquals(OK, response.getStatus()); - } @Test public void cannotCreateWithInvalidEmailFormat() { // group creation - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); // perform test GroupUserDTO dto = new GroupUserDTO(); @@ -161,24 +165,26 @@ public void cannotCreateWithInvalidEmailFormat() { dto.setEmail("pparker@.test.test"); request = HttpRequest.POST("/group_membership", dto); HttpRequest finalRequest = request; - HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { + HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - Optional bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.INVALID_EMAIL_FORMAT.equals(map.get("code")))); + assertEquals(BAD_REQUEST, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.INVALID_EMAIL_FORMAT.equals(dpmErrorResponse.getCode()))); } @Test public void cannotCreateWithSameEmailAndGroupAsExisting() { // group creation - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -193,10 +199,11 @@ public void cannotCreateWithSameEmailAndGroupAsExisting() { blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_MEMBERSHIP_ALREADY_EXISTS.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_MEMBERSHIP_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -210,10 +217,11 @@ public void cannotCreateIfGroupSpecifiedDoesNotExist() { blockingClient.exchange(request); }); assertEquals(NOT_FOUND, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_NOT_FOUND.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_NOT_FOUND.equals(dpmErrorResponse.getCode()))); } @Test @@ -228,21 +236,23 @@ public void cannotCreateWithoutGroupSpecified() { blockingClient.exchange(request); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_MEMBERSHIP_REQUIRES_GROUP_ASSOCIATION.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_MEMBERSHIP_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } // list @Test public void canSeeAllMemberships() { // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -252,11 +262,12 @@ public void canSeeAllMemberships() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -309,7 +320,7 @@ public void membershipsOrderedByEmail() { assertExpectedEmailAndGroupName(content, 7, zack, firstGroupCreatedName); } - private void createMemberships(Group group, String... emails) { + private void createMemberships(SimpleGroupDTO group, String... emails) { for(String email: emails) { GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(group.getId()); @@ -320,16 +331,17 @@ private void createMemberships(Group group, String... emails) { } } - private Group createGroup(String groupName) { - Group group = new Group(groupName); + private SimpleGroupDTO createGroup(String groupName) { + SimpleGroupDTO group = new SimpleGroupDTO(); + group.setName(groupName); HttpRequest request = HttpRequest.POST("/groups/save", group); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - return response.getBody(Group.class).get(); + return response.getBody(SimpleGroupDTO.class).get(); } private void createGroupAndMemberships(String groupName, String... emails) { - Group group = createGroup(groupName); + SimpleGroupDTO group = createGroup(groupName); createMemberships(group, emails); } @@ -346,11 +358,12 @@ void assertExpectedEmailAndGroupName(List content, int index, String expectedEma @Test public void canSeeAllMembershipsFilteredByGroupNameCaseInsensitive() { // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -360,11 +373,12 @@ public void canSeeAllMembershipsFilteredByGroupNameCaseInsensitive() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -382,11 +396,12 @@ public void canSeeAllMembershipsFilteredByGroupNameCaseInsensitive() { @Test public void canSeeAllMembershipsFilteredByUserEmailCaseInsensitive() { // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -396,11 +411,12 @@ public void canSeeAllMembershipsFilteredByUserEmailCaseInsensitive() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -418,11 +434,12 @@ public void canSeeAllMembershipsFilteredByUserEmailCaseInsensitive() { @Test public void canSeeAllMembershipsFilteredByGroup() { // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -434,11 +451,12 @@ public void canSeeAllMembershipsFilteredByGroup() { assertTrue(bobOptional.isPresent()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -482,11 +500,12 @@ public void canSeeAllMembershipsFilteredByGroup() { // update @Test public void canUpdate() { - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -509,11 +528,12 @@ public void canUpdate() { @Test public void cannotAttemptToSaveNewWithUpdateEndpoint() { - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -527,21 +547,23 @@ public void cannotAttemptToSaveNewWithUpdateEndpoint() { blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.GROUP_MEMBERSHIP_CANNOT_CREATE_WITH_UPDATE.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.GROUP_MEMBERSHIP_CANNOT_CREATE_WITH_UPDATE.equals(dpmErrorResponse.getCode()))); } // delete @Test public void canDelete() { // group creation - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -592,11 +614,12 @@ public void canCreate() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -626,11 +649,12 @@ public void cannotCreateIfNotMemberOfGroup() { mockSecurityService.postConstruct(); // save group without members - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); loginAsNonAdmin(); @@ -643,10 +667,11 @@ public void cannotCreateIfNotMemberOfGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -654,11 +679,12 @@ public void cannotCreateIfNonGroupAdminMemberOfGroup() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -683,10 +709,11 @@ public void cannotCreateIfNonGroupAdminMemberOfGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -694,7 +721,8 @@ public void canUpdate() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); HttpResponse response = blockingClient.exchange(request, GroupUserResponseDTO.class); assertEquals(OK, response.getStatus()); @@ -729,11 +757,12 @@ public void cannotUpdateIfNonGroupAdminMemberOfGroup() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -757,21 +786,23 @@ public void cannotUpdateIfNonGroupAdminMemberOfGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test public void canDeleteFromGroup() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -806,11 +837,12 @@ public void canDeleteFromGroup() { public void deleteUserIfNonAdminAndNoGroupMemberships() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -850,10 +882,11 @@ public void deleteUserIfNonAdminAndNoGroupMemberships() { blockingClient.exchange(finalRequest); }); assertEquals(NOT_FOUND, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.USER_NOT_FOUND.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.USER_NOT_FOUND.equals(dpmErrorResponse.getCode()))); } @Test @@ -861,11 +894,12 @@ public void cannotDeleteIfNotMemberOfGroup() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -888,10 +922,11 @@ public void cannotDeleteIfNotMemberOfGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -899,11 +934,12 @@ public void cannotDeleteIfNonGroupAdminMemberOfGroup() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); User justin = userRepository.findByEmail("jjones@test.test").get(); @@ -935,10 +971,11 @@ public void cannotDeleteIfNonGroupAdminMemberOfGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } @@ -966,11 +1003,12 @@ public void canSeeMembershipsOfGroupsIAmAMemberOf() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -980,11 +1018,12 @@ public void canSeeMembershipsOfGroupsIAmAMemberOf() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1013,11 +1052,12 @@ public void cannotSeeAllMemberships() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1027,11 +1067,12 @@ public void cannotSeeAllMemberships() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1060,11 +1101,12 @@ public void canSeeCommonGroupMembershipsFilteredByGroupNameCaseInsensitive() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1074,11 +1116,12 @@ public void canSeeCommonGroupMembershipsFilteredByGroupNameCaseInsensitive() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1106,11 +1149,12 @@ public void canSeeCommonGroupMembershipsFilteredByUserEmailCaseInsensitive() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1120,11 +1164,12 @@ public void canSeeCommonGroupMembershipsFilteredByUserEmailCaseInsensitive() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1152,11 +1197,12 @@ public void canSeeCommonGroupMembershipsFilteredByGroup() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1166,11 +1212,12 @@ public void canSeeCommonGroupMembershipsFilteredByGroup() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1217,11 +1264,12 @@ public void cannotSeeOtherGroupMembershipsFilteredByGroupName() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1231,11 +1279,12 @@ public void cannotSeeOtherGroupMembershipsFilteredByGroupName() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1263,11 +1312,12 @@ public void cannotSeeOtherGroupMembershipsFilteredByUserEmail() { mockSecurityService.postConstruct(); // first group and member - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1277,11 +1327,12 @@ public void cannotSeeOtherGroupMembershipsFilteredByUserEmail() { assertEquals(OK, response.getStatus()); // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = response.getBody(Group.class).get(); + secondaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1313,11 +1364,12 @@ public void shouldBeConsideredValid() { HttpResponse response; // other group and member - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = (Group) response.getBody(Group.class).get(); + secondaryGroup = (SimpleGroupDTO) response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto1 = new GroupUserDTO(); dto1.setPermissionsGroup(secondaryGroup.getId()); @@ -1348,11 +1400,12 @@ public void shouldHaveGroupPermissionsUpdatedIfAdminUpdatesMembership() { HttpResponse response; // group - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = (Group) response.getBody(Group.class).get(); + secondaryGroup = (SimpleGroupDTO) response.getBody(SimpleGroupDTO.class).get(); // memberships GroupUserDTO dto1 = new GroupUserDTO(); @@ -1447,17 +1500,19 @@ public void shouldHaveGroupPermissionsUpdatedIfAdminDeletesMembership() { HttpResponse response; // group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); request = HttpRequest.POST("/groups/save", primaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = (Group) response.getBody(Group.class).get(); + primaryGroup = (SimpleGroupDTO) response.getBody(SimpleGroupDTO.class).get(); - Group secondaryGroup = new Group("SecondaryGroup"); + SimpleGroupDTO secondaryGroup = new SimpleGroupDTO(); + secondaryGroup.setName("SecondaryGroup"); request = HttpRequest.POST("/groups/save", secondaryGroup); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - secondaryGroup = (Group) response.getBody(Group.class).get(); + secondaryGroup = (SimpleGroupDTO) response.getBody(SimpleGroupDTO.class).get(); // memberships GroupUserDTO dto1 = new GroupUserDTO(); @@ -1539,11 +1594,12 @@ public void cannotCreate() { mockSecurityService.postConstruct(); // save group without members - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); loginAsNonAdmin(); @@ -1556,10 +1612,11 @@ public void cannotCreate() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1567,11 +1624,12 @@ public void cannotUpdate() { mockSecurityService.postConstruct(); // save group without members - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); GroupUserDTO dto = new GroupUserDTO(); dto.setPermissionsGroup(primaryGroup.getId()); @@ -1592,10 +1650,11 @@ public void cannotUpdate() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1603,11 +1662,12 @@ public void cannotDeleteFromGroup() { mockSecurityService.postConstruct(); // create group - Group primaryGroup = new Group("PrimaryGroup"); + SimpleGroupDTO primaryGroup = new SimpleGroupDTO(); + primaryGroup.setName("PrimaryGroup"); HttpRequest request = HttpRequest.POST("/groups/save", primaryGroup); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - primaryGroup = response.getBody(Group.class).get(); + primaryGroup = response.getBody(SimpleGroupDTO.class).get(); // create member with above group GroupUserDTO dtoNewUser = new GroupUserDTO(); @@ -1628,10 +1688,11 @@ public void cannotDeleteFromGroup() { blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1643,10 +1704,11 @@ public void shouldBeConsideredInvalid() { blockingClient.exchange(finalRequest); }); assertEquals(NOT_FOUND, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.USER_IS_NOT_VALID.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.USER_IS_NOT_VALID.equals(dpmErrorResponse.getCode()))); } } } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/SecurityServiceReplacement.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/SecurityServiceReplacement.java index 7c310cac..1d894f86 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/SecurityServiceReplacement.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/SecurityServiceReplacement.java @@ -13,15 +13,11 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager; -import io.micronaut.context.annotation.Replaces; import io.micronaut.security.authentication.Authentication; import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; -import io.unityfoundation.dds.permissions.manager.model.user.UserRole; +import jakarta.annotation.PostConstruct; -import javax.annotation.PostConstruct; -import java.util.List; -import java.util.Map; import java.util.Optional; public class SecurityServiceReplacement implements SecurityService { diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TemplateServiceTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TemplateServiceTest.java index 4490b4b5..868c7efd 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TemplateServiceTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TemplateServiceTest.java @@ -20,9 +20,11 @@ import org.junit.jupiter.api.Test; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; @MicronautTest public class TemplateServiceTest { diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java index 11ec6439..e371b6a9 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java @@ -26,8 +26,8 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; -import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; @@ -41,7 +41,9 @@ import io.unityfoundation.dds.permissions.manager.testing.util.EntityLifecycleUtil; import jakarta.inject.Inject; import jakarta.inject.Singleton; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; import java.time.Instant; import java.util.*; @@ -122,19 +124,21 @@ void cannotCreateOnItsOwnWithoutAGroupAssociation(){ blockingClient.exchange(request); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_REQUIRES_GROUP_ASSOCIATION.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test void canCreateWithGroupAssociation(){ - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -157,11 +161,12 @@ void canCreateWithGroupAssociation(){ @Test public void cannotCreateGroupWithNullNorWhitespace() { - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -177,10 +182,11 @@ public void cannotCreateGroupWithNullNorWhitespace() { blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); topicDTO.setName(" "); request = HttpRequest.POST("/topics/save", topicDTO); @@ -189,20 +195,22 @@ public void cannotCreateGroupWithNullNorWhitespace() { blockingClient.exchange(finalRequest1); }); assertEquals(BAD_REQUEST, exception1.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); } @Test public void cannotCreateWithNameLessThanThreeCharacters() { - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -219,10 +227,11 @@ public void cannotCreateWithNameLessThanThreeCharacters() { blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -230,11 +239,12 @@ public void createWithDescriptionAndDenyIfDescriptionIsMoreThanFourThousandChars HttpResponse response; // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -261,10 +271,11 @@ public void createWithDescriptionAndDenyIfDescriptionIsMoreThanFourThousandChars blockingClient.exchange(finalRequest, ApplicationDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_DESCRIPTION_CANNOT_BE_MORE_THAN_FOUR_THOUSAND_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_DESCRIPTION_CANNOT_BE_MORE_THAN_FOUR_THOUSAND_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -272,11 +283,12 @@ public void createWithDescriptionWithFourThousandChars() { HttpResponse response; // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -397,11 +409,11 @@ public void createWithPrivateGroup() { blockingClient.exchange(finalRequest, TopicDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(itm -> ResponseStatusCodes.TOPIC_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(itm.get("code")))); - + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(dpmErrorResponse.getCode()))); // create public topic (not allowed) TopicDTO publicTopicDTO = new TopicDTO(); @@ -415,19 +427,21 @@ public void createWithPrivateGroup() { blockingClient.exchange(finalRequest1, TopicDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(itm -> ResponseStatusCodes.TOPIC_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(itm.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_CANNOT_CREATE_NOR_UPDATE_UNDER_PRIVATE_GROUP.equals(dpmErrorResponse.getCode()))); } @Test public void createShouldTrimNameWhitespaces() { - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -447,11 +461,12 @@ public void createShouldTrimNameWhitespaces() { @Test public void cannotUpdateTopicNameNorKind() { - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -474,28 +489,29 @@ public void cannotUpdateTopicNameNorKind() { topicDTO.setName("UpdatedTestTopic2"); request = HttpRequest.POST("/topics/save", topicDTO); HttpRequest finalRequest = request; - HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { + HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - Optional bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_NAME_UPDATE_NOT_ALLOWED.equals(map.get("code")))); - + assertEquals(BAD_REQUEST, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_NAME_UPDATE_NOT_ALLOWED.equals(dpmErrorResponse.getCode()))); topicDTO.setName(originalName); topicDTO.setKind(TopicKind.C); request = HttpRequest.POST("/topics/save", topicDTO); HttpRequest finalRequest1 = request; - thrown = assertThrows(HttpClientResponseException.class, () -> { + exception = assertThrows(HttpClientResponseException.class, () -> { blockingClient.exchange(finalRequest1); }); - assertEquals(BAD_REQUEST, thrown.getStatus()); - bodyOptional = thrown.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_KIND_UPDATE_NOT_ALLOWED.equals(map.get("code")))); + assertEquals(BAD_REQUEST, exception.getStatus()); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_KIND_UPDATE_NOT_ALLOWED.equals(dpmErrorResponse.getCode()))); } @Test @@ -503,11 +519,12 @@ public void canUpdateTopicDescriptionAndOrPublic() { HttpRequest request; HttpResponse response; - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); request = HttpRequest.POST("/groups/save", theta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -590,11 +607,12 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { @Test public void cannotCreateTopicWithSameNameInGroup() { - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -619,21 +637,23 @@ public void cannotCreateTopicWithSameNameInGroup() { blockingClient.exchange(finalRequest, TopicDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.TOPIC_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } //show @Test void canShowTopicAssociatedToAGroup(){ // create group - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -708,19 +728,21 @@ void canListAllTopicsAndTopicsWithSameNameCanExistSitewide(){ // Yellow - Abc123 & Xyz789 // create groups - Group green = new Group("Green"); + SimpleGroupDTO green = new SimpleGroupDTO(); + green.setName("Green"); HttpRequest request = HttpRequest.POST("/groups/save", green); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional greenOptional = response.getBody(Group.class); + Optional greenOptional = response.getBody(SimpleGroupDTO.class); assertTrue(greenOptional.isPresent()); green = greenOptional.get(); - Group yellow = new Group("Yellow"); + SimpleGroupDTO yellow = new SimpleGroupDTO(); + yellow.setName("Yellow"); request = HttpRequest.POST("/groups/save", yellow); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional yellowOptional = response.getBody(Group.class); + Optional yellowOptional = response.getBody(SimpleGroupDTO.class); assertTrue(yellowOptional.isPresent()); yellow = yellowOptional.get(); @@ -765,19 +787,21 @@ void canListAllTopicsWithFilter(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -834,19 +858,21 @@ void canLisTopicsWithGroupId(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -911,19 +937,21 @@ void canListAllTopicsNameInAscendingOrderByDefault(){ // Zeta - Abc123 & Def456 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -989,19 +1017,21 @@ void canListAllTopicsNameInDescendingOrder(){ // Zeta - Abc123 & Def456 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -1077,11 +1107,12 @@ void canCreateTopic(){ mockSecurityService.postConstruct(); mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1113,11 +1144,12 @@ void canDeleteTopic(){ mockSecurityService.postConstruct(); mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1156,11 +1188,12 @@ void cannotDeleteAnApplication(){ mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1188,10 +1221,11 @@ void cannotDeleteAnApplication(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } @@ -1220,11 +1254,12 @@ void cannotCreateTopic(){ mockSecurityService.postConstruct(); mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1250,10 +1285,11 @@ void cannotCreateTopic(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1262,11 +1298,12 @@ void cannotDeleteTopic(){ mockSecurityService.postConstruct(); mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1298,10 +1335,11 @@ void cannotDeleteTopic(){ blockingClient.exchange(request2); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1316,19 +1354,21 @@ void canShowTopicWithAssociatedGroup(){ // Zeta - Abc123 - None // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -1384,19 +1424,21 @@ void cannotShowTopicIfTopicBelongsToAGroupIAmNotAMemberOf(){ // Omega - Abc123 - None // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group omega = new Group("Omega"); + SimpleGroupDTO omega = new SimpleGroupDTO(); + omega.setName("Omega"); request = HttpRequest.POST("/groups/save", omega); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional omegaOptional = response.getBody(Group.class); + Optional omegaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(omegaOptional.isPresent()); omega = omegaOptional.get(); @@ -1441,10 +1483,11 @@ void cannotShowTopicIfTopicBelongsToAGroupIAmNotAMemberOf(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1503,19 +1546,21 @@ void canListAllTopicsLimitedToMembership(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -1572,11 +1617,12 @@ void canListTopicsWithFilterLimitedToGroupMembership(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1589,11 +1635,12 @@ void canListTopicsWithFilterLimitedToGroupMembership(){ assertEquals(OK, response.getStatus()); // other group - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -1672,11 +1719,12 @@ void canListTopicsWithGroupParameterLimitedToGroupMembership(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1689,11 +1737,12 @@ void canListTopicsWithGroupParameterLimitedToGroupMembership(){ assertEquals(OK, response.getStatus()); // other group - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -1827,11 +1876,12 @@ void cannotCreateTopic(){ mockSecurityService.postConstruct(); mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1849,10 +1899,11 @@ void cannotCreateTopic(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1861,11 +1912,12 @@ void cannotDeleteTopic(){ mockSecurityService.postConstruct(); mockAuthenticationFetcher.setAuthentication(mockSecurityService.getAuthentication().get()); - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -1890,10 +1942,11 @@ void cannotDeleteTopic(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1908,19 +1961,21 @@ void cannotShowTopicWithAssociatedGroup(){ // Zeta - Abc123 - None // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -1954,10 +2009,11 @@ void cannotShowTopicWithAssociatedGroup(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } @@ -2030,11 +2086,12 @@ void cannotListAllTopics(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -2047,11 +2104,12 @@ void cannotListAllTopics(){ assertEquals(OK, response.getStatus()); // other group - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); @@ -2098,11 +2156,12 @@ void cannotShowATopicWithGroupAssociation(){ // Zeta - Abc123 // create groups - Group theta = new Group("Theta"); + SimpleGroupDTO theta = new SimpleGroupDTO(); + theta.setName("Theta"); HttpRequest request = HttpRequest.POST("/groups/save", theta); - HttpResponse response = blockingClient.exchange(request, Group.class); + HttpResponse response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); theta = thetaOptional.get(); @@ -2115,11 +2174,12 @@ void cannotShowATopicWithGroupAssociation(){ assertEquals(OK, response.getStatus()); // other group - Group zeta = new Group("Zeta"); + SimpleGroupDTO zeta = new SimpleGroupDTO(); + zeta.setName("Zeta"); request = HttpRequest.POST("/groups/save", zeta); - response = blockingClient.exchange(request, Group.class); + response = blockingClient.exchange(request, SimpleGroupDTO.class); assertEquals(OK, response.getStatus()); - Optional zetaOptional = response.getBody(Group.class); + Optional zetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(zetaOptional.isPresent()); zeta = zetaOptional.get(); diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java index bf78ece9..8119da92 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java @@ -26,6 +26,7 @@ import io.micronaut.security.authentication.ServerAuthentication; import io.micronaut.security.utils.SecurityService; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserRepository; @@ -123,10 +124,11 @@ void cannotCreateOnItsOwnWithoutAGroupAssociation() { blockingClient.exchange(request, CreateTopicSetDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_REQUIRES_GROUP_ASSOCIATION.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_SET_REQUIRES_GROUP_ASSOCIATION.equals(dpmErrorResponse.getCode()))); } @Test @@ -210,10 +212,11 @@ public void cannotCreateWithNullNorWhitespace() { blockingClient.exchange(finalRequest, CreateTopicSetDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_SET_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); topicSetDTO.setName(" "); request = HttpRequest.POST("/topic-sets", topicSetDTO); @@ -222,10 +225,11 @@ public void cannotCreateWithNullNorWhitespace() { blockingClient.exchange(finalRequest1, CreateTopicSetDTO.class); }); assertEquals(BAD_REQUEST, exception1.getStatus()); - bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_NAME_CANNOT_BE_BLANK_OR_NULL.equals(map.get("code")))); + listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + dpmErrorResponses = listOptional.get(); + list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_SET_NAME_CANNOT_BE_BLANK_OR_NULL.equals(dpmErrorResponse.getCode()))); } @Test @@ -242,10 +246,11 @@ public void cannotCreateWithNameLessThanThreeCharacters() { entityUtil.createTopicSet("A", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(map.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_SET_NAME_CANNOT_BE_LESS_THAN_THREE_CHARACTERS.equals(dpmErrorResponse.getCode()))); } @Test @@ -296,10 +301,10 @@ public void cannotUpdateGroupAssociation() { blockingClient.exchange(finalRequest); }); assertEquals(BAD_REQUEST, thrown.getStatus()); - Optional bodyOptional = thrown.getResponse().getBody(List.class); + Optional bodyOptional = thrown.getResponse().getBody(Object[].class); assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_ALREADY_EXISTS.equals(map.get("code")))); + Object[] objects = bodyOptional.get(); +// assertTrue(objects.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_ALREADY_EXISTS.equals(map.get("code")))); } @Test @@ -354,10 +359,11 @@ public void cannotCreateTopicSetWithSameNameInGroup() { entityUtil.createTopicSet("Abc123", theta.getId()); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional bodyOptional = exception.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); - assertTrue(list.stream().anyMatch(group -> ResponseStatusCodes.TOPIC_SET_ALREADY_EXISTS.equals(group.get("code")))); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_SET_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } //show @@ -692,10 +698,11 @@ void cannotAddTopicToATopicSetWithDifferentAssociatedGroup(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(CONFLICT, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_SET_AND_TOPIC_DOES_NOT_BELONG_TO_SAME_GROUP.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_SET_AND_TOPIC_DOES_NOT_BELONG_TO_SAME_GROUP.equals(dpmErrorResponse.getCode()))); } @Test @@ -747,10 +754,11 @@ void cannotAddTopicToATopicSetIfPreviouslyAdded(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(BAD_REQUEST, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_ALREADY_EXISTS.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_ALREADY_EXISTS.equals(dpmErrorResponse.getCode()))); } @Test @@ -793,10 +801,11 @@ void cannotRemoveTopicFromATopicSetIfTopicDoesNotExists(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(NOT_FOUND, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.TOPIC_DOES_NOT_EXISTS_IN_TOPIC_SET.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.TOPIC_DOES_NOT_EXISTS_IN_TOPIC_SET.equals(dpmErrorResponse.getCode()))); } @Test @@ -1145,10 +1154,11 @@ void cannotCreateTopicSet(){ entityUtil.createTopicSet("Abc123", theta.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1185,10 +1195,11 @@ void cannotDeleteTopicSet(){ blockingClient.exchange(request2); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1293,10 +1304,11 @@ void cannotShowTopicSetIfTopicSetBelongsToAGroupIAmNotAMemberOf(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // list @@ -1538,10 +1550,11 @@ void cannotAddTopicToTopicSet(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1595,10 +1608,11 @@ void cannotRemoveTopicFromTopicSet(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } @@ -1643,10 +1657,11 @@ void cannotCreateTopicSet(){ entityUtil.createTopicSet("Abc123", theta.getId()); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // delete @@ -1681,10 +1696,11 @@ void cannotDeleteTopicSet(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } // show @@ -1727,10 +1743,11 @@ void cannotShowTopicSetWithAssociatedGroup(){ blockingClient.exchange(finalRequest); }); assertEquals(UNAUTHORIZED,exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1775,10 +1792,11 @@ void cannotAddTopicToTopicSet(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } @Test @@ -1832,10 +1850,11 @@ void cannotRemoveTopicFromTopicSet(){ blockingClient.exchange(finalRequest, TopicSetDTO.class); }); assertEquals(UNAUTHORIZED, exception.getStatus()); - Optional listOptional = exception.getResponse().getBody(List.class); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); assertTrue(listOptional.isPresent()); - List list = listOptional.get(); - assertTrue(list.stream().anyMatch(map -> ResponseStatusCodes.UNAUTHORIZED.equals(map.get("code")))); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); + assertTrue(list.stream().anyMatch(dpmErrorResponse -> ResponseStatusCodes.UNAUTHORIZED.equals(dpmErrorResponse.getCode()))); } } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/UniversalSearchApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/UniversalSearchApiTest.java index 9fc6ea59..1a768103 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/UniversalSearchApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/UniversalSearchApiTest.java @@ -86,7 +86,7 @@ class UniversalSearchApiTest { @Requires(property = "spec.name", value = "UniversalSearchApiTest") @Singleton - static class MockAuthenticationFetcher implements AuthenticationFetcher { + static class MockAuthenticationFetcher implements AuthenticationFetcher> { @Override public Publisher fetchAuthentication(HttpRequest request) { return Publishers.just(Authentication.build("montesm@test.test.com")); diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/WebSocketTests.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/WebSocketTests.java index f0d1cc07..be3ea00c 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/WebSocketTests.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/WebSocketTests.java @@ -33,9 +33,10 @@ import io.micronaut.websocket.annotation.OnClose; import io.micronaut.websocket.annotation.OnMessage; import io.micronaut.websocket.annotation.OnOpen; +import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.application.OnUpdateApplicationWebSocket; -import io.unityfoundation.dds.permissions.manager.model.group.Group; +import io.unityfoundation.dds.permissions.manager.model.group.SimpleGroupDTO; import io.unityfoundation.dds.permissions.manager.model.topic.OnUpdateTopicWebSocket; import io.unityfoundation.dds.permissions.manager.model.topic.TopicDTO; import io.unityfoundation.dds.permissions.manager.model.topic.TopicKind; @@ -54,7 +55,6 @@ import java.net.URI; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicReference; @@ -62,7 +62,6 @@ import static io.micronaut.http.HttpStatus.BAD_REQUEST; import static io.micronaut.http.HttpStatus.OK; import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertTrue; @Property(name = "spec.name", value = "WebSocketTests") @MicronautTest @@ -194,9 +193,9 @@ void websocketEmitMessageOnTopicUpdate(){ // create groups response = entityUtil.createGroup("Theta"); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); // create topic response = entityUtil.createTopic("Abc123", TopicKind.B, theta.getId()); @@ -244,9 +243,9 @@ void websocketEmitMessageOnApplicationUpdate(){ // create groups response = entityUtil.createGroup("Theta"); assertEquals(OK, response.getStatus()); - Optional thetaOptional = response.getBody(Group.class); + Optional thetaOptional = response.getBody(SimpleGroupDTO.class); assertTrue(thetaOptional.isPresent()); - Group theta = thetaOptional.get(); + SimpleGroupDTO theta = thetaOptional.get(); // create applications response = entityUtil.createApplication("TestApplication", theta.getId()); @@ -285,11 +284,12 @@ void websocketEmitMessageOnApplicationUpdate(){ } assertTrue(applicationsWsClient.replies.contains(OnUpdateApplicationWebSocket.APPLICATION_UPDATED)); - } catch (HttpClientResponseException e) { - assertEquals(BAD_REQUEST, e.getStatus()); - Optional bodyOptional = e.getResponse().getBody(List.class); - assertTrue(bodyOptional.isPresent()); - List list = bodyOptional.get(); + } catch (HttpClientResponseException exception) { + assertEquals(BAD_REQUEST, exception.getStatus()); + Optional listOptional = exception.getResponse().getBody(DPMErrorResponse[].class); + assertTrue(listOptional.isPresent()); + DPMErrorResponse[] dpmErrorResponses = listOptional.get(); + List list = List.of(dpmErrorResponses); System.out.println("application list "+list); } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/XMLEscaperTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/XMLEscaperTest.java index 0331c473..73bdde2a 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/XMLEscaperTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/XMLEscaperTest.java @@ -18,7 +18,7 @@ import jakarta.inject.Inject; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; @MicronautTest public class XMLEscaperTest { diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/testing/util/DbCleanup.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/testing/util/DbCleanup.java index f95ccc43..a08d469d 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/testing/util/DbCleanup.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/testing/util/DbCleanup.java @@ -14,11 +14,11 @@ package io.unityfoundation.dds.permissions.manager.testing.util; import io.unityfoundation.dds.permissions.manager.model.action.ActionRepository; +import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionIntervalRepository; import io.unityfoundation.dds.permissions.manager.model.actiontopic.ActionTopicRepository; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationRepository; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrantRepository; import io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermissionRepository; -import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionIntervalRepository; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserRepository; import io.unityfoundation.dds.permissions.manager.model.topic.TopicRepository; @@ -26,8 +26,7 @@ import io.unityfoundation.dds.permissions.manager.model.topicsettopic.TopicSetTopicRepository; import io.unityfoundation.dds.permissions.manager.model.user.UserRepository; import jakarta.inject.Singleton; - -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; @Singleton public class DbCleanup { From c82ee23a698e8ff0240a35d042e893eee6bf2b88 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:15:22 -0600 Subject: [PATCH 06/18] Use jakarta namespace Signed-off-by: montesm --- .../dds/permissions/manager/ActionController.java | 5 ++--- .../manager/ActionIntervalController.java | 9 ++++----- .../dds/permissions/manager/AdminController.java | 3 +-- .../permissions/manager/ApplicationController.java | 4 ++-- .../manager/ApplicationGrantController.java | 11 +++++------ .../manager/ApplicationPermissionController.java | 7 +++---- .../manager/GrantDurationController.java | 5 ++--- .../dds/permissions/manager/GroupController.java | 3 +-- .../manager/GroupMembershipController.java | 2 +- .../dds/permissions/manager/RunApplication.java | 5 ----- .../dds/permissions/manager/TopicController.java | 3 +-- .../permissions/manager/TopicSetController.java | 5 ++--- .../manager/UniversalSearchController.java | 7 ++++--- .../permissions/manager/model/action/Action.java | 3 +-- .../manager/model/action/ActionPartition.java | 2 +- .../manager/model/action/ActionService.java | 9 ++++++--- .../model/actioninterval/ActionInterval.java | 9 ++++----- .../actioninterval/ActionIntervalService.java | 4 ++-- .../manager/model/actiontopic/ActionTopic.java | 3 +-- .../manager/model/application/Application.java | 6 +++--- .../model/application/ApplicationRepository.java | 4 ++-- .../model/application/ApplicationService.java | 14 +++++++------- .../model/applicationgrant/ApplicationGrant.java | 7 +++---- .../ApplicationPermission.java | 2 +- .../model/applicationpermission/ReadPartition.java | 2 +- .../applicationpermission/WritePartition.java | 2 +- .../manager/model/grantduration/GrantDuration.java | 9 ++++----- .../model/grantduration/GrantDurationService.java | 4 ++-- .../dds/permissions/manager/model/group/Group.java | 8 ++++---- .../manager/model/group/GroupRepository.java | 2 +- .../manager/model/groupuser/GroupUser.java | 3 +-- .../model/groupuser/GroupUserRepository.java | 3 +-- .../manager/model/groupuser/GroupUserService.java | 4 ++-- .../dds/permissions/manager/model/topic/Topic.java | 6 +++--- .../manager/model/topic/TopicRepository.java | 2 +- .../manager/model/topic/TopicService.java | 2 +- .../manager/model/topicset/TopicSet.java | 10 +++------- .../manager/model/topicset/TopicSetService.java | 2 +- .../manager/model/topicsettopic/TopicSetTopic.java | 3 +-- .../dds/permissions/manager/model/user/User.java | 5 ++--- .../manager/model/user/UserService.java | 5 +---- .../manager/search/UniversalSearchParams.java | 7 +++---- .../security/BCryptPasswordEncoderService.java | 3 +-- .../permissions/manager/security/RefreshToken.java | 12 ++++++------ .../manager/security/RefreshTokenRepository.java | 6 +++--- .../manager/security/UserIsAdminInterceptor.java | 1 - 46 files changed, 102 insertions(+), 131 deletions(-) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionController.java index 03ac9630..df4ba578 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionController.java @@ -28,9 +28,8 @@ import io.unityfoundation.dds.permissions.manager.model.action.dto.ActionDTO; import io.unityfoundation.dds.permissions.manager.model.action.dto.CreateActionDTO; import io.unityfoundation.dds.permissions.manager.model.action.dto.UpdateActionDTO; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Controller("/api/actions") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionIntervalController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionIntervalController.java index 54dfc89b..88336d9c 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionIntervalController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ActionIntervalController.java @@ -23,12 +23,11 @@ import io.micronaut.security.annotation.Secured; import io.micronaut.security.rules.SecurityRule; import io.swagger.v3.oas.annotations.tags.Tag; -import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.CreateActionIntervalDTO; -import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.ActionIntervalDTO; import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionIntervalService; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.ActionIntervalDTO; +import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.CreateActionIntervalDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Controller("/api/action_intervals") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/AdminController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/AdminController.java index 51f5ee2b..b38a7a6f 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/AdminController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/AdminController.java @@ -34,8 +34,7 @@ import io.unityfoundation.dds.permissions.manager.model.user.AdminDTO; import io.unityfoundation.dds.permissions.manager.model.user.UserService; import io.unityfoundation.dds.permissions.manager.security.UserIsAdmin; - -import javax.validation.Valid; +import jakarta.validation.Valid; @UserIsAdmin @Controller("/api/admins") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationController.java index ea3d89cd..61566f46 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationController.java @@ -33,11 +33,11 @@ import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationDTO; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationService; +import jakarta.mail.MessagingException; +import jakarta.validation.Valid; import org.bouncycastle.mail.smime.SMIMEException; import org.bouncycastle.operator.OperatorCreationException; -import javax.mail.MessagingException; -import javax.validation.Valid; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantController.java index e20b98fc..ddb721d8 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationGrantController.java @@ -23,17 +23,16 @@ import io.micronaut.security.annotation.Secured; import io.micronaut.security.rules.SecurityRule; import io.swagger.v3.oas.annotations.tags.Tag; -import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.DetailedGrantDTO; -import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.GrantDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrantService; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.CreateGrantDTO; +import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.DetailedGrantDTO; +import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.GrantDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.UpdateGrantDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import org.reactivestreams.Publisher; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - import static io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermissionService.APPLICATION_GRANT_TOKEN; @Controller("/api/application_grants") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionController.java index 4aded69b..644a6a1b 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/ApplicationPermissionController.java @@ -22,14 +22,13 @@ import io.micronaut.security.annotation.Secured; import io.micronaut.security.rules.SecurityRule; import io.swagger.v3.oas.annotations.tags.Tag; +import io.unityfoundation.dds.permissions.manager.model.applicationpermission.AccessPermissionBodyDTO; import io.unityfoundation.dds.permissions.manager.model.applicationpermission.AccessPermissionDTO; import io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermissionService; -import io.unityfoundation.dds.permissions.manager.model.applicationpermission.AccessPermissionBodyDTO; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; import org.reactivestreams.Publisher; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; - import static io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermissionService.APPLICATION_GRANT_TOKEN; @Controller("/api/application_permissions") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/GrantDurationController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/GrantDurationController.java index 052e425a..2f39edd7 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/GrantDurationController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/GrantDurationController.java @@ -26,9 +26,8 @@ import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDurationService; import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.CreateGrantDurationDTO; import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.GrantDurationDTO; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Controller("/api/grant_durations") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupController.java index 7806e1c0..2b6e8d82 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupController.java @@ -32,8 +32,7 @@ import io.unityfoundation.dds.permissions.manager.exception.DPMErrorResponse; import io.unityfoundation.dds.permissions.manager.model.group.*; import io.unityfoundation.dds.permissions.manager.security.UserIsAdmin; - -import javax.validation.Valid; +import jakarta.validation.Valid; @Controller("/api/groups") @Secured(SecurityRule.IS_AUTHENTICATED) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupMembershipController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupMembershipController.java index 943c2081..ea52419e 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupMembershipController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/GroupMembershipController.java @@ -32,8 +32,8 @@ import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserResponseDTO; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; +import jakarta.validation.Valid; -import javax.validation.Valid; import java.util.Map; @Controller("/api/group_membership") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/RunApplication.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/RunApplication.java index 4e5aea11..bf268963 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/RunApplication.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/RunApplication.java @@ -13,11 +13,6 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager; -import io.micronaut.context.ApplicationContextBuilder; -import io.micronaut.context.ApplicationContextConfigurer; -import io.micronaut.context.annotation.ContextConfigurer; -import io.micronaut.context.env.Environment; -import io.micronaut.core.annotation.NonNull; import io.micronaut.core.annotation.TypeHint; import io.micronaut.runtime.Micronaut; import io.swagger.v3.oas.annotations.OpenAPIDefinition; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicController.java index 71a291d0..aa15bc94 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicController.java @@ -32,8 +32,7 @@ import io.unityfoundation.dds.permissions.manager.model.topic.TopicDTO; import io.unityfoundation.dds.permissions.manager.model.topic.TopicKind; import io.unityfoundation.dds.permissions.manager.model.topic.TopicService; - -import javax.validation.Valid; +import jakarta.validation.Valid; @Controller("/api/topics") @Secured(SecurityRule.IS_AUTHENTICATED) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicSetController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicSetController.java index 3fabb4b3..80643c06 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicSetController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/TopicSetController.java @@ -27,9 +27,8 @@ import io.unityfoundation.dds.permissions.manager.model.topicset.dto.CreateTopicSetDTO; import io.unityfoundation.dds.permissions.manager.model.topicset.dto.TopicSetDTO; import io.unityfoundation.dds.permissions.manager.model.topicset.dto.UpdateTopicSetDTO; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Controller("/api/topic-sets") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/UniversalSearchController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/UniversalSearchController.java index fdfacb5c..ab373c75 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/UniversalSearchController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/UniversalSearchController.java @@ -14,7 +14,9 @@ package io.unityfoundation.dds.permissions.manager; import io.micronaut.data.model.Page; -import io.micronaut.http.annotation.*; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.RequestBean; import io.micronaut.scheduling.TaskExecutors; import io.micronaut.scheduling.annotation.ExecuteOn; import io.micronaut.security.annotation.Secured; @@ -23,8 +25,7 @@ import io.unityfoundation.dds.permissions.manager.search.SearchResponseDTO; import io.unityfoundation.dds.permissions.manager.search.UniversalSearchParams; import io.unityfoundation.dds.permissions.manager.search.UniversalSearchService; - -import javax.validation.Valid; +import jakarta.validation.Valid; @Controller("/api/search") @Secured(SecurityRule.IS_AUTHENTICATED) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/Action.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/Action.java index 940fd67b..c1f6c720 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/Action.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/Action.java @@ -19,12 +19,11 @@ import io.micronaut.data.annotation.DateUpdated; import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionInterval; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrant; -import io.unityfoundation.dds.permissions.manager.model.topic.Topic; import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; +import jakarta.persistence.*; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; -import javax.persistence.*; import java.time.Instant; import java.util.Collections; import java.util.HashSet; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionPartition.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionPartition.java index 9e390000..4c1dedc4 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionPartition.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionPartition.java @@ -13,7 +13,7 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.action; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "permissions_action_partition") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionService.java index f9884899..1ae04401 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/action/ActionService.java @@ -38,10 +38,13 @@ import io.unityfoundation.dds.permissions.manager.model.user.User; import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import jakarta.inject.Singleton; +import jakarta.transaction.Transactional; +import jakarta.validation.constraints.NotNull; -import javax.transaction.Transactional; -import javax.validation.constraints.NotNull; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionInterval.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionInterval.java index 9ccd89ce..48bdebe8 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionInterval.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionInterval.java @@ -17,11 +17,11 @@ import io.micronaut.core.annotation.NonNull; import io.micronaut.core.annotation.Nullable; import io.unityfoundation.dds.permissions.manager.model.group.Group; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.time.Instant; @Entity @@ -36,7 +36,6 @@ public class ActionInterval { // @OnDelete(action = OnDeleteAction.CASCADE) // private Set topics = new HashSet<>(); - @NonNull @NotBlank @Size(min = 3) private String name; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionIntervalService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionIntervalService.java index e7279f0f..d261d086 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionIntervalService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actioninterval/ActionIntervalService.java @@ -21,16 +21,16 @@ import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.action.ActionRepository; -import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.CreateActionIntervalDTO; import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.ActionIntervalDTO; +import io.unityfoundation.dds.permissions.manager.model.actioninterval.dto.CreateActionIntervalDTO; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; import io.unityfoundation.dds.permissions.manager.model.user.User; import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import jakarta.inject.Singleton; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.util.List; import java.util.Objects; import java.util.Optional; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actiontopic/ActionTopic.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actiontopic/ActionTopic.java index 348dfbc1..a1931cdc 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actiontopic/ActionTopic.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/actiontopic/ActionTopic.java @@ -17,8 +17,7 @@ import io.micronaut.core.annotation.NonNull; import io.unityfoundation.dds.permissions.manager.model.action.Action; import io.unityfoundation.dds.permissions.manager.model.topic.Topic; - -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "permissions_action_topic") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/Application.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/Application.java index e0821db7..01a3dcc0 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/Application.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/Application.java @@ -18,10 +18,10 @@ import io.micronaut.data.annotation.DateCreated; import io.micronaut.data.annotation.DateUpdated; import io.unityfoundation.dds.permissions.manager.model.group.Group; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; import java.time.Instant; @Entity diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationRepository.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationRepository.java index 5f18b8c3..d35e9c88 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationRepository.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationRepository.java @@ -19,9 +19,9 @@ import io.micronaut.data.model.Pageable; import io.micronaut.data.repository.PageableRepository; import io.unityfoundation.dds.permissions.manager.model.group.Group; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationService.java index 597d890f..cab037bd 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/application/ApplicationService.java @@ -24,8 +24,8 @@ import io.micronaut.security.token.jwt.generator.JwtTokenGenerator; import io.micronaut.security.token.jwt.generator.claims.JWTClaimsSetGenerator; import io.micronaut.security.token.jwt.validator.AuthenticationJWTClaimsSetAdapter; -import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; +import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.action.Action; import io.unityfoundation.dds.permissions.manager.model.action.ActionPartition; import io.unityfoundation.dds.permissions.manager.model.action.ActionService; @@ -48,6 +48,12 @@ import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import io.unityfoundation.dds.permissions.manager.util.XMLEscaper; import jakarta.inject.Singleton; +import jakarta.mail.MessagingException; +import jakarta.mail.Session; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; +import jakarta.xml.bind.DatatypeConverter; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; @@ -81,12 +87,6 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.Store; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMultipart; -import javax.mail.internet.MimeMessage; -import javax.xml.bind.DatatypeConverter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringReader; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrant.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrant.java index cd78ce3f..fe32e85d 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrant.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrant.java @@ -18,10 +18,9 @@ import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; import io.unityfoundation.dds.permissions.manager.model.group.Group; - -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; @Entity @Table(name = "permissions_application_grant") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermission.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermission.java index 02d9c8a2..8bde0362 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermission.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermission.java @@ -17,10 +17,10 @@ import io.micronaut.core.annotation.NonNull; import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.topic.Topic; +import jakarta.persistence.*; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; -import javax.persistence.*; import java.util.Collections; import java.util.HashSet; import java.util.Set; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ReadPartition.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ReadPartition.java index d7e6d5d3..3dad9dec 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ReadPartition.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ReadPartition.java @@ -13,7 +13,7 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationpermission; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "permissions_partition") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/WritePartition.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/WritePartition.java index 39b77369..132133ee 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/WritePartition.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/WritePartition.java @@ -13,7 +13,7 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.model.applicationpermission; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "permissions_partition") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDuration.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDuration.java index 459a04ef..35884f7d 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDuration.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDuration.java @@ -16,11 +16,10 @@ import io.micronaut.core.annotation.NonNull; import io.unityfoundation.dds.permissions.manager.model.group.Group; - -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.PositiveOrZero; -import javax.validation.constraints.Size; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.PositiveOrZero; +import jakarta.validation.constraints.Size; @Entity @Table(name = "permissions_grant_duration") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDurationService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDurationService.java index 8607cc36..6b6456ba 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDurationService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/grantduration/GrantDurationService.java @@ -21,16 +21,16 @@ import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrantRepository; -import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.GrantDurationDTO; import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.CreateGrantDurationDTO; +import io.unityfoundation.dds.permissions.manager.model.grantduration.dto.GrantDurationDTO; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; import io.unityfoundation.dds.permissions.manager.model.user.User; import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import jakarta.inject.Singleton; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.util.List; import java.util.Objects; import java.util.Optional; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/Group.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/Group.java index 4b137397..09761ed4 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/Group.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/Group.java @@ -16,18 +16,18 @@ import io.micronaut.core.annotation.NonNull; import io.micronaut.core.annotation.Nullable; -import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionInterval; +import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrant; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; import io.unityfoundation.dds.permissions.manager.model.topic.Topic; import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; import java.util.Collections; import java.util.HashSet; import java.util.Set; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/GroupRepository.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/GroupRepository.java index ea405bd9..cecb0d60 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/GroupRepository.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/group/GroupRepository.java @@ -18,8 +18,8 @@ import io.micronaut.data.model.Page; import io.micronaut.data.model.Pageable; import io.micronaut.data.repository.PageableRepository; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUser.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUser.java index 3de86d5e..210f878a 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUser.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUser.java @@ -16,8 +16,7 @@ import io.micronaut.core.annotation.NonNull; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.user.User; - -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "permissions_group_user") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserRepository.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserRepository.java index 8c77a067..1e8c1713 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserRepository.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserRepository.java @@ -20,10 +20,9 @@ import io.micronaut.data.repository.PageableRepository; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.user.User; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.util.List; -import java.util.Optional; @Repository public interface GroupUserRepository extends PageableRepository { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserService.java index 0d48cbd5..72d799b2 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/groupuser/GroupUserService.java @@ -19,8 +19,8 @@ import io.micronaut.http.HttpStatus; import io.micronaut.http.MutableHttpResponse; import io.micronaut.http.annotation.Body; -import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; +import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupAdminRole; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; @@ -28,8 +28,8 @@ import io.unityfoundation.dds.permissions.manager.model.user.UserRepository; import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import jakarta.inject.Singleton; +import jakarta.transaction.Transactional; -import javax.transaction.Transactional; import java.util.*; import java.util.stream.Collectors; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/Topic.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/Topic.java index 3b92b4d0..ec75dd00 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/Topic.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/Topic.java @@ -19,10 +19,10 @@ import io.micronaut.data.annotation.DateCreated; import io.micronaut.data.annotation.DateUpdated; import io.unityfoundation.dds.permissions.manager.model.group.Group; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; import java.time.Instant; @Entity diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicRepository.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicRepository.java index a41ed571..5827bfb0 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicRepository.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicRepository.java @@ -19,8 +19,8 @@ import io.micronaut.data.model.Pageable; import io.micronaut.data.repository.PageableRepository; import io.unityfoundation.dds.permissions.manager.model.group.Group; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicService.java index a8a1a9ab..fcf1240d 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topic/TopicService.java @@ -19,8 +19,8 @@ import io.micronaut.http.HttpStatus; import io.micronaut.http.MutableHttpResponse; import io.micronaut.security.authentication.AuthenticationException; -import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; +import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.actiontopic.ActionTopicRepository; import io.unityfoundation.dds.permissions.manager.model.applicationpermission.ApplicationPermissionService; import io.unityfoundation.dds.permissions.manager.model.group.Group; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSet.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSet.java index cc8799ff..e0e556ef 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSet.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSet.java @@ -18,15 +18,11 @@ import io.micronaut.data.annotation.DateCreated; import io.micronaut.data.annotation.DateUpdated; import io.unityfoundation.dds.permissions.manager.model.group.Group; -import io.unityfoundation.dds.permissions.manager.model.topic.Topic; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; import java.time.Instant; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; @Entity @Table(name = "permissions_topic_set") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSetService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSetService.java index 50209af1..f5b078cd 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSetService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicset/TopicSetService.java @@ -33,8 +33,8 @@ import io.unityfoundation.dds.permissions.manager.model.user.User; import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import jakarta.inject.Singleton; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.NotNull; import java.time.Instant; import java.util.List; import java.util.Map; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicsettopic/TopicSetTopic.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicsettopic/TopicSetTopic.java index 9e170dbc..2597a0d5 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicsettopic/TopicSetTopic.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/topicsettopic/TopicSetTopic.java @@ -17,8 +17,7 @@ import io.micronaut.core.annotation.NonNull; import io.unityfoundation.dds.permissions.manager.model.topic.Topic; import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; - -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "permissions_topic_set_topic") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/User.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/User.java index 21bcc374..47beace2 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/User.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/User.java @@ -15,9 +15,8 @@ import io.micronaut.core.annotation.NonNull; import io.micronaut.data.annotation.DateUpdated; - -import javax.persistence.*; -import javax.validation.constraints.Email; +import jakarta.persistence.*; +import jakarta.validation.constraints.Email; @Entity @Table(name = "permissions_user") diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/UserService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/UserService.java index 5feeb630..717723f9 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/UserService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/user/UserService.java @@ -18,17 +18,14 @@ import io.micronaut.data.model.Pageable; import io.micronaut.data.model.Sort; import io.micronaut.http.HttpResponse; -import io.micronaut.http.HttpStatus; -import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; -import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUser; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; import io.unityfoundation.dds.permissions.manager.security.SecurityUtil; import jakarta.inject.Singleton; +import jakarta.transaction.Transactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.transaction.Transactional; import java.util.Collections; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/UniversalSearchParams.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/UniversalSearchParams.java index ce32b3db..942b739f 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/UniversalSearchParams.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/search/UniversalSearchParams.java @@ -13,16 +13,15 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.search; -import io.micronaut.core.annotation.Introspected; import io.micronaut.core.annotation.Nullable; import io.micronaut.data.model.Pageable; import io.micronaut.http.HttpRequest; import io.micronaut.http.annotation.QueryValue; +import io.micronaut.serde.annotation.Serdeable; +import jakarta.validation.Valid; -import javax.validation.Valid; - -@Introspected +@Serdeable public class UniversalSearchParams { private HttpRequest httpRequest; diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/BCryptPasswordEncoderService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/BCryptPasswordEncoderService.java index 01c61de5..86900d65 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/BCryptPasswordEncoderService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/BCryptPasswordEncoderService.java @@ -17,13 +17,12 @@ import io.micronaut.core.annotation.NonNull; import jakarta.annotation.PostConstruct; import jakarta.inject.Singleton; +import jakarta.validation.constraints.NotBlank; import org.bouncycastle.crypto.generators.Argon2BytesGenerator; import org.bouncycastle.crypto.params.Argon2Parameters; import org.bouncycastle.util.encoders.Hex; -import javax.validation.constraints.NotBlank; import java.nio.charset.StandardCharsets; -import java.util.Arrays; @Singleton public class BCryptPasswordEncoderService { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshToken.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshToken.java index 4993545c..8e0e8abc 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshToken.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshToken.java @@ -15,13 +15,13 @@ import io.micronaut.core.annotation.NonNull; import io.micronaut.data.annotation.DateCreated; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.time.Instant; @Entity diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenRepository.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenRepository.java index e1c9b8a7..55d65002 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenRepository.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenRepository.java @@ -16,10 +16,10 @@ import io.micronaut.core.annotation.NonNull; import io.micronaut.data.annotation.Repository; import io.micronaut.data.repository.CrudRepository; +import jakarta.transaction.Transactional; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; -import javax.transaction.Transactional; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.util.Optional; @Repository diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/UserIsAdminInterceptor.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/UserIsAdminInterceptor.java index 560cbd29..e86875b0 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/UserIsAdminInterceptor.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/UserIsAdminInterceptor.java @@ -17,7 +17,6 @@ import io.micronaut.aop.MethodInterceptor; import io.micronaut.aop.MethodInvocationContext; import io.micronaut.core.annotation.Nullable; - import io.micronaut.http.HttpStatus; import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; import io.unityfoundation.dds.permissions.manager.exception.DPMException; From 5cbae15299c3e45887b8791d1c3904076d08e75c Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:16:41 -0600 Subject: [PATCH 07/18] Optimize imports Signed-off-by: montesm --- .../dds/permissions/manager/Bootstrap.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/Bootstrap.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/Bootstrap.java index c70f177e..1e488ed8 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/Bootstrap.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/Bootstrap.java @@ -19,17 +19,17 @@ import io.micronaut.core.util.StringUtils; import io.micronaut.runtime.event.annotation.EventListener; import io.micronaut.runtime.server.event.ServerStartupEvent; +import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionInterval; import io.unityfoundation.dds.permissions.manager.model.application.Application; +import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrant; +import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; import io.unityfoundation.dds.permissions.manager.model.group.Group; import io.unityfoundation.dds.permissions.manager.model.group.GroupRepository; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUser; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserRepository; import io.unityfoundation.dds.permissions.manager.model.topic.Topic; -import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; -import io.unityfoundation.dds.permissions.manager.model.actioninterval.ActionInterval; -import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; import io.unityfoundation.dds.permissions.manager.model.topic.TopicKind; -import io.unityfoundation.dds.permissions.manager.model.applicationgrant.ApplicationGrant; +import io.unityfoundation.dds.permissions.manager.model.topicset.TopicSet; import io.unityfoundation.dds.permissions.manager.model.user.User; import io.unityfoundation.dds.permissions.manager.model.user.UserRepository; import org.slf4j.Logger; @@ -37,11 +37,8 @@ import java.time.Instant; import java.time.OffsetDateTime; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; @Requires(property = "dpm.bootstrap.data.enabled", value = StringUtils.TRUE) @ConfigurationProperties("dpm.bootstrap") From b251d4fddc95ef14593a9ad2816b4e935788d933 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:17:06 -0600 Subject: [PATCH 08/18] Use Serde for DPMErrorResponse Signed-off-by: montesm --- .../dds/permissions/manager/exception/DPMErrorResponse.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DPMErrorResponse.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DPMErrorResponse.java index 839cf422..c641bb7f 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DPMErrorResponse.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/exception/DPMErrorResponse.java @@ -13,9 +13,9 @@ // limitations under the License. package io.unityfoundation.dds.permissions.manager.exception; -import io.micronaut.core.annotation.Introspected; +import io.micronaut.serde.annotation.Serdeable; -@Introspected +@Serdeable public class DPMErrorResponse { private String id; From 18321c512b691917b4d9f2cf2de1a61294759e96 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:18:37 -0600 Subject: [PATCH 09/18] JWTClaims moved to Claims Signed-off-by: montesm --- .../applicationgrant/ApplicationGrantService.java | 10 +++++----- .../ApplicationPermissionService.java | 14 ++++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrantService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrantService.java index 112ec72f..8b9bf657 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrantService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationgrant/ApplicationGrantService.java @@ -20,7 +20,7 @@ import io.micronaut.data.model.Pageable; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; -import io.micronaut.security.token.jwt.generator.claims.JwtClaims; +import io.micronaut.security.token.Claims; import io.micronaut.security.token.jwt.generator.claims.JwtClaimsSetAdapter; import io.micronaut.security.token.jwt.validator.JwtTokenValidator; import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; @@ -30,9 +30,9 @@ import io.unityfoundation.dds.permissions.manager.model.action.dto.ActionDTO; import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationRepository; +import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.CreateGrantDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.DetailedGrantDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.GrantDTO; -import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.CreateGrantDTO; import io.unityfoundation.dds.permissions.manager.model.applicationgrant.dto.UpdateGrantDTO; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDuration; import io.unityfoundation.dds.permissions.manager.model.grantduration.GrantDurationRepository; @@ -175,12 +175,12 @@ public GrantDTO findById(Long grantId) { public Publisher> create(String grantToken, CreateGrantDTO createGrantDTO) { return Publishers.map(jwtTokenValidator.validateToken(grantToken, null), authentication -> { JWT jwt; - JwtClaims claims; + Claims claims; try { jwt = JWTParser.parse(grantToken); claims = new JwtClaimsSetAdapter(jwt.getJWTClaimsSet()); - if (claims.get(JwtClaims.SUBJECT) != null) { - Long applicationId = Long.valueOf((String) claims.get(JwtClaims.SUBJECT)); + if (claims.get(Claims.SUBJECT) != null) { + Long applicationId = Long.valueOf((String) claims.get(Claims.SUBJECT)); return create(applicationId, createGrantDTO); } else { throw new DPMException(ResponseStatusCodes.APPLICATION_GRANT_TOKEN_PARSE_EXCEPTION, HttpStatus.BAD_REQUEST); diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermissionService.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermissionService.java index 3fba7116..95b6e8a7 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermissionService.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/model/applicationpermission/ApplicationPermissionService.java @@ -20,11 +20,11 @@ import io.micronaut.data.model.Pageable; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; -import io.micronaut.security.token.jwt.generator.claims.JwtClaims; +import io.micronaut.security.token.Claims; import io.micronaut.security.token.jwt.generator.claims.JwtClaimsSetAdapter; import io.micronaut.security.token.jwt.validator.JwtTokenValidator; -import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.ResponseStatusCodes; +import io.unityfoundation.dds.permissions.manager.exception.DPMException; import io.unityfoundation.dds.permissions.manager.model.application.Application; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationRepository; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; @@ -36,7 +36,9 @@ import org.reactivestreams.Publisher; import java.text.ParseException; -import java.util.*; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; @Singleton @@ -174,12 +176,12 @@ private Page getPublicApplicationPermissionsPage(boolean public Publisher> addAccess(String grantToken, Long topicId, AccessPermissionBodyDTO accessPermissionBodyDTO) { return Publishers.map(jwtTokenValidator.validateToken(grantToken, null), authentication -> { JWT jwt; - JwtClaims claims; + Claims claims; try { jwt = JWTParser.parse(grantToken); claims = new JwtClaimsSetAdapter(jwt.getJWTClaimsSet()); - if (claims.get(JwtClaims.SUBJECT) != null) { - Long applicationId = Long.valueOf((String) claims.get(JwtClaims.SUBJECT)); + if (claims.get(Claims.SUBJECT) != null) { + Long applicationId = Long.valueOf((String) claims.get(Claims.SUBJECT)); return addAccess(applicationId, topicId, accessPermissionBodyDTO); } else { throw new DPMException(ResponseStatusCodes.APPLICATION_GRANT_TOKEN_PARSE_EXCEPTION, HttpStatus.BAD_REQUEST); From 86a7112020e63f13444bf8d10e485715287c8c37 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:26:26 -0600 Subject: [PATCH 10/18] Update overriden security classes Signed-off-by: montesm --- .../AuthenticationProviderUserPassword.java | 10 +++------- .../security/DPMIntrospectionController.java | 4 ++-- ...ermissionsManagerAuthenticationMapper.java | 19 +++++++++++-------- .../security/RefreshTokenPersistenceImpl.java | 11 +++-------- .../AdminControllerSecuredWithRoleTest.java | 2 +- .../AuthenticationFetcherReplacement.java | 2 +- .../MockDPMIntrospectionController.java | 3 ++- 7 files changed, 23 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/AuthenticationProviderUserPassword.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/AuthenticationProviderUserPassword.java index 9a2e7d3d..2815557b 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/AuthenticationProviderUserPassword.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/AuthenticationProviderUserPassword.java @@ -22,15 +22,11 @@ import io.micronaut.security.authentication.AuthenticationRequest; import io.micronaut.security.authentication.AuthenticationResponse; import io.unityfoundation.dds.permissions.manager.model.application.ApplicationService; -import io.unityfoundation.dds.permissions.manager.model.user.UserRole; import jakarta.inject.Singleton; import org.reactivestreams.Publisher; -import java.util.Collections; -import java.util.List; - @Singleton -public class AuthenticationProviderUserPassword implements AuthenticationProvider { +public class AuthenticationProviderUserPassword implements AuthenticationProvider { @Nullable @Property(name = "permissions-manager.test.username") @@ -56,8 +52,8 @@ public AuthenticationProviderUserPassword(Environment environment, ApplicationSe } @Override - public Publisher authenticate(@Nullable HttpRequest httpRequest, - AuthenticationRequest authenticationRequest) { + public Publisher authenticate(@Nullable HttpRequest httpRequest, + AuthenticationRequest authenticationRequest) { String identity = (String) authenticationRequest.getIdentity(); String password = (String) authenticationRequest.getSecret(); diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/DPMIntrospectionController.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/DPMIntrospectionController.java index 9bbfa24f..35675156 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/DPMIntrospectionController.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/DPMIntrospectionController.java @@ -36,7 +36,6 @@ import io.micronaut.security.rules.SecurityRule; import io.micronaut.security.token.validator.RefreshTokenValidator; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; -import jakarta.inject.Singleton; import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +44,7 @@ import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.Optional; +import java.util.function.Function; @Replaces(IntrospectionController.class) @@ -95,7 +95,7 @@ public Publisher> echo(@Nullable Authentication authentic } private Publisher> getIntrospectionAndValidResponse(Authentication authentication, HttpRequest request) { - return Publishers.map(Publishers.map(processor.introspect(authentication, request), response -> { + return Publishers.map(Publishers.map(processor.introspect(authentication, request), (Function) response -> { groupUserService.checkUserValidity().forEach(response::addExtension); return introspectionResponseAsJsonString(response); }), HttpResponse::ok); diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/PermissionsManagerAuthenticationMapper.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/PermissionsManagerAuthenticationMapper.java index 39f663bc..665e1ded 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/PermissionsManagerAuthenticationMapper.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/PermissionsManagerAuthenticationMapper.java @@ -14,6 +14,7 @@ package io.unityfoundation.dds.permissions.manager.security; import io.micronaut.context.annotation.Replaces; +import io.micronaut.core.async.publisher.Publishers; import io.micronaut.security.authentication.AuthenticationFailureReason; import io.micronaut.security.authentication.AuthenticationResponse; import io.micronaut.security.oauth2.endpoint.authorization.state.State; @@ -23,10 +24,10 @@ import io.micronaut.security.oauth2.endpoint.token.response.OpenIdTokenResponse; import io.unityfoundation.dds.permissions.manager.model.groupuser.GroupUserService; import io.unityfoundation.dds.permissions.manager.model.user.User; -import io.unityfoundation.dds.permissions.manager.model.user.UserRole; import io.unityfoundation.dds.permissions.manager.model.user.UserService; import jakarta.inject.Named; import jakarta.inject.Singleton; +import org.reactivestreams.Publisher; import java.util.*; @@ -44,15 +45,16 @@ public PermissionsManagerAuthenticationMapper(UserService userService, GroupUser } @Override - public AuthenticationResponse createAuthenticationResponse(String providerName, - OpenIdTokenResponse tokenResponse, - OpenIdClaims openIdClaims, - State state) { + public Publisher createAuthenticationResponse(String providerName, + OpenIdTokenResponse tokenResponse, + OpenIdClaims openIdClaims, + State state) { return getAuthenticationResponse(openIdClaims.getEmail()); } - public AuthenticationResponse getAuthenticationResponse(String userEmail) { - return Optional.ofNullable(userEmail) + public Publisher getAuthenticationResponse(String userEmail) { + return Publishers.just( + Optional.ofNullable(userEmail) .flatMap(userService::getUserByEmail) .map(user -> isNonAdminAndNotAMemberOfAnyGroups(user) ? AuthenticationResponse.failure(AuthenticationFailureReason.USER_DISABLED) : @@ -61,7 +63,8 @@ public AuthenticationResponse getAuthenticationResponse(String userEmail) { Collections.emptyList(), userAttributes(userEmail, user) )) - .orElseGet(() -> AuthenticationResponse.failure(AuthenticationFailureReason.USER_NOT_FOUND)); + .orElseGet(() -> AuthenticationResponse.failure(AuthenticationFailureReason.USER_NOT_FOUND)) + ); } private boolean isNonAdminAndNotAMemberOfAnyGroups(User user) { diff --git a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenPersistenceImpl.java b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenPersistenceImpl.java index b2aa6dc4..01b50025 100644 --- a/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenPersistenceImpl.java +++ b/app/src/main/java/io/unityfoundation/dds/permissions/manager/security/RefreshTokenPersistenceImpl.java @@ -27,11 +27,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collections; import java.util.List; import java.util.Optional; -import static io.micronaut.security.errors.IssuingAnAccessTokenErrorCode.INVALID_CLIENT; import static io.micronaut.security.errors.IssuingAnAccessTokenErrorCode.INVALID_GRANT; @Singleton @@ -87,12 +85,9 @@ public Publisher getAuthentication(String refreshToken) { } // oauth user login - Optional authentication = - authenticationMapper.getAuthenticationResponse(username).getAuthentication(); - if (authentication.isEmpty()) { - throw new OauthErrorResponseException(INVALID_CLIENT); - } - return Publishers.just(authentication.get()); + Publisher authentication = + Publishers.map(authenticationMapper.getAuthenticationResponse(username), authenticationResponse -> authenticationResponse.getAuthentication().get()); + return authentication; } } else { throw new OauthErrorResponseException(INVALID_GRANT, "refresh token not found", null); diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminControllerSecuredWithRoleTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminControllerSecuredWithRoleTest.java index 78207ea5..bca4dd20 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminControllerSecuredWithRoleTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/AdminControllerSecuredWithRoleTest.java @@ -52,7 +52,7 @@ void putApiAdminsRemoveAdminRequiresAdminsRole(@Client("/") HttpClient httpClien @Requires(property = "spec.name", value = "AdminControllerSecuredWithRoleTest") @Singleton - static class MockAuthenticationFetcher implements AuthenticationFetcher { + static class MockAuthenticationFetcher implements AuthenticationFetcher> { @Override public Publisher fetchAuthentication(HttpRequest request) { diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/AuthenticationFetcherReplacement.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/AuthenticationFetcherReplacement.java index 4b135c14..e54631ad 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/AuthenticationFetcherReplacement.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/AuthenticationFetcherReplacement.java @@ -19,7 +19,7 @@ import io.micronaut.security.filters.AuthenticationFetcher; import org.reactivestreams.Publisher; -public class AuthenticationFetcherReplacement implements AuthenticationFetcher { +public class AuthenticationFetcherReplacement implements AuthenticationFetcher> { private Authentication authentication; diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/MockDPMIntrospectionController.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/MockDPMIntrospectionController.java index 17bd71f1..333ee379 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/MockDPMIntrospectionController.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/MockDPMIntrospectionController.java @@ -42,6 +42,7 @@ import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.Optional; +import java.util.function.Function; @Replaces(IntrospectionController.class) @Requires(env = Environment.TEST) @@ -90,7 +91,7 @@ public Publisher> echo(@NonNull HttpRequest request) { } private Publisher> getIntrospectionAndValidResponse(Authentication authentication, HttpRequest request) { - return Publishers.map(Publishers.map(processor.introspect(authentication, request), response -> { + return Publishers.map(Publishers.map(processor.introspect(authentication, request), (Function) response -> { groupUserService.checkUserValidity().forEach(response::addExtension); return introspectionResponseAsJsonString(response); }), HttpResponse::ok); From 835d0af938de05bd377e1bd4b30d37d665c563c6 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 19 Dec 2023 14:34:25 -0600 Subject: [PATCH 11/18] Use Java 17 in GH Actions Signed-off-by: montesm --- .github/workflows/cypress.yml | 2 +- .github/workflows/gradle.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index e8ca8838..a1258829 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -28,7 +28,7 @@ jobs: - name: Set up JDK 11 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' - name: Run the server with Gradle env: diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index eefb5cce..1f1b4dee 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -40,7 +40,7 @@ jobs: - name: Set up JDK 11 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' - name: Build with Gradle env: From ac21c80c4c2a83551544c13e8d71cee7fda49d10 Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 26 Dec 2023 15:10:13 -0600 Subject: [PATCH 12/18] Match date time formats between serde-parsed and Java Instant Signed-off-by: montesm --- app/build.gradle | 2 +- .../dds/permissions/manager/ApplicationApiTest.java | 6 ++---- .../dds/permissions/manager/TopicApiTest.java | 3 ++- .../dds/permissions/manager/TopicSetApiTest.java | 3 ++- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fa8f94da..9c919250 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,9 +43,9 @@ dependencies { annotationProcessor("io.micronaut.validation:micronaut-validation-processor") annotationProcessor("io.micronaut.serde:micronaut-serde-processor") annotationProcessor("io.micronaut:micronaut-graal") + compileOnly("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut.serde:micronaut-serde-jackson") implementation("io.micronaut:micronaut-http-client") - implementation("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut:micronaut-management") implementation("io.micronaut.data:micronaut-data-hibernate-jpa") implementation("io.micronaut.problem:micronaut-problem-json") diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java index abae94e8..de0d9435 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java @@ -50,6 +50,7 @@ import java.text.Collator; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -864,10 +865,7 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { assertEquals("This is a description", updatedApplication.getDescription()); assertNotEquals(date, updatedApplication.getDateCreated()); assertNotEquals(date, updatedApplication.getDateUpdated()); - assertEquals(createdDate, updatedApplication.getDateCreated()); - System.out.println("created.updateDate " + updatedDate); - System.out.println("updatedApplication.getDateUpdated() " + updatedApplication.getDateUpdated()); - + assertEquals(createdDate.truncatedTo(ChronoUnit.MICROS), updatedApplication.getDateCreated()); assertNotEquals(updatedDate, updatedApplication.getDateUpdated()); } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java index e371b6a9..e6513589 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java @@ -46,6 +46,7 @@ import org.junit.jupiter.api.Test; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -601,7 +602,7 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { assertEquals("This is a description", updatedTopic.getDescription()); assertNotEquals(date, updatedTopic.getDateCreated()); assertNotEquals(date, updatedTopic.getDateUpdated()); - assertEquals(createdDate, updatedTopic.getDateCreated()); + assertEquals(createdDate.truncatedTo(ChronoUnit.MICROS), updatedTopic.getDateCreated()); assertNotEquals(updatedDate, updatedTopic.getDateUpdated()); } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java index 8119da92..bb9acb76 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java @@ -46,6 +46,7 @@ import org.junit.jupiter.api.Test; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -186,7 +187,7 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { assertNotEquals(date, updatedTopicSet.getDateCreated()); assertNotEquals(date, updatedTopicSet.getDateUpdated()); assertEquals("Xyz789", updatedTopicSet.getName()); - assertEquals(createdDate, updatedTopicSet.getDateCreated()); + assertEquals(createdDate.truncatedTo(ChronoUnit.MICROS), updatedTopicSet.getDateCreated()); assertNotEquals(updatedDate, updatedTopicSet.getDateUpdated()); } From 3ce8bee1c5d4cacdcbcd5997533f5dd448fd204e Mon Sep 17 00:00:00 2001 From: montesm Date: Tue, 26 Dec 2023 15:27:08 -0600 Subject: [PATCH 13/18] Fix tests that are off my a microsecond. Update to assert by milliseconds Signed-off-by: montesm --- .../dds/permissions/manager/ApplicationApiTest.java | 2 +- .../unityfoundation/dds/permissions/manager/TopicApiTest.java | 2 +- .../dds/permissions/manager/TopicSetApiTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java index de0d9435..60a7ecb3 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/ApplicationApiTest.java @@ -865,7 +865,7 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { assertEquals("This is a description", updatedApplication.getDescription()); assertNotEquals(date, updatedApplication.getDateCreated()); assertNotEquals(date, updatedApplication.getDateUpdated()); - assertEquals(createdDate.truncatedTo(ChronoUnit.MICROS), updatedApplication.getDateCreated()); + assertEquals(createdDate.truncatedTo(ChronoUnit.MILLIS), updatedApplication.getDateCreated().truncatedTo(ChronoUnit.MILLIS)); assertNotEquals(updatedDate, updatedApplication.getDateUpdated()); } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java index e6513589..7f83355b 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicApiTest.java @@ -602,7 +602,7 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { assertEquals("This is a description", updatedTopic.getDescription()); assertNotEquals(date, updatedTopic.getDateCreated()); assertNotEquals(date, updatedTopic.getDateUpdated()); - assertEquals(createdDate.truncatedTo(ChronoUnit.MICROS), updatedTopic.getDateCreated()); + assertEquals(createdDate.truncatedTo(ChronoUnit.MILLIS), updatedTopic.getDateCreated().truncatedTo(ChronoUnit.MILLIS)); assertNotEquals(updatedDate, updatedTopic.getDateUpdated()); } diff --git a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java index bb9acb76..ad565e32 100644 --- a/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java +++ b/app/src/test/java/io/unityfoundation/dds/permissions/manager/TopicSetApiTest.java @@ -187,7 +187,7 @@ public void createdLastUpdatedFieldsArePopulatedAndNotEditable() { assertNotEquals(date, updatedTopicSet.getDateCreated()); assertNotEquals(date, updatedTopicSet.getDateUpdated()); assertEquals("Xyz789", updatedTopicSet.getName()); - assertEquals(createdDate.truncatedTo(ChronoUnit.MICROS), updatedTopicSet.getDateCreated()); + assertEquals(createdDate.truncatedTo(ChronoUnit.MILLIS), updatedTopicSet.getDateCreated().truncatedTo(ChronoUnit.MILLIS)); assertNotEquals(updatedDate, updatedTopicSet.getDateUpdated()); } From 8248178fd28bd67e4bdbdcc48613f1c6b9ee0484 Mon Sep 17 00:00:00 2001 From: montesm Date: Wed, 27 Dec 2023 10:45:40 -0600 Subject: [PATCH 14/18] Change to accurate name in gradle workflow Signed-off-by: montesm --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 1f1b4dee..e78693a7 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -37,7 +37,7 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' From 05dbc3704d0fb1c68ff5302fa9151816afbc78b6 Mon Sep 17 00:00:00 2001 From: montesm Date: Wed, 27 Dec 2023 10:46:53 -0600 Subject: [PATCH 15/18] Response now contains empty content instead of null Signed-off-by: montesm --- frontend/src/lib/Header.svelte | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/frontend/src/lib/Header.svelte b/frontend/src/lib/Header.svelte index c9e3ad56..5141b39d 100644 --- a/frontend/src/lib/Header.svelte +++ b/frontend/src/lib/Header.svelte @@ -79,24 +79,21 @@ if (permissionsForGroupContext?.data?.content || $isAdmin) { permissionsForGroupContext = permissionsForGroupContext.data.content; - if ((permissionsForGroupContext && permissionsForGroupContext[0].groupAdmin) || $isAdmin) { + if ((permissionsForGroupContext?.length > 0 && permissionsForGroupContext[0].groupAdmin) || $isAdmin) { isGroupAdminInContext = true; isGroupAdminToolip = tooltips['isGroupAdmin']; } else { isGroupAdminInContext = false; isGroupAdminToolip = tooltips['isNotGroupAdmin']; } - if ((permissionsForGroupContext && permissionsForGroupContext[0].topicAdmin) || $isAdmin) { + if ((permissionsForGroupContext?.length > 0 && permissionsForGroupContext[0].topicAdmin) || $isAdmin) { isTopicAdminInContext = true; isTopicAdminTooltip = tooltips['isTopicAdmin']; } else { isTopicAdminInContext = false; isTopicAdminTooltip = tooltips['isNotTopicAdmin']; } - if ( - (permissionsForGroupContext && permissionsForGroupContext[0].applicationAdmin) || - $isAdmin - ) { + if ((permissionsForGroupContext?.length > 0 && permissionsForGroupContext[0].applicationAdmin) || $isAdmin) { isApplicationAdminInContext = true; isApplicationAdminTooltip = tooltips['isApplicationAdmin']; } else { From 10403ddb4d6409e2d71a70bbcfea267f37f1f741 Mon Sep 17 00:00:00 2001 From: montesm Date: Thu, 28 Dec 2023 16:05:29 -0600 Subject: [PATCH 16/18] Upgrade to 4.2.2 Signed-off-by: montesm --- app/build.gradle | 11 +++++------ app/gradle.properties | 2 +- app/micronaut-cli.yml | 2 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 22 +++++++++++++--------- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9c919250..728b978c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,9 +23,8 @@ plugins { id("com.github.johnrengelman.shadow") version "8.1.1" id("jacoco") id("com.gorylenko.gradle-git-properties") version "2.4.1" - id("io.micronaut.application") version "4.0.0" - id("io.micronaut.test-resources") version "4.0.0" - id("io.micronaut.aot") version "4.0.0" + id("io.micronaut.application") version "4.2.1" + id("io.micronaut.test-resources") version "4.2.1" } version = "0.1" @@ -38,12 +37,13 @@ repositories { dependencies { annotationProcessor("io.micronaut.data:micronaut-data-processor") + annotationProcessor("io.micronaut:micronaut-http-validation") annotationProcessor("io.micronaut.openapi:micronaut-openapi") annotationProcessor("io.micronaut.security:micronaut-security-annotations") - annotationProcessor("io.micronaut.validation:micronaut-validation-processor") annotationProcessor("io.micronaut.serde:micronaut-serde-processor") annotationProcessor("io.micronaut:micronaut-graal") compileOnly("io.micronaut:micronaut-jackson-databind") + implementation("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut.serde:micronaut-serde-jackson") implementation("io.micronaut:micronaut-http-client") implementation("io.micronaut:micronaut-management") @@ -53,9 +53,8 @@ dependencies { implementation("io.micronaut.security:micronaut-security-oauth2") implementation("io.micronaut.sql:micronaut-jdbc-hikari") implementation("io.swagger.core.v3:swagger-annotations") - implementation("jakarta.annotation:jakarta.annotation-api") - implementation("io.micronaut.validation:micronaut-validation") implementation("io.micronaut:micronaut-websocket") + implementation("jakarta.persistence:jakarta.persistence-api:3.1.0") runtimeOnly("ch.qos.logback:logback-classic") diff --git a/app/gradle.properties b/app/gradle.properties index c9de9c7a..5b0db5a8 100644 --- a/app/gradle.properties +++ b/app/gradle.properties @@ -11,4 +11,4 @@ # 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. -micronautVersion=4.0.0 +micronautVersion=4.2.2 diff --git a/app/micronaut-cli.yml b/app/micronaut-cli.yml index 35297b75..b3fbe76e 100644 --- a/app/micronaut-cli.yml +++ b/app/micronaut-cli.yml @@ -16,4 +16,4 @@ defaultPackage: io.unityfoundation.dds.permissions.manager testFramework: junit sourceLanguage: java buildTool: gradle -features: [annotation-api, app-name, data, data-jpa, gradle, h2, http-client, jackson-databind, java, java-application, jdbc-tomcat, junit, logback, management, micronaut-build, netty-server, openapi, problem-json, readme, security-annotations, security-jwt, security-oauth2, shade, yaml] +features: [annotation-api, app-name, data, data-jpa, gradle, h2, http-client, jackson-databind, java, java-application, jdbc-tomcat, junit, logback, management, micronaut-build, micronaut-http-validation, netty-server, openapi, problem-json, readme, security-annotations, security-jwt, security-oauth2, shade, yaml] diff --git a/gradle.properties b/gradle.properties index c9de9c7a..5b0db5a8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ # 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. -micronautVersion=4.0.0 +micronautVersion=4.2.2 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644 GIT binary patch delta 37652 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 delta 36122 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 Ac-xW1# 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 Q>rd#Eb%7 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37aef8d3..3fa8f862 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cbb..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ From a01b8cdcbed78b220a294cf64b38698cf841eb1f Mon Sep 17 00:00:00 2001 From: montesm Date: Thu, 28 Dec 2023 16:57:22 -0600 Subject: [PATCH 17/18] Add back validation dependencies. Signed-off-by: montesm --- app/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 728b978c..3a3ad340 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,6 +42,7 @@ dependencies { annotationProcessor("io.micronaut.security:micronaut-security-annotations") annotationProcessor("io.micronaut.serde:micronaut-serde-processor") annotationProcessor("io.micronaut:micronaut-graal") + annotationProcessor("io.micronaut.validation:micronaut-validation-processor") compileOnly("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut:micronaut-jackson-databind") implementation("io.micronaut.serde:micronaut-serde-jackson") @@ -55,6 +56,7 @@ dependencies { implementation("io.swagger.core.v3:swagger-annotations") implementation("io.micronaut:micronaut-websocket") implementation("jakarta.persistence:jakarta.persistence-api:3.1.0") + implementation("io.micronaut.validation:micronaut-validation") runtimeOnly("ch.qos.logback:logback-classic") From 2cd4e129e6458d42104080a6c1bbc1e260bf0362 Mon Sep 17 00:00:00 2001 From: montesm Date: Fri, 29 Dec 2023 10:12:06 -0600 Subject: [PATCH 18/18] Refactor and add wait to cypress tests Signed-off-by: montesm --- frontend/cypress/e2e/action_intervals.cy.js | 10 ++--- frontend/cypress/e2e/applications_add.cy.js | 2 +- .../cypress/e2e/applications_b_edit.cy.js | 7 +-- frontend/cypress/e2e/topic-sets_add_one.cy.js | 43 +++++++++---------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/frontend/cypress/e2e/action_intervals.cy.js b/frontend/cypress/e2e/action_intervals.cy.js index d1572ff9..d55ce8d5 100644 --- a/frontend/cypress/e2e/action_intervals.cy.js +++ b/frontend/cypress/e2e/action_intervals.cy.js @@ -25,16 +25,14 @@ describe('Action Interval Capabilities', () => { cy.visit('/action-intervals'); cy.get('[data-cy="group-input"]') - .type("alpha"); - - cy.wait(500); - - cy.get('[data-cy="group-input"]').type('{downArrow}').type('{enter}'); + .type("alpha") + .wait(700) + .type('{downArrow}') + .type('{enter}'); cy.get('[data-cy="add-action-interval"]') .click(); - cy.get('[data-cy="action-interval-name-input"]').type('First Action Interval'); cy.get(':nth-child(3) > .date-time-field').type('{selectall}{backspace}').type('2023-10-01').type('{enter}'); diff --git a/frontend/cypress/e2e/applications_add.cy.js b/frontend/cypress/e2e/applications_add.cy.js index bd8dc8cb..fd06c12b 100644 --- a/frontend/cypress/e2e/applications_add.cy.js +++ b/frontend/cypress/e2e/applications_add.cy.js @@ -27,7 +27,7 @@ describe('Applications Capabilities', () => { cy.get('[data-cy="group-input"]') .type("alpha"); - cy.wait(500); + cy.wait(700); cy.get('[data-cy="group-input"]').type('{downArrow}').type('{enter}'); diff --git a/frontend/cypress/e2e/applications_b_edit.cy.js b/frontend/cypress/e2e/applications_b_edit.cy.js index 9fa4ecea..2686c75c 100644 --- a/frontend/cypress/e2e/applications_b_edit.cy.js +++ b/frontend/cypress/e2e/applications_b_edit.cy.js @@ -39,11 +39,12 @@ describe('Applications Capabilities', () => { cy.get('[data-cy="save-application"]') .click(); + cy.wait(1000); + cy.visit('/applications'); cy.get('td').should('not.eq', 'Test Application'); - cy.get('td').contains('New Application'); - - }); + cy.get('td').contains('New Application', {timeout: 7000}); + }); }); diff --git a/frontend/cypress/e2e/topic-sets_add_one.cy.js b/frontend/cypress/e2e/topic-sets_add_one.cy.js index 246c25af..9912e50d 100644 --- a/frontend/cypress/e2e/topic-sets_add_one.cy.js +++ b/frontend/cypress/e2e/topic-sets_add_one.cy.js @@ -25,11 +25,10 @@ describe('Topics Capabilities', () => { cy.visit('/topic-sets'); cy.get('[data-cy="group-input"]') - .type("alpha"); - - cy.wait(500); - - cy.get('[data-cy="group-input"]').type('{downArrow}').type('{enter}'); + .type("alpha") + .wait(500) + .type('{downArrow}') + .type('{enter}'); cy.get('[data-cy="add-topic"]') .click(); @@ -40,6 +39,8 @@ describe('Topics Capabilities', () => { cy.get('[data-cy="button-add-topic"]') .click({ force: true }); + cy.wait(500); + cy.get('.header-title') .contains('Test Topic Set Alpha'); @@ -49,34 +50,33 @@ describe('Topics Capabilities', () => { cy.visit('/topic-sets'); cy.get('[data-cy="group-input"]') - .type("alpha"); - - cy.wait(500); - - cy.get('[data-cy="group-input"]').type('{downArrow}').type('{enter}'); + .type("alpha") + .wait(700) + .type('{downArrow}') + .type('{enter}'); cy.contains('Test Topic Set Alpha').click(); + cy.wait(1000); + cy.get('.svelte-select') .type('topic') - cy.wait(1000); cy.contains('Test Topic 123').click(); - cy.get('[data-cy="topic"]').contains('Test Topic 123'); + cy.get('[data-cy="topic"]').contains('Test Topic 123', {timeout: 7000}); }); it('should delete the topic from the topic set.', () => { cy.visit('/topic-sets'); cy.get('[data-cy="group-input"]') - .type("alpha"); - - cy.wait(500); - - cy.get('[data-cy="group-input"]').type('{downArrow}').type('{enter}'); + .type("alpha") + .wait(500) + .type('{downArrow}') + .type('{enter}'); cy.contains('Test Topic Set Alpha').click(); cy.contains('Test Topic 123').click(); @@ -94,11 +94,10 @@ describe('Topics Capabilities', () => { cy.visit('/topic-sets'); cy.get('[data-cy="group-input"]') - .type("alpha"); - - cy.wait(500); - - cy.get('[data-cy="group-input"]').type('{downArrow}').type('{enter}'); + .type("alpha") + .wait(500) + .type('{downArrow}') + .type('{enter}'); cy.get('[data-cy="delete-topic-icon"]').last().click();