Repository: SAP/cloud-security-xsuaa-integration
Pull request #471 (2021-02-15 15:25:52)

java-security: load environment from VCAP_SERVICES formatted json file
- prerequisite for spring-security


Patch:
diff --git a/java-security/src/main/java/com/sap/cloud/security/config/Environments.java b/java-security/src/main/java/com/sap/cloud/security/config/Environments.java
index 85fc8469..19659d07 100644
--- a/java-security/src/main/java/com/sap/cloud/security/config/Environments.java
+++ b/java-security/src/main/java/com/sap/cloud/security/config/Environments.java
@@ -2,6 +2,9 @@ package com.sap.cloud.security.config;
 
 import com.sap.cloud.security.config.cf.CFEnvironment;
 
+import java.io.InputStream;
+import java.util.Scanner;
+
 /**
  * Central entry point to access the current SAP Cloud Platform
  * {@link Environment}.
@@ -21,8 +24,24 @@ public class Environments {
 	 */
 	public static Environment getCurrent() {
 		// TODO Kubernetes: probe in which environment it runs currently: CF or
-		// Kubernetes
 		return cfEnvironment;
 	}
 
+	/**
+	 * Reads {@link Environment} not from system environment but from
+	 * {@link InputStream}.
+	 * 
+	 * @param input
+	 *            e.g. from file
+	 * @return the environment
+	 */
+	public static Environment readFromInput(InputStream input) {
+		Scanner scanner = new Scanner(input);
+		StringBuilder vcapServices = new StringBuilder();
+		while (scanner.hasNext()) {
+			vcapServices.append(scanner.nextLine());
+		}
+		return CFEnvironment.getInstance(str -> vcapServices.toString(), str -> null);
+	}
+
 }
diff --git a/java-security/src/main/java/com/sap/cloud/security/config/cf/CFEnvironment.java b/java-security/src/main/java/com/sap/cloud/security/config/cf/CFEnvironment.java
index 504b77c4..061e2be4 100644
--- a/java-security/src/main/java/com/sap/cloud/security/config/cf/CFEnvironment.java
+++ b/java-security/src/main/java/com/sap/cloud/security/config/cf/CFEnvironment.java
@@ -36,7 +36,7 @@ public class CFEnvironment implements Environment {
 		return getInstance(System::getenv, System::getProperty);
 	}
 
-	static CFEnvironment getInstance(UnaryOperator<String> systemEnvironmentProvider,
+	public static CFEnvironment getInstance(UnaryOperator<String> systemEnvironmentProvider,
 			UnaryOperator<String> systemPropertiesProvider) {
 		CFEnvironment instance = new CFEnvironment();
 		instance.systemEnvironmentProvider = systemEnvironmentProvider;


Test patch:
diff --git a/java-security/src/test/java/com/sap/cloud/security/config/EnvironmentsTest.java b/java-security/src/test/java/com/sap/cloud/security/config/EnvironmentsTest.java
index cd796d93..5488cba3 100644
--- a/java-security/src/test/java/com/sap/cloud/security/config/EnvironmentsTest.java
+++ b/java-security/src/test/java/com/sap/cloud/security/config/EnvironmentsTest.java
@@ -1,11 +1,25 @@
 package com.sap.cloud.security.config;
 
+import com.sap.cloud.security.config.cf.CFConstants;
+import org.apache.commons.io.IOUtils;
 import org.junit.Test;
 
+import java.io.IOException;
+import java.io.InputStream;
+
+import static com.sap.cloud.security.config.cf.CFConstants.SERVICE_PLAN;
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class EnvironmentsTest {
 
+	private final InputStream vcapMultipleXsuaa;
+
+	public EnvironmentsTest() throws IOException {
+		vcapMultipleXsuaa = IOUtils.toInputStream(
+				IOUtils.resourceToString("/vcapXsuaaServiceMultipleBindings.json", UTF_8), UTF_8);
+	}
+
 	@Test
 	public void getCurrent_returnsOnlySingleInstance() {
 		Environment firstEnvironment = Environments.getCurrent();
@@ -20,4 +34,30 @@ public class EnvironmentsTest {
 		// supported
 		assertThat(Environments.getCurrent().getType()).isEqualTo(Environment.Type.CF);
 	}
-}
\ No newline at end of file
+
+	@Test
+	public void readFromInputMultipleInstances() {
+		Environment cut = Environments.readFromInput(vcapMultipleXsuaa);
+
+		assertThat(cut.getNumberOfXsuaaConfigurations()).isEqualTo(2);
+		OAuth2ServiceConfiguration appServConfig = cut.getXsuaaConfiguration();
+		OAuth2ServiceConfiguration brokerServConfig = cut.getXsuaaConfigurationForTokenExchange();
+
+		assertThat(appServConfig.getService()).isEqualTo(Service.XSUAA);
+		assertThat(CFConstants.Plan.from(appServConfig.getProperty(SERVICE_PLAN)))
+				.isEqualTo(CFConstants.Plan.APPLICATION);
+
+		assertThat(brokerServConfig).isNotEqualTo(appServConfig);
+		assertThat(brokerServConfig.getService()).isEqualTo(Service.XSUAA);
+		assertThat(CFConstants.Plan.from(brokerServConfig.getProperty(SERVICE_PLAN)))
+				.isEqualTo(CFConstants.Plan.BROKER);
+		assertThat(brokerServConfig).isSameAs(cut.getXsuaaConfigurationForTokenExchange());
+	}
+
+	@Test
+	public void readFromInputDoesNotOverwriteCurrentEnvironment() {
+		Environment cut = Environments.readFromInput(vcapMultipleXsuaa);
+
+		assertThat(cut).isNotSameAs(Environments.getCurrent());
+	}
+}