use of org.eclipse.linuxtools.internal.docker.core.OAuth2Utils.BearerTokenResponse in project linuxtools by eclipse.
the class AbstractRegistry method retrieveTagsFromDockerHub.
/**
* Retrieves the list of tags for a given repository, assuming that the
* target registry is Docker Hub.
*
* @param client
* the client to use
* @param repository
* the repository to look-up
* @return the list of tags for the given repository
* @throws CancellationException
* if the computation was cancelled
*/
private List<IRepositoryTag> retrieveTagsFromDockerHub(final Client client, final String repository) throws DockerException {
try {
// if the given repository is an official repository, we need to
// prepend
// with 'library'
final String repoName = // $NON-NLS-1$
repository.contains("/") ? // $NON-NLS-1$
repository : // $NON-NLS-1$
"library/" + repository;
// Docker Hub Registry may require a Bearer token which needs to be
// retrieved if the initial request returned a 401/Forbidden
// response.
// In that case, the "Www-Authenticate" response header provides the
// information needed to obtain a token.
// attempt to query the registry without a bearer token
final WebTarget queryTagsResource = client.target(getHTTPServerAddress()).path(// $NON-NLS-1$
"v2").path(repoName).path("tags").path(// $NON-NLS-1$ //$NON-NLS-2$
"list");
// return queryTagsResource.request(APPLICATION_JSON_TYPE).async()
// .method(GET, REPOSITORY_TAGS_RESULT_LIST).get();
final Response response = queryTagsResource.request(APPLICATION_JSON_TYPE).async().get().get(10, TimeUnit.SECONDS);
if (response.getStatus() == 200) {
return response.readEntity(RepositoryTagV2.class).getTags();
} else if (response.getStatus() != 401) {
// "Unauthorized"
throw new DockerException(NLS.bind(Messages.ImageTagsList_failure, repository, response.readEntity(String.class)));
}
// for "Unauthorized response, let's get a Bearer token and try
// again
final String wwwAuthenticateResponseHeader = response.getHeaderString(// $NON-NLS-1$
"Www-Authenticate");
// parse the header which should have the following form:
// Bearer
// realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:jboss/wildfly:pull
final Map<String, String> authenticateInfo = OAuth2Utils.parseWwwAuthenticateHeader(wwwAuthenticateResponseHeader);
if (authenticateInfo == null || // $NON-NLS-1$
!authenticateInfo.containsKey("realm") || // $NON-NLS-1$
!authenticateInfo.containsKey("service") || !authenticateInfo.containsKey("scope")) {
// $NON-NLS-1$
throw new DockerException(NLS.bind(Messages.ImageTagsList_failure_invalidWwwAuthenticateFormat, repository));
}
// now, call the auth service to obtain a Bearer token:
// $NON-NLS-1$
final String realm = authenticateInfo.get("realm");
// $NON-NLS-1$
final String service = authenticateInfo.get("service");
// $NON-NLS-1$
final String scope = authenticateInfo.get("scope");
final WebTarget bearerTokenRetrievalTarget = client.target(realm).queryParam("service", // $NON-NLS-1$
service).queryParam("scope", // $NON-NLS-1$
scope);
final BearerTokenResponse bearerTokenRetrievalResponse = bearerTokenRetrievalTarget.request(APPLICATION_JSON_TYPE).async().get(BearerTokenResponse.class).get(10, TimeUnit.SECONDS);
// finally, perform the same request, using the Bearer token:
final WebTarget queryTagsResourceWithBearerTokenTarget = client.target(getHTTPServerAddress()).path(// $NON-NLS-1$
"v2").path(repoName).path("tags").path(// $NON-NLS-1$ //$NON-NLS-2$
"list");
return queryTagsResourceWithBearerTokenTarget.request(APPLICATION_JSON_TYPE).header(// $NON-NLS-1$
"Authorization", // $NON-NLS-1$
"Bearer " + bearerTokenRetrievalResponse.getToken()).async().get(RepositoryTagV2.class).get(10, TimeUnit.SECONDS).getTags();
} catch (TimeoutException | ExecutionException | InterruptedException e) {
throw new DockerException(NLS.bind(Messages.ImageTagsList_failure, repository, e.getMessage()), e);
}
}
Aggregations