Skip to content

Commit 0de9534

Browse files
authored
Allow to pass auth token to build registry (#677)
Signed-off-by: Valentin Delaye <jonesbusy@users.noreply.github.com>
1 parent 012f162 commit 0de9534

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

src/main/java/land/oras/Registry.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.util.function.Supplier;
4343
import land.oras.auth.AuthProvider;
4444
import land.oras.auth.AuthStoreAuthenticationProvider;
45+
import land.oras.auth.BearerTokenProvider;
4546
import land.oras.auth.HttpClient;
4647
import land.oras.auth.NoAuthProvider;
4748
import land.oras.auth.RegistriesConf;
@@ -294,6 +295,15 @@ public Registry copy(String newRegistry) {
294295
return new Builder().from(this).withRegistry(newRegistry).build();
295296
}
296297

298+
/**
299+
* Return a new registry with a new auth external token and same settings
300+
* @param authToken The new refreshed token
301+
* @return The new registry
302+
*/
303+
public Registry withAuthToken(String authToken) {
304+
return new Builder().from(this).withAuthToken(authToken).build();
305+
}
306+
297307
/**
298308
* Return a new registry as insecure but with same settings
299309
* @return The new registry
@@ -1281,6 +1291,18 @@ public Builder withAuthProvider(AuthProvider authProvider) {
12811291
return this;
12821292
}
12831293

1294+
/**
1295+
* Use given auth token for the registry.
1296+
* Useful when the auth token is obtained by other mean (like a token exchange).
1297+
* Caller are responsible to handle token expiration if any
1298+
* @param authToken The auth token
1299+
* @return The builder
1300+
*/
1301+
public Builder withAuthToken(String authToken) {
1302+
registry.setAuthProvider(new BearerTokenProvider(authToken));
1303+
return this;
1304+
}
1305+
12841306
/**
12851307
* Set the maximum number of concurrent downloads when pulling an artifact with multiple layers. Default is 4.
12861308
* @param parallelism The maximum number of parallel uploads/download

src/main/java/land/oras/auth/BearerTokenProvider.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public final class BearerTokenProvider implements AuthProvider {
4747
*/
4848
public BearerTokenProvider() {}
4949

50+
/**
51+
* Create a new bearer token provider
52+
* @param token The token
53+
*/
54+
public BearerTokenProvider(String token) {
55+
setToken(new HttpClient.TokenResponse(token, null, null, null, null));
56+
}
57+
5058
/**
5159
* Get the token
5260
* @return The token

src/test/java/land/oras/RegistryWireMockTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,34 @@ class RegistryWireMockTest {
8383
@TempDir
8484
private static Path homeDir3;
8585

86+
@Test
87+
void shouldPassBearerTokenWithExternalRequestedToken(WireMockRuntimeInfo wmRuntimeInfo) {
88+
Registry registry = Registry.Builder.builder()
89+
.insecure()
90+
.withAuthToken("insecure-token")
91+
.build();
92+
93+
// Ensure WireMock accept only our token
94+
WireMock wireMock = wmRuntimeInfo.getWireMock();
95+
wireMock.register(WireMock.get(WireMock.urlEqualTo("/v2/library/artifact-text/tags/list"))
96+
.withHeader("Authorization", equalTo("Bearer insecure-token"))
97+
.willReturn(WireMock.okJson(JsonUtils.toJson(new Tags("artifact-text", List.of("latest", "0.1.1"))))));
98+
wireMock.register(WireMock.get(WireMock.urlEqualTo("/v2/library/artifact-text/tags/list"))
99+
.withHeader("Authorization", equalTo("Bearer invalid-token"))
100+
.willReturn(WireMock.unauthorized()));
101+
102+
registry.getTags(ContainerRef.parse("%s/library/artifact-text"
103+
.formatted(wmRuntimeInfo.getHttpBaseUrl().replace("http://", ""))));
104+
105+
// Ensure it fail with invalid token
106+
final Registry newRegistry = registry.withAuthToken("invalid-token");
107+
OrasException e = assertThrows(
108+
OrasException.class,
109+
() -> newRegistry.getTags(ContainerRef.parse("%s/library/artifact-text"
110+
.formatted(wmRuntimeInfo.getHttpBaseUrl().replace("http://", "")))));
111+
assertEquals(401, e.getStatusCode());
112+
}
113+
86114
@Test
87115
void shouldFailToGetManifestOn403(WireMockRuntimeInfo wmRuntimeInfo) {
88116

0 commit comments

Comments
 (0)