Repository: SAP/cloud-security-xsuaa-integration
Pull request #358 (2020-08-25 11:07:44)

Json object.get as string list


Patch:
diff --git a/README.md b/README.md
index 675842ee..8637adb2 100644
--- a/README.md
+++ b/README.md
@@ -21,8 +21,11 @@ The SAP Java Buildpack integrates token validation into the tomcat server. Appli
 - The application is deployed using the SAP Java Buildpack with version <= `v1.24.1`
 - You use `sap_java_buildpack` (e.g. in your `manifest.yml`)
 
-### Upcoming (Incompatible) Change
-SAP Java Buildpacks makes use of deprecated (Spring) Security libraries and needs to be updated. The new SAP Java Buildpack version will use the [`java-security`](/java-security) library. Please expect little migration efforts in the api for accessing token information. A Migration Guide will be provided. 
+### Changes with SAP Java Buildpack 1.26.0
+The former SAP Java Buildpack versions have used deprecated (Spring) Security libraries and had to be updated. As of version 1.26.0 SAP Java Buildpack uses the [`java-security`](/java-security) library. Please consider these (migration) guides:
+
+- [MANDATORY: clean-up deprecated dependencies](https://github.com/SAP/cloud-security-xsuaa-integration/blob/master/java-security/Migration_SAPJavaBuildpackProjects.md)
+- [OPTIONAL: Leverage new APIs and features](https://github.com/SAP/cloud-security-xsuaa-integration/blob/master/java-security/Migration_SAPJavaBuildpackProjects_V2.md)
 
 ### Sample
 See [sap-java-builpack-api-usage](samples/sap-java-buildpack-api-usage) for an example.
diff --git a/java-api/src/main/java/com/sap/cloud/security/json/JsonObject.java b/java-api/src/main/java/com/sap/cloud/security/json/JsonObject.java
index f0bd5d4a..08c7199a 100644
--- a/java-api/src/main/java/com/sap/cloud/security/json/JsonObject.java
+++ b/java-api/src/main/java/com/sap/cloud/security/json/JsonObject.java
@@ -43,6 +43,23 @@ public interface JsonObject {
 	 */
 	<T> List<T> getAsList(String name, Class<T> type);
 
+	/**
+	 * Parses the json object for the given property {@code name} and returns a
+	 * String list. If the property with the given name is not found, an empty
+	 * list is returned.
+	 *
+	 * For example {@code "aud" : "single-value"} or {@code "aud" : ["value-1", "value-2"]}
+	 *
+	 * @param name
+	 *            the property inside this json object which contains a String list.
+	 * @return the String list.
+	 * @throws JsonParsingException
+	 *             if the json object with the given key is not a String array or
+	 *             of type String.
+	 * @see #getAsString
+	 */
+	List<String> getAsStringList(String name);
+
 	/**
 	 * Returns the string identified by the given property {@code name}. If the
 	 * property with the given name is not found, null is returned.
diff --git a/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java b/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java
index b2abea12..d9481047 100644
--- a/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java
+++ b/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java
@@ -47,6 +47,19 @@ public class DefaultJsonObject implements JsonObject {
 		return getJSONArray(name).map(jsonArray -> castToListOfType(jsonArray, type)).orElse(Collections.emptyList());
 	}
 
+	@Override
+	public List<String> getAsStringList(String name) {
+		List<String> list = new ArrayList<>();
+		if(contains(name)) {
+			if (getJsonObject().get(name) instanceof String) {
+				list.add(getAsString(name));
+			} else {
+				list = getAsList(name, String.class);
+			}
+		}
+		return list;
+	}
+
 	@Override
 	@Nullable
 	public String getAsString(String name) {
diff --git a/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java b/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java
index 61028ca1..d5f247d4 100644
--- a/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java
+++ b/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java
@@ -74,7 +74,7 @@ public abstract class AbstractToken implements Token {
 	@Nullable
 	@Override
 	public List<String> getClaimAsStringList(@Nonnull String claimName) {
-		return tokenBody.getAsList(claimName, String.class);
+		return tokenBody.getAsStringList(claimName);
 	}
 
 	@Nullable
diff --git a/java-security/src/main/java/com/sap/cloud/security/token/SapIdToken.java b/java-security/src/main/java/com/sap/cloud/security/token/SapIdToken.java
index d54e1bec..873c22a5 100644
--- a/java-security/src/main/java/com/sap/cloud/security/token/SapIdToken.java
+++ b/java-security/src/main/java/com/sap/cloud/security/token/SapIdToken.java
@@ -1,14 +1,11 @@
 package com.sap.cloud.security.token;
 
 import com.sap.cloud.security.config.Service;
-import com.sap.cloud.security.json.JsonParsingException;
 import com.sap.cloud.security.xsuaa.jwt.DecodedJwt;
 
 import javax.annotation.Nonnull;
 
 import java.security.Principal;
-import java.util.LinkedHashSet;
-import java.util.Set;
 
 import static com.sap.cloud.security.token.TokenClaims.SAP_GLOBAL_USER_ID;
 
@@ -34,14 +31,4 @@ public class SapIdToken extends AbstractToken {
 		return Service.IAS;
 	}
 
-	@Override
-	public Set<String> getAudiences() {
-		try {
-			return super.getAudiences();
-		} catch (JsonParsingException e) {
-			final Set<String> audiences = new LinkedHashSet<>();
-			audiences.add(getClaimAsString(TokenClaims.AUDIENCE));
-			return audiences;
-		}
-	}
 }


Test patch:
diff --git a/java-security/src/test/java/com/sap/cloud/security/json/DefaultJsonObjectTest.java b/java-security/src/test/java/com/sap/cloud/security/json/DefaultJsonObjectTest.java
index fab9e563..2966e19c 100644
--- a/java-security/src/test/java/com/sap/cloud/security/json/DefaultJsonObjectTest.java
+++ b/java-security/src/test/java/com/sap/cloud/security/json/DefaultJsonObjectTest.java
@@ -79,6 +79,26 @@ public class DefaultJsonObjectTest {
 		assertThat(list).first().isEqualTo("a");
 	}
 
+	@Test
+	public void getAsStringList_keyDoesExistButNoList_returnsList() {
+		assertThat(cut.getAsString(KEY_1)).isEqualTo(STRING_TEXT);
+
+		assertThat(cut.getAsStringList(KEY_1)).contains(STRING_TEXT);
+		assertThat(cut.getAsStringList(KEY_1)).size().isEqualTo(1);
+
+		assertThat(cut.getAsStringList(KEY_1)).size().isEqualTo(1);
+	}
+
+	@Test
+	public void getAsStringList_keyExists_returnsList() {
+		cut = createJsonParser(KEY_2, STRING_LIST_VALUE);
+
+		List<String> list = cut.getAsStringList(KEY_2);
+
+		assertThat(list).hasSize(3);
+		assertThat(list).first().isEqualTo("a");
+	}
+
 	@Test
 	public void getAsListOfStrings_keyDoesNotExist_returnsEmptyList() {
 		assertThat(cut.getAsList("keyDoesNotExist", String.class)).isEmpty();