io.sphere.sdk.client.TokensSupplierImpl Maven / Gradle / Ivy
package io.sphere.sdk.client;
import com.fasterxml.jackson.databind.JsonNode;
import io.sphere.sdk.http.*;
import io.sphere.sdk.json.JsonException;
import io.sphere.sdk.json.SphereJsonUtils;
import io.sphere.sdk.meta.BuildInfo;
import io.sphere.sdk.models.SphereException;
import io.sphere.sdk.utils.MapUtils;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
import static io.sphere.sdk.client.SphereAuth.AUTH_LOGGER;
import static io.sphere.sdk.http.HttpMethod.POST;
import static java.lang.String.format;
/**
* Component that can fetch SPHERE.IO access tokens.
* Does not refresh them,
*/
final class TokensSupplierImpl extends AutoCloseableService implements TokensSupplier {
private final SphereAuthConfig config;
private final HttpClient httpClient;
private final boolean closeHttpClient;
private boolean isClosed = false;
private TokensSupplierImpl(final SphereAuthConfig config, final HttpClient httpClient, final boolean closeHttpClient) {
this.config = config;
this.httpClient = httpClient;
this.closeHttpClient = closeHttpClient;
}
static TokensSupplier of(final SphereAuthConfig config, final HttpClient httpClient, final boolean closeHttpClient) {
return new TokensSupplierImpl(config, httpClient, closeHttpClient);
}
/**
* Executes a http auth sphere request and fetches a new access token.
* @return future of a token
*/
@Override
public CompletionStage get() {
AUTH_LOGGER.debug(() -> "Fetching new token.");
final HttpRequest httpRequest = newRequest();
final CompletionStage httpResponseStage = httpClient.execute(httpRequest);
final CompletionStage result = httpResponseStage.thenApply((response) -> parseResponse(response, httpRequest));
result.whenCompleteAsync(this::logTokenResult);
return result;
}
private void logTokenResult(final Tokens nullableTokens, final Throwable nullableThrowable) {
if (nullableTokens != null) {
AUTH_LOGGER.debug(() -> "Successfully fetched token that expires in " + Optional.ofNullable(nullableTokens.getExpiresIn()).map(x -> x.toString()).orElse("an unknown time") + ".");
} else {
AUTH_LOGGER.error(() -> "Failed to fetch token.", nullableThrowable);
}
}
@Override
protected synchronized void internalClose() {
if (!isClosed) {
if (closeHttpClient) {
closeQuietly(httpClient);
}
isClosed = true;
}
}
private HttpRequest newRequest() {
final String usernamePassword = format("%s:%s", config.getClientId(), config.getClientSecret());
final String encodedString = Base64.getEncoder().encodeToString(usernamePassword.getBytes(StandardCharsets.UTF_8));
final HttpHeaders httpHeaders = HttpHeaders
.of(HttpHeaders.AUTHORIZATION, "Basic " + encodedString)
.plus(HttpHeaders.USER_AGENT, BuildInfo.userAgent())
.plus(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
final FormUrlEncodedHttpRequestBody body = FormUrlEncodedHttpRequestBody.of(MapUtils.mapOf("grant_type", "client_credentials", "scope", format("manage_project:%s", config.getProjectKey())));
return HttpRequest.of(POST, config.getAuthUrl() + "/oauth/token", httpHeaders, body);
}
/** Parses Tokens from a response from the backend authorization service.
* @param httpResponse Response from the authorization service.
* @param httpRequest the request which belongs to the response
*/
private Tokens parseResponse(final HttpResponse httpResponse, final HttpRequest httpRequest) {
try {
if (httpResponse.getStatusCode() == 401 && httpResponse.getResponseBody() != null) {
ClientErrorException exception = new UnauthorizedException(httpResponse.toString());
try {
final JsonNode jsonNode = SphereJsonUtils.parse(httpResponse.getResponseBody());
final String error = jsonNode.get("error").asText();
if (error.equals("invalid_client")) {
exception = new InvalidClientCredentialsException(config);
}
} catch (final JsonException e) {
exception = new UnauthorizedException(httpResponse.toString(), e);
}
throw exception;
}
return SphereJsonUtils.readObject(httpResponse.getResponseBody(), Tokens.typeReference());
} catch (final SphereException exception) {
exception.setProjectKey(config.getProjectKey());
exception.setUnderlyingHttpResponse(httpResponse);
exception.setHttpRequest(httpRequest);
throw exception;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy