diff --git a/build.gradle b/build.gradle index 03f4f5bd3a4..62062237652 100644 --- a/build.gradle +++ b/build.gradle @@ -68,6 +68,8 @@ subprojects { exclude(group: "org.hamcrest", module: "hamcrest-core") exclude(group: "org.hamcrest", module: "hamcrest-library") exclude(group: "org.springframework.boot", module: "spring-boot-starter-logging") + exclude(group: "org.apache.directory.server", module: "apacheds-core") + exclude(group: "org.apache.directory.server", module: "apacheds-protocol-ldap") exclude(group: "org.skyscreamer", module: "jsonassert") exclude(group: "com.vaadin.external.google", module: "android-json") exclude(group: "com.unboundid.components", module: "json") @@ -126,8 +128,11 @@ subprojects { // gradle might stop the test run due to the failFast but still concludes with BUILD SUCCESSFUL (if the retry is successful) failFast = false useJUnitPlatform() - // Reduced from 1024m to 640m - unit tests don't need as much as integration tests - jvmArgs += ["-Xmx640m", + // Increased to 1536m for Spring Boot 4 compatibility + jvmArgs += ["-Xmx1536m", + "-Xms512m", + "-XX:MaxMetaspaceSize=512m", + "-XX:+UseG1GC", "-XX:+StartAttachListener", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/var/log/uaa-tests.hprof" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c87bb9fa917..2b42b08f350 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,9 +21,10 @@ orgJson = "20251224" passay = "2.0.0" selenium = "4.44.0" sonarqube = "7.3.0.8198" -springBoot = "3.5.14" +springBoot = "4.0.6" springDependencyManagement = "1.1.7" -springDocOpenapi = "2.8.17" +springDocOpenapi = "3.0.2" +springRetry = "2.0.12" statsdClient = "3.1.0" unboundIdScimSdk = "2.0.0" velocity = "2.4.1" @@ -55,6 +56,7 @@ velocity = { module = "org.apache.velocity:velocity-engine-core", version.ref = xmlSecurity = { module = "org.apache.santuario:xmlsec", version.ref = "xmlSecurity" } # AspectJ +aspectJRt = { module = "org.aspectj:aspectjrt" } aspectJWeaver = { module = "org.aspectj:aspectjweaver" } # Awaitility @@ -75,7 +77,8 @@ eclipseJgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version.ref = "ecl # FasterXML Jackson jacksonAnnotations = { module = "com.fasterxml.jackson.core:jackson-annotations" } -jacksonDatabind = { module = "com.fasterxml.jackson.core:jackson-databind" } +jacksonDatabind = { module = "tools.jackson.core:jackson-databind" } +jacksonDataformatYaml = { module = "tools.jackson.dataformat:jackson-dataformat-yaml" } # Flyway flywayCore = { module = "org.flywaydb:flyway-core" } @@ -154,6 +157,7 @@ springBeans = { module = "org.springframework:spring-beans" } springContext = { module = "org.springframework:spring-context" } springContextSupport = { module = "org.springframework:spring-context-support" } springJdbc = { module = "org.springframework:spring-jdbc" } +springRetry = { module ="org.springframework.retry:spring-retry", version.ref = "springRetry" } springTest = { module = "org.springframework:spring-test" } springTx = { module = "org.springframework:spring-tx" } springWeb = { module = "org.springframework:spring-web" } @@ -161,12 +165,17 @@ springWebMvc = { module = "org.springframework:spring-webmvc" } # Spring Boot springBootBom = { module = "org.springframework.boot:spring-boot-dependencies", version.ref = "springBoot" } +springBootFlyway = { module = "org.springframework.boot:spring-boot-flyway" } +springBootJdbc = { module = "org.springframework.boot:spring-boot-jdbc" } +springBootSql = { module = "org.springframework.boot:spring-boot-sql" } springBootStarter = { module = "org.springframework.boot:spring-boot-starter" } springBootStarterLog4j2 = { module = "org.springframework.boot:spring-boot-starter-log4j2" } springBootStarterMail = { module = "org.springframework.boot:spring-boot-starter-mail" } springBootStarterTest = { module = "org.springframework.boot:spring-boot-starter-test" } springBootStarterTomcat = { module = "org.springframework.boot:spring-boot-starter-tomcat" } +springBootStarterTomcatRuntime = { module = "org.springframework.boot:spring-boot-starter-tomcat-runtime" } springBootStarterWeb = { module = "org.springframework.boot:spring-boot-starter-web" } +springBootTransaction = { module = "org.springframework.boot:spring-boot-transaction" } # Spring Data springLdapCore = { module = "org.springframework.ldap:spring-ldap-core" } @@ -178,6 +187,7 @@ springDocOpenapi = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui springRestdocs = { module = "org.springframework.restdocs:spring-restdocs-mockmvc" } # Spring Security +springSecurityAccess = { module = "org.springframework.security:spring-security-access" } springSecurityConfig = { module = "org.springframework.security:spring-security-config" } springSecurityCore = { module = "org.springframework.security:spring-security-core" } springSecurityLdap = { module = "org.springframework.security:spring-security-ldap" } diff --git a/metrics-data/src/main/java/org/cloudfoundry/identity/uaa/util/JsonUtils.java b/metrics-data/src/main/java/org/cloudfoundry/identity/uaa/util/JsonUtils.java index 48eb6ccd8d9..ea2ed7e69f9 100644 --- a/metrics-data/src/main/java/org/cloudfoundry/identity/uaa/util/JsonUtils.java +++ b/metrics-data/src/main/java/org/cloudfoundry/identity/uaa/util/JsonUtils.java @@ -15,19 +15,30 @@ package org.cloudfoundry.identity.uaa.util; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JsonParser; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.cfg.ConstructorDetector; +import tools.jackson.databind.cfg.DateTimeFeature; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.core.JacksonException; -import java.io.IOException; import java.io.Serial; import java.util.Date; import java.util.Map; public class JsonUtils { - private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper objectMapper = JsonMapper.builder() + .enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) + .enable(SerializationFeature.FAIL_ON_EMPTY_BEANS) + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .constructorDetector(ConstructorDetector.DEFAULT.withAllowImplicitWithDefaultConstructor(false)) + .build(); private JsonUtils() { throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); @@ -36,7 +47,7 @@ private JsonUtils() { public static String writeValueAsString(Object object) throws JsonUtilException { try { return objectMapper.writeValueAsString(object); - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -44,7 +55,7 @@ public static String writeValueAsString(Object object) throws JsonUtilException public static byte[] writeValueAsBytes(Object object) throws JsonUtilException { try { return objectMapper.writeValueAsBytes(object); - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -56,7 +67,7 @@ public static T readValue(String s, Class clazz) throws JsonUtilException } else { return null; } - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -65,7 +76,7 @@ public static Map readValueAsMap(final String input) { try { final JsonNode rootNode = objectMapper.readTree(input); return getNodeAsMap(rootNode); - } catch (final JsonProcessingException e) { + } catch (final JacksonException e) { throw new JsonUtilException(e); } } @@ -77,7 +88,7 @@ public static T readValue(byte[] data, Class clazz) throws JsonUtilExcept } else { return null; } - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -89,7 +100,7 @@ public static T readValue(String s, TypeReference typeReference) { } else { return null; } - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -101,7 +112,7 @@ public static T readValue(byte[] data, TypeReference typeReference) { } else { return null; } - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -113,7 +124,7 @@ public static T convertValue(Object object, Class toClazz) throws JsonUti } else { return objectMapper.convertValue(object, toClazz); } - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | JacksonException e) { throw new JsonUtilException(e); } } @@ -121,7 +132,7 @@ public static T convertValue(Object object, Class toClazz) throws JsonUti public static JsonNode readTree(JsonParser p) { try { return objectMapper.readTree(p); - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -133,7 +144,7 @@ public static JsonNode readTree(String s) { } else { return null; } - } catch (IOException e) { + } catch (JacksonException e) { throw new JsonUtilException(e); } } @@ -170,7 +181,7 @@ public static String serializeExcludingProperties(Object object, String... prope public static String getNodeAsString(JsonNode node, String fieldName, String defaultValue) { JsonNode typeNode = node.get(fieldName); - return typeNode == null ? defaultValue : typeNode.asText(defaultValue); + return typeNode == null ? defaultValue : typeNode.asString(defaultValue); } public static int getNodeAsInt(JsonNode node, String fieldName, int defaultValue) { diff --git a/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/metrics/MetricsQueueTest.java b/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/metrics/MetricsQueueTest.java index 31aee824787..04d32880435 100644 --- a/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/metrics/MetricsQueueTest.java +++ b/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/metrics/MetricsQueueTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.metrics; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/util/JsonUtilsTest.java b/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/util/JsonUtilsTest.java index 0353aab762c..8dccc30d4d0 100644 --- a/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/util/JsonUtilsTest.java +++ b/metrics-data/src/test/java/org/cloudfoundry/identity/uaa/util/JsonUtilsTest.java @@ -1,19 +1,17 @@ package org.cloudfoundry.identity.uaa.util; -import com.fasterxml.jackson.core.JacksonException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.core.JsonParser; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.annotation.JsonDeserialize; import org.cloudfoundry.identity.uaa.metrics.UrlGroup; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ValueDeserializer; -import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.List; @@ -141,83 +139,82 @@ void cannotInstantiate() { } @Test - - void throwsException_writeValueAsString() throws JsonProcessingException { + void throwsException_writeValueAsString() throws JacksonException { JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.writeValueAsString(new Object()) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.lang.Object"); + assertThat(exception.getMessage()).startsWith("tools.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.lang.Object"); } @Test - void throwsException_writeValueAsBytes() throws JsonProcessingException { + void throwsException_writeValueAsBytes() throws JacksonException { JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.writeValueAsBytes(new Object()) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.lang.Object"); + assertThat(exception.getMessage()).startsWith("tools.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.lang.Object"); } @Test - void throwsException_readValue() throws JsonProcessingException { + void throwsException_readValue() throws JacksonException { JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readValue("invalid json", String.class) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'invalid'"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unrecognized token 'invalid'"); exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readValue("invalid json".getBytes(), String.class) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'invalid'"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unrecognized token 'invalid'"); exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readValue("invalid json", new TypeReference() {}) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'invalid'"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unrecognized token 'invalid'"); exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readValue("invalid json".getBytes(), new TypeReference() {}) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'invalid'"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unrecognized token 'invalid'"); } @Test - void throwsException_readValueAsMap() throws JsonProcessingException { + void throwsException_readValueAsMap() throws JacksonException { JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readValueAsMap("invalid json") ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'invalid'"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unrecognized token 'invalid'"); } @Test - void throwsException_convertValue() throws JsonProcessingException { + void throwsException_convertValue() throws JacksonException { JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.convertValue(Boolean.TRUE, Integer.class) ); - assertThat(exception.getMessage()).startsWith("java.lang.IllegalArgumentException: Cannot deserialize value of type `java.lang.Integer` from Boolean value"); + assertThat(exception.getMessage()).startsWith("tools.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.Integer` from Boolean value"); } @Test - void throwsException_readTree() throws JsonProcessingException { + void throwsException_readTree() throws JacksonException { assertThat(JsonUtils.readTree((String)null)).isNull(); JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readTree("invalid json") ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'invalid'"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unrecognized token 'invalid'"); } @Test - void throwsException_readTreeWithParserArg() throws JsonProcessingException { + void throwsException_readTreeWithParserArg() throws JacksonException { JsonUtils.JsonUtilException exception = assertThrows(JsonUtils.JsonUtilException.class, () -> JsonUtils.readValue("{'valid':'json'}", SerializerTestObject.class) ); - assertThat(exception.getMessage()).startsWith("com.fasterxml.jackson.core.JsonParseException: Unexpected character"); + assertThat(exception.getMessage()).startsWith("tools.jackson.core.exc.StreamReadException: Unexpected character"); } @Test - void readNodes() throws JsonProcessingException { + void readNodes() throws JacksonException { JsonUtils.readValue(""" { "date": "1320105600000", @@ -253,10 +250,10 @@ private Object getTestObject() { private static class SerializerTestObject { } - private static class TestDeserializer extends JsonDeserializer { + private static class TestDeserializer extends ValueDeserializer { @Override - public SerializerTestObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { + public SerializerTestObject deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = JsonUtils.readTree(p); JsonUtils.getNodeAsBoolean(node, "invalid", true); JsonUtils.getNodeAsInt(node, "invalid", 0); diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/approval/Approval.java b/model/src/main/java/org/cloudfoundry/identity/uaa/approval/Approval.java index f16d36b36f3..be9e455b849 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/approval/Approval.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/approval/Approval.java @@ -19,8 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import org.cloudfoundry.identity.uaa.impl.JsonDateDeserializer; import org.cloudfoundry.identity.uaa.impl.JsonDateSerializer; import org.cloudfoundry.identity.uaa.approval.impl.ApprovalsJsonDeserializer; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/approval/impl/ApprovalsJsonDeserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/approval/impl/ApprovalsJsonDeserializer.java index a3a70a89e70..8b0e11845f4 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/approval/impl/ApprovalsJsonDeserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/approval/impl/ApprovalsJsonDeserializer.java @@ -1,13 +1,12 @@ package org.cloudfoundry.identity.uaa.approval.impl; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; import org.cloudfoundry.identity.uaa.approval.Approval; import org.cloudfoundry.identity.uaa.approval.Approval.ApprovalStatus; +import tools.jackson.databind.ValueDeserializer; -import java.io.IOException; import java.util.Date; /******************************************************************************* @@ -22,14 +21,14 @@ * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. *******************************************************************************/ -public class ApprovalsJsonDeserializer extends JsonDeserializer { +public class ApprovalsJsonDeserializer extends ValueDeserializer { @Override - public Approval deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + public Approval deserialize(JsonParser jp, DeserializationContext ctxt) { Approval approval = new Approval(); while (jp.nextToken() != JsonToken.END_OBJECT) { - if (jp.getCurrentToken() == JsonToken.FIELD_NAME) { - String fieldName = jp.getCurrentName(); + if (jp.currentToken() == JsonToken.PROPERTY_NAME) { + String fieldName = jp.currentName(); jp.nextToken(); if ("userId".equalsIgnoreCase(fieldName)) { approval.setUserId(jp.readValueAs(String.class)); diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/client/Jackson2ArrayOrStringDeserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/client/Jackson2ArrayOrStringDeserializer.java index 36c74345e81..f07aca709f5 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/client/Jackson2ArrayOrStringDeserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/client/Jackson2ArrayOrStringDeserializer.java @@ -1,15 +1,13 @@ package org.cloudfoundry.identity.uaa.client; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.databind.type.SimpleType; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.deser.std.StdDeserializer; import org.springframework.util.StringUtils; -import java.io.IOException; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; @@ -30,14 +28,19 @@ public Jackson2ArrayOrStringDeserializer() { @Override public JavaType getValueType() { - return SimpleType.construct(String.class); + return getValueType(null); } @Override - public Set deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { - JsonToken token = jp.getCurrentToken(); + public JavaType getValueType(DeserializationContext ctxt) { + return ctxt != null ? ctxt.constructType(String.class) : super.getValueType(ctxt); + } + + @Override + public Set deserialize(JsonParser jp, DeserializationContext ctxt) { + JsonToken token = jp.currentToken(); if (token.isScalarValue()) { - String list = jp.getText(); + String list = jp.getString(); list = list.replaceAll("\\s+", ","); return new LinkedHashSet<>(Arrays.asList(StringUtils.commaDelimitedListToStringArray(list))); } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/client/UaaClientDetails.java b/model/src/main/java/org/cloudfoundry/identity/uaa/client/UaaClientDetails.java index e5364693939..92418c12927 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/client/UaaClientDetails.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/client/UaaClientDetails.java @@ -6,7 +6,9 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import tools.jackson.databind.annotation.JsonDeserialize; import org.cloudfoundry.identity.uaa.oauth.provider.ClientDetails; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityCoreVersion; @@ -78,7 +80,7 @@ public class UaaClientDetails implements ClientDetails { @JsonProperty("refresh_token_validity") private Integer refreshTokenValiditySeconds; - @com.fasterxml.jackson.annotation.JsonIgnore + @JsonSetter(nulls = Nulls.AS_EMPTY) private transient Map additionalInformation = new LinkedHashMap<>(); @JsonProperty("client_jwt_config") diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/codestore/ExpiringCode.java b/model/src/main/java/org/cloudfoundry/identity/uaa/codestore/ExpiringCode.java index d102ec4e050..549ba49cc93 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/codestore/ExpiringCode.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/codestore/ExpiringCode.java @@ -14,16 +14,12 @@ package org.cloudfoundry.identity.uaa.codestore; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Data; import java.sql.Timestamp; import java.util.Objects; @Data -@JsonSerialize -@JsonDeserialize public class ExpiringCode { private String code; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializer.java index da8cab1d8a7..d49a19adac4 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializer.java @@ -13,35 +13,34 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.impl; -import com.fasterxml.jackson.core.JsonLocation; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; -import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import tools.jackson.core.exc.StreamReadException; +import tools.jackson.databind.ValueDeserializer; + /** * JSON deserializer for Jackson to handle regular date instances as timestamps * in ISO format. */ -public class JsonDateDeserializer extends JsonDeserializer { +public class JsonDateDeserializer extends ValueDeserializer { public static final String DATE_FORMATTER = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; @Override - public Date deserialize(JsonParser parser, DeserializationContext context) throws IOException { - return getDate(parser.getText(), parser.getCurrentLocation()); + public Date deserialize(JsonParser parser, DeserializationContext context) { + return getDate(parser.getString(), parser); } - public static Date getDate(String text, JsonLocation loc) throws IOException { + public static Date getDate(String text, JsonParser parser) { try { return new SimpleDateFormat(DATE_FORMATTER).parse(text); } catch (ParseException e) { - throw new JsonParseException("Could not parse date:" + text, loc, e); + throw new StreamReadException(parser, "Could not parse date:" + text, e); } } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializer.java index 5a0154f8484..cb9d80877ea 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializer.java @@ -14,24 +14,24 @@ package org.cloudfoundry.identity.uaa.impl; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; -import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; + import static org.cloudfoundry.identity.uaa.impl.JsonDateDeserializer.DATE_FORMATTER; /** * JSON serializer for Jackson to handle regular date instances as timestamps in * ISO format. */ -public class JsonDateSerializer extends JsonSerializer { +public class JsonDateSerializer extends ValueSerializer { @Override - public void serialize(Date date, JsonGenerator generator, SerializerProvider provider) throws IOException { + public void serialize(Date date, JsonGenerator generator, SerializationContext provider) { String formatted = new SimpleDateFormat(DATE_FORMATTER).format(date); generator.writeString(formatted); } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/ClientJwtCredential.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/ClientJwtCredential.java index 9dbc0ebae50..98f39e8b174 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/ClientJwtCredential.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/ClientJwtCredential.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import lombok.Data; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.springframework.util.StringUtils; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/grant/AuthorizationCodeAccessTokenProvider.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/grant/AuthorizationCodeAccessTokenProvider.java index f257bd17f0f..1f3954f0913 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/grant/AuthorizationCodeAccessTokenProvider.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/client/grant/AuthorizationCodeAccessTokenProvider.java @@ -80,7 +80,7 @@ public String obtainAuthorizationCode(OAuth2ProtectedResourceDetails details, Ac ResponseExtractor> extractor = new ResponseExtractor<>() { @Override public ResponseEntity extractData(ClientHttpResponse response) throws IOException { - if (response.getHeaders().containsKey("Set-Cookie")) { + if (response.getHeaders().containsHeader("Set-Cookie")) { copy.setCookie(response.getHeaders().getFirst("Set-Cookie")); } return delegate.extractData(response); diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessToken.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessToken.java index 77fb37ab00a..fd7bd5498ca 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessToken.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessToken.java @@ -1,7 +1,7 @@ package org.cloudfoundry.identity.uaa.oauth.common; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import java.util.Date; import java.util.Map; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Deserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Deserializer.java index b94dd986551..472fa805962 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Deserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Deserializer.java @@ -1,14 +1,13 @@ package org.cloudfoundry.identity.uaa.oauth.common; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.deser.std.StdDeserializer; import org.cloudfoundry.identity.uaa.oauth.common.util.OAuth2Utils; import org.cloudfoundry.identity.uaa.oauth.token.CompositeToken; +import tools.jackson.core.exc.StreamReadException; -import java.io.IOException; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @@ -34,7 +33,7 @@ public OAuth2AccessTokenJackson2Deserializer() { } @Override - public OAuth2AccessToken deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + public OAuth2AccessToken deserialize(JsonParser jp, DeserializationContext ctxt) { String idTokenValue = null; String tokenValue = null; @@ -48,18 +47,18 @@ public OAuth2AccessToken deserialize(JsonParser jp, DeserializationContext ctxt) String name = jp.currentName(); jp.nextToken(); if (OAuth2AccessToken.ACCESS_TOKEN.equals(name)) { - tokenValue = jp.getText(); + tokenValue = jp.getString(); } else if (CompositeToken.ID_TOKEN.equals(name)) { - idTokenValue = jp.getText(); + idTokenValue = jp.getString(); } else if (OAuth2AccessToken.TOKEN_TYPE.equals(name)) { - tokenType = jp.getText(); + tokenType = jp.getString(); } else if (OAuth2AccessToken.REFRESH_TOKEN.equals(name)) { - refreshToken = jp.getText(); + refreshToken = jp.getString(); } else if (OAuth2AccessToken.EXPIRES_IN.equals(name)) { try { expiresIn = jp.getLongValue(); - } catch (JsonParseException e) { - expiresIn = Long.valueOf(jp.getText()); + } catch (StreamReadException e) { + expiresIn = Long.valueOf(jp.getString()); } } else if (OAuth2AccessToken.SCOPE.equals(name)) { scope = parseScope(jp); @@ -83,15 +82,15 @@ public OAuth2AccessToken deserialize(JsonParser jp, DeserializationContext ctxt) return accessToken; } - private Set parseScope(JsonParser jp) throws IOException { + private Set parseScope(JsonParser jp) { Set scope; - if (jp.getCurrentToken() == JsonToken.START_ARRAY) { + if (jp.currentToken() == JsonToken.START_ARRAY) { scope = new TreeSet<>(); while (jp.nextToken() != JsonToken.END_ARRAY) { scope.add(jp.getValueAsString()); } } else { - String text = jp.getText(); + String text = jp.getString(); scope = OAuth2Utils.parseParameterList(text); } return scope; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Serializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Serializer.java index dd590de212d..b68ecccff3e 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Serializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2Serializer.java @@ -1,12 +1,11 @@ package org.cloudfoundry.identity.uaa.oauth.common; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.ser.std.StdSerializer; import org.cloudfoundry.identity.uaa.oauth.token.CompositeToken; import org.springframework.util.Assert; +import tools.jackson.databind.SerializationContext; -import java.io.IOException; import java.util.Date; import java.util.Map; import java.util.Set; @@ -30,21 +29,21 @@ public OAuth2AccessTokenJackson2Serializer() { } @Override - public void serialize(OAuth2AccessToken token, JsonGenerator jgen, SerializerProvider provider) throws IOException { + public void serialize(OAuth2AccessToken token, JsonGenerator jgen, SerializationContext provider) { jgen.writeStartObject(); - jgen.writeStringField(OAuth2AccessToken.ACCESS_TOKEN, token.getValue()); - jgen.writeStringField(OAuth2AccessToken.TOKEN_TYPE, token.getTokenType()); + jgen.writeStringProperty(OAuth2AccessToken.ACCESS_TOKEN, token.getValue()); + jgen.writeStringProperty(OAuth2AccessToken.TOKEN_TYPE, token.getTokenType()); if (token instanceof CompositeToken compositeToken && compositeToken.getIdTokenValue() != null) { - jgen.writeStringField(CompositeToken.ID_TOKEN, compositeToken.getIdTokenValue()); + jgen.writeStringProperty(CompositeToken.ID_TOKEN, compositeToken.getIdTokenValue()); } OAuth2RefreshToken refreshToken = token.getRefreshToken(); if (refreshToken != null) { - jgen.writeStringField(OAuth2AccessToken.REFRESH_TOKEN, refreshToken.getValue()); + jgen.writeStringProperty(OAuth2AccessToken.REFRESH_TOKEN, refreshToken.getValue()); } Date expiration = token.getExpiration(); if (expiration != null) { long now = System.currentTimeMillis(); - jgen.writeNumberField(OAuth2AccessToken.EXPIRES_IN, (expiration.getTime() - now) / 1000); + jgen.writeNumberProperty(OAuth2AccessToken.EXPIRES_IN, (expiration.getTime() - now) / 1000); } Set scope = token.getScope(); if (scope != null && !scope.isEmpty()) { @@ -54,11 +53,11 @@ public void serialize(OAuth2AccessToken token, JsonGenerator jgen, SerializerPro scopes.append(s); scopes.append(" "); } - jgen.writeStringField(OAuth2AccessToken.SCOPE, scopes.substring(0, scopes.length() - 1)); + jgen.writeStringProperty(OAuth2AccessToken.SCOPE, scopes.substring(0, scopes.length() - 1)); } Map additionalInformation = token.getAdditionalInformation(); for (Map.Entry entry : additionalInformation.entrySet()) { - jgen.writeObjectField(entry.getKey(), entry.getValue()); + jgen.writePOJOProperty(entry.getKey(), entry.getValue()); } jgen.writeEndObject(); } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2Exception.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2Exception.java index c2c01eec38d..ed574b87189 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2Exception.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2Exception.java @@ -1,7 +1,7 @@ package org.cloudfoundry.identity.uaa.oauth.common.exceptions; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import java.util.HashMap; import java.util.Map; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Deserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Deserializer.java index 2bc0d1658f5..ca38f59d810 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Deserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Deserializer.java @@ -1,12 +1,11 @@ package org.cloudfoundry.identity.uaa.oauth.common.exceptions; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.deser.std.StdDeserializer; import org.cloudfoundry.identity.uaa.oauth.common.util.OAuth2Utils; -import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,16 +31,16 @@ public OAuth2ExceptionJackson2Deserializer() { } @Override - public OAuth2Exception deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + public OAuth2Exception deserialize(JsonParser jp, DeserializationContext ctxt) { - JsonToken t = jp.getCurrentToken(); + JsonToken t = jp.currentToken(); if (t == JsonToken.START_OBJECT) { t = jp.nextToken(); } Map errorParams = new HashMap<>(); - for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { + for (; t == JsonToken.PROPERTY_NAME; t = jp.nextToken()) { // Must point to field name - String fieldName = jp.getCurrentName(); + String fieldName = jp.currentName(); // And then the value... t = jp.nextToken(); // Note: must handle null explicitly here; value deserializers won't @@ -53,7 +52,7 @@ public OAuth2Exception deserialize(JsonParser jp, DeserializationContext ctxt) t } else if (t == JsonToken.START_OBJECT) { value = jp.readValueAs(Map.class); } else { - value = jp.getText(); + value = jp.getString(); } errorParams.put(fieldName, value); } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Serializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Serializer.java index 5a5761b7676..f895a98d012 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Serializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/common/exceptions/OAuth2ExceptionJackson2Serializer.java @@ -1,12 +1,12 @@ package org.cloudfoundry.identity.uaa.oauth.common.exceptions; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.ser.std.StdSerializer; -import java.io.IOException; import java.util.Map.Entry; +import tools.jackson.databind.SerializationContext; + /** * Moved class implementation of from spring-security-oauth2 into UAA * @@ -26,15 +26,15 @@ public OAuth2ExceptionJackson2Serializer() { } @Override - public void serialize(OAuth2Exception value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + public void serialize(OAuth2Exception value, JsonGenerator jgen, SerializationContext provider) { jgen.writeStartObject(); - jgen.writeStringField(OAuth2Exception.ERROR, value.getOAuth2ErrorCode()); - jgen.writeStringField(OAuth2Exception.DESCRIPTION, value.getMessage()); + jgen.writeStringProperty(OAuth2Exception.ERROR, value.getOAuth2ErrorCode()); + jgen.writeStringProperty(OAuth2Exception.DESCRIPTION, value.getMessage()); if (value.getAdditionalInformation() != null) { for (Entry entry : value.getAdditionalInformation().entrySet()) { String key = entry.getKey(); String add = entry.getValue(); - jgen.writeStringField(key, add); + jgen.writeStringProperty(key, add); } } jgen.writeEndObject(); diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKey.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKey.java index 19a677c2500..971115bafc0 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKey.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKey.java @@ -15,8 +15,8 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import com.nimbusds.jose.HeaderParameterNames; import com.nimbusds.jose.jwk.JWKParameterNames; import org.cloudfoundry.identity.uaa.util.UaaStringUtils; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializer.java index 0a33a1bdf47..4f5fb259314 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializer.java @@ -15,23 +15,23 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; import com.nimbusds.jose.jwk.JWKParameterNames; import org.cloudfoundry.identity.uaa.util.JsonUtils; +import tools.jackson.databind.ValueDeserializer; import java.util.Arrays; /** * See https://tools.ietf.org/html/rfc7517 */ -public class JsonWebKeyDeserializer extends JsonDeserializer { +public class JsonWebKeyDeserializer extends ValueDeserializer { @Override public JsonWebKey deserialize(JsonParser p, DeserializationContext ctxt) { - JsonNode node = JsonUtils.readTree(p); - String kty = node.get(JWKParameterNames.KEY_TYPE).asText("Unknown"); + JsonNode node = p.readValueAsTree(); + String kty = node.get(JWKParameterNames.KEY_TYPE).asString("Unknown"); if (Arrays.stream(JsonWebKey.KeyType.values()).noneMatch(knownKeyType -> knownKeyType.name().equals(kty))) { return null; } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeySerializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeySerializer.java index f93d5930a22..10b562bf1b8 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeySerializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeySerializer.java @@ -15,24 +15,24 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; -import java.io.IOException; import java.util.Map; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; + /** * See https://tools.ietf.org/html/rfc7517 */ -public class JsonWebKeySerializer extends JsonSerializer { +public class JsonWebKeySerializer extends ValueSerializer { @Override - public void serialize(JsonWebKey value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(JsonWebKey value, JsonGenerator gen, SerializationContext serializers) { gen.writeStartObject(); for (Map.Entry entry : value.getKeyProperties().entrySet()) { - gen.writeFieldName(entry.getKey()); - gen.writeObject(entry.getValue()); + gen.writeName(entry.getKey()); + gen.writePOJO(entry.getValue()); } gen.writeEndObject(); } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/CompositeToken.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/CompositeToken.java index 4f1844f61e6..faa80e0a427 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/CompositeToken.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/CompositeToken.java @@ -13,8 +13,8 @@ */ package org.cloudfoundry.identity.uaa.oauth.token; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import org.cloudfoundry.identity.uaa.oauth.common.DefaultOAuth2AccessToken; import org.cloudfoundry.identity.uaa.oauth.common.OAuth2AccessToken; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupport.java b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupport.java index 063218c1dbe..02581a46bc8 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupport.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupport.java @@ -133,7 +133,7 @@ protected OAuth2AccessToken retrieveToken(AccessTokenRequest request, OAuth2Prot ResponseExtractor extractor = new ResponseExtractor<>() { @Override public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { - if (response.getHeaders().containsKey("Set-Cookie")) { + if (response.getHeaders().containsHeader("Set-Cookie")) { copy.setCookie(response.getHeaders().getFirst("Set-Cookie")); } return delegate.extractData(response); diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProvider.java b/model/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProvider.java index a4aa40b3234..7a0c496e8f3 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProvider.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/provider/IdentityProvider.java @@ -15,22 +15,20 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import lombok.Getter; import org.cloudfoundry.identity.uaa.EntityWithAlias; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.springframework.util.StringUtils; - +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.ValueSerializer; import jakarta.validation.constraints.NotNull; -import java.io.IOException; import java.util.Date; import static org.cloudfoundry.identity.uaa.constants.OriginKeys.KEYSTONE; @@ -322,53 +320,53 @@ public void setSerializeConfigRaw(boolean serializeConfigRaw) { this.serializeConfigRaw = serializeConfigRaw; } - public static class IdentityProviderSerializer extends JsonSerializer { + public static class IdentityProviderSerializer extends ValueSerializer { @Override - public void serialize(IdentityProvider value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(IdentityProvider value, JsonGenerator gen, SerializationContext serializers) { gen.writeStartObject(); - gen.writeStringField(FIELD_TYPE, value.getType()); + gen.writeStringProperty(FIELD_TYPE, value.getType()); if (value.isSerializeConfigRaw()) { - gen.writeObjectField(FIELD_CONFIG, value.getConfig()); + gen.writePOJOProperty(FIELD_CONFIG, value.getConfig()); } else { - gen.writeStringField(FIELD_CONFIG, JsonUtils.writeValueAsString(value.getConfig())); + gen.writeStringProperty(FIELD_CONFIG, JsonUtils.writeValueAsString(value.getConfig())); } - gen.writeStringField(FIELD_ID, value.getId()); - gen.writeStringField(FIELD_ORIGIN_KEY, value.getOriginKey()); - gen.writeStringField(FIELD_NAME, value.getName()); - gen.writeNumberField(FIELD_VERSION, value.getVersion()); + gen.writeStringProperty(FIELD_ID, value.getId()); + gen.writeStringProperty(FIELD_ORIGIN_KEY, value.getOriginKey()); + gen.writeStringProperty(FIELD_NAME, value.getName()); + gen.writeNumberProperty(FIELD_VERSION, value.getVersion()); writeDateField(FIELD_CREATED, value.getCreated(), gen); writeDateField(FIELD_LAST_MODIFIED, value.getLastModified(), gen); - gen.writeBooleanField(FIELD_ACTIVE, value.isActive()); - gen.writeStringField(FIELD_IDENTITY_ZONE_ID, value.getIdentityZoneId()); - gen.writeStringField(FIELD_ALIAS_ID, value.getAliasId()); - gen.writeStringField(FIELD_ALIAS_ZID, value.getAliasZid()); + gen.writeBooleanProperty(FIELD_ACTIVE, value.isActive()); + gen.writeStringProperty(FIELD_IDENTITY_ZONE_ID, value.getIdentityZoneId()); + gen.writeStringProperty(FIELD_ALIAS_ID, value.getAliasId()); + gen.writeStringProperty(FIELD_ALIAS_ZID, value.getAliasZid()); gen.writeEndObject(); } - public void writeDateField(String fieldName, Date value, JsonGenerator gen) throws IOException { + public void writeDateField(String fieldName, Date value, JsonGenerator gen) { if (value != null) { - gen.writeNumberField(fieldName, value.getTime()); + gen.writeNumberProperty(fieldName, value.getTime()); } else { - gen.writeNullField(fieldName); + gen.writeNullProperty(fieldName); } } } - public static class IdentityProviderDeserializer extends JsonDeserializer { + public static class IdentityProviderDeserializer extends ValueDeserializer { @Override public IdentityProvider deserialize(JsonParser jp, DeserializationContext ctxt) { IdentityProvider result = new IdentityProvider(); //determine the type of IdentityProvider - JsonNode node = JsonUtils.readTree(jp); + JsonNode node = jp.readValueAsTree(); String type = getNodeAsString(node, FIELD_TYPE, UNKNOWN); //deserialize based on type String config; JsonNode configNode = node.get("config"); if (configNode == null) { config = null; - } else if (configNode.isTextual()) { - config = configNode.textValue(); + } else if (configNode.isString()) { + config = configNode.asString(); } else { config = configNode.toString(); } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimCore.java b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimCore.java index d0764936f2f..013fedd26e0 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimCore.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimCore.java @@ -13,6 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.scim; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.util.Assert; @@ -28,6 +29,7 @@ public abstract class ScimCore { private ScimMeta meta = new ScimMeta(); + @JsonCreator protected ScimCore(String id) { this.id = id; } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimGroup.java b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimGroup.java index faede273a1e..b8e381d5ff0 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimGroup.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimGroup.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.scim; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.List; @@ -24,7 +24,7 @@ import static java.util.Optional.ofNullable; -@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class ScimGroup extends ScimCore { diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimMeta.java b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimMeta.java index 19cab607d42..b76b3c7f591 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimMeta.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimMeta.java @@ -16,8 +16,8 @@ import java.util.Date; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import org.cloudfoundry.identity.uaa.impl.JsonDateDeserializer; import org.cloudfoundry.identity.uaa.impl.JsonDateSerializer; @@ -40,7 +40,7 @@ public ScimMeta(Date created, Date lastModified, int version) { this.version = version; } - @JsonSerialize(using = JsonDateSerializer.class, include = JsonSerialize.Inclusion.NON_NULL) + @JsonSerialize(using = JsonDateSerializer.class) public Date getCreated() { return created; } @@ -50,7 +50,7 @@ public void setCreated(Date created) { this.created = created; } - @JsonSerialize(using = JsonDateSerializer.class, include = JsonSerialize.Inclusion.NON_NULL) + @JsonSerialize(using = JsonDateSerializer.class) public Date getLastModified() { return lastModified; } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimUser.java b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimUser.java index 7801586de59..0cd82c61419 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimUser.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/ScimUser.java @@ -34,8 +34,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import lombok.Setter; @@ -588,7 +588,8 @@ public void setSalt(String salt) { this.salt = salt; } - @JsonSerialize(using = JsonDateSerializer.class, include = JsonSerialize.Inclusion.NON_NULL) + @JsonSerialize(using = JsonDateSerializer.class) + @JsonInclude(JsonInclude.Include.NON_NULL) public Date getPasswordLastModified() { if (passwordLastModified != null) { return passwordLastModified; diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/impl/ScimUserJsonDeserializer.java b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/impl/ScimUserJsonDeserializer.java index eb781d6c9ba..2726d835949 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/scim/impl/ScimUserJsonDeserializer.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/scim/impl/ScimUserJsonDeserializer.java @@ -13,30 +13,29 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.scim.impl; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.exc.UnrecognizedPropertyException; import org.cloudfoundry.identity.uaa.approval.Approval; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.impl.JsonDateDeserializer; import org.cloudfoundry.identity.uaa.scim.ScimMeta; import org.cloudfoundry.identity.uaa.scim.ScimUser; +import tools.jackson.databind.ValueDeserializer; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; -public class ScimUserJsonDeserializer extends JsonDeserializer { +public class ScimUserJsonDeserializer extends ValueDeserializer { @Override - public ScimUser deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + public ScimUser deserialize(JsonParser jp, DeserializationContext ctxt) { ScimUser user = new ScimUser(); while (jp.nextToken() != JsonToken.END_OBJECT) { - if (jp.getCurrentToken() == JsonToken.FIELD_NAME) { - String fieldName = jp.getCurrentName(); + if (jp.currentToken() == JsonToken.PROPERTY_NAME) { + String fieldName = jp.currentName(); jp.nextToken(); if ("id".equalsIgnoreCase(fieldName)) { @@ -96,7 +95,7 @@ public ScimUser deserialize(JsonParser jp, DeserializationContext ctxt) throws I user.setSalt(jp.readValueAs(String.class)); } else if ("passwordLastModified".equalsIgnoreCase(fieldName)) { if (jp.getValueAsString() != null) { - user.setPasswordLastModified(JsonDateDeserializer.getDate(jp.getValueAsString(), jp.getCurrentLocation())); + user.setPasswordLastModified(JsonDateDeserializer.getDate(jp.getValueAsString(), jp)); } } else if ("approvals".equalsIgnoreCase(fieldName)) { user.setApprovals(new HashSet<>(Arrays.asList(jp.readValueAs(Approval[].class)))); @@ -109,7 +108,7 @@ public ScimUser deserialize(JsonParser jp, DeserializationContext ctxt) throws I user.setPreviousLogonTime(jp.getValueAsLong()); } } else { - throw new UnrecognizedPropertyException("unrecognized field", jp.getCurrentLocation(), + throw UnrecognizedPropertyException.from(jp, ScimUser.class, fieldName, Collections.emptySet()); } } diff --git a/model/src/main/java/org/cloudfoundry/identity/uaa/zone/ClientSecretPolicy.java b/model/src/main/java/org/cloudfoundry/identity/uaa/zone/ClientSecretPolicy.java index 419d7d40b46..fc6c0c47103 100644 --- a/model/src/main/java/org/cloudfoundry/identity/uaa/zone/ClientSecretPolicy.java +++ b/model/src/main/java/org/cloudfoundry/identity/uaa/zone/ClientSecretPolicy.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.cloudfoundry.identity.uaa.authentication.GenericPasswordPolicy; -@JsonIgnoreProperties(ignoreUnknown = true) +@JsonIgnoreProperties(ignoreUnknown = true, value = {"expireSecretInMonths"}) public class ClientSecretPolicy extends GenericPasswordPolicy { @Override @@ -68,10 +68,12 @@ public ClientSecretPolicy(int minLength, this.setExpireSecretInMonths(expireSecretInMonths); } + @JsonIgnore public int getExpireSecretInMonths() { return expireSecretInMonths; } + @JsonIgnore public ClientSecretPolicy setExpireSecretInMonths(int expireSecretInMonths) { this.expireSecretInMonths = expireSecretInMonths; return this; diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/account/OpenIdConfigurationTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/account/OpenIdConfigurationTests.java index 5205c21b2ae..306909ac989 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/account/OpenIdConfigurationTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/account/OpenIdConfigurationTests.java @@ -1,11 +1,11 @@ package org.cloudfoundry.identity.uaa.account; -import com.fasterxml.jackson.core.JsonProcessingException; import org.cloudfoundry.identity.uaa.test.JsonTranslation; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.json.BasicJsonTester; import org.springframework.test.util.ReflectionTestUtils; +import tools.jackson.core.JacksonException; import java.lang.reflect.Field; @@ -51,7 +51,7 @@ void defaultClaims() { } @Test - void allNulls() throws JsonProcessingException { + void allNulls() throws JacksonException { OpenIdConfiguration openIdConfiguration = new OpenIdConfiguration(null, null); for (Field field : OpenIdConfiguration.class.getDeclaredFields()) { diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/client/UaaClientDetailsTest.java b/model/src/test/java/org/cloudfoundry/identity/uaa/client/UaaClientDetailsTest.java index afc486e7195..4eabfb44843 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/client/UaaClientDetailsTest.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/client/UaaClientDetailsTest.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.client; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -152,7 +154,7 @@ void jsonSerialize() throws Exception { UaaClientDetails details = new UaaClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER"); details.setClientId("foo"); details.setClientSecret("bar"); - String value = new ObjectMapper().writeValueAsString(details); + String value = new JsonMapper().writeValueAsString(details); assertThat(value).contains("client_id") .contains("client_secret") .contains("authorized_grant_types") @@ -164,14 +166,14 @@ void jsonSerializeAdditionalInformation() throws Exception { UaaClientDetails details = new UaaClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER"); details.setClientId("foo"); details.setAdditionalInformation(Collections.singletonMap("foo", "bar")); - String value = new ObjectMapper().writeValueAsString(details); + String value = new JsonMapper().writeValueAsString(details); assertThat(value).contains("\"foo\":\"bar\""); } @Test void jsonDeserialize() throws Exception { String value = "{\"foo\":\"bar\",\"client_id\":\"foo\",\"scope\":[\"bar\",\"foo\"],\"authorized_grant_types\":[\"authorization_code\"],\"authorities\":[\"ROLE_USER\"]}"; - UaaClientDetails details = new ObjectMapper().readValue(value, UaaClientDetails.class); + UaaClientDetails details = new JsonMapper().readValue(value, UaaClientDetails.class); UaaClientDetails expected = new UaaClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER"); expected.setAdditionalInformation(Collections.singletonMap("foo", (Object) "bar")); assertThat(details).isEqualTo(expected); @@ -181,7 +183,7 @@ void jsonDeserialize() throws Exception { void jsonDeserializeWithArraysAsStrings() throws Exception { // Collection values can be deserialized from space or comma-separated lists String value = "{\"foo\":\"bar\",\"client_id\":\"foo\",\"scope\":\"bar foo\",\"authorized_grant_types\":\"authorization_code\",\"authorities\":\"ROLE_USER,ROLE_ADMIN\"}"; - UaaClientDetails details = new ObjectMapper().readValue(value, UaaClientDetails.class); + UaaClientDetails details = new JsonMapper().readValue(value, UaaClientDetails.class); UaaClientDetails expected = new UaaClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER,ROLE_ADMIN"); expected.setAdditionalInformation(Collections.singletonMap("foo", (Object) "bar")); assertThat(details).isEqualTo(expected); diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializerTest.java b/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializerTest.java index 914dff369c0..75a911a8642 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializerTest.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateDeserializerTest.java @@ -14,10 +14,10 @@ package org.cloudfoundry.identity.uaa.impl; -import com.fasterxml.jackson.core.JsonLocation; import org.junit.jupiter.api.Test; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.json.JsonMapper; -import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -30,8 +30,9 @@ class JsonDateDeserializerTest { Exception exceptionOccured; @Test - void parsing() throws IOException, ParseException { - Date d = JsonDateDeserializer.getDate(testDateString, new JsonLocation(null, 22, 0, 0)); + void parsing() throws ParseException { + JsonParser jp = JsonMapper.shared().createParser("\"" + testDateString + "\""); + Date d = JsonDateDeserializer.getDate(testDateString, jp); assertThat((long) d.getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(testDateString).getTime()); } @@ -42,7 +43,8 @@ void parsingParallel() throws InterruptedException { threadArray[i] = new Thread(() -> { try { - Date d = JsonDateDeserializer.getDate(testDateString, new JsonLocation(null, 22, 0, 0)); + JsonParser jp = JsonMapper.shared().createParser("\"" + testDateString + "\""); + Date d = JsonDateDeserializer.getDate(testDateString, jp); if (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(testDateString).getTime() != d.getTime()) { throw new Exception("Unexpected date"); } diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializerTest.java b/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializerTest.java index deb7898f2c5..210be7f07fc 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializerTest.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/impl/JsonDateSerializerTest.java @@ -1,11 +1,10 @@ package org.cloudfoundry.identity.uaa.impl; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.json.JsonMapper; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @@ -16,10 +15,10 @@ class JsonDateSerializerTest { Exception exceptionOccurred; @Test - void formatting() throws IOException { + void formatting() { Date now = new Date(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); - JsonGenerator gen = new JsonFactory().createGenerator(bos); + JsonGenerator gen = JsonMapper.shared().createGenerator(bos); new JsonDateSerializer().serialize(now, gen, null); gen.close(); assertThat(bos).hasToString("\"%s\"".formatted(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(now))); @@ -34,7 +33,7 @@ void formattingParallel() throws InterruptedException { try { Date now = new Date(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); - JsonGenerator gen = new JsonFactory().createGenerator(bos); + JsonGenerator gen = JsonMapper.shared().createGenerator(bos); new JsonDateSerializer().serialize(now, gen, null); gen.close(); if (!"\"%s\"".formatted(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(now)) @@ -47,9 +46,7 @@ void formattingParallel() throws InterruptedException { } }); } - for ( - - int i = 0; i < 1000; i++) { + for (int i = 0; i < 1000; i++) { threadArray[i].start(); } for (int i = 0; i < 1000; i++) { diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/client/token/grant/AuthorizationCodeAccessTokenProviderWithConversionTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/client/token/grant/AuthorizationCodeAccessTokenProviderWithConversionTests.java index d273f6cf8cb..54c2f3c11fc 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/client/token/grant/AuthorizationCodeAccessTokenProviderWithConversionTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/client/token/grant/AuthorizationCodeAccessTokenProviderWithConversionTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.client.token.grant; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.cloudfoundry.identity.uaa.oauth.client.grant.AuthorizationCodeAccessTokenProvider; import org.cloudfoundry.identity.uaa.oauth.client.resource.AuthorizationCodeResourceDetails; import org.cloudfoundry.identity.uaa.oauth.client.resource.OAuth2AccessDeniedException; @@ -145,7 +147,7 @@ void getAccessTokenFromJson() throws Exception { final OAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); requestFactory = new ClientHttpRequestFactory() { public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { - return new StubClientHttpRequest(new ObjectMapper().writeValueAsString(token)); + return new StubClientHttpRequest(new JsonMapper().writeValueAsString(token)); } }; AccessTokenRequest request = new DefaultAccessTokenRequest(); @@ -162,7 +164,7 @@ void getErrorFromJson() { requestFactory = new ClientHttpRequestFactory() { public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { return new StubClientHttpRequest(HttpStatus.BAD_REQUEST, - new ObjectMapper().writeValueAsString(exception)); + new JsonMapper().writeValueAsString(exception)); } }; AccessTokenRequest request = new DefaultAccessTokenRequest(); diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/JsonSerializationTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/JsonSerializationTests.java index 67adb94cf59..f1f09d1acf1 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/JsonSerializationTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/JsonSerializationTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.common; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InvalidClientException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.OAuth2Exception; import org.junit.jupiter.api.Test; @@ -19,7 +21,7 @@ class JsonSerializationTests { void defaultSerialization() throws Exception { DefaultOAuth2AccessToken accessToken = new DefaultOAuth2AccessToken("FOO"); accessToken.setExpiration(new Date(System.currentTimeMillis() + 10000)); - String result = new ObjectMapper().writeValueAsString(accessToken); + String result = new JsonMapper().writeValueAsString(accessToken); // System.err.println(result); assertThat(result).as("Wrong token: " + result).contains("\"token_type\":\"bearer\"") .as("Wrong token: " + result).contains("\"access_token\":\"FOO\"") @@ -31,7 +33,7 @@ void refreshSerialization() throws Exception { DefaultOAuth2AccessToken accessToken = new DefaultOAuth2AccessToken("FOO"); accessToken.setRefreshToken(new DefaultOAuth2RefreshToken("BAR")); accessToken.setExpiration(new Date(System.currentTimeMillis() + 10000)); - String result = new ObjectMapper().writeValueAsString(accessToken); + String result = new JsonMapper().writeValueAsString(accessToken); // System.err.println(result); assertThat(result).as("Wrong token: " + result).contains("\"token_type\":\"bearer\"") .as("Wrong token: " + result).contains("\"access_token\":\"FOO\"") @@ -43,7 +45,7 @@ void refreshSerialization() throws Exception { void exceptionSerialization() throws Exception { InvalidClientException exception = new InvalidClientException("FOO"); exception.addAdditionalInformation("foo", "bar"); - String result = new ObjectMapper().writeValueAsString(exception); + String result = new JsonMapper().writeValueAsString(exception); // System.err.println(result); assertThat(result).as("Wrong result: " + result).contains("\"error\":\"invalid_client\"") .as("Wrong result: " + result).contains("\"error_description\":\"FOO\"") @@ -53,7 +55,7 @@ void exceptionSerialization() throws Exception { @Test void defaultDeserialization() throws Exception { String accessToken = "{\"access_token\": \"FOO\", \"expires_in\": 100, \"token_type\": \"mac\"}"; - OAuth2AccessToken result = new ObjectMapper().readValue(accessToken, OAuth2AccessToken.class); + OAuth2AccessToken result = new JsonMapper().readValue(accessToken, OAuth2AccessToken.class); // System.err.println(result); assertThat(result.getValue()).isEqualTo("FOO"); assertThat(result.getTokenType()).isEqualTo("mac"); @@ -63,7 +65,7 @@ void defaultDeserialization() throws Exception { @Test void exceptionDeserialization() throws Exception { String exception = "{\"error\": \"invalid_client\", \"error_description\": \"FOO\", \"foo\": \"bar\"}"; - OAuth2Exception result = new ObjectMapper().readValue(exception, OAuth2Exception.class); + OAuth2Exception result = new JsonMapper().readValue(exception, OAuth2Exception.class); // System.err.println(result); assertThat(result.getMessage()).isEqualTo("FOO"); assertThat(result.getOAuth2ErrorCode()).isEqualTo("invalid_client"); diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2DeserializerTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2DeserializerTests.java index ea23cad6e04..ff9d766b6cb 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2DeserializerTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2DeserializerTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.common; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,7 +22,7 @@ class OAuth2AccessTokenJackson2DeserializerTests extends BaseOAuth2AccessTokenJa @BeforeEach void createObjectMapper() { - mapper = new ObjectMapper(); + mapper = new JsonMapper(); } @Test diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2SerializerTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2SerializerTests.java index 52a386e51b4..34f8f93fd50 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2SerializerTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/OAuth2AccessTokenJackson2SerializerTests.java @@ -1,7 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.common; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,7 +21,7 @@ class OAuth2AccessTokenJackson2SerializerTests extends BaseOAuth2AccessTokenJack @BeforeEach void createObjectMapper() { - mapper = new ObjectMapper(); + mapper = new JsonMapper(); } @Test @@ -60,11 +61,11 @@ void writeValueAsStringWithNullScope() { accessToken.getScope().add(null); } catch (NullPointerException e) { // short circuit NPE from Java 7 (which is correct but only relevant for this test) - throw new JsonMappingException("Scopes cannot be null or empty. Got [null]"); + throw new IllegalArgumentException("Scopes cannot be null or empty. Got [null]"); } mapper.writeValueAsString(accessToken); }) - .isInstanceOf(JsonMappingException.class) + .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("Scopes cannot be null or empty. Got [null]"); } @@ -73,7 +74,7 @@ void writeValueAsStringWithEmptyStringScope() { accessToken.getScope().clear(); accessToken.getScope().add(""); assertThatThrownBy(() -> mapper.writeValueAsString(accessToken)) - .isInstanceOf(JsonMappingException.class) + .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("Scopes cannot be null or empty. Got []"); } diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionDeserializerTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionDeserializerTests.java index a2093a54ab8..c7ea08d491f 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionDeserializerTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionDeserializerTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.common.exception; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.cloudfoundry.identity.uaa.oauth.common.exceptions.BadClientCredentialsException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InsufficientScopeException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InvalidClientException; @@ -28,7 +30,7 @@ class OAuth2ExceptionDeserializerTests { @BeforeAll static void setUpClass() { - mapper = new ObjectMapper(); + mapper = new JsonMapper(); } @Test diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionJackson2DeserializerTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionJackson2DeserializerTests.java index 21b721baab8..b98defc4d24 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionJackson2DeserializerTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionJackson2DeserializerTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.common.exception; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InsufficientScopeException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InvalidClientException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InvalidGrantException; @@ -27,7 +29,7 @@ class OAuth2ExceptionJackson2DeserializerTests { @BeforeAll static void setUpClass() { - mapper = new ObjectMapper(); + mapper = new JsonMapper(); } @Test diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionSerializerTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionSerializerTests.java index 49c91cf8380..aad4c877c08 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionSerializerTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/common/exception/OAuth2ExceptionSerializerTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.common.exception; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.cloudfoundry.identity.uaa.oauth.common.exceptions.BadClientCredentialsException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InsufficientScopeException; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InvalidClientException; @@ -35,7 +37,7 @@ class OAuth2ExceptionSerializerTests { @BeforeAll static void setUpClass() { - mapper = new ObjectMapper(); + mapper = new JsonMapper(); } @AfterEach diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializerTest.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializerTest.java index 2102bfe4035..6696d243a5e 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializerTest.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyDeserializerTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.junit.jupiter.api.Test; diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyTests.java index 13ee2372fd8..3ce29b1d881 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.junit.jupiter.api.Test; diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupportTests.java b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupportTests.java index cbdd6ebef82..9ea3dceed04 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupportTests.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/OAuth2AccessTokenSupportTests.java @@ -1,6 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.token; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.cloudfoundry.identity.uaa.oauth.client.resource.ClientCredentialsResourceDetails; import org.cloudfoundry.identity.uaa.oauth.client.resource.OAuth2AccessDeniedException; import org.cloudfoundry.identity.uaa.oauth.common.AuthenticationScheme; @@ -51,7 +53,7 @@ class OAuth2AccessTokenSupportTests { private final AccessTokenRequest request = new DefaultAccessTokenRequest(); - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new JsonMapper(); private final OAuth2AccessTokenSupport support = new OAuth2AccessTokenSupport() { }; diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonMatcher.java b/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonMatcher.java index 6c9c0ae3881..7c9ca600763 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonMatcher.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonMatcher.java @@ -1,10 +1,12 @@ package org.cloudfoundry.identity.uaa.test; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.hamcrest.BaseMatcher; import org.hamcrest.Description; +import tools.jackson.core.JacksonException; import static org.cloudfoundry.identity.uaa.test.ModelTestUtils.getResourceAsString; @@ -22,12 +24,12 @@ static org.hamcrest.Matcher isJsonString(String expectedJson) { } private final String expectedJson; - private JsonProcessingException jsonException; + private JacksonException jsonException; private JsonMatcher(String expectedJson) { this.expectedJson = expectedJson; this.jsonException = null; - this.mapper = new ObjectMapper(); + this.mapper = new JsonMapper(); } @Override @@ -40,7 +42,7 @@ public boolean matches(Object actualJson) { final JsonNode expectedTree = mapper.readTree(expectedJson); return expectedTree.equals(actualTree); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { jsonException = e; return false; } diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonTranslation.java b/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonTranslation.java index 2e60a19a5e8..2d99dcc0510 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonTranslation.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/test/JsonTranslation.java @@ -1,8 +1,10 @@ package org.cloudfoundry.identity.uaa.test; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.junit.jupiter.api.Test; +import tools.jackson.core.JacksonException; import java.io.IOException; @@ -45,7 +47,9 @@ protected void setUp( this.withAllNullFields = withAllNullFields; this.jsonFileName = subjectClass.getSimpleName() + ".json"; - this.objectMapper = new ObjectMapper(); + this.objectMapper = JsonMapper.builder() + .enable(tools.jackson.databind.cfg.DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) + .build(); } protected ObjectMapper getObjectMapper() { @@ -58,7 +62,7 @@ private void validate() { } @Test - void toJson() throws JsonProcessingException { + void toJson() throws JacksonException { validate(); assertThat(subjectClass.getResourceAsStream(jsonFileName)).as("file <%s/%s> must exist on classpath".formatted(subjectClass.getPackage().getName().replace(".", "/"), jsonFileName)).isNotNull(); @@ -80,7 +84,7 @@ void fromJson() throws IOException { } @Test - void withNullFields_checkIsEmptyJson() throws IllegalAccessException, InstantiationException, JsonProcessingException { + void withNullFields_checkIsEmptyJson() throws IllegalAccessException, InstantiationException, JacksonException { assumeTrue(EXPECT_EMPTY_JSON.equals(withAllNullFields), "To configure this test, use %s instead of %s".formatted(EXPECT_EMPTY_JSON, withAllNullFields)); validate(); @@ -90,7 +94,7 @@ void withNullFields_checkIsEmptyJson() throws IllegalAccessException, Instantiat } @Test - void withNullFields_compareToFile() throws JsonProcessingException, IllegalAccessException, InstantiationException { + void withNullFields_compareToFile() throws JacksonException, IllegalAccessException, InstantiationException { assumeTrue(EXPECT_NULLS_IN_JSON.equals(withAllNullFields), "To configure this test, use %s instead of %s".formatted(EXPECT_NULLS_IN_JSON, withAllNullFields)); validate(); diff --git a/model/src/test/java/org/cloudfoundry/identity/uaa/zone/LoginConsentTest.java b/model/src/test/java/org/cloudfoundry/identity/uaa/zone/LoginConsentTest.java index 19023b26a06..016c469196e 100644 --- a/model/src/test/java/org/cloudfoundry/identity/uaa/zone/LoginConsentTest.java +++ b/model/src/test/java/org/cloudfoundry/identity/uaa/zone/LoginConsentTest.java @@ -1,13 +1,15 @@ package org.cloudfoundry.identity.uaa.zone; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class LoginConsentTest { - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new JsonMapper(); @Test void testDefaultConstructor() { diff --git a/server/build.gradle b/server/build.gradle index 8551e765ed4..0b8de4e3660 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -20,9 +20,13 @@ dependencies { implementation(libs.springJdbc) implementation(libs.springWeb) implementation(libs.springSecurityCore) + implementation(libs.springSecurityAccess) implementation(libs.springSecurityWeb) implementation(libs.springSecurityConfig) implementation(libs.springBootStarterMail) + implementation(libs.springBootSql) + implementation(libs.springBootJdbc) + implementation(libs.springBootTransaction) implementation(libs.openSamlApi) implementation(libs.springSecuritySamlServiceProvider) implementation(libs.xmlSecurity) @@ -35,6 +39,10 @@ dependencies { implementation(libs.guava) + // OpenAPI documentation + implementation(libs.springDocOpenapi) + + implementation(libs.aspectJRt) implementation(libs.aspectJWeaver) implementation(libs.thymeLeaf) { @@ -62,6 +70,7 @@ dependencies { implementation(libs.flywayHsqlDb) implementation(libs.flywayMySql) implementation(libs.flywayPostgresql) + implementation(libs.springBootFlyway) implementation(libs.hsqldb) implementation(libs.snakeyaml) diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailAccountCreationService.java b/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailAccountCreationService.java index 97b86c6552b..b114ffb3473 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailAccountCreationService.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailAccountCreationService.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.account; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore; import org.cloudfoundry.identity.uaa.constants.OriginKeys; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailChangeEmailService.java b/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailChangeEmailService.java index 92606560c19..31b649a7d73 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailChangeEmailService.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/account/EmailChangeEmailService.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.account; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore; import org.cloudfoundry.identity.uaa.constants.OriginKeys; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java b/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java index 6325801ec5c..04b7bb1b04f 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/account/ResetPasswordController.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.account; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore; import org.cloudfoundry.identity.uaa.message.MessageService; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/AbstractUaaEvent.java b/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/AbstractUaaEvent.java index 5382919d04a..a86a0bda9ce 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/AbstractUaaEvent.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/AbstractUaaEvent.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.audit.event; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.audit.AuditEvent; import org.cloudfoundry.identity.uaa.audit.AuditEventType; import org.cloudfoundry.identity.uaa.audit.UaaAuditService; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/TokenIssuedEvent.java b/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/TokenIssuedEvent.java index ddc5d9899a0..717d334558d 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/TokenIssuedEvent.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/audit/event/TokenIssuedEvent.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.audit.event; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.audit.AuditEvent; import org.cloudfoundry.identity.uaa.audit.AuditEventType; import org.cloudfoundry.identity.uaa.oauth.common.OAuth2AccessToken; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/ClientDetailsAuthenticationProvider.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/ClientDetailsAuthenticationProvider.java index 13b5cfbf5a0..6b59a9aa40a 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/ClientDetailsAuthenticationProvider.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/ClientDetailsAuthenticationProvider.java @@ -53,7 +53,7 @@ public class ClientDetailsAuthenticationProvider extends DaoAuthenticationProvid public ClientDetailsAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder encoder, JwtClientAuthentication jwtClientAuthentication) { super(userDetailsService); - setPasswordEncoder(encoder); + setPasswordEncoder(new EmptyPasswordAwareEncoder(encoder)); this.jwtClientAuthentication = jwtClientAuthentication; } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/EmptyPasswordAwareEncoder.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/EmptyPasswordAwareEncoder.java new file mode 100644 index 00000000000..6e12b2cf6af --- /dev/null +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/EmptyPasswordAwareEncoder.java @@ -0,0 +1,72 @@ +package org.cloudfoundry.identity.uaa.authentication; + +import org.springframework.security.crypto.bcrypt.BCrypt; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.Set; + +/** + * Wraps a {@link PasswordEncoder} to allow empty raw passwords. + * Spring Security 7 {@code AbstractValidatingPasswordEncoder} returns {@code false} from {@code matches()} + * when {@code rawPassword.length() == 0}. UAA legitimately supports clients with no secret (e.g. CF CLI), + * whose stored hash is the encoding of an empty string. + */ +class EmptyPasswordAwareEncoder implements PasswordEncoder { + + private static final String NOOP_PREFIX = "{noop}"; + private static final String BCRYPT_PREFIX = "{bcrypt}"; + private static final Set BCRYPT_HASH_PREFIXES = Set.of("$2a$", "$2b$", "$2y$"); + + private final PasswordEncoder delegate; + + EmptyPasswordAwareEncoder(PasswordEncoder delegate) { + this.delegate = delegate; + } + + @Override + public String encode(CharSequence rawPassword) { + return delegate.encode(rawPassword); + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + if (rawPassword != null && rawPassword.isEmpty()) { + return emptyPasswordMatchesStoredHash(encodedPassword); + } + + return delegate.matches(rawPassword, encodedPassword); + } + + private boolean emptyPasswordMatchesStoredHash(String encodedPassword) { + if (encodedPassword == null) { + return false; + } + + if (NOOP_PREFIX.equals(encodedPassword)) { + return true; + } + + String extracted = extractPasswordValue(encodedPassword); + return isBcryptHash(extracted) && bcryptMatchesEmpty(extracted); + } + + private String extractPasswordValue(String encodedPassword) { + if (encodedPassword.startsWith(BCRYPT_PREFIX)) { + return encodedPassword.substring(BCRYPT_PREFIX.length()); + } + + return encodedPassword; + } + + private boolean isBcryptHash(String value) { + return BCRYPT_HASH_PREFIXES.stream().anyMatch(value::startsWith); + } + + private boolean bcryptMatchesEmpty(String hash) { + try { + return BCrypt.checkpw("", hash); + } catch (IllegalArgumentException e) { + return false; + } + } +} diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthentication.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthentication.java index 39145472301..088a018f50e 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthentication.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthentication.java @@ -13,8 +13,8 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.authentication; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import lombok.Getter; import lombok.Setter; import lombok.ToString; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationDeserializer.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationDeserializer.java index 3077cc1c84b..3c7d03adfa6 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationDeserializer.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationDeserializer.java @@ -13,15 +13,14 @@ */ package org.cloudfoundry.identity.uaa.authentication; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonMappingException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationContext; import org.springframework.security.core.GrantedAuthority; +import tools.jackson.databind.DatabindException; +import tools.jackson.databind.ValueDeserializer; -import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Set; @@ -30,9 +29,9 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; -public class UaaAuthenticationDeserializer extends JsonDeserializer implements UaaAuthenticationJsonBase { +public class UaaAuthenticationDeserializer extends ValueDeserializer implements UaaAuthenticationJsonBase { @Override - public UaaAuthentication deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + public UaaAuthentication deserialize(JsonParser jp, DeserializationContext ctxt) { UaaAuthenticationDetails details = null; UaaPrincipal princpal = null; List authorities = emptyList(); @@ -46,10 +45,10 @@ public UaaAuthentication deserialize(JsonParser jp, DeserializationContext ctxt) String idpIdToken = null; Map> userAttributes = emptyMap(); while (jp.nextToken() != JsonToken.END_OBJECT) { - if (jp.getCurrentToken() == JsonToken.FIELD_NAME) { - String fieldName = jp.getCurrentName(); + if (jp.currentToken() == JsonToken.PROPERTY_NAME) { + String fieldName = jp.currentName(); jp.nextToken(); - if (NULL_STRING.equals(jp.getText())) { + if (NULL_STRING.equals(jp.getString())) { //do nothing } else if (DETAILS.equals(fieldName)) { details = jp.readValueAs(UaaAuthenticationDetails.class); @@ -85,7 +84,7 @@ public UaaAuthentication deserialize(JsonParser jp, DeserializationContext ctxt) } } if (princpal == null) { - throw new JsonMappingException("Missing " + UaaPrincipal.class.getName()); + throw DatabindException.from(jp, "Missing " + UaaPrincipal.class.getName()); } UaaAuthentication uaaAuthentication = new UaaAuthentication(princpal, null, diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationSerializer.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationSerializer.java index 1c6ca4a79c6..d35b199a4ff 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationSerializer.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaAuthenticationSerializer.java @@ -13,30 +13,28 @@ */ package org.cloudfoundry.identity.uaa.authentication; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -import java.io.IOException; - -public class UaaAuthenticationSerializer extends JsonSerializer implements UaaAuthenticationJsonBase { +public class UaaAuthenticationSerializer extends ValueSerializer implements UaaAuthenticationJsonBase { @Override - public void serialize(UaaAuthentication value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(UaaAuthentication value, JsonGenerator gen, SerializationContext serializers) { gen.writeStartObject(); if (value.getDetails() instanceof UaaAuthenticationDetails) { - gen.writeObjectField(DETAILS, value.getDetails()); + gen.writePOJOProperty(DETAILS, value.getDetails()); } - gen.writeObjectField(PRINCIPAL, value.getPrincipal()); - gen.writeObjectField(AUTHORITIES, serializeAuthorites(value.getAuthorities())); - gen.writeObjectField(EXTERNAL_GROUPS, value.getExternalGroups()); - gen.writeNumberField(EXPIRES_AT, value.getExpiresAt()); - gen.writeNumberField(AUTH_TIME, value.getAuthenticatedTime()); - gen.writeBooleanField(AUTHENTICATED, value.isAuthenticated()); - gen.writeObjectField(PREVIOIUS_LOGIN_SUCCESS_TIME, value.getLastLoginSuccessTime()); - gen.writeObjectField(USER_ATTRIBUTES, value.getUserAttributesAsMap()); - gen.writeObjectField(AUTHENTICATION_METHODS, value.getAuthenticationMethods()); - gen.writeObjectField(AUTHN_CONTEXT_CLASS_REF, value.getAuthContextClassRef()); - gen.writeObjectField(IDP_ID_TOKEN, value.getIdpIdToken()); + gen.writePOJOProperty(PRINCIPAL, value.getPrincipal()); + gen.writePOJOProperty(AUTHORITIES, serializeAuthorites(value.getAuthorities())); + gen.writePOJOProperty(EXTERNAL_GROUPS, value.getExternalGroups()); + gen.writeNumberProperty(EXPIRES_AT, value.getExpiresAt()); + gen.writeNumberProperty(AUTH_TIME, value.getAuthenticatedTime()); + gen.writeBooleanProperty(AUTHENTICATED, value.isAuthenticated()); + gen.writePOJOProperty(PREVIOIUS_LOGIN_SUCCESS_TIME, value.getLastLoginSuccessTime()); + gen.writePOJOProperty(USER_ATTRIBUTES, value.getUserAttributesAsMap()); + gen.writePOJOProperty(AUTHENTICATION_METHODS, value.getAuthenticationMethods()); + gen.writePOJOProperty(AUTHN_CONTEXT_CLASS_REF, value.getAuthContextClassRef()); + gen.writePOJOProperty(IDP_ID_TOKEN, value.getIdpIdToken()); gen.writeEndObject(); } } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaLoginHint.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaLoginHint.java index e11f0fc39ef..db03a5f9cca 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaLoginHint.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/UaaLoginHint.java @@ -1,9 +1,9 @@ package org.cloudfoundry.identity.uaa.authentication; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.core.JacksonException; -import java.io.IOException; import java.io.Serial; import java.io.Serializable; import java.net.URLDecoder; @@ -13,7 +13,7 @@ public class UaaLoginHint implements Serializable { @Serial private static final long serialVersionUID = 4021539346161285037L; private String origin; - private static ObjectMapper mapper = new ObjectMapper(); + private static ObjectMapper mapper = new JsonMapper(); public static UaaLoginHint parseRequestParameter(String loginHint) { if (loginHint == null) { @@ -22,7 +22,7 @@ public static UaaLoginHint parseRequestParameter(String loginHint) { try { loginHint = URLDecoder.decode(loginHint, StandardCharsets.UTF_8); return mapper.readValue(loginHint, UaaLoginHint.class); - } catch (IOException e) { + } catch (JacksonException e) { return null; } } @@ -46,7 +46,7 @@ public void setOrigin(String origin) { public String toString() { try { return mapper.writeValueAsString(this); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return super.toString(); } } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinAuthenticationManager.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinAuthenticationManager.java index b76a1202999..513c8cd6add 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinAuthenticationManager.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinAuthenticationManager.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.authentication.manager; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.cloudfoundry.identity.uaa.authentication.AuthzAuthenticationRequest; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinRequestConverter.java b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinRequestConverter.java index 6a45efb78d3..a5674bf5746 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinRequestConverter.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/authentication/manager/AutologinRequestConverter.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.authentication.manager; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.login.AutologinRequest; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.util.LinkedMaskingMultiValueMap; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/client/JdbcClientMetadataProvisioning.java b/server/src/main/java/org/cloudfoundry/identity/uaa/client/JdbcClientMetadataProvisioning.java index 9bd3c507f9a..1ce1e95b486 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/client/JdbcClientMetadataProvisioning.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/client/JdbcClientMetadataProvisioning.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.client; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.codec.binary.Base64; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.util.UaaStringUtils; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/client/SocialClientUserDetails.java b/server/src/main/java/org/cloudfoundry/identity/uaa/client/SocialClientUserDetails.java index 7ddaf8ff859..12864d7c755 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/client/SocialClientUserDetails.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/client/SocialClientUserDetails.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonDeserialize; import org.cloudfoundry.identity.uaa.user.UaaAuthority; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/db/beans/DatabaseConfiguration.java b/server/src/main/java/org/cloudfoundry/identity/uaa/db/beans/DatabaseConfiguration.java index 9063e7e4fcc..9e5d0ed252c 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/db/beans/DatabaseConfiguration.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/db/beans/DatabaseConfiguration.java @@ -6,9 +6,9 @@ import org.cloudfoundry.identity.uaa.resources.jdbc.MySqlLimitSqlAdapter; import org.cloudfoundry.identity.uaa.resources.jdbc.PostgresLimitSqlAdapter; import org.jspecify.annotations.NonNull; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/error/UaaException.java b/server/src/main/java/org/cloudfoundry/identity/uaa/error/UaaException.java index d0be7a3ae02..c6c5a972642 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/error/UaaException.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/error/UaaException.java @@ -13,8 +13,8 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.error; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.OAuth2Exception; import java.util.Map; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/impl/config/JacksonMapperCustomizer.java b/server/src/main/java/org/cloudfoundry/identity/uaa/impl/config/JacksonMapperCustomizer.java new file mode 100644 index 00000000000..26c191f80cd --- /dev/null +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/impl/config/JacksonMapperCustomizer.java @@ -0,0 +1,43 @@ +package org.cloudfoundry.identity.uaa.impl.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.cfg.ConstructorDetector; +import tools.jackson.databind.cfg.DateTimeFeature; +import tools.jackson.databind.json.JsonMapper; + +import java.util.List; + +@Configuration +public class JacksonMapperCustomizer implements WebMvcConfigurer { + + @Bean + @Primary + public JsonMapper jsonMapper() { + return JsonMapper.builder() + .enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) + .enable(SerializationFeature.FAIL_ON_EMPTY_BEANS) + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .constructorDetector(ConstructorDetector.DEFAULT.withAllowImplicitWithDefaultConstructor(false)) + .build(); + } + + @Override + public void extendMessageConverters(List> converters) { + JsonMapper mapper = jsonMapper(); + for (int i = 0; i < converters.size(); i++) { + if (converters.get(i) instanceof JacksonJsonHttpMessageConverter) { + converters.set(i, new JacksonJsonHttpMessageConverter(mapper)); + break; + } + } + } +} diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/EmailInvitationsService.java b/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/EmailInvitationsService.java index c88899e518d..5cf72fe9a6c 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/EmailInvitationsService.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/EmailInvitationsService.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.invitations; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore; import org.cloudfoundry.identity.uaa.provider.NoSuchClientException; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/InvitationsController.java b/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/InvitationsController.java index eaac83dbd49..e66afe37e56 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/InvitationsController.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/InvitationsController.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.invitations; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequestWrapper; import jakarta.servlet.http.HttpServletResponse; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/AuthorizationAttributesParser.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/AuthorizationAttributesParser.java index 09e7ce0e30c..5cf420650f2 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/AuthorizationAttributesParser.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/AuthorizationAttributesParser.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.cloudfoundry.identity.uaa.util.JsonUtils; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java index 19fb952e658..f7b37a86077 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication; import org.cloudfoundry.identity.uaa.authentication.UaaAuthenticationDetails; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/beans/OauthEndpointBeanConfiguration.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/beans/OauthEndpointBeanConfiguration.java index 079a9cf003a..679bca691f0 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/beans/OauthEndpointBeanConfiguration.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/beans/OauthEndpointBeanConfiguration.java @@ -84,6 +84,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; @@ -92,6 +93,7 @@ import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; @@ -457,6 +459,11 @@ ClientDetailsAuthenticationProvider clientAuthenticationProvider( ); } + @Bean + AuthenticationEventPublisher defaultAuthenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + return new DefaultAuthenticationEventPublisher(applicationEventPublisher); + } + @Bean("clientAuthenticationManager") AuthenticationManager clientAuthenticationManager( @Autowired ClientDetailsAuthenticationProvider provider, diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyHelper.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyHelper.java index c1c57ba01bf..f9151905cfc 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyHelper.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/jwk/JsonWebKeyHelper.java @@ -15,7 +15,7 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.jwk.JWK; import org.cloudfoundry.identity.uaa.util.JsonUtils; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/openid/IdToken.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/openid/IdToken.java index 4278fd98480..3280efbf490 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/openid/IdToken.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/openid/IdToken.java @@ -1,5 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth.openid; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -74,31 +75,33 @@ public class IdToken { public final String revSig; private Map tokenActor; - public IdToken(String sub, - List aud, - String iss, - Date exp, - Date iat, - Date authTime, - Set amr, - Set acr, - String azp, - String givenName, - String familyName, - Long previousLogonTime, - String phoneNumber, - Set roles, - Map> userAttributes, - Boolean emailVerified, - String nonce, - String email, - String clientId, - String grantType, - String userName, - String zid, - String origin, - String jti, - String revSig) { + @JsonCreator + public IdToken( + @JsonProperty("sub") String sub, + @JsonProperty("aud") List aud, + @JsonProperty("iss") String iss, + @JsonProperty("exp") Date exp, + @JsonProperty(IAT) Date iat, + @JsonProperty(AUTH_TIME) Date authTime, + @JsonProperty("amr") Set amr, + @JsonProperty(ACR) Set acr, + @JsonProperty("azp") String azp, + @JsonProperty(GIVEN_NAME) String givenName, + @JsonProperty(FAMILY_NAME) String familyName, + @JsonProperty(PREVIOUS_LOGON_TIME) Long previousLogonTime, + @JsonProperty(PHONE_NUMBER) String phoneNumber, + @JsonProperty("roles") Set roles, + @JsonProperty(USER_ATTRIBUTES) Map> userAttributes, + @JsonProperty(EMAIL_VERIFIED) Boolean emailVerified, + @JsonProperty("nonce") String nonce, + @JsonProperty("email") String email, + @JsonProperty(CID) String clientId, + @JsonProperty(GRANT_TYPE) String grantType, + @JsonProperty(USER_NAME) String userName, + @JsonProperty("zid") String zid, + @JsonProperty("origin") String origin, + @JsonProperty("jti") String jti, + @JsonProperty(REVOCATION_SIGNATURE) String revSig) { this.sub = sub; this.aud = aud; this.iss = iss; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/provider/error/OAuth2AuthenticationEntryPoint.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/provider/error/OAuth2AuthenticationEntryPoint.java index 1e09dc8c091..d47bbaa976f 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/provider/error/OAuth2AuthenticationEntryPoint.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/provider/error/OAuth2AuthenticationEntryPoint.java @@ -45,7 +45,7 @@ public void commence(HttpServletRequest request, HttpServletResponse response, A protected ResponseEntity enhanceResponse(ResponseEntity response, Exception exception) { HttpHeaders headers = response.getHeaders(); String existing = null; - if (headers.containsKey(WWW_AUTHENTICATE)) { + if (headers.containsHeader(WWW_AUTHENTICATE)) { existing = extractTypePrefix(headers.getFirst(WWW_AUTHENTICATE)); } StringBuilder builder = new StringBuilder(); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManager.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManager.java index 326b9057053..40589aa85a2 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManager.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManager.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.provider.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/OidcMetadataFetcher.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/OidcMetadataFetcher.java index 713dbf01d7a..815b20e2268 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/OidcMetadataFetcher.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/OidcMetadataFetcher.java @@ -1,6 +1,7 @@ package org.cloudfoundry.identity.uaa.provider.oauth; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import org.cloudfoundry.identity.uaa.cache.UrlContentCache; @@ -18,8 +19,8 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import tools.jackson.core.JacksonException; -import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Collections; @@ -134,8 +135,8 @@ private OidcMetadata fetchMetadata(URL discoveryUrl, boolean shouldDoSslValidati rawContents = contentCache.getUrlContent(discoveryUrl.toString(), nonTrustingRestTemplate); } try { - return new ObjectMapper().readValue(rawContents, OidcMetadata.class); - } catch (IOException e) { + return new JsonMapper().readValue(rawContents, OidcMetadata.class); + } catch (JacksonException e) { throw new OidcMetadataFetchingException(e); } } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/BootstrapSamlIdentityProviderData.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/BootstrapSamlIdentityProviderData.java index dec15bf8b8d..639598ced18 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/BootstrapSamlIdentityProviderData.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/BootstrapSamlIdentityProviderData.java @@ -185,7 +185,7 @@ public void setIdentityProviders(Map> providers) { IdentityProvider provider = parseSamlProvider(def); if (def.getType() == SamlIdentityProviderDefinition.MetadataLocation.DATA) { RelyingPartyRegistration metadataDelegate = samlConfigurator.getExtendedMetadataDelegate(def); - def.setIdpEntityId(metadataDelegate.getAssertingPartyDetails().getEntityId()); + def.setIdpEntityId(metadataDelegate.getAssertingPartyMetadata().getEntityId()); } IdentityProviderWrapper wrapper = new IdentityProviderWrapper<>(provider); wrapper.setOverride(override == null || override); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProvider.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProvider.java index 3e438781b32..945adc95a8e 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProvider.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProvider.java @@ -242,7 +242,7 @@ public static Converter createDefau result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_DESTINATION, message)); } String assertingPartyEntityId = token.getRelyingPartyRegistration() - .getAssertingPartyDetails() + .getAssertingPartyMetadata() .getEntityId(); if (!StringUtils.hasText(issuer) || !issuer.equals(assertingPartyEntityId)) { String message = "Invalid issuer [%s] for SAML response [%s]".formatted(issuer, response.getID()); @@ -595,7 +595,7 @@ private static ValidationContext createValidationContext(AssertionToken assertio } else { recipientList = Set.of(relyingPartyRegistration.getAssertionConsumerServiceLocation()); } - String assertingPartyEntityId = relyingPartyRegistration.getAssertingPartyDetails().getEntityId(); + String assertingPartyEntityId = relyingPartyRegistration.getAssertingPartyMetadata().getEntityId(); Map params = new HashMap<>(); Assertion assertion = assertionToken.getAssertion(); if (!saml2Bearer && assertionContainsInResponseTo(assertion)) { diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSamlVerificationUtils.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSamlVerificationUtils.java index 5043a81e7a1..0a28068b90f 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSamlVerificationUtils.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSamlVerificationUtils.java @@ -65,11 +65,11 @@ static VerifierPartial verifySignature(StatusResponseType object, RelyingPartyRe static SignatureTrustEngine trustEngine(RelyingPartyRegistration registration) { Set credentials = new HashSet<>(); - Collection keys = registration.getAssertingPartyDetails().getVerificationX509Credentials(); + Collection keys = registration.getAssertingPartyMetadata().getVerificationX509Credentials(); for (Saml2X509Credential key : keys) { BasicX509Credential cred = new BasicX509Credential(key.getCertificate()); cred.setUsageType(UsageType.SIGNING); - cred.setEntityId(registration.getAssertingPartyDetails().getEntityId()); + cred.setEntityId(registration.getAssertingPartyMetadata().getEntityId()); credentials.add(cred); } CredentialResolver credentialsResolver = new CollectionCredentialResolver(credentials); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilder.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilder.java index be03059b82e..efabfb2742c 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilder.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilder.java @@ -87,7 +87,7 @@ public static RelyingPartyRegistration buildRelyingPartyRegistration(Params buil }) // alter the default value of the APs wantAuthnRequestsSigned, // to reflect the UAA configured desire to always sign/or-not the AuthnRequest - .assertingPartyDetails(details -> { + .assertingPartyMetadata(details -> { details.wantAuthnRequestsSigned(params.requestSigned); details.signingAlgorithms(alg -> { alg.clear(); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfigurator.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfigurator.java index d6db5c569d4..dcc8f07c25d 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfigurator.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfigurator.java @@ -87,7 +87,7 @@ public synchronized String validateSamlIdentityProviderDefinition(SamlIdentityPr } SamlIdentityProviderDefinition clone = providerDefinition.clone(); added = getExtendedMetadataDelegate(clone); - String entityIDToBeAdded = added.getAssertingPartyDetails().getEntityId(); + String entityIDToBeAdded = added.getAssertingPartyMetadata().getEntityId(); if (!hasText(entityIDToBeAdded)) { throw new IllegalStateException("Emtpy entityID for SAML provider with zoneId:" + providerDefinition.getZoneId() + " and origin:" + providerDefinition.getIdpEntityAlias()); } @@ -100,7 +100,7 @@ public synchronized String validateSamlIdentityProviderDefinition(SamlIdentityPr continue; } RelyingPartyRegistration existingProvider = getExtendedMetadataDelegate(existing); - if (entityIDToBeAdded.equals(existingProvider.getAssertingPartyDetails().getEntityId()) && !existing.getUniqueAlias().equals(clone.getUniqueAlias())) { + if (entityIDToBeAdded.equals(existingProvider.getAssertingPartyMetadata().getEntityId()) && !existing.getUniqueAlias().equals(clone.getUniqueAlias())) { entityIDexists = true; break; } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandler.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandler.java index 77dbf522017..f57c11a9521 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandler.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandler.java @@ -6,6 +6,7 @@ import org.cloudfoundry.identity.uaa.provider.oauth.ExternalOAuthLogoutSuccessHandler; import org.springframework.security.core.Authentication; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2RelyingPartyInitiatedLogoutSuccessHandler; @@ -94,7 +95,7 @@ private boolean shouldPerformSamlRelyingPartyLogout(HttpServletRequest request, return false; } - String singleLogoutServiceLocation = Optional.ofNullable(registration.getAssertingPartyDetails()).map(RelyingPartyRegistration.AssertingPartyDetails::getSingleLogoutServiceLocation).orElse(null); + String singleLogoutServiceLocation = Optional.ofNullable(registration.getAssertingPartyMetadata()).map(AssertingPartyMetadata::getSingleLogoutServiceLocation).orElse(null); return singleLogoutServiceLocation != null; } } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolver.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolver.java index 08e102eb217..75b138e46b6 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolver.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolver.java @@ -91,7 +91,7 @@ public RelyingPartyRegistration resolve(HttpServletRequest request, String relyi String assertionConsumerServiceLocation = templateResolver.apply(relyingPartyRegistration.getAssertionConsumerServiceLocation()); String singleLogoutServiceLocation = templateResolver.apply(relyingPartyRegistration.getSingleLogoutServiceLocation()); String singleLogoutServiceResponseLocation = templateResolver.apply(relyingPartyRegistration.getSingleLogoutServiceResponseLocation()); - return RelyingPartyRegistration.withRelyingPartyRegistration(relyingPartyRegistration).entityId(relyingPartyEntityId).assertionConsumerServiceLocation(assertionConsumerServiceLocation).singleLogoutServiceLocation(singleLogoutServiceLocation).singleLogoutServiceResponseLocation(singleLogoutServiceResponseLocation).build(); + return relyingPartyRegistration.mutate().entityId(relyingPartyEntityId).assertionConsumerServiceLocation(assertionConsumerServiceLocation).singleLogoutServiceLocation(singleLogoutServiceLocation).singleLogoutServiceResponseLocation(singleLogoutServiceResponseLocation).build(); } } } @@ -130,7 +130,7 @@ private static String resolveUrlTemplate(String template, String baseUrl, Relyin } private static Map constructUriVariables(String baseUrl, RelyingPartyRegistration relyingParty) { - String entityId = relyingParty.getAssertingPartyDetails().getEntityId(); + String entityId = relyingParty.getAssertingPartyMetadata().getEntityId(); String registrationId = relyingParty.getRegistrationId(); Map uriVariables = new HashMap<>(); UriComponents uriComponents = UriComponentsBuilder.fromUriString(baseUrl).replaceQuery(null).fragment(null).build(); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/core/http/CredentialIdTypeJWTjsonField.java b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/core/http/CredentialIdTypeJWTjsonField.java index 93d3d1089f0..eb363017c40 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/core/http/CredentialIdTypeJWTjsonField.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/core/http/CredentialIdTypeJWTjsonField.java @@ -4,10 +4,8 @@ import org.apache.commons.lang3.StringUtils; import org.cloudfoundry.identity.uaa.ratelimiting.core.config.exception.RateLimitingConfigException; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -39,7 +37,7 @@ public AuthorizationCredentialIdExtractor factory(String keyTypeParameters) { } static class SectionFieldJWT extends SectionJWT { - private final ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper = new JsonMapper(); private final AuthorizationCredentialIdExtractorErrorLogger errorLogger; private final String field; @@ -66,7 +64,7 @@ protected String from(JWTparts jp) { valueFound = value.toString(); } } - catch (JsonProcessingException | RuntimeException e) { + catch (RuntimeException e) { errorLogger.log(e); } return valueFound == null ? null : ("|" + valueFound + "|"); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/internal/RateLimiterStatus.java b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/internal/RateLimiterStatus.java index 0fb0ddb784e..547af6f7a34 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/internal/RateLimiterStatus.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/internal/RateLimiterStatus.java @@ -6,13 +6,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import lombok.Builder; import lombok.Getter; import lombok.ToString; import org.cloudfoundry.identity.uaa.ratelimiting.internal.common.InternalLimiterFactoriesSupplier; import org.cloudfoundry.identity.uaa.ratelimiting.util.NanoTimeSupplier; +import tools.jackson.core.JacksonException; import static com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -75,8 +76,8 @@ public String toString() { try { json = OM.writerWithDefaultPrettyPrinter().writeValueAsString(this); } - catch (JsonProcessingException e) { - json = "JsonProcessingException (" + e.getMessage() + "): " + catch (JacksonException e) { + json = "JacksonException (" + e.getMessage() + "): " + "current: " + current + "fromSource: " + fromSource; } @@ -115,5 +116,5 @@ public static RateLimiterStatus noRateLimiting(long now) { return builder().current(Current.builder().status(CurrentStatus.DISABLED).asOf(now).build()).build(); } - private static final ObjectMapper OM = new ObjectMapper(); + private static final ObjectMapper OM = new JsonMapper(); } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/scim/endpoints/ChangeEmailEndpoints.java b/server/src/main/java/org/cloudfoundry/identity/uaa/scim/endpoints/ChangeEmailEndpoints.java index d742b24742e..2bab13a786b 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/scim/endpoints/ChangeEmailEndpoints.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/scim/endpoints/ChangeEmailEndpoints.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.account.EmailChange; import org.cloudfoundry.identity.uaa.account.EmailChangeResponse; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/security/ContextSensitiveOAuth2SecurityExpressionMethods.java b/server/src/main/java/org/cloudfoundry/identity/uaa/security/ContextSensitiveOAuth2SecurityExpressionMethods.java index 0e16b75ce08..c33cfea5cf4 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/security/ContextSensitiveOAuth2SecurityExpressionMethods.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/security/ContextSensitiveOAuth2SecurityExpressionMethods.java @@ -15,7 +15,7 @@ import java.util.Map; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; import org.cloudfoundry.identity.uaa.oauth.UaaOauth2Authentication; import org.cloudfoundry.identity.uaa.oauth.jwt.Jwt; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessor.java b/server/src/main/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessor.java index 50f795fc454..eeb017c524d 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessor.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessor.java @@ -15,6 +15,7 @@ package org.cloudfoundry.identity.uaa.security.web; import jakarta.servlet.RequestDispatcher; +import org.apache.tomcat.util.http.InvalidParameterException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -267,6 +268,13 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) request.getRequestDispatcher("/rejected").forward(request, response); return; } + if (x instanceof InvalidParameterException) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"error\":\"parameter_parsing_error\",\"error_description\":\"One of the parameters was incorrectly encoded\"}"); + response.flushBuffer(); + return; + } ReasonPhrase reasonPhrase = getErrorMap().get(x.getClass()); if (null == reasonPhrase) { for (Class clazz : getErrorMap().keySet()) { diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/util/UaaHttpRequestUtils.java b/server/src/main/java/org/cloudfoundry/identity/uaa/util/UaaHttpRequestUtils.java index ae134a38b6f..84d80e839db 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/util/UaaHttpRequestUtils.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/util/UaaHttpRequestUtils.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.util; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import jakarta.servlet.http.HttpServletRequest; import org.apache.hc.client5.http.ConnectionKeepAliveStrategy; import org.apache.hc.client5.http.HttpRequestRetryStrategy; diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtils.java b/server/src/main/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtils.java index b7d2f6d71a8..58c70b9c121 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtils.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtils.java @@ -10,10 +10,12 @@ import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InsufficientScopeException; import org.cloudfoundry.identity.uaa.oauth.provider.expression.OAuth2ExpressionUtils; import org.cloudfoundry.identity.uaa.security.ContextSensitiveOAuth2SecurityExpressionMethods; +import org.jspecify.annotations.Nullable; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authorization.AuthenticatedAuthorizationManager; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.authorization.AuthorizationResult; import org.springframework.security.core.Authentication; import org.springframework.security.web.access.intercept.RequestAuthorizationContext; @@ -44,13 +46,13 @@ public static class AnyOfAuthorizationManager implements AuthorizationManager missingScopes = new LinkedHashSet<>(); @Override - public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext object) { + public AuthorizationResult authorize(Supplier authentication, RequestAuthorizationContext object) { for (var authorizationManager : this.delegateAuthorizationManagers) { - AuthorizationDecision decision = authorizationManager.check(authentication, object); - if (decision != null) { - if (decision.isGranted()) { - return decision; - } else if (decision instanceof ScopeTrackingAuthorizationDecision scopeDecision) { + AuthorizationResult result = authorizationManager.authorize(authentication, object); + if (result != null) { + if (result.isGranted()) { + return result; + } else if (result instanceof ScopeTrackingAuthorizationDecision scopeDecision) { missingScopes.addAll(scopeDecision.getScopes()); } } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/web/SelfCheckAuthorizationManager.java b/server/src/main/java/org/cloudfoundry/identity/uaa/web/SelfCheckAuthorizationManager.java index 75fd7fcdcc4..b65a21c5b1c 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/web/SelfCheckAuthorizationManager.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/web/SelfCheckAuthorizationManager.java @@ -4,8 +4,10 @@ import jakarta.servlet.http.HttpServletRequest; import org.cloudfoundry.identity.uaa.security.IsSelfCheck; +import org.jspecify.annotations.Nullable; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.authorization.AuthorizationResult; import org.springframework.security.core.Authentication; import org.springframework.security.web.access.intercept.RequestAuthorizationContext; @@ -63,12 +65,12 @@ private SelfCheckAuthorizationManager(CheckType type, IsSelfCheck selfCheck, int } @Override - public void verify(Supplier authentication, RequestAuthorizationContext context) { + public void verify(Supplier authentication, RequestAuthorizationContext context) { AuthorizationManager.super.verify(authentication, context); } @Override - public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) { + public AuthorizationResult authorize(Supplier authentication, RequestAuthorizationContext context) { HttpServletRequest request = context.getRequest(); switch (type) { case USER -> { diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/web/WebConfig.java b/server/src/main/java/org/cloudfoundry/identity/uaa/web/WebConfig.java index 83fad996dba..73418dd941e 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/web/WebConfig.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/web/WebConfig.java @@ -1,22 +1,15 @@ package org.cloudfoundry.identity.uaa.web; import org.cloudfoundry.identity.uaa.authentication.manager.AutologinRequestConverter; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; -/** - * Web stack configuration. It relies on Spring Boot's {@link WebMvcAutoConfiguration}, - * with a few adjustments in a properties file to match the legacy behavior from UAA. - */ @Configuration @EnableWebMvc -@PropertySource("classpath:spring-mvc.properties") class WebConfig implements WebMvcConfigurer { @Override diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/zone/beans/IdentityZoneSecurityConfiguration.java b/server/src/main/java/org/cloudfoundry/identity/uaa/zone/beans/IdentityZoneSecurityConfiguration.java index 8fac364c212..7945723ecc2 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/zone/beans/IdentityZoneSecurityConfiguration.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/zone/beans/IdentityZoneSecurityConfiguration.java @@ -16,6 +16,7 @@ import org.springframework.security.authentication.ProviderManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AnonymousConfigurer; import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer; import org.springframework.security.config.authentication.AuthenticationManagerBeanDefinitionParser; import org.springframework.security.config.http.SessionCreationPolicy; @@ -125,6 +126,7 @@ public SecurityFilterChain identityZones( }) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .addFilterBefore(oauth2ResourceFilter, AbstractPreAuthenticatedProcessingFilter.class) + .anonymous(AnonymousConfigurer::disable) .csrf(CsrfConfigurer::disable) .exceptionHandling(exception -> { exception.authenticationEntryPoint(oauthAuthenticationEntryPoint); diff --git a/server/src/main/resources/spring-mvc.properties b/server/src/main/resources/spring-mvc.properties deleted file mode 100644 index 4e089ef848c..00000000000 --- a/server/src/main/resources/spring-mvc.properties +++ /dev/null @@ -1,22 +0,0 @@ -# ----------------------------------------------------------------------------- -# Spring Boot has some defaults that differ from non-Boot Spring. This file -# configures Boot to match the behaviors from previous xml-based configuration. - - -# ----------------------------------------------------------------------------- -# In a Spring @Controller, when you set values in the Model object and issue a -# redirect with `return "redirect:foobar"`, Spring will append Model attributes -# to the redirect URI by default. Spring Boot does not do this and needs to be -# configured. -# -# See for example InvitationsController#processErrorReload -# Permalink: https://github.com/cloudfoundry/uaa/blob/a7a98407d627857ffdf637f94c3b5763cd3017dc/server/src/main/java/org/cloudfoundry/identity/uaa/invitations/InvitationsController.java#L300-L302 -# This property is deprecated: Deprecated for removal in Spring MVC -# spring.mvc.ignore-default-model-on-redirect=false - - -# ----------------------------------------------------------------------------- -# In Spring, defaults from Jackson are used. Dates (e.g. "2025-02-06T11:04:12") -# are serialized as timestamps, integers that look like 1339478482000000. In -# Spring Boot, by default they are issued as raw strings. -spring.jackson.serialization.write-dates-as-timestamps=true \ No newline at end of file diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/ServerRunningExtension.java b/server/src/test/java/org/cloudfoundry/identity/uaa/ServerRunningExtension.java index 2f994d504b1..6bcce4c5b00 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/ServerRunningExtension.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/ServerRunningExtension.java @@ -34,9 +34,15 @@ import org.springframework.http.client.support.HttpAccessor; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.cfg.ConstructorDetector; +import tools.jackson.databind.json.JsonMapper; import org.springframework.web.util.UriUtils; import java.io.IOException; @@ -44,6 +50,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; +import java.util.List; import java.util.Map; import static java.nio.charset.StandardCharsets.UTF_8; @@ -271,7 +278,7 @@ public ResponseEntity postForRedirect(String path, HttpHeaders headers, Mu } headers.remove("Cookie"); - if (exchange.getHeaders().containsKey("Set-Cookie")) { + if (exchange.getHeaders().containsHeader("Set-Cookie")) { for (String cookie : exchange.getHeaders().get("Set-Cookie")) { headers.add("Cookie", cookie); } @@ -300,6 +307,18 @@ public void setRestTemplate(RestOperations restTemplate) { public RestTemplate createRestTemplate() { RestTemplate newClient = new RestTemplate(); + JsonMapper mapper = JsonMapper.builder() + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .constructorDetector(ConstructorDetector.DEFAULT.withAllowImplicitWithDefaultConstructor(false)) + .build(); + List> converters = newClient.getMessageConverters(); + for (int i = 0; i < converters.size(); i++) { + if (converters.get(i) instanceof JacksonJsonHttpMessageConverter) { + converters.set(i, new JacksonJsonHttpMessageConverter(mapper)); + break; + } + } newClient.setRequestFactory(new StatelessRequestFactory()); newClient.setErrorHandler(new ResponseErrorHandler() { // Pass errors through in response entity for status code analysis diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/annotations/WithDatabaseContext.java b/server/src/test/java/org/cloudfoundry/identity/uaa/annotations/WithDatabaseContext.java index f0cc7c1901a..b76cfc228aa 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/annotations/WithDatabaseContext.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/annotations/WithDatabaseContext.java @@ -7,9 +7,9 @@ import org.cloudfoundry.identity.uaa.util.beans.PasswordEncoderConfig; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration; +import org.springframework.boot.transaction.autoconfigure.TransactionAutoConfiguration; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.test.context.web.WebAppConfiguration; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/CurrentUserCookieRequestFilterTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/CurrentUserCookieRequestFilterTest.java index 8d3ba6dd1c4..8a3a7f2ba8e 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/CurrentUserCookieRequestFilterTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/CurrentUserCookieRequestFilterTest.java @@ -99,8 +99,8 @@ void whenCurrentUserExceptionOccurs_respondWithInternalServerError() throws Curr assertThat(res.getStatus()).isEqualTo(500); assertThat(res.getContentType()).isEqualTo("application/json"); - assertThat(JsonUtils.readTree(res.getContentAsString()).get("error").textValue()).isEqualTo("current_user_cookie_error"); - assertThat(JsonUtils.readTree(res.getContentAsString()).get("error_description").textValue()).isEqualTo("There was a problem while creating the Current-User cookie for user id user-guid"); + assertThat(JsonUtils.readTree(res.getContentAsString()).get("error").asString()).isEqualTo("current_user_cookie_error"); + assertThat(JsonUtils.readTree(res.getContentAsString()).get("error_description").asString()).isEqualTo("There was a problem while creating the Current-User cookie for user id user-guid"); verifyNoInteractions(filterChain); } } \ No newline at end of file diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/EmptyPasswordAwareEncoderTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/EmptyPasswordAwareEncoderTest.java new file mode 100644 index 00000000000..55b5a9cd306 --- /dev/null +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/authentication/EmptyPasswordAwareEncoderTest.java @@ -0,0 +1,73 @@ +package org.cloudfoundry.identity.uaa.authentication; + +import org.junit.jupiter.api.Test; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import static org.assertj.core.api.Assertions.assertThat; + +class EmptyPasswordAwareEncoderTest { + + private final PasswordEncoder bcrypt = new BCryptPasswordEncoder(); + private final EmptyPasswordAwareEncoder encoder = new EmptyPasswordAwareEncoder(bcrypt); + + @Test + void emptyRawPassword_matchesBcryptHashOfEmptyString() { + assertThat(encoder.matches("", bcrypt.encode(""))).isTrue(); + } + + @Test + void emptyRawPassword_matchesNoopPrefixWithEmptyValue() { + assertThat(encoder.matches("", "{noop}")).isTrue(); + } + + @Test + void emptyRawPassword_doesNotMatchBcryptHashOfNonEmptyString() { + assertThat(encoder.matches("", bcrypt.encode("notempty"))).isFalse(); + } + + @Test + void emptyRawPassword_doesNotMatchNullStoredPassword() { + assertThat(encoder.matches("", null)).isFalse(); + } + + @Test + void emptyRawPassword_doesNotMatchRawEmptyStoredValue() { + assertThat(encoder.matches("", "")).isFalse(); + } + + @Test + void emptyRawPassword_doesNotMatchEmptyBracesPrefix() { + assertThat(encoder.matches("", "{}")).isFalse(); + } + + @Test + void emptyRawPassword_doesNotMatchUnknownPrefixWithEmptyValue() { + assertThat(encoder.matches("", "{plaintext}")).isFalse(); + assertThat(encoder.matches("", "{argon2}")).isFalse(); + } + + @Test + void emptyRawPassword_doesNotMatchUnknownPrefixWrappingBcryptEmptyHash() { + String bcryptEmpty = bcrypt.encode(""); + assertThat(encoder.matches("", "{sha256}" + bcryptEmpty)).isFalse(); + } + + @Test + void emptyRawPassword_doesNotMatchBcryptPrefixWithoutHash() { + assertThat(encoder.matches("", "{bcrypt}")).isFalse(); + } + + @Test + void nonEmptyRawPassword_delegatesToWrappedEncoder() { + String encoded = bcrypt.encode("secret"); + assertThat(encoder.matches("secret", encoded)).isTrue(); + assertThat(encoder.matches("wrong", encoded)).isFalse(); + } + + @Test + void encode_delegatesToWrappedEncoder() { + String encoded = encoder.encode("secret"); + assertThat(bcrypt.matches("secret", encoded)).isTrue(); + } +} diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/config/IdentityZoneConfigurationTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/config/IdentityZoneConfigurationTests.java index a1d00f6f18d..13710f028db 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/config/IdentityZoneConfigurationTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/config/IdentityZoneConfigurationTests.java @@ -87,6 +87,16 @@ void deserializeClientSecretPolicyJSON_withUnknownProperties_doesNotFail() { JsonUtils.readValue(config, ClientSecretPolicy.class); } + @Test + void clientSecretPolicy_expireSecretInMonths_isIgnoredInJson() { + ClientSecretPolicy policy = new ClientSecretPolicy(5, 12, 1, 1, 1, 1, 6); + String json = JsonUtils.writeValueAsString(policy); + assertThat(json).doesNotContain("expireSecretInMonths"); + + ClientSecretPolicy back = JsonUtils.readValue(json, ClientSecretPolicy.class); + assertThat(back.getExpireSecretInMonths()).isEqualTo(-1); + } + @Test void deserializeLinksJSON_withUnknownProperties_doesNotFail() { String config = "{ \"unknown-property\": \"unknown-value\"}"; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/login/CurrentUserCookieFactoryTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/login/CurrentUserCookieFactoryTest.java index 1ac83289cb6..e0300c63418 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/login/CurrentUserCookieFactoryTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/login/CurrentUserCookieFactoryTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.login; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/DeprecatedUaaTokenServicesTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/DeprecatedUaaTokenServicesTests.java index 7f087ef22c0..6e74a7cc998 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/DeprecatedUaaTokenServicesTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/DeprecatedUaaTokenServicesTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/approval/ApprovalsAdminEndpointsTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/approval/ApprovalsAdminEndpointsTests.java index 290d4566e00..b2ae9d9f857 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/approval/ApprovalsAdminEndpointsTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/approval/ApprovalsAdminEndpointsTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth.approval; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.unboundid.scim.sdk.AttributePath; import com.unboundid.scim.sdk.SCIMFilter; import org.cloudfoundry.identity.uaa.annotations.WithDatabaseContext; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/RsaJsonWebKeyTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/RsaJsonWebKeyTests.java index b5ebd800473..70732d44c71 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/RsaJsonWebKeyTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwk/RsaJsonWebKeyTests.java @@ -15,7 +15,7 @@ package org.cloudfoundry.identity.uaa.oauth.jwk; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.nimbusds.jose.util.Base64URL; import com.nimbusds.jose.util.BigIntegerUtils; import org.apache.commons.collections4.map.HashedMap; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwt/JwtHeaderHelperTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwt/JwtHeaderHelperTest.java index cadc79c139f..48973734fd0 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwt/JwtHeaderHelperTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/jwt/JwtHeaderHelperTest.java @@ -1,7 +1,8 @@ package org.cloudfoundry.identity.uaa.oauth.jwt; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; import org.cloudfoundry.identity.uaa.test.RandomParametersJunitExtension; import org.cloudfoundry.identity.uaa.test.RandomParametersJunitExtension.RandomValue; import org.junit.jupiter.api.BeforeEach; @@ -33,7 +34,7 @@ class JWS { @BeforeEach void setup() { - objectNode = new ObjectMapper().createObjectNode(); + objectNode = new JsonMapper().createObjectNode(); objectNode.put("kid", "key-id"); objectNode.put("alg", "key-alg"); objectNode.put("enc", "key-encoding"); @@ -114,7 +115,7 @@ void shouldSerializeOnlyWithValidRequiredHeaders() { class OptionalHeaders { @BeforeEach void setup() { - objectNode = new ObjectMapper().createObjectNode(); + objectNode = new JsonMapper().createObjectNode(); } @ParameterizedTest diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/AbstractDefaultTokenServicesTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/AbstractDefaultTokenServicesTests.java index e799cc0a280..2f39560560e 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/AbstractDefaultTokenServicesTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/AbstractDefaultTokenServicesTests.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; import java.io.Serial; import java.util.Arrays; @@ -244,7 +245,7 @@ protected static class TestAuthentication extends AbstractAuthenticationToken { private final String principal; public TestAuthentication(String name, boolean authenticated) { - super(null); + super((Collection) null); setAuthenticated(authenticated); this.principal = name; } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/ClientDetailsServiceBuilder.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/ClientDetailsServiceBuilder.java index 97199d22e5b..38990099265 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/ClientDetailsServiceBuilder.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/ClientDetailsServiceBuilder.java @@ -25,15 +25,15 @@ public class ClientDetailsServiceBuilder clientBuilders = new ArrayList<>(); - public InMemoryClientDetailsServiceBuilder inMemory() throws Exception { + public InMemoryClientDetailsServiceBuilder inMemory() { return new InMemoryClientDetailsServiceBuilder(); } @SuppressWarnings("rawtypes") - public ClientDetailsServiceBuilder clients(final ClientDetailsService clientDetailsService) throws Exception { + public ClientDetailsServiceBuilder clients(final ClientDetailsService clientDetailsService) { return new ClientDetailsServiceBuilder() { @Override - public ClientDetailsService build() throws Exception { + public ClientDetailsService build() { return clientDetailsService; } }; @@ -46,7 +46,7 @@ public ClientBuilder withClient(String clientId) { } @Override - public ClientDetailsService build() throws Exception { + public ClientDetailsService build() { for (ClientBuilder clientDetailsBldr : clientBuilders) { addClient(clientDetailsBldr.clientId, clientDetailsBldr.build()); } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/TokenStoreBaseTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/TokenStoreBaseTests.java index d09b54713f8..0481697a568 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/TokenStoreBaseTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/provider/token/TokenStoreBaseTests.java @@ -10,6 +10,7 @@ import org.cloudfoundry.identity.uaa.oauth.provider.RequestTokenFactory; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; import java.io.Serial; import java.util.Collection; @@ -203,7 +204,7 @@ protected static class TestAuthentication extends AbstractAuthenticationToken { private final String principal; public TestAuthentication(String name, boolean authenticated) { - super(null); + super((Collection) null); setAuthenticated(authenticated); this.principal = name; } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/matchers/AbstractOAuth2AccessTokenMatchers.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/matchers/AbstractOAuth2AccessTokenMatchers.java index f35422ec0b3..00298a949d8 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/matchers/AbstractOAuth2AccessTokenMatchers.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/token/matchers/AbstractOAuth2AccessTokenMatchers.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth.token.matchers; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.oauth.KeyInfoService; import org.cloudfoundry.identity.uaa.oauth.common.OAuth2AccessToken; import org.cloudfoundry.identity.uaa.oauth.common.OAuth2RefreshToken; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerIT.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerIT.java index 225813b5622..6dd31a442e1 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerIT.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerIT.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.provider.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.github.benmanes.caffeine.cache.Ticker; import com.nimbusds.jose.JWSSigner; import org.apache.commons.codec.binary.Base64; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerTest.java index f31894bd580..3aba7797f69 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/oauth/ExternalOAuthAuthenticationManagerTest.java @@ -952,10 +952,10 @@ void oidcJwtBearerProviderProxyThrowException() throws JOSEException, MalformedU })); HttpEntity httpEntity = httpEntityArgumentCaptor.getValue(); HttpHeaders httpHeaders = httpEntity.getHeaders(); - assertThat(httpHeaders).containsKey("Authorization") - .containsEntry("Authorization", Collections.singletonList("Basic aWRlbnRpdHk6c2VjcmV0")) - .containsKey("Accept") - .containsEntry("Content-Type", Collections.singletonList("application/x-www-form-urlencoded")); + assertThat(httpHeaders.containsHeader("Authorization")).isTrue(); + assertThat(httpHeaders.get("Authorization")).isEqualTo(Collections.singletonList("Basic aWRlbnRpdHk6c2VjcmV0")); + assertThat(httpHeaders.containsHeader("Accept")).isTrue(); + assertThat(httpHeaders.get("Content-Type")).isEqualTo(Collections.singletonList("application/x-www-form-urlencoded")); } @Test @@ -1012,7 +1012,7 @@ void oidcPasswordGrantWithForwardHeader() throws JOSEException, MalformedURLExce assertThat(headers.getAccept()).isEqualTo(Collections.singletonList(MediaType.APPLICATION_JSON)); assertThat(headers.getContentType()).isEqualTo(MediaType.APPLICATION_FORM_URLENCODED); assertAuthorizationHeaderIsSetAndStartsWithBasic(headers); - assertThat(headers).containsKey("X-Forwarded-For"); + assertThat(headers.containsHeader("X-Forwarded-For")).isTrue(); final List xForwardedForHeaders = headers.get("X-Forwarded-For"); assertThat(xForwardedForHeaders).hasSize(1); assertThat(xForwardedForHeaders.getFirst()).isEqualTo("203.0.113.1"); @@ -1117,7 +1117,7 @@ void oidcPasswordGrantWithPrompts() throws MalformedURLException, JOSEException assertThat(headers.getAccept()).isEqualTo(Collections.singletonList(MediaType.APPLICATION_JSON)); assertThat(headers.getContentType()).isEqualTo(MediaType.APPLICATION_FORM_URLENCODED); assertAuthorizationHeaderIsSetAndStartsWithBasic(headers); - assertThat(headers).doesNotContainKey("X-Forwarded-For"); + assertThat(headers.containsHeader("X-Forwarded-For")).isFalse(); } @Test @@ -1165,7 +1165,7 @@ public RestTemplate getRestTemplate(AbstractExternalOAuthIdentityProviderDefinit } private static void assertAuthorizationHeaderIsSetAndStartsWithBasic(final HttpHeaders headers) { - assertThat(headers).containsKey("Authorization"); + assertThat(headers.containsHeader("Authorization")).isTrue(); final List authorizationHeaders = headers.get("Authorization"); assertThat(authorizationHeaders).hasSize(1); assertThat(authorizationHeaders.getFirst()).startsWith("Basic "); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/ConfiguratorRelyingPartyRegistrationRepositoryTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/ConfiguratorRelyingPartyRegistrationRepositoryTest.java index 64cdc94eff9..a26e27c7532 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/ConfiguratorRelyingPartyRegistrationRepositoryTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/ConfiguratorRelyingPartyRegistrationRepositoryTest.java @@ -16,6 +16,7 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.security.saml2.Saml2Exception; import org.springframework.security.saml2.core.Saml2X509Credential; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.util.FileCopyUtils; @@ -119,8 +120,8 @@ void findByRegistrationIdWithMultipleInDb() { .returns("{baseUrl}/saml/SSO/alias/entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", RelyingPartyRegistration.AssertingPartyDetails::getEntityId); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", AssertingPartyMetadata::getEntityId); } @Test @@ -167,8 +168,8 @@ void buildsCorrectRegistrationWhenMetadataXmlIsStored() { .returns("{baseUrl}/saml/SSO/alias/entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", RelyingPartyRegistration.AssertingPartyDetails::getEntityId); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", AssertingPartyMetadata::getEntityId); } @Test @@ -222,8 +223,8 @@ void buildsCorrectRegistrationWhenMetadataLocationIsStored() { .returns("{baseUrl}/saml/SSO/alias/entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", RelyingPartyRegistration.AssertingPartyDetails::getEntityId); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", AssertingPartyMetadata::getEntityId); } @Test @@ -271,10 +272,10 @@ void buildsCorrectRegistrationWhenZoneIdIsStored() { .returns("{baseUrl}/saml/SSO/alias/zoneDomain.entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/zoneDomain.entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", RelyingPartyRegistration.AssertingPartyDetails::getEntityId) + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", AssertingPartyMetadata::getEntityId) // signature algorithm defaults to SHA256 - .extracting(RelyingPartyRegistration.AssertingPartyDetails::getSigningAlgorithms) + .extracting(AssertingPartyMetadata::getSigningAlgorithms) .isEqualTo(List.of(ALGO_ID_SIGNATURE_RSA_SHA256)); } @@ -347,7 +348,7 @@ void withSha512SignatureAlgorithm() { when(configurator.getIdentityProviderDefinitionsForZone(identityZone)).thenReturn(List.of(definition)); RelyingPartyRegistration registration = repository.findByRegistrationId(REGISTRATION_ID); - assertThat(registration.getAssertingPartyDetails().getSigningAlgorithms()) + assertThat(registration.getAssertingPartyMetadata().getSigningAlgorithms()) .hasSize(1) .first() .isEqualTo(ALGO_ID_SIGNATURE_RSA_SHA512); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/DefaultRelyingPartyRegistrationRepositoryTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/DefaultRelyingPartyRegistrationRepositoryTest.java index 86d370329bc..40f3543f6be 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/DefaultRelyingPartyRegistrationRepositoryTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/DefaultRelyingPartyRegistrationRepositoryTest.java @@ -12,6 +12,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.saml2.core.Saml2X509Credential; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import java.security.Security; @@ -81,8 +82,8 @@ void findByRegistrationId() { .returns("{baseUrl}/saml/SSO/alias/entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("entityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("entityId", AssertingPartyMetadata::getEntityId); } @Test @@ -104,10 +105,10 @@ void findByRegistrationIdForZone() { .returns("{baseUrl}/saml/SSO/alias/testzone.entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/testzone.entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("testzone.entityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId) + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("testzone.entityId", AssertingPartyMetadata::getEntityId) // signature algorithm defaults to SHA256 - .extracting(RelyingPartyRegistration.AssertingPartyDetails::getSigningAlgorithms) + .extracting(AssertingPartyMetadata::getSigningAlgorithms) .isEqualTo(List.of(ALGO_ID_SIGNATURE_RSA_SHA256)); } @@ -204,7 +205,7 @@ void withSha512SignatureAlgorithm() { when(identityZoneConfig.getSamlConfig()).thenReturn(samlConfig); RelyingPartyRegistration registration = repository.findByRegistrationId(REGISTRATION_ID); - assertThat(registration.getAssertingPartyDetails().getSigningAlgorithms()) + assertThat(registration.getAssertingPartyMetadata().getSigningAlgorithms()) .hasSize(1) .first() .isEqualTo(ALGO_ID_SIGNATURE_RSA_SHA512); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProviderUnitTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProviderUnitTests.java index 4f4ed1092e3..951f2989d33 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProviderUnitTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/OpenSaml5AuthenticationProviderUnitTests.java @@ -1,6 +1,5 @@ package org.cloudfoundry.identity.uaa.provider.saml; -import com.fasterxml.jackson.databind.ObjectMapper; import net.shibboleth.shared.xml.SerializeSupport; import org.cloudfoundry.identity.uaa.provider.saml.OpenSaml5AuthenticationProvider.ResponseToken; import org.cloudfoundry.identity.uaa.zone.IdentityZone; @@ -501,8 +500,8 @@ void authenticateWhenAssertionContainsAttributesThenItSucceeds() { // gh-11785 @Test void deserializeWhenAssertionContainsAttributesThenWorks() throws Exception { - ObjectMapper mapper = new ObjectMapper(); ClassLoader loader = getClass().getClassLoader(); + com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper(); mapper.registerModules(SecurityJackson2Modules.getModules(loader)); Response response = response(); Assertion assertion = assertion(); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilderTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilderTest.java index 28a4f962970..163323162dd 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilderTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/RelyingPartyRegistrationBuilderTest.java @@ -7,6 +7,7 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.security.saml2.Saml2Exception; import org.springframework.security.saml2.core.Saml2X509Credential; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.util.FileCopyUtils; @@ -54,9 +55,9 @@ void buildsRelyingPartyRegistrationFromLocation() { .returns("{baseUrl}/saml/SSO/alias/entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", RelyingPartyRegistration.AssertingPartyDetails::getEntityId) - .returns(true, RelyingPartyRegistration.AssertingPartyDetails::getWantAuthnRequestsSigned); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", AssertingPartyMetadata::getEntityId) + .returns(true, AssertingPartyMetadata::getWantAuthnRequestsSigned); } @Test @@ -83,9 +84,9 @@ void buildsRelyingPartyRegistrationFromXML() { .returns("{baseUrl}/saml/SSO/alias/entityIdAlias", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityIdAlias", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", RelyingPartyRegistration.AssertingPartyDetails::getEntityId) - .returns(false, RelyingPartyRegistration.AssertingPartyDetails::getWantAuthnRequestsSigned); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("https://idp-saml.ua3.int/simplesaml/saml2/idp/metadata.php", AssertingPartyMetadata::getEntityId) + .returns(false, AssertingPartyMetadata::getWantAuthnRequestsSigned); } @Test @@ -114,7 +115,7 @@ void withCredentials() { .extracting(Saml2X509Credential::getCertificate) .containsOnly(x509Certificate1()); - assertThat(registration.getAssertingPartyDetails().getSigningAlgorithms()) + assertThat(registration.getAssertingPartyMetadata().getSigningAlgorithms()) .hasSize(2) .containsOnly(SignatureAlgorithm.SHA512.getSignatureAlgorithmURI(), SignatureAlgorithm.SHA256.getSignatureAlgorithmURI()); } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2BearerGrantAuthenticationConverterTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2BearerGrantAuthenticationConverterTest.java index d8a57f3459c..85a7cb18c99 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2BearerGrantAuthenticationConverterTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2BearerGrantAuthenticationConverterTest.java @@ -1,6 +1,5 @@ package org.cloudfoundry.identity.uaa.provider.saml; -import com.fasterxml.jackson.databind.ObjectMapper; import net.shibboleth.shared.xml.SerializeSupport; import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; import org.cloudfoundry.identity.uaa.impl.config.RestTemplateConfig; @@ -259,8 +258,8 @@ void authenticateWhenAssertionContainsAttributesThenItSucceeds() { // gh-11785 @Test void deserializeWhenAssertionContainsAttributesThenWorks() throws Exception { - ObjectMapper mapper = new ObjectMapper(); ClassLoader loader = getClass().getClassLoader(); + com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper(); mapper.registerModules(SecurityJackson2Modules.getModules(loader)); Assertion assertion = assertion(); List attributes = TestOpenSamlObjects.attributeStatements(); @@ -557,11 +556,11 @@ private RelyingPartyRegistration.Builder registration() { return TestRelyingPartyRegistrations.noCredentials() .entityId(RELYING_PARTY_ENTITY_ID) .assertionConsumerServiceLocation(DESTINATION) - .assertingPartyDetails(party -> party.entityId(ASSERTING_PARTY_ENTITY_ID)); + .assertingPartyMetadata(party -> party.entityId(ASSERTING_PARTY_ENTITY_ID)); } private RelyingPartyRegistration.Builder verifying(RelyingPartyRegistration.Builder builder) { - return builder.assertingPartyDetails(party -> party + return builder.assertingPartyMetadata(party -> party .verificationX509Credentials(c -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))); } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2TestUtils.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2TestUtils.java index 1cfe92c6b9a..6ea0d9860e7 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2TestUtils.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/Saml2TestUtils.java @@ -244,11 +244,11 @@ public static RelyingPartyRegistration.Builder registration() { return TestRelyingPartyRegistrations.noCredentials() .entityId(RELYING_PARTY_ENTITY_ID) .assertionConsumerServiceLocation(DESTINATION) - .assertingPartyDetails(party -> party.entityId(ASSERTING_PARTY_ENTITY_ID)); + .assertingPartyMetadata(party -> party.entityId(ASSERTING_PARTY_ENTITY_ID)); } public static RelyingPartyRegistration.Builder verifying(RelyingPartyRegistration.Builder builder) { - return builder.assertingPartyDetails(party -> party + return builder.assertingPartyMetadata(party -> party .verificationX509Credentials(c -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))); } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfiguratorTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfiguratorTests.java index 0e1344b17b4..ed887219734 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfiguratorTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlIdentityProviderConfiguratorTests.java @@ -147,7 +147,7 @@ void getEntityID() { } case "simplesamlphp-url": { RelyingPartyRegistration extendedMetadataDelegate = configurator.getExtendedMetadataDelegate(def); - assertThat(extendedMetadataDelegate.getAssertingPartyDetails().getEntityId()).isEqualTo("http://simplesamlphp.somewhere.com/saml2/idp/metadata.php"); + assertThat(extendedMetadataDelegate.getAssertingPartyMetadata().getEntityId()).isEqualTo("http://simplesamlphp.somewhere.com/saml2/idp/metadata.php"); break; } default: diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlRelyingPartyRegistrationRepositoryConfigTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlRelyingPartyRegistrationRepositoryConfigTest.java index b733e64b3eb..3928d4f7cdc 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlRelyingPartyRegistrationRepositoryConfigTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/SamlRelyingPartyRegistrationRepositoryConfigTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; @@ -85,7 +86,7 @@ void buildsRegistrationForExample() { .returns("{baseUrl}/saml/SSO/alias/entityId", RelyingPartyRegistration::getAssertionConsumerServiceLocation) .returns("{baseUrl}/saml/SingleLogout/alias/entityId", RelyingPartyRegistration::getSingleLogoutServiceResponseLocation) // from xml - .extracting(RelyingPartyRegistration::getAssertingPartyDetails) - .returns("entityId", RelyingPartyRegistration.AssertingPartyDetails::getEntityId); + .extracting(RelyingPartyRegistration::getAssertingPartyMetadata) + .returns("entityId", AssertingPartyMetadata::getEntityId); } } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestOpenSamlObjects.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestOpenSamlObjects.java index 36720470fab..380a9d41d82 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestOpenSamlObjects.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestOpenSamlObjects.java @@ -503,7 +503,7 @@ public static LogoutRequest assertingPartyLogoutRequest(RelyingPartyRegistration logoutRequest.setNameID(nameId); IssuerBuilder issuerBuilder = new IssuerBuilder(); Issuer issuer = issuerBuilder.buildObject(); - issuer.setValue(registration.getAssertingPartyDetails().getEntityId()); + issuer.setValue(registration.getAssertingPartyMetadata().getEntityId()); logoutRequest.setIssuer(issuer); logoutRequest.setDestination(registration.getSingleLogoutServiceLocation()); return logoutRequest; @@ -517,7 +517,7 @@ public static LogoutRequest assertingPartyLogoutRequestNameIdInEncryptedId(Relyi NameID nameId = nameIdBuilder.buildObject(); nameId.setValue("user"); logoutRequest.setNameID(null); - Saml2X509Credential credential = registration.getAssertingPartyDetails() + Saml2X509Credential credential = registration.getAssertingPartyMetadata() .getEncryptionX509Credentials() .iterator() .next(); @@ -525,7 +525,7 @@ public static LogoutRequest assertingPartyLogoutRequestNameIdInEncryptedId(Relyi logoutRequest.setEncryptedID(encrypted); IssuerBuilder issuerBuilder = new IssuerBuilder(); Issuer issuer = issuerBuilder.buildObject(); - issuer.setValue(registration.getAssertingPartyDetails().getEntityId()); + issuer.setValue(registration.getAssertingPartyMetadata().getEntityId()); logoutRequest.setIssuer(issuer); logoutRequest.setDestination(registration.getSingleLogoutServiceLocation()); return logoutRequest; @@ -544,7 +544,7 @@ public static LogoutResponse assertingPartyLogoutResponse(RelyingPartyRegistrati logoutResponse.setStatus(status); IssuerBuilder issuerBuilder = new IssuerBuilder(); Issuer issuer = issuerBuilder.buildObject(); - issuer.setValue(registration.getAssertingPartyDetails().getEntityId()); + issuer.setValue(registration.getAssertingPartyMetadata().getEntityId()); logoutResponse.setIssuer(issuer); logoutResponse.setDestination(registration.getSingleLogoutServiceResponseLocation()); return logoutResponse; @@ -561,9 +561,9 @@ public static LogoutRequest relyingPartyLogoutRequest(RelyingPartyRegistration r logoutRequest.setNameID(nameId); IssuerBuilder issuerBuilder = new IssuerBuilder(); Issuer issuer = issuerBuilder.buildObject(); - issuer.setValue(registration.getAssertingPartyDetails().getEntityId()); + issuer.setValue(registration.getAssertingPartyMetadata().getEntityId()); logoutRequest.setIssuer(issuer); - logoutRequest.setDestination(registration.getAssertingPartyDetails().getSingleLogoutServiceLocation()); + logoutRequest.setDestination(registration.getAssertingPartyMetadata().getSingleLogoutServiceLocation()); return logoutRequest; } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestRelyingPartyRegistrations.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestRelyingPartyRegistrations.java index 2bfe428f869..7719263ecf1 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestRelyingPartyRegistrations.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/TestRelyingPartyRegistrations.java @@ -48,7 +48,7 @@ public static RelyingPartyRegistration.Builder relyingPartyRegistration() { .nameIdFormat("format") .assertionConsumerServiceLocation(assertionConsumerServiceLocation) .singleLogoutServiceLocation(singleLogoutServiceLocation) - .assertingPartyDetails(c -> c.entityId(apEntityId).singleSignOnServiceLocation(singleSignOnServiceLocation)) + .assertingPartyMetadata(c -> c.entityId(apEntityId).singleSignOnServiceLocation(singleSignOnServiceLocation)) .signingX509Credentials(c -> c.add(signingCredential)) .decryptionX509Credentials(c -> c.add(verificationCertificate)); } @@ -59,7 +59,7 @@ public static RelyingPartyRegistration.Builder noCredentials() { .singleLogoutServiceLocation("https://rp.example.org/logout/saml2/request") .singleLogoutServiceResponseLocation("https://rp.example.org/logout/saml2/response") .assertionConsumerServiceLocation("https://rp.example.org/acs") - .assertingPartyDetails(party -> party.entityId("ap-entity-id") + .assertingPartyMetadata(party -> party.entityId("ap-entity-id") .singleSignOnServiceLocation("https://ap.example.org/sso") .singleLogoutServiceLocation("https://ap.example.org/logout/saml2/request") .singleLogoutServiceResponseLocation("https://ap.example.org/logout/saml2/response")); @@ -69,7 +69,7 @@ public static RelyingPartyRegistration.Builder full() { return noCredentials() .signingX509Credentials(c -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential())) .decryptionX509Credentials(c -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential())) - .assertingPartyDetails(party -> party.verificationX509Credentials( + .assertingPartyMetadata(party -> party.verificationX509Credentials( c -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))); } } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandlerTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandlerTest.java index 92518cd3ad9..e847f2a8490 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandlerTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaDelegatingLogoutSuccessHandlerTest.java @@ -10,6 +10,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.core.Authentication; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2RelyingPartyInitiatedLogoutSuccessHandler; @@ -82,8 +83,8 @@ void shouldPerformSamlRelyingPartyLogout() throws ServletException, IOException when(mockPrincipal.getRelyingPartyRegistrationId()).thenReturn(REG_ID); var mockRegistration = mock(RelyingPartyRegistration.class); when(relyingPartyRegistrationResolver.resolve(any(), eq(REG_ID))).thenReturn(mockRegistration); - var mockAssertingPartyDetails = mock(RelyingPartyRegistration.AssertingPartyDetails.class); - when(mockRegistration.getAssertingPartyDetails()).thenReturn(mockAssertingPartyDetails); + var mockAssertingPartyDetails = mock(AssertingPartyMetadata.class); + when(mockRegistration.getAssertingPartyMetadata()).thenReturn(mockAssertingPartyDetails); when(mockAssertingPartyDetails.getSingleLogoutServiceLocation()).thenReturn(URL); logoutSuccessHandler.onLogoutSuccess(request, response, authentication); @@ -140,8 +141,8 @@ void nullSingleLogoutServiceLocationFallsThruToZoneAwareWhitelistLogoutHandler() when(mockPrincipal.getRelyingPartyRegistrationId()).thenReturn(REG_ID); var mockRegistration = mock(RelyingPartyRegistration.class); when(relyingPartyRegistrationResolver.resolve(any(), eq(REG_ID))).thenReturn(mockRegistration); - var mockAssertingPartyDetails = mock(RelyingPartyRegistration.AssertingPartyDetails.class); - when(mockRegistration.getAssertingPartyDetails()).thenReturn(mockAssertingPartyDetails); + var mockAssertingPartyDetails = mock(AssertingPartyMetadata.class); + when(mockRegistration.getAssertingPartyMetadata()).thenReturn(mockAssertingPartyDetails); logoutSuccessHandler.onLogoutSuccess(request, response, authentication); verifyCorrectOnLogoutSuccessCalled(false, false, true); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolverTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolverTests.java index 47f98c2c8b1..dc30ff63129 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolverTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/provider/saml/UaaRelyingPartyRegistrationResolverTests.java @@ -24,6 +24,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; +import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; @@ -34,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -104,16 +106,25 @@ void resolveWhenRequestIsWithValiddSamlResponseFromSimplySamlButNoTrust() { void resolveWhenRequestIsWithValiddSamlResponseFromSimplySaml() { MockHttpServletRequest request = new MockHttpServletRequest(); RelyingPartyRegistration newMock = mock(RelyingPartyRegistration.class); - RelyingPartyRegistration.AssertingPartyDetails details = mock(RelyingPartyRegistration.AssertingPartyDetails.class); + RelyingPartyRegistration.Builder builder = mock(RelyingPartyRegistration.Builder.class); + AssertingPartyMetadata details = mock(AssertingPartyMetadata.class); doReturn("simpleID").when(newMock).getRegistrationId(); doReturn("simpleEndityID").when(newMock).getEntityId(); - doReturn(details).when(newMock).getAssertingPartyDetails(); + doReturn(details).when(newMock).getAssertingPartyMetadata(); doReturn("simpleEndityID").when(details).getEntityId(); doReturn("sso").when(details).getSingleSignOnServiceLocation(); doReturn("acs").when(newMock).getAssertionConsumerServiceLocation(); + doReturn("sls").when(newMock).getSingleLogoutServiceLocation(); + doReturn("slsr").when(newMock).getSingleLogoutServiceResponseLocation(); doReturn(mock(Saml2MessageBinding.class)).when(newMock).getSingleLogoutServiceBinding(); doReturn(mock(Saml2MessageBinding.class)).when(details).getSingleSignOnServiceBinding(); doReturn(mock(Saml2MessageBinding.class)).when(newMock).getAssertionConsumerServiceBinding(); + doReturn(builder).when(newMock).mutate(); + doReturn(builder).when(builder).entityId(anyString()); + doReturn(builder).when(builder).assertionConsumerServiceLocation(anyString()); + doReturn(builder).when(builder).singleLogoutServiceLocation(anyString()); + doReturn(builder).when(builder).singleLogoutServiceResponseLocation(anyString()); + doReturn(newMock).when(builder).build(); doReturn(newMock).when(repository).findByRegistrationId("http://uaa-acceptance.cf-app.com/saml-idp"); request.setRequestURI("/some/path/cloudfoundry-saml-login"); request.setMethod("POST"); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/security/CsrfAwareEntryPointAndDeniedHandlerTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/security/CsrfAwareEntryPointAndDeniedHandlerTest.java index 2b7f127fc94..beea633b157 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/security/CsrfAwareEntryPointAndDeniedHandlerTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/security/CsrfAwareEntryPointAndDeniedHandlerTest.java @@ -53,7 +53,7 @@ void handleWhenNotLoggedInAndNoCsrf() throws Exception { assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FOUND); assertThat(ex).isSameAs(request.getAttribute(WebAttributes.ACCESS_DENIED_403)); assertThat(response.isCommitted()).isTrue(); - assertThat(response.getHeader("Location")).isEqualTo("http://localhost/login"); + assertThat(response.getHeader("Location")).isEqualTo("/login"); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_MOVED_TEMPORARILY); } @@ -74,7 +74,7 @@ void handleWhenNotLoggedIn() throws Exception { assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_FOUND); assertThat(ex).isSameAs(request.getAttribute(WebAttributes.ACCESS_DENIED_403)); assertThat(response.isCommitted()).isTrue(); - assertThat(response.getHeader("Location")).isEqualTo("http://localhost/login"); + assertThat(response.getHeader("Location")).isEqualTo("/login"); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_MOVED_TEMPORARILY); } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessorTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessorTests.java index 72238f9dd49..71ed3c8358a 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessorTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/security/web/SecurityFilterChainPostProcessorTests.java @@ -1,8 +1,11 @@ package org.cloudfoundry.identity.uaa.security.web; +import org.apache.tomcat.util.http.InvalidParameterException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.web.SecurityFilterChain; import jakarta.servlet.Filter; @@ -146,4 +149,22 @@ public static class AfterFilter extends TestFilter1 { public static class BeforeFilter extends TestFilter1 { } + + @Test + void uaaLoggingFilter_invalidParameterException_returns400JsonAndDoesNotPropagate() throws Exception { + processor.postProcessAfterInitialization(fc, ""); + Filter loggingFilter = fc.getFilters().getFirst(); + + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/oauth/token"); + MockHttpServletResponse response = new MockHttpServletResponse(); + FilterChain chain = (req, res) -> { + throw new InvalidParameterException("bad encoding"); + }; + + loggingFilter.doFilter(request, response, chain); + + assertThat(response.getStatus()).isEqualTo(400); + assertThat(response.getContentType()).contains("application/json"); + assertThat(response.getContentAsString()).contains("parameter_parsing_error"); + } } \ No newline at end of file diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/test/network/NetworkTestUtils.java b/server/src/test/java/org/cloudfoundry/identity/uaa/test/network/NetworkTestUtils.java index 396d196a190..9c9af7f819e 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/test/network/NetworkTestUtils.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/test/network/NetworkTestUtils.java @@ -167,11 +167,11 @@ public boolean wasInvoked() { public void handle(HttpExchange httpExchange) throws IOException { wasInvoked = true; HttpsExchange exchange = (HttpsExchange) httpExchange; - for (Map.Entry> entry : headers.entrySet()) { - for (String value : entry.getValue()) { - exchange.getResponseHeaders().add(entry.getKey(), value); + headers.forEach((key, values) -> { + for (String value : values) { + exchange.getResponseHeaders().add(key, value); } - } + }); exchange.getResponseHeaders().add("Access-Control-Allow-Origin", "*"); exchange.sendResponseHeaders(200, responseBody.length()); OutputStream os = exchange.getResponseBody(); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtilsTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtilsTests.java index 0a8c1785335..09c422e5eaf 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtilsTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/web/AuthorizationManagersUtilsTests.java @@ -6,6 +6,7 @@ import org.cloudfoundry.identity.uaa.test.ModelTestUtils; import org.cloudfoundry.identity.uaa.zone.IdentityZone; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.AnonymousAuthenticationToken; @@ -43,7 +44,7 @@ static void afterAll() { void noAuthenticationManager() { AuthorizationManager authManager = AuthorizationManagersUtils.anyOf(); - var authorizationDecision = authManager.check(() -> FULLY_AUTHENTICATED, null); + var authorizationDecision = authManager.authorize(() -> FULLY_AUTHENTICATED, null); assertThat(authorizationDecision.isGranted()).isFalse(); } @@ -53,11 +54,11 @@ void oneAuthenticationManager() { var granted = granted(); var notGranted = notGranted(); var unknown = unknown(); - assertThat(AuthorizationManagersUtils.anyOf().or(granted).check(() -> FULLY_AUTHENTICATED, null).isGranted()).isTrue(); + assertThat(AuthorizationManagersUtils.anyOf().or(granted).authorize(() -> FULLY_AUTHENTICATED, null).isGranted()).isTrue(); assertThat(granted.called).isTrue(); - assertThat(AuthorizationManagersUtils.anyOf().or(notGranted).check(() -> FULLY_AUTHENTICATED, null).isGranted()).isFalse(); + assertThat(AuthorizationManagersUtils.anyOf().or(notGranted).authorize(() -> FULLY_AUTHENTICATED, null).isGranted()).isFalse(); assertThat(notGranted.called).isTrue(); - assertThat(AuthorizationManagersUtils.anyOf().or(unknown).check(() -> FULLY_AUTHENTICATED, null).isGranted()).isFalse(); + assertThat(AuthorizationManagersUtils.anyOf().or(unknown).authorize(() -> FULLY_AUTHENTICATED, null).isGranted()).isFalse(); assertThat(unknown.called).isTrue(); } @@ -71,7 +72,7 @@ void manyAuthenticationManagers() { .or(granted) .or(unknown); - assertThat(authorizationManager.check(() -> FULLY_AUTHENTICATED, null).isGranted()).isTrue(); + assertThat(authorizationManager.authorize(() -> FULLY_AUTHENTICATED, null).isGranted()).isTrue(); assertThat(notGranted.called).isTrue(); assertThat(granted.called).isTrue(); assertThat(unknown.called).isFalse(); @@ -82,10 +83,10 @@ void anonymous() { AuthorizationManager authManager = AuthorizationManagersUtils.anyOf() .anonymous(); - assertThat(authManager.check(() -> ANONYMOUS, null).isGranted()).isTrue(); - assertThat(authManager.check(() -> NOT_AUTHENTICATED, null).isGranted()).isFalse(); - assertThat(authManager.check(() -> FULLY_AUTHENTICATED, null).isGranted()).isFalse(); - assertThat(authManager.check(() -> REMEMBER_ME, null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> ANONYMOUS, null).isGranted()).isTrue(); + assertThat(authManager.authorize(() -> NOT_AUTHENTICATED, null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> FULLY_AUTHENTICATED, null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> REMEMBER_ME, null).isGranted()).isFalse(); } @Test @@ -93,26 +94,26 @@ void fullyAuthenticated() { AuthorizationManager authManager = AuthorizationManagersUtils.anyOf() .fullyAuthenticated(); - assertThat(authManager.check(() -> ANONYMOUS, null).isGranted()).isFalse(); - assertThat(authManager.check(() -> NOT_AUTHENTICATED, null).isGranted()).isFalse(); - assertThat(authManager.check(() -> FULLY_AUTHENTICATED, null).isGranted()).isTrue(); - assertThat(authManager.check(() -> REMEMBER_ME, null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> ANONYMOUS, null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> NOT_AUTHENTICATED, null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> FULLY_AUTHENTICATED, null).isGranted()).isTrue(); + assertThat(authManager.authorize(() -> REMEMBER_ME, null).isGranted()).isFalse(); } @Test void uaaAdmin() { AuthorizationManager authManager = AuthorizationManagersUtils.anyOf().isUaaAdmin(); - assertThat(authManager.check(() -> withScopes("foo.bar"), null).isGranted()).isFalse(); - assertThat(authManager.check(() -> withScopes("uaa.admin"), null).isGranted()).isTrue(); + assertThat(authManager.authorize(() -> withScopes("foo.bar"), null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> withScopes("uaa.admin"), null).isGranted()).isTrue(); } @Test void hasScope() { AuthorizationManager authManager = AuthorizationManagersUtils.anyOf().hasScope("foo.bar"); - assertThat(authManager.check(() -> withScopes("uaa.admin"), null).isGranted()).isFalse(); - assertThat(authManager.check(() -> withScopes("uaa.admin", "foo.bar"), null).isGranted()).isTrue(); + assertThat(authManager.authorize(() -> withScopes("uaa.admin"), null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> withScopes("uaa.admin", "foo.bar"), null).isGranted()).isTrue(); } @Test @@ -120,7 +121,7 @@ void throwOnError() { AuthorizationManager authManager = AuthorizationManagersUtils.anyOf(true).hasScope("foo.bar"); assertThatThrownBy( - () -> {authManager.check(() -> withScopes("uaa.admin"), null);} + () -> {authManager.authorize(() -> withScopes("uaa.admin"), null);} ).getCause().isInstanceOf(InsufficientScopeException.class); } @@ -131,8 +132,8 @@ void zoneAdmin() { IdentityZoneHolder.set(ModelTestUtils.identityZone("someZoneId", "some-domain")); - assertThat(authManager.check(() -> withScopes("foo.bar"), null).isGranted()).isFalse(); - assertThat(authManager.check(() -> withScopes("zones.someZoneId.admin"), null).isGranted()).isTrue(); + assertThat(authManager.authorize(() -> withScopes("foo.bar"), null).isGranted()).isFalse(); + assertThat(authManager.authorize(() -> withScopes("zones.someZoneId.admin"), null).isGranted()).isTrue(); } static class TestAuthManager implements AuthorizationManager { @@ -161,7 +162,7 @@ public static TestAuthManager unknown() { } @Override - public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext object) { + public AuthorizationDecision authorize(Supplier authentication, RequestAuthorizationContext object) { called = true; return authorizationDecision; } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java index c14f69fca29..75487928681 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java @@ -142,9 +142,15 @@ void saveToken_MakeAnExpiredTokenInResponse_whenNoTokenInRequest() { MockHttpServletResponse response = new MockHttpServletResponse(); repo.saveToken(null, request, response); - Cookie cookie = response.getCookie("X-Uaa-Csrf"); - assertThat(cookie.getMaxAge()).isZero(); - assertThat(cookie.getValue()).isNotEmpty(); + // Spring Framework 7: MockHttpServletResponse.getCookie() no longer parses + // Set-Cookie headers added via addHeader(). Check the header directly instead. + String setCookieHeader = response.getHeader("Set-Cookie"); + assertThat(setCookieHeader).contains("X-Uaa-Csrf="); + // Max-Age=0 or Expires at Unix epoch indicates expired/deleted cookie + assertThat(setCookieHeader).satisfiesAnyOf( + header -> assertThat(header).contains("Max-Age=0"), + header -> assertThat(header).contains("Expires=Thu, 1 Jan 1970") + ); } private MockHttpServletResponse saveTokenAndReturnResponse(boolean isSecure, String protocol) { diff --git a/statsd-lib/src/test/java/org/cloudfoundry/identity/statsd/integration/IntegrationTestUtils.java b/statsd-lib/src/test/java/org/cloudfoundry/identity/statsd/integration/IntegrationTestUtils.java index 8e7a1a6b1d9..0bacdb7fc10 100644 --- a/statsd-lib/src/test/java/org/cloudfoundry/identity/statsd/integration/IntegrationTestUtils.java +++ b/statsd-lib/src/test/java/org/cloudfoundry/identity/statsd/integration/IntegrationTestUtils.java @@ -15,7 +15,7 @@ public class IntegrationTestUtils { static final String TEST_PASSWORD = "koala"; static void copyCookies(ResponseEntity response, HttpHeaders headers) { - if (response.getHeaders().containsKey("Set-Cookie")) { + if (response.getHeaders().containsHeader("Set-Cookie")) { for (String cookie : response.getHeaders().get("Set-Cookie")) { headers.add("Cookie", cookie); } diff --git a/statsd/build.gradle b/statsd/build.gradle index c23ec0a6770..38f632b5063 100644 --- a/statsd/build.gradle +++ b/statsd/build.gradle @@ -13,8 +13,7 @@ repositories { dependencies { implementation(project(":cloudfoundry-identity-statsd-lib")) implementation(libs.springBootStarterWeb) - providedCompile(libs.tomcatEmbed) - providedRuntime(libs.springBootStarterTomcat) + providedRuntime(libs.springBootStarterTomcatRuntime) } test { diff --git a/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootConfiguration.java b/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootConfiguration.java index 6e1f53088af..cdace122df6 100644 --- a/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootConfiguration.java +++ b/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootConfiguration.java @@ -11,7 +11,7 @@ import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; diff --git a/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizer.java b/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizer.java index b78de70f4bc..00e79fe0937 100644 --- a/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizer.java +++ b/uaa/src/main/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizer.java @@ -4,8 +4,8 @@ import org.apache.catalina.valves.ErrorReportValve; import org.apache.coyote.http11.Http11NioProtocol; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.web.error.ErrorPage; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.http.HttpStatus; import org.springframework.security.web.firewall.RequestRejectedException; @@ -37,7 +37,7 @@ public void customize(TomcatServletWebServerFactory factory) { factory.addEngineValves(getErrorReportValve()); if (this.serverHttp.port() > 0) { - factory.addAdditionalTomcatConnectors( + factory.addAdditionalConnectors( getHttpPort( this.serverHttp ) diff --git a/uaa/src/test/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizerTest.java b/uaa/src/test/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizerTest.java index 63face84a86..38656fc9560 100644 --- a/uaa/src/test/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizerTest.java +++ b/uaa/src/test/java/org/cloudfoundry/experimental/boot/UaaBootServerCustomizerTest.java @@ -9,8 +9,9 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; @@ -25,9 +26,10 @@ @DefaultTestContext @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) @TestPropertySource(properties = {"server.http.port = 8081"}) +@Import(UaaBootServerCustomizer.class) class UaaBootServerCustomizerTest { - @SpyBean + @MockitoSpyBean UaaBootServerCustomizer customizer; @Test @@ -47,7 +49,7 @@ void customizerAddedReportValve() { void localhostConnectorAdded() throws UnknownHostException { ArgumentCaptor captor = ArgumentCaptor.forClass(TomcatServletWebServerFactory.class); Mockito.verify(customizer, Mockito.atMostOnce()).customize(captor.capture()); - List connectors = captor.getValue().getAdditionalTomcatConnectors(); + List connectors = captor.getValue().getAdditionalConnectors(); assertThat(connectors).isNotEmpty(); assertThat(connectors).hasSize(1); Connector httpConnector = connectors.getFirst(); diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/DefaultTestContext.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/DefaultTestContext.java index 9019ff5f53e..ca79ba385e0 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/DefaultTestContext.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/DefaultTestContext.java @@ -12,8 +12,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; -import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.annotation.Bean; @@ -58,12 +56,6 @@ webEnvironment = SpringBootTest.WebEnvironment.MOCK ) @SpringJUnitConfig(initializers = {TestPropertyInitializer.class, YamlServletProfileInitializer.class}) -@EnableAutoConfiguration(exclude = { - // Conflicts with UaaJdbcSessionConfig - SessionAutoConfiguration.class, - // Conflicts with LdapSearchAndCompareConfig/LdapSearchAndBindConfig/LdapSimpleBindConfig - LdapAutoConfiguration.class -}) public @interface DefaultTestContext { } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/client/ClientMetadataAdminEndpointsMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/client/ClientMetadataAdminEndpointsMockMvcTest.java index bcedc50b71a..647671c2872 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/client/ClientMetadataAdminEndpointsMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/client/ClientMetadataAdminEndpointsMockMvcTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.client; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.assertj.core.groups.Tuple; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.test.TestClient; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java index 14ab5ab91e7..41bd3ad6992 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java @@ -13,7 +13,8 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.integration; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import org.cloudfoundry.identity.uaa.ServerRunningExtension; import org.cloudfoundry.identity.uaa.approval.Approval; import org.cloudfoundry.identity.uaa.client.InvalidClientDetailsException; @@ -137,7 +138,7 @@ void listClientsWithExtremePaginationDefaultsTo500() throws Exception { ResponseEntity result = serverRunning.getForString("/oauth/clients?count=3000", myHeaders); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - SearchResults searchResults = new ObjectMapper().readValue(result.getBody(), SearchResults.class); + SearchResults searchResults = new JsonMapper().readValue(result.getBody(), SearchResults.class); assertThat(searchResults.getItemsPerPage()).isEqualTo(500); assertThat(searchResults.getResources()).hasSize(500); assertThat(searchResults.getTotalResults()).isGreaterThan(500); @@ -405,12 +406,12 @@ void nonImplicitGrantClientWithSecret() { Collections.singletonList("bar"))); } clients[clients.length - 1].setClientSecret(null); - ResponseEntity result = + ResponseEntity result = serverRunning.getRestTemplate().exchange( serverRunning.getUrl("/oauth/clients/tx"), HttpMethod.POST, new HttpEntity<>(clients, headers), - UaaException.class); + UaaClientDetails[].class); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.CREATED); for (String id : ids) { ClientDetails client = getClient(id); diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/IdentityZoneEndpointsIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/IdentityZoneEndpointsIntegrationTests.java index 66ef632ca48..29b0e9c2bcc 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/IdentityZoneEndpointsIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/IdentityZoneEndpointsIntegrationTests.java @@ -180,7 +180,7 @@ void updateZoneAllowedGroups() { new ParameterizedTypeReference<>() { }, id); - assertThat(response.getStatusCode()).as(response.getBody()).isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + assertThat(response.getStatusCode()).as(response.getBody()).isEqualTo(HttpStatus.UNPROCESSABLE_CONTENT); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/LdapIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/LdapIntegrationTests.java index d6b447a6a30..f393e45f407 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/LdapIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/LdapIntegrationTests.java @@ -13,7 +13,7 @@ */ package org.cloudfoundry.identity.uaa.integration; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.ServerRunningExtension; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.constants.OriginKeys; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordChangeEndpointIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordChangeEndpointIntegrationTests.java index c8955221341..9ffb72fd948 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordChangeEndpointIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordChangeEndpointIntegrationTests.java @@ -134,7 +134,7 @@ void changePasswordSameAsOldFails() { .exchange(serverRunning.getUrl(userEndpoint) + "/{id}/password", HttpMethod.PUT, new HttpEntity<>(change, headers), Void.class, joe.getId()); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNPROCESSABLE_ENTITY); + assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNPROCESSABLE_CONTENT); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordGrantIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordGrantIntegrationTests.java index 5a0bbc26842..c15a481af95 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordGrantIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/PasswordGrantIntegrationTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.integration; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.ServerRunningExtension; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimGroupEndpointsIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimGroupEndpointsIntegrationTests.java index 52ab4006cc1..6bcdbbd88c0 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimGroupEndpointsIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimGroupEndpointsIntegrationTests.java @@ -619,7 +619,7 @@ private OAuth2AccessToken getAccessToken(String clientId, String clientSecret, S .contains("username") .contains("password"); - if (response.getHeaders().containsKey("Set-Cookie")) { + if (response.getHeaders().containsHeader("Set-Cookie")) { String cookie = response.getHeaders().getFirst("Set-Cookie"); int nameLength = cookie.indexOf('='); cookies.addCookie(new BasicClientCookie(cookie.substring(0, nameLength), cookie.substring(nameLength + 1))); diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimUserEndpointsIntegrationTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimUserEndpointsIntegrationTests.java index 9b74a55971b..4dcfc6ca85e 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimUserEndpointsIntegrationTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimUserEndpointsIntegrationTests.java @@ -277,7 +277,7 @@ void updateUserWithBadAttributeFails() { ResponseEntity response = client.exchange(serverRunning.getUrl(userEndpoint) + "/{id}", HttpMethod.PUT, new HttpEntity(map, headers), Map.class, joe.getId()); Map joe1 = response.getBody(); - assertThat(((String) joe1.get("message")).toLowerCase()).as("Wrong message: " + joe1).contains("unrecognized field"); + assertThat(((String) joe1.get("message")).toLowerCase()).as("Wrong message: " + joe1).contains("unrecognized property"); } @SuppressWarnings({"rawtypes", "unchecked"}) diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/DefaultIntegrationTestConfig.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/DefaultIntegrationTestConfig.java index eb3a9701f5c..59c890bd8a5 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/DefaultIntegrationTestConfig.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/DefaultIntegrationTestConfig.java @@ -15,6 +15,7 @@ import com.icegreen.greenmail.util.GreenMail; import com.icegreen.greenmail.util.ServerSetup; +import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils; import org.cloudfoundry.identity.uaa.oauth.client.test.TestAccounts; import org.cloudfoundry.identity.uaa.test.UaaTestAccounts; import org.cloudfoundry.identity.uaa.test.UaaWebDriver; @@ -125,7 +126,7 @@ public GreenMail greenMail(@Value("${smtp.port}") int port) { @Bean public RestTemplate restTemplate() { - return new RestTemplate(); + return IntegrationTestUtils.createConfiguredRestTemplate(); } @Bean diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/ImplicitGrantIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/ImplicitGrantIT.java index 4df5373a496..073ed7853dd 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/ImplicitGrantIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/ImplicitGrantIT.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.integration.feature; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.oauth.client.test.TestAccounts; import org.cloudfoundry.identity.uaa.oauth.jwt.Jwt; import org.cloudfoundry.identity.uaa.oauth.jwt.JwtHelper; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/OIDCLoginIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/OIDCLoginIT.java index e8b80955a0c..beff7c2da22 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/OIDCLoginIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/OIDCLoginIT.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.integration.feature; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; import org.cloudfoundry.identity.uaa.ServerRunningExtension; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/PrivateKeyJwtClientAuthIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/PrivateKeyJwtClientAuthIT.java index cbed9ea03d9..a251a3bf161 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/PrivateKeyJwtClientAuthIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/PrivateKeyJwtClientAuthIT.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.integration.feature; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.ServerRunningExtension; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginCustomUserAttributesIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginCustomUserAttributesIT.java index 0ceb61a7b76..248664bb78d 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginCustomUserAttributesIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginCustomUserAttributesIT.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.integration.feature; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.ServerRunningExtension; import org.cloudfoundry.identity.uaa.account.UserInfoResponse; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginEmailIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginEmailIT.java index 19fcce0bd45..22f6a5aa22c 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginEmailIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginEmailIT.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.integration.feature; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.ServerRunningExtension; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.constants.OriginKeys; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginIT.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginIT.java index 8ab632744f9..205549ac4ab 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginIT.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/feature/SamlLoginIT.java @@ -158,6 +158,8 @@ void clearWebDriverOfCookies() { LogoutDoEndpoint.logout(webDriver, baseUrl.replace("localhost", domain)); new Page(webDriver).clearCookies(); } + webDriver.get(samlServerConfig.getSamlServerUrl() + "/index.php"); + webDriver.manage().deleteAllCookies(); SamlLogoutAuthSourceEndpoint.assertThatLogoutAuthSource_goesToSamlWelcomePage(webDriver, samlServerConfig); } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/util/IntegrationTestUtils.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/util/IntegrationTestUtils.java index 628d79ed7eb..51a7aad47fe 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/util/IntegrationTestUtils.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/util/IntegrationTestUtils.java @@ -1,6 +1,10 @@ package org.cloudfoundry.identity.uaa.integration.util; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.cfg.ConstructorDetector; +import tools.jackson.databind.json.JsonMapper; import com.icegreen.greenmail.util.GreenMail; import com.icegreen.greenmail.util.GreenMailUtil; import jakarta.mail.internet.MimeMessage; @@ -58,7 +62,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -263,8 +269,30 @@ public static ClientCredentialsResourceDetails getClientCredentialsResource(Stri return resource; } + public static RestTemplate createConfiguredRestTemplate() { + RestTemplate template = new RestTemplate(); + configureRestTemplate(template); + return template; + } + + public static void configureRestTemplate(RestTemplate template) { + JsonMapper mapper = JsonMapper.builder() + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .constructorDetector(ConstructorDetector.DEFAULT.withAllowImplicitWithDefaultConstructor(false)) + .build(); + List> converters = template.getMessageConverters(); + for (int i = 0; i < converters.size(); i++) { + if (converters.get(i) instanceof JacksonJsonHttpMessageConverter) { + converters.set(i, new JacksonJsonHttpMessageConverter(mapper)); + break; + } + } + } + public static RestTemplate getClientCredentialsTemplate(ClientCredentialsResourceDetails details) { RestTemplate client = new OAuth2RestTemplate(details); + configureRestTemplate(client); client.setRequestFactory(new StatelessRequestFactory()); client.setErrorHandler(new OAuth2ErrorHandler(details) { // Pass errors through in response entity for status code analysis @@ -315,7 +343,7 @@ public static ScimUser createUserWithPhone(RestTemplate client, } public static ScimUser createUser(String token, String url, ScimUser user, String zoneSwitchId) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -338,7 +366,7 @@ public static ScimUser createUser(String token, String url, ScimUser user, Strin } public static void updateUser(String token, String url, ScimUser user) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -364,7 +392,7 @@ public static ScimUser getUser(String token, String url, String origin, String u } public static ScimUser getUserByZone(String token, String url, String subdomain, String username) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -393,7 +421,7 @@ public static ScimUser getUserByZone(String token, String url, String subdomain, } public static ScimUser getUser(String token, String url, String userId) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -416,7 +444,7 @@ public static String getUserId(String token, String url, String origin, String u } public static String getUserIdByField(String token, String url, String origin, String field, String fieldValue) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -450,7 +478,7 @@ public static String getUsernameById(String token, String url, String userId) { public static void deleteUser(String zoneAdminToken, String url, String userId) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + zoneAdminToken); @@ -514,7 +542,7 @@ public static ScimGroup getGroup(String token, String zoneId, String url, String displayName) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -569,7 +597,7 @@ private static ScimGroup updateGroup(String token, String zoneId, String url, ScimGroup group) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -609,7 +637,7 @@ public static ScimGroupExternalMember mapExternalGroup(String token, String url, ScimGroupExternalMember scimGroup) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -636,7 +664,7 @@ public static void deleteGroup(String token, String url, String groupId ) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); template.setErrorHandler(fiveHundredErrorHandler); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Authorization", "bearer " + token); @@ -713,7 +741,7 @@ public static void addMemberToGroup(RestTemplate client, public static UaaClientDetails getClient(String token, String url, String clientId) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -752,7 +780,7 @@ public static UaaClientDetails createClientAsZoneAdmin(String zoneAdminToken, String zoneId, UaaClientDetails client) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + zoneAdminToken); @@ -782,7 +810,7 @@ public static UaaClientDetails createOrUpdateClient(String adminToken, String switchToZoneId, UaaClientDetails client) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); template.setErrorHandler(new DefaultResponseErrorHandler() { @Override protected boolean hasError(HttpStatusCode statusCode) { @@ -826,7 +854,7 @@ public static void updateClient(String url, String token, UaaClientDetails client) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + token); @@ -865,7 +893,7 @@ public static IdentityProvider get private static List> getProviders(String zoneAdminToken, String url, String zoneId) { - RestTemplate client = new RestTemplate(); + RestTemplate client = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + zoneAdminToken); @@ -893,7 +921,7 @@ public static void deleteProvider(String zoneAdminToken, if (provider == null) { return; } - RestTemplate client = new RestTemplate(); + RestTemplate client = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Authorization", "bearer " + zoneAdminToken); headers.add(IdentityZoneSwitchingFilter.HEADER, zoneId); @@ -1060,7 +1088,7 @@ public static IdentityProvider String url, IdentityProvider provider) { - RestTemplate client = new RestTemplate(); + RestTemplate client = createConfiguredRestTemplate(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add("Accept", APPLICATION_JSON_VALUE); headers.add("Authorization", "bearer " + accessToken); @@ -1102,7 +1130,7 @@ public static IdentityProvider public static String getClientCredentialsToken(String baseUrl, String clientId, String clientSecret) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); template.setRequestFactory(new StatelessRequestFactory()); MultiValueMap formData = new LinkedMultiValueMap<>(); formData.add("grant_type", "client_credentials"); @@ -1144,7 +1172,7 @@ public static Map getPasswordToken(String baseUrl, String password, String scopes, String loginHint) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); template.getMessageConverters().addFirst(new StringHttpMessageConverter(StandardCharsets.UTF_8)); template.setRequestFactory(new StatelessRequestFactory()); MultiValueMap formData = new LinkedMultiValueMap<>(); @@ -1181,7 +1209,7 @@ public static Map getJwtBearerToken(String baseUrl, String assertion, String loginHint, String scopes) { - RestTemplate template = new RestTemplate(); + RestTemplate template = createConfiguredRestTemplate(); template.getMessageConverters().addFirst(new StringHttpMessageConverter(StandardCharsets.UTF_8)); template.setRequestFactory(new StatelessRequestFactory()); MultiValueMap formData = new LinkedMultiValueMap<>(); @@ -1214,23 +1242,7 @@ public static Map getJwtBearerToken(String baseUrl, public static String getClientCredentialsToken(ServerRunningExtension serverRunning, String clientId, String clientSecret) { - MultiValueMap formData = new LinkedMultiValueMap<>(); - formData.add("grant_type", "client_credentials"); - formData.add("client_id", clientId); - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - headers.set("Authorization", - "Basic " + new String(BASE_64_ENCODER.encode("%s:%s".formatted(clientId, clientSecret).getBytes()))); - - @SuppressWarnings("rawtypes") - ResponseEntity response = serverRunning.postForMap("/oauth/token", formData, headers); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - - final Map responseBody = response.getBody(); - assertThat(responseBody).isNotNull(); - @SuppressWarnings("unchecked") - OAuth2AccessToken accessToken = DefaultOAuth2AccessToken.valueOf(responseBody); - return accessToken.getValue(); + return getClientCredentialsToken(serverRunning.getBaseUrl(), clientId, clientSecret); } public static String getAccessTokenByAuthCode(ServerRunningExtension serverRunning, @@ -1548,7 +1560,7 @@ public static Map getAuthorizationCodeTokenMap(ServerRunningExte } public static void extractCookies(ResponseEntity response, BasicCookieStore cookies) { - if (response.getHeaders().containsKey("Set-Cookie")) { + if (response.getHeaders().containsHeader("Set-Cookie")) { for (String cookie : response.getHeaders().get("Set-Cookie")) { int nameLength = cookie.indexOf('='); cookies.addCookie(new BasicClientCookie(cookie.substring(0, nameLength), cookie.substring(nameLength + 1))); @@ -1557,7 +1569,7 @@ public static void extractCookies(ResponseEntity response, BasicCookieStore c } public static void copyCookies(ResponseEntity response, HttpHeaders headers) { - if (response.getHeaders().containsKey("Set-Cookie")) { + if (response.getHeaders().containsHeader("Set-Cookie")) { for (String cookie : response.getHeaders().get("Set-Cookie")) { headers.add("Cookie", cookie); } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcTests.java index a4a4ed83e54..eed24cf4c05 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.invitations; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcZonePathTests.java index 33a4a9921f8..d72b0f38510 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/invitations/InvitationsEndpointMockMvcZonePathTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.invitations; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerMockMvcTest.java index 9ed5f0f5811..4863bd7707b 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerMockMvcTest.java @@ -261,7 +261,7 @@ void submit_password_change_when_not_authenticated() throws Exception { validPost.with(cookieCsrf()); mockMvc.perform(validPost) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); } static class PasswordPolicyWithInvalidPassword { diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerZonePathMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerZonePathMockMvcTest.java index 938277853dc..a6d6302e209 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerZonePathMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ForcePasswordChangeControllerZonePathMockMvcTest.java @@ -324,8 +324,8 @@ void submit_password_change_when_not_authenticated(ZoneResolutionMode mode) thro .param("password_confirmation", "test"); validPost.with(cookieCsrf()); String expectedRedirect = mode == ZoneResolutionMode.ZONE_PATH - ? "http://localhost/z/" + subdomain + "/login" - : "http://" + subdomain + ".localhost/login"; + ? "/z/" + subdomain + "/login" + : "/login"; mockMvc.perform(validPost) .andExpect(status().isFound()) .andExpect(redirectedUrl(expectedRedirect)); diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcTests.java index 199744922ac..2deb1b5536b 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcTests.java @@ -58,7 +58,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; + import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; @@ -185,7 +185,7 @@ void acceptInvitationShouldNotLogYouIn() throws Exception { .accept(MediaType.TEXT_HTML) ) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @Test @@ -271,7 +271,7 @@ void invalid_code() throws Exception { .accept(MediaType.TEXT_HTML) ) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); } @Test @@ -364,7 +364,7 @@ void acceptInvitationSetsYourPassword() throws Exception { .accept(MediaType.TEXT_HTML) ) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcZonePathTests.java index a83d95cc990..d68937e0f40 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/InvitationsServiceMockMvcZonePathTests.java @@ -73,7 +73,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; + import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; @@ -295,7 +295,7 @@ void acceptInvitationShouldNotLogYouIn() throws Exception { .accept(MediaType.TEXT_HTML) ) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @ParameterizedTest @@ -337,7 +337,7 @@ void acceptInvitationShouldNotLogYouInWithinZone(ZoneResolutionMode mode) throws MockHttpSession session = (MockHttpSession) result.getRequest().getSession(false); mockMvc.perform(get("/profile").session(session).accept(MediaType.TEXT_HTML)) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @Test @@ -538,7 +538,7 @@ void invalid_code() throws Exception { .accept(MediaType.TEXT_HTML) ) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); } @ParameterizedTest @@ -595,7 +595,7 @@ void invalid_codeWithinZone(ZoneResolutionMode mode) throws Exception { mockMvc.perform(get("/profile").session(session).accept(MediaType.TEXT_HTML)) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @Test @@ -641,7 +641,7 @@ void acceptInvitationSetsYourPassword() throws Exception { .accept(MediaType.TEXT_HTML) ) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @ParameterizedTest @@ -700,7 +700,7 @@ void acceptInvitationSetsYourPasswordWithinZone(ZoneResolutionMode mode) throws session = (MockHttpSession) result.getRequest().getSession(false); mockMvc.perform(get("/profile").session(session).accept(MediaType.TEXT_HTML)) .andExpect(status().isFound()) - .andExpect(redirectedUrlPattern("**/login")); + .andExpect(redirectedUrl("/login")); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginInfoEndpointDocs.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginInfoEndpointDocs.java index 18802ee195c..461c411c6e3 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginInfoEndpointDocs.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginInfoEndpointDocs.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.login; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication; import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal; import org.cloudfoundry.identity.uaa.mock.EndpointDocs; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcTests.java index cd751453880..052b9ce2348 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcTests.java @@ -51,7 +51,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -201,7 +201,7 @@ public class LoginMockMvcTests { private IdentityZone identityZone; private File originalLimitedModeStatusFile; - @MockBean + @MockitoBean OidcMetadataFetcher oidcMetadataFetcher; @BeforeEach @@ -516,7 +516,7 @@ void cookie_csrf() throws Exception { mockMvc.perform(invalidPost) .andDo(print()) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login?error=invalid_login_request")); + .andExpect(redirectedUrl("/login?error=invalid_login_request")); session = new MockHttpSession(); String csrfValue = "12345"; @@ -529,7 +529,7 @@ void cookie_csrf() throws Exception { ) .andDo(print()) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login?error=invalid_login_request")); + .andExpect(redirectedUrl("/login?error=invalid_login_request")); MockHttpServletRequestBuilder validPost = post("/uaa/login.do") .session(session) @@ -1553,6 +1553,8 @@ void loginHintRedirect() throws Exception { MockHttpSession session = new MockHttpSession(); SavedRequest savedRequest = mock(DefaultSavedRequest.class); when(savedRequest.getParameterValues("login_hint")).thenReturn(new String[]{"example.com"}); + when(savedRequest.getRedirectUrl()).thenReturn("http://" + identityZone.getSubdomain() + ".localhost/login"); + when(savedRequest.getMethod()).thenReturn("GET"); SessionUtils.setSavedRequestSession(MockMvcUtils.getZoneSession(session), savedRequest); MvcResult mvcResult = mockMvc.perform(get("/login") @@ -1765,7 +1767,7 @@ void deactivatedProviderIsRemovedFromSamlLoginLinks() throws Exception { void changeEmailWithoutAuthenticationReturnsRedirect() throws Exception { mockMvc.perform(get("/change_email").accept(TEXT_HTML)) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); } @Test @@ -1888,14 +1890,14 @@ void changeEmailDoNotLoggedIn() throws Exception { .with(cookieCsrf()); mockMvc.perform(changeEmail) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); changeEmail = post("/change_email.do") .accept(TEXT_HTML) .with(cookieCsrf()); mockMvc.perform(changeEmail) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); changeEmail = post("/change_email.do") .accept(TEXT_HTML) @@ -1982,7 +1984,7 @@ void csrfForInvitationAcceptPost() throws Exception { mockMvc.perform(post) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login?error=invalid_login_request")); + .andExpect(redirectedUrl("/login?error=invalid_login_request")); //not logged in, valid CSRF(can't happen) post = post("/invitations/accept.do") @@ -1994,7 +1996,7 @@ void csrfForInvitationAcceptPost() throws Exception { mockMvc.perform(post) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login")); + .andExpect(redirectedUrl("/login")); } /** diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcZonePathTests.java index e4c8c547480..bd07e1a0ba3 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/LoginMockMvcZonePathTests.java @@ -57,7 +57,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -203,7 +203,7 @@ public class LoginMockMvcZonePathTests { private IdentityZone identityZone; private File originalLimitedModeStatusFile; - @MockBean + @MockitoBean OidcMetadataFetcher oidcMetadataFetcher; @BeforeEach @@ -616,8 +616,8 @@ void cookie_csrf(ZoneResolutionMode mode) throws Exception { scimUserProvisioning.createUser(zoneUser, "koala", zone.getId()); MockHttpSession session = new MockHttpSession(); String expectedInvalidRedirect = mode == ZoneResolutionMode.ZONE_PATH - ? "http://localhost/z/" + subdomain + "/login?error=invalid_login_request" - : "http://" + subdomain + ".localhost/login?error=invalid_login_request"; + ? "/z/" + subdomain + "/login?error=invalid_login_request" + : "/login?error=invalid_login_request"; MockHttpServletRequestBuilder invalidPost = mode.createRequestBuilder(subdomain, HttpMethod.POST, "/login.do") .session(session).param("username", "marissa").param("password", "koala"); @@ -1916,6 +1916,11 @@ void loginHintRedirect(ZoneResolutionMode mode) throws Exception { MockHttpSession session = new MockHttpSession(); SavedRequest savedRequest = mock(DefaultSavedRequest.class); when(savedRequest.getParameterValues("login_hint")).thenReturn(new String[]{"example.com"}); + String redirectUrl = mode == ZoneResolutionMode.ZONE_PATH + ? "http://localhost/z/" + identityZone.getSubdomain() + "/login" + : "http://" + identityZone.getSubdomain() + ".localhost/login"; + when(savedRequest.getRedirectUrl()).thenReturn(redirectUrl); + when(savedRequest.getMethod()).thenReturn("GET"); SessionUtils.setSavedRequestSession(MockMvcUtils.getZoneSession(session, mode, identityZone.getSubdomain()), savedRequest); MvcResult mvcResult = mockMvc.perform(mode.createRequestBuilder(identityZone.getSubdomain(), HttpMethod.GET, "/login") @@ -2137,8 +2142,8 @@ void changeEmailWithoutAuthenticationReturnsRedirect(ZoneResolutionMode mode) th String subdomain = new AlphanumericRandomValueStringGenerator(24).generate().toLowerCase(); IdentityZone zone = MockMvcUtils.createOtherIdentityZone(subdomain, mockMvc, webApplicationContext, false, IdentityZoneHolder.getCurrentZoneId()); String expectedRedirect = mode == ZoneResolutionMode.ZONE_PATH - ? "http://localhost/z/" + subdomain + "/login" - : "http://" + subdomain + ".localhost/login"; + ? "/z/" + subdomain + "/login" + : "/login"; mockMvc.perform(mode.createRequestBuilder(zone.getSubdomain(), HttpMethod.GET, "/change_email").accept(TEXT_HTML)) .andExpect(status().isFound()) .andExpect(redirectedUrl(expectedRedirect)); @@ -2300,8 +2305,8 @@ void changeEmailDoNotLoggedIn(ZoneResolutionMode mode) throws Exception { scimUserProvisioning.createUser(marissa, "koala", zone.getId()); SecurityContext marissaContext = getMarissaSecurityContext(webApplicationContext, zone.getId()); String expectedLoginRedirect = mode == ZoneResolutionMode.ZONE_PATH - ? "http://localhost/z/" + subdomain + "/login" - : "http://" + subdomain + ".localhost/login"; + ? "/z/" + subdomain + "/login" + : "/login"; MockHttpServletRequestBuilder changeEmail = mode.createRequestBuilder(zone.getSubdomain(), HttpMethod.POST, "/change_email.do") .accept(TEXT_HTML) @@ -2310,13 +2315,6 @@ void changeEmailDoNotLoggedIn(ZoneResolutionMode mode) throws Exception { .andExpect(status().isFound()) .andExpect(redirectedUrl(expectedLoginRedirect)); - changeEmail = mode.createRequestBuilder(zone.getSubdomain(), HttpMethod.POST, "/change_email.do") - .accept(TEXT_HTML) - .with(cookieCsrf()); - mockMvc.perform(changeEmail) - .andExpect(status().isFound()) - .andExpect(redirectedUrl(expectedLoginRedirect)); - changeEmail = mode.createRequestBuilder(zone.getSubdomain(), HttpMethod.POST, "/change_email.do") .accept(TEXT_HTML) .with(cookieCsrf().useInvalidToken()) @@ -2383,8 +2381,8 @@ void csrfForInvitationAcceptPost(ZoneResolutionMode mode) throws Exception { ExpiringCode code = expiringCodeStore.generateCode(JsonUtils.writeValueAsString(codeData), new Timestamp(System.currentTimeMillis() + 1000 * 60), null, zone.getId()); String expectedLoginRedirect = mode == ZoneResolutionMode.ZONE_PATH - ? "http://localhost/z/" + subdomain + "/login" - : "http://" + subdomain + ".localhost/login"; + ? "/z/" + subdomain + "/login" + : "/login"; //logged in with valid CSRF MockHttpServletRequestBuilder post = mode.createRequestBuilder(zone.getSubdomain(), HttpMethod.POST, "/invitations/accept.do") diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcTests.java index 6737009bf18..5f2a63a7129 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcTests.java @@ -340,7 +340,7 @@ void resettingAPasswordNoCsrfParameter() throws Exception { mockMvc.perform(createChangePasswordRequest(users.getFirst(), code, false)) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login?error=invalid_login_request")); + .andExpect(redirectedUrl("/login?error=invalid_login_request")); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcZonePathTests.java index d1dacba9dc5..e4c0a564d8d 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/login/ResetPasswordControllerMockMvcZonePathTests.java @@ -355,7 +355,7 @@ void resettingAPasswordNoCsrfParameter() throws Exception { mockMvc.perform(createChangePasswordRequest(users.getFirst(), code, false)) .andExpect(status().isFound()) - .andExpect(redirectedUrl("http://localhost/login?error=invalid_login_request")); + .andExpect(redirectedUrl("/login?error=invalid_login_request")); } @Test diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/audit/AuditCheckMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/audit/AuditCheckMockMvcTests.java index 745b2357abb..cd0ea90d0aa 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/audit/AuditCheckMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/audit/AuditCheckMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.audit; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.commons.codec.binary.Base64; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcTests.java index 436b18ad07e..8f48a2ea560 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.clients; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.base.Strings; import com.google.common.collect.Iterables; import org.cloudfoundry.identity.uaa.DefaultTestContext; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcZonePathTests.java index 0de0225ba36..ff20e8fdc3a 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/clients/ClientAdminEndpointsMockMvcZonePathTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.clients; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.base.Strings; import com.google.common.collect.Iterables; import org.cloudfoundry.identity.uaa.DefaultTestContext; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/AbstractLdapMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/AbstractLdapMockMvcTest.java index fbbc37517bc..02abd502624 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/AbstractLdapMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/AbstractLdapMockMvcTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.ldap; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Sets; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.audit.AuditEventType; @@ -1125,7 +1125,10 @@ void nestedLdapScopes() { Authentication auth = manager.authenticate(token); assertThat(auth).isNotNull(); defaultAuthorities.addAll(Arrays.asList("test.read", "test.write", "test.everything")); - assertThat(UaaStringUtils.getStringsFromAuthorities(auth.getAuthorities())).containsExactlyInAnyOrderElementsOf(defaultAuthorities); + Set actualAuthorities = UaaStringUtils.getStringsFromAuthorities(auth.getAuthorities()).stream() + .filter(a -> a != null && !a.startsWith("FACTOR_")) + .collect(java.util.stream.Collectors.toSet()); + assertThat(actualAuthorities).containsExactlyInAnyOrderElementsOf(defaultAuthorities); IdentityZoneHolder.clear(); } @@ -1167,7 +1170,10 @@ void doTestNestedLdapGroupsMappedToScopes(String username, String password, Stri void validateUserAuthorities(String[] expected, Authentication auth) { Set defaultAuthorities = new HashSet<>(zone.getZone().getIdentityZone().getConfig().getUserConfig().getDefaultGroups()); Collections.addAll(defaultAuthorities, expected); - assertThat(UaaStringUtils.getStringsFromAuthorities(auth.getAuthorities())).containsExactlyInAnyOrderElementsOf(defaultAuthorities); + Set actualAuthorities = UaaStringUtils.getStringsFromAuthorities(auth.getAuthorities()).stream() + .filter(a -> a != null && !a.startsWith("FACTOR_")) + .collect(java.util.stream.Collectors.toSet()); + assertThat(actualAuthorities).containsExactlyInAnyOrderElementsOf(defaultAuthorities); } @Test @@ -1258,18 +1264,18 @@ void doTestNestedLdapGroupsMappedToScopesWithDefaultScopes(String username, Stri assertThat(auth).isNotNull(); Set defaultAuthorities = Sets.newHashSet(zone.getZone().getIdentityZone().getConfig().getUserConfig().getDefaultGroups()); defaultAuthorities.addAll(Arrays.asList(expected)); - assertThat(UaaStringUtils.getStringsFromAuthorities(auth.getAuthorities())).containsExactlyInAnyOrderElementsOf(defaultAuthorities); + Set actualAuthorities = UaaStringUtils.getStringsFromAuthorities(auth.getAuthorities()).stream() + .filter(a -> a != null && !a.startsWith("FACTOR_")) + .collect(java.util.stream.Collectors.toSet()); + assertThat(actualAuthorities).containsExactlyInAnyOrderElementsOf(defaultAuthorities); } String[] getAuthorities(Collection authorities) { - String[] result = new String[authorities != null ? authorities.size() : 0]; - if (result.length > 0) { - int index = 0; - for (GrantedAuthority a : authorities) { - result[index++] = a.getAuthority(); - } - } - return result; + if (authorities == null) return new String[0]; + return authorities.stream() + .map(GrantedAuthority::getAuthority) + .filter(a -> a != null && !a.startsWith("FACTOR_")) + .toArray(String[]::new); } void updateLdapProvider() throws Exception { diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapProviderDefinitionDeserializeTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapProviderDefinitionDeserializeTests.java index edc64b7a7a6..81fead4d615 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapProviderDefinitionDeserializeTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapProviderDefinitionDeserializeTests.java @@ -15,7 +15,7 @@ package org.cloudfoundry.identity.uaa.mock.ldap; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.provider.IdentityProvider; import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsAliasMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsAliasMockMvcTests.java index d87986d79a1..f17b231d983 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsAliasMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsAliasMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.providers; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.constants.ClientAuthentication; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcTests.java index 7092a72b4cc..f56e0344adb 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcTests.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.mock.providers; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.lang3.RandomStringUtils; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.audit.AuditEventType; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcZonePathTests.java index 0ddeda45983..3c1c7175880 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/providers/IdentityProviderEndpointsMockMvcZonePathTests.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.mock.providers; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.lang3.RandomStringUtils; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.audit.AuditEventType; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/JwtBearerGrantMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/JwtBearerGrantMockMvcTests.java index 7a646259bdc..4c640f4cda4 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/JwtBearerGrantMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/JwtBearerGrantMockMvcTests.java @@ -15,7 +15,7 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.mock.util.JwtTokenUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/ListUserTokenMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/ListUserTokenMockMvcTests.java index bea5ea6ebfc..bf850faae84 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/ListUserTokenMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/ListUserTokenMockMvcTests.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; import org.cloudfoundry.identity.uaa.oauth.common.util.RandomValueStringGenerator; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/RefreshTokenMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/RefreshTokenMockMvcTests.java index f0b332cf286..33d5a2f7c12 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/RefreshTokenMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/RefreshTokenMockMvcTests.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Lists; import org.apache.hc.core5.http.HttpStatus; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java index 44dc08ba084..df52518327b 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import jakarta.servlet.http.HttpSession; import org.apache.commons.collections4.map.HashedMap; import org.cloudfoundry.identity.uaa.DefaultTestContext; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockZonePathTests.java index 39f3a23d6c2..95ff220c63f 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockZonePathTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import jakarta.servlet.http.HttpSession; import org.apache.commons.collections4.map.HashedMap; import org.cloudfoundry.identity.uaa.DefaultTestContext; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcTest.java index dbc3802cd93..bdf3187fe58 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcZonePathTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcZonePathTest.java index da1e2787e7f..2106693dbfe 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcZonePathTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenRevocationEndpointMockMvcZonePathTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/UserTokenMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/UserTokenMockMvcTests.java index 33718fd6993..4aac5db2b8c 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/UserTokenMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/UserTokenMockMvcTests.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.mock.token; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/JwtTokenUtils.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/JwtTokenUtils.java index f1a0890c06a..1b358c2b077 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/JwtTokenUtils.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/JwtTokenUtils.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.util; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.oauth.KeyInfoService; import org.cloudfoundry.identity.uaa.oauth.common.exceptions.InvalidTokenException; import org.cloudfoundry.identity.uaa.oauth.jwt.Jwt; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/MockMvcUtils.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/MockMvcUtils.java index 360ba5bde73..703d122ffdb 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/MockMvcUtils.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/util/MockMvcUtils.java @@ -14,7 +14,7 @@ package org.cloudfoundry.identity.uaa.mock.util; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.RandomStringUtils; import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcTests.java index 77acca6d62f..aaa79ea28a7 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcTests.java @@ -1,7 +1,7 @@ package org.cloudfoundry.identity.uaa.mock.zones; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.JsonNode; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.approval.Approval; import org.cloudfoundry.identity.uaa.approval.ApprovalStore; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcZonePathTests.java index 66a4f4aec60..1483de915ee 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/IdentityZoneEndpointsMockMvcZonePathTests.java @@ -1,7 +1,7 @@ package org.cloudfoundry.identity.uaa.mock.zones; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.JsonNode; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.approval.Approval; import org.cloudfoundry.identity.uaa.approval.ApprovalStore; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/ZonesWriteScopeMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/ZonesWriteScopeMockMvcTest.java index 2ee02ec750e..19b404e2bf4 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/ZonesWriteScopeMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/zones/ZonesWriteScopeMockMvcTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.mock.zones; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; @@ -78,7 +78,7 @@ void getZoneByIdWithZonesWriteScope() throws Exception { String jsonResponse = result.getResponse().getContentAsString(); JsonNode responseNode = JsonUtils.readTree(jsonResponse); - assertThat(responseNode.get("id").asText()).isEqualTo(zone.getId()); + assertThat(responseNode.get("id").asString()).isEqualTo(zone.getId()); mockMvc.perform( get("/identity-zones/" + zone2.getId()) @@ -112,7 +112,7 @@ void getZonesWithZonesWriteScope() throws Exception { String jsonResponse = result.getResponse().getContentAsString(); JsonNode responseNode = JsonUtils.readTree(jsonResponse); - assertThat(responseNode.get(0).get("id").asText()).isEqualTo(zone.getId()); + assertThat(responseNode.get(0).get("id").asString()).isEqualTo(zone.getId()); assertThat(responseNode.get(1)).isNull(); } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcTest.java index 0b7ba3b72bc..ab64f335b88 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.codec.binary.Base64; import org.cloudfoundry.identity.uaa.mock.token.AbstractTokenMockMvcTests; import org.cloudfoundry.identity.uaa.oauth.token.TokenConstants; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcZonePathTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcZonePathTest.java index bde282c8501..5b89f0ae378 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcZonePathTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/CheckTokenEndpointMockMvcZonePathTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.codec.binary.Base64; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; import org.cloudfoundry.identity.uaa.mock.util.ZoneResolutionMode; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpointMockMvcZonePathTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpointMockMvcZonePathTest.java index 7c2f80fbcab..c790eea04ea 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpointMockMvcZonePathTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpointMockMvcZonePathTest.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.client.UaaClientDetails; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; import org.cloudfoundry.identity.uaa.mock.util.ZoneResolutionMode; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java index 99ca2ba04eb..b2f6ec3f51f 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.oauth; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcTest.java index 6754ac1aa33..41b0b233bbc 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.core.context.SecurityContextHolder; @@ -57,7 +57,7 @@ class LoginPagePerformanceMockMvcTest { private File originalLimitedModeStatusFile; - @MockBean + @MockitoBean OidcMetadataFetcher oidcMetadataFetcher; @BeforeEach diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcZonePathTest.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcZonePathTest.java index 01033b7d9e4..16971251256 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcZonePathTest.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/performance/LoginPagePerformanceMockMvcZonePathTest.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.core.context.SecurityContextHolder; @@ -60,7 +60,7 @@ class LoginPagePerformanceMockMvcZonePathTest { private File originalLimitedModeStatusFile; - @MockBean + @MockitoBean OidcMetadataFetcher oidcMetadataFetcher; @BeforeEach diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/PasswordResetEndpointMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/PasswordResetEndpointMockMvcTests.java index 8b5a4e410db..8c867feac79 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/PasswordResetEndpointMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/PasswordResetEndpointMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeType; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointDocs.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointDocs.java index 043ed6e07b8..c5416b7a419 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointDocs.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointDocs.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.apache.commons.lang3.ArrayUtils; import org.cloudfoundry.identity.uaa.mock.EndpointDocs; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcTests.java index 448258b74ef..d1686563ded 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcTests.java @@ -1,8 +1,8 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ObjectNode; import com.google.common.collect.Sets; import org.apache.commons.codec.binary.Base64; import org.cloudfoundry.identity.uaa.DefaultTestContext; @@ -1118,7 +1118,7 @@ void patch_has_one_path() throws Exception { .header("Authorization", "Bearer " + scimWriteToken) .header("Content-Type", APPLICATION_JSON_VALUE)) .andDo(print()) - .andExpect(header().string("Location", "http://localhost/login?error=invalid_login_request")) + .andExpect(header().string("Location", "/login?error=invalid_login_request")) .andExpect(status().isFound()); //gets caught by the ui filter for unknown URIs but wantsJson; } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcZonePathTests.java index eb9c6341f69..59ac379d774 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimGroupEndpointsMockMvcZonePathTests.java @@ -1,8 +1,8 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ObjectNode; import com.google.common.collect.Sets; import org.apache.commons.codec.binary.Base64; import org.cloudfoundry.identity.uaa.DefaultTestContext; @@ -1120,7 +1120,7 @@ void patch_has_one_path() throws Exception { .header("Authorization", "Bearer " + scimWriteToken) .header("Content-Type", APPLICATION_JSON_VALUE)) .andDo(print()) - .andExpect(header().string("Location", "http://localhost/login?error=invalid_login_request")) + .andExpect(header().string("Location", "/login?error=invalid_login_request")) .andExpect(status().isFound()); //gets caught by the ui filter for unknown URIs but wantsJson; } diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsAliasMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsAliasMockMvcTests.java index 1df3b5d86b1..84ee99c50f0 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsAliasMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsAliasMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import org.cloudfoundry.identity.uaa.DefaultTestContext; import org.cloudfoundry.identity.uaa.HttpMethodEnum; import org.cloudfoundry.identity.uaa.alias.AliasMockMvcTestBase; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcTests.java index 92951144e50..7e395dd5b41 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Lists; import org.apache.commons.lang3.RandomStringUtils; import org.apache.hc.core5.http.NameValuePair; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcZonePathTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcZonePathTests.java index 727eab6015b..8f3f3ce4ed7 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcZonePathTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsMockMvcZonePathTests.java @@ -1,6 +1,6 @@ package org.cloudfoundry.identity.uaa.scim.endpoints; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; import com.google.common.collect.Lists; import org.apache.commons.lang3.RandomStringUtils; import org.apache.hc.core5.http.NameValuePair; diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsTests.java index 56a33672e71..78a6a4f2f55 100644 --- a/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsTests.java +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/scim/endpoints/ScimUserEndpointsTests.java @@ -1158,7 +1158,11 @@ private void validatePasswordForUaaOriginOnly(VerificationMode verificationMode, verify(mockPasswordValidator, verificationMode).validate("password"); jdbcTemplate.query("select password from users where id=?", rs -> { - assertThat(passwordEncoder.matches(expectedPassword, rs.getString(1))).isTrue(); + if (expectedPassword.isEmpty()) { + assertThat(rs.getString(1)).isEqualTo("{noop}"); + } else { + assertThat(passwordEncoder.matches(expectedPassword, rs.getString(1))).isTrue(); + } }, created.getId()); }