Home / Class/ DockerRegistryConfigAuthenticationTests Class — spring-boot Architecture

DockerRegistryConfigAuthenticationTests Class — spring-boot Architecture

Architecture documentation for the DockerRegistryConfigAuthenticationTests class in DockerRegistryConfigAuthenticationTests.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

buildpack/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfigAuthenticationTests.java lines 54–434

@ExtendWith(OutputCaptureExtension.class)
class DockerRegistryConfigAuthenticationTests {

	private final Map<String, String> environment = new LinkedHashMap<>();

	private final Map<String, Exception> helperExceptions = new LinkedHashMap<>();

	private final Map<String, CredentialHelper> credentialHelpers = new HashMap<>();

	@BeforeEach
	void cleanup() {
		DockerRegistryConfigAuthentication.credentialFromHelperCache.clear();
	}

	@WithResource(name = "config.json", content = """
			{
			  "auths": {
			    "https://index.docker.io/v1/": {
			      "auth": "dXNlcm5hbWU6cGFzc3dvcmQ=",
			      "email": "test@example.com"
			    }
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenAuthForDockerDomain(@ResourcesRoot Path directory) {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "https://index.docker.io/v1/")
			.containsEntry("username", "username")
			.containsEntry("password", "password")
			.containsEntry("email", "test@example.com");
	}

	@WithResource(name = "config.json", content = """
			{
			  "auths": {
			    "https://index.docker.io/v1/": {
			      "auth": "dXNlcm5hbWU6cGFzc3dvcmQ=",
			      "email": "test@example.com"
			    }
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenAuthForLegacyDockerDomain(@ResourcesRoot Path directory) {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("index.docker.io/ubuntu:latest");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "https://index.docker.io/v1/")
			.containsEntry("username", "username")
			.containsEntry("password", "password")
			.containsEntry("email", "test@example.com");
	}

	@WithResource(name = "config.json", content = """
			{
			  "auths": {
				"my-registry.example.com": {
				  "auth": "Y3VzdG9tVXNlcjpjdXN0b21QYXNz"
				}
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenAuthForCustomDomain(@ResourcesRoot Path directory) {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "my-registry.example.com")
			.containsEntry("username", "customUser")
			.containsEntry("password", "customPass")
			.containsEntry("email", null);
	}

	@WithResource(name = "config.json", content = """
			{
			  "auths": {
				"https://my-registry.example.com": {
				  "auth": "Y3VzdG9tVXNlcjpjdXN0b21QYXNz"
				}
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenAuthForCustomDomainWithLegacyFormat(@ResourcesRoot Path directory) {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "https://my-registry.example.com")
			.containsEntry("username", "customUser")
			.containsEntry("password", "customPass")
			.containsEntry("email", null);
	}

	@WithResource(name = "config.json", content = """
			{
			}
			""")
	@Test
	void getAuthHeaderWhenEmptyConfigDirectoryReturnsFallback(@ResourcesRoot Path directory) {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest");
		String authHeader = getAuthHeader(imageReference, DockerRegistryAuthentication.EMPTY_USER);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "")
			.containsEntry("username", "")
			.containsEntry("password", "")
			.containsEntry("email", "");
	}

	@WithResource(name = "config.json", content = """
				{
				  "credsStore": "desktop"
				}
			""")
	@WithResource(name = "credentials.json", content = """
			{
			  "ServerURL": "https://index.docker.io/v1/",
			  "Username": "<token>",
			  "Secret": "secret"
			}
			""")
	@Test
	void getAuthHeaderWhenUsingHelperFromCredsStore(@ResourcesRoot Path directory) throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest");
		mockHelper("desktop", "https://index.docker.io/v1/", "credentials.json");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(1).containsEntry("identitytoken", "secret");
	}

	@WithResource(name = "config.json", content = """
			{
			  "auths": {
			    "gcr.io": {
			      "email": "test@example.com"
			    }
			  },
			  "credsStore": "desktop",
			  "credHelpers": {
			    "gcr.io": "gcr"
			  }
			}
			""")
	@WithResource(name = "credentials.json", content = """
			{
			  "ServerURL": "https://my-gcr.io",
			  "Username": "username",
			  "Secret": "secret"
			}
			""")
	@Test
	void getAuthHeaderWhenUsingHelperFromCredsStoreAndUseEmailFromAuth(@ResourcesRoot Path directory) throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("gcr.io/ubuntu:latest");
		mockHelper("gcr", "gcr.io", "credentials.json");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "https://my-gcr.io")
			.containsEntry("username", "username")
			.containsEntry("password", "secret")
			.containsEntry("email", "test@example.com");
	}

	@WithResource(name = "config.json", content = """
			{
			  "credsStore": "desktop",
			  "credHelpers": {
			    "gcr.io": "gcr"
			  }
			}
			""")
	@WithResource(name = "credentials.json", content = """
			{
			  "Username": "username",
			  "Secret": "secret"
			}
			""")
	@Test
	void getAuthHeaderWhenUsingHelperFromCredHelpersUsesProvidedServerUrl(@ResourcesRoot Path directory)
			throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("gcr.io/ubuntu:latest");
		mockHelper("gcr", "gcr.io", "credentials.json");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "gcr.io")
			.containsEntry("username", "username")
			.containsEntry("password", "secret")
			.containsEntry("email", null);
	}

	@WithResource(name = "config.json", content = """
			{
			"auths": {
			    "gcr.io": {
			      "auth": "dXNlcm5hbWU6cGFzc3dvcmQ=",
			      "email": "test@example.com"
			    }
			  },
			  "credsStore": "desktop",
			  "credHelpers": {
			    "gcr.io": "gcr"
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenUsingHelperThatFailsLogsErrorAndReturnsFromAuths(@ResourcesRoot Path directory)
			throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("gcr.io/ubuntu:latest");
		CredentialHelper helper = mockHelper("gcr");
		given(helper.get("gcr.io")).willThrow(new IOException("Failed to obtain credentials for registry"));
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "gcr.io")
			.containsEntry("username", "username")
			.containsEntry("password", "password")
			.containsEntry("email", "test@example.com");
		assertThat(this.helperExceptions).hasSize(1);
		assertThat(this.helperExceptions.keySet().iterator().next())
			.contains("Error retrieving credentials for 'gcr.io' due to: Failed to obtain credentials for registry");
	}

	@WithResource(name = "config.json", content = """
			{
			  "credsStore": "desktop",
			  "credHelpers": {
			    "gcr.io": "gcr"
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenUsingHelperThatFailsAndNoAuthLogsErrorAndReturnsFallback(@ResourcesRoot Path directory)
			throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("gcr.io/ubuntu:latest");
		CredentialHelper helper = mockHelper("gcr");
		given(helper.get("gcr.io")).willThrow(new IOException("Failed to obtain credentials for registry"));
		String authHeader = getAuthHeader(imageReference, DockerRegistryAuthentication.EMPTY_USER);
		assertThat(authHeader).isNotNull();
		assertThat(this.helperExceptions).hasSize(1);
		assertThat(this.helperExceptions.keySet().iterator().next())
			.contains("Error retrieving credentials for 'gcr.io' due to: Failed to obtain credentials for registry");
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "")
			.containsEntry("username", "")
			.containsEntry("password", "")
			.containsEntry("email", "");
	}

	@WithResource(name = "config.json", content = """
			{
			  "credsStore": "desktop",
			  "credHelpers": {
			    "gcr.io": ""
			  }
			}
			""")
	@Test
	void getAuthHeaderWhenEmptyCredHelperReturnsFallbackAndDoesNotUseCredStore(@ResourcesRoot Path directory)
			throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		ImageReference imageReference = ImageReference.of("gcr.io/ubuntu:latest");
		CredentialHelper desktopHelper = mockHelper("desktop");
		String authHeader = getAuthHeader(imageReference, DockerRegistryAuthentication.EMPTY_USER);
		assertThat(authHeader).isNotNull();
		// The Docker CLI appears to prioritize the credential helper over the
		// credential store, even when the helper is empty.
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "")
			.containsEntry("username", "")
			.containsEntry("password", "")
			.containsEntry("email", "");
		then(desktopHelper).should(never()).get(any(String.class));
	}

	@WithResource(name = "config.json", content = """
			{
			  "credsStore": "desktop"
			}
			""")
	@Test
	void getAuthHeaderReturnsFallbackWhenImageReferenceNull(@ResourcesRoot Path directory) throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		CredentialHelper desktopHelper = mockHelper("desktop");
		String authHeader = getAuthHeader(null, DockerRegistryAuthentication.EMPTY_USER);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "")
			.containsEntry("username", "")
			.containsEntry("password", "")
			.containsEntry("email", "");
		then(desktopHelper).should(never()).get(any(String.class));
	}

	@WithResource(name = "config.json", content = """
			{
			  "auths": {
			    "https://my-registry.example.com": {
			      "email": "test@example.com"
			    }
			  },
			  "credsStore": "desktop"
			}
			""")
	@WithResource(name = "credentials.json", content = """
			{
			  "Username": "username",
			  "Secret": "secret"
			}
			""")
	@Test
	void getAuthHeaderWhenUsingHelperFromCredHelpersUsesImageReferenceServerUrlAsFallback(@ResourcesRoot Path directory)
			throws Exception {
		this.environment.put("DOCKER_CONFIG", directory.toString());
		mockHelper("desktop", "my-registry.example.com", "credentials.json");
		ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest");
		String authHeader = getAuthHeader(imageReference);
		assertThat(authHeader).isNotNull();
		assertThat(decode(authHeader)).hasSize(4)
			.containsEntry("serveraddress", "my-registry.example.com")
			.containsEntry("username", "username")
			.containsEntry("password", "secret")
			.containsEntry("email", "test@example.com");
	}

	private @Nullable String getAuthHeader(@Nullable ImageReference imageReference) {
		return getAuthHeader(imageReference, null);
	}

	private @Nullable String getAuthHeader(@Nullable ImageReference imageReference,
			@Nullable DockerRegistryAuthentication fallback) {
		DockerRegistryConfigAuthentication authentication = getAuthentication(fallback);
		return authentication.getAuthHeader(imageReference);
	}

	private DockerRegistryConfigAuthentication getAuthentication(@Nullable DockerRegistryAuthentication fallback) {
		Function<String, @Nullable CredentialHelper> credentialHelperFactory = this.credentialHelpers::get;
		return new DockerRegistryConfigAuthentication(fallback, this.helperExceptions::put, this.environment::get,
				credentialHelperFactory);
	}

	private void mockHelper(String name, String serverUrl, String credentialsResourceName) throws Exception {
		CredentialHelper helper = mockHelper(name);
		given(helper.get(serverUrl)).willReturn(getCredentials(credentialsResourceName));
	}

	private CredentialHelper mockHelper(String name) {
		CredentialHelper helper = mock(CredentialHelper.class);
		this.credentialHelpers.put(name, helper);
		return helper;
	}

	private Credential getCredentials(String resourceName) throws Exception {
		try (InputStream inputStream = new ClassPathResource(resourceName).getInputStream()) {
			return new Credential(SharedJsonMapper.get().readTree(inputStream));
		}
	}

	private Map<String, String> decode(String authHeader) {
		return SharedJsonMapper.get().readValue(Base64.getDecoder().decode(authHeader), new TypeReference<>() {
		});
	}

}

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free