001
002package io.vrap.rmf.base.client.oauth2;
003
004import java.io.UnsupportedEncodingException;
005import java.net.URLEncoder;
006import java.nio.charset.StandardCharsets;
007import java.util.concurrent.CompletableFuture;
008import java.util.concurrent.CompletionException;
009
010import io.vrap.rmf.base.client.*;
011import io.vrap.rmf.base.client.http.InternalLogger;
012import io.vrap.rmf.base.client.utils.Utils;
013import io.vrap.rmf.base.client.utils.json.JsonUtils;
014
015public abstract class BaseAuthTokenSupplier extends AutoCloseableService implements TokenSupplier {
016    protected final VrapHttpClient vrapHttpClient;
017    protected final ApiHttpRequest apiHttpRequest;
018    protected final InternalLogger logger = InternalLogger.getLogger(LOGGER_AUTH);
019
020    public BaseAuthTokenSupplier(final VrapHttpClient vrapHttpClient, ApiHttpRequest apiHttpRequest) {
021        this.vrapHttpClient = vrapHttpClient;
022        this.apiHttpRequest = apiHttpRequest;
023    }
024
025    @Override
026    public CompletableFuture<AuthenticationToken> getToken() {
027        return vrapHttpClient.execute(apiHttpRequest).whenComplete((response, throwable) -> {
028            logger.info(() -> String.format("%s %s %s", apiHttpRequest.getMethod().name(), apiHttpRequest.getUri(),
029                response.getStatusCode()));
030            if (throwable != null) {
031                logger.error(() -> response, throwable);
032            }
033            else {
034                logger.debug(() -> response);
035            }
036        }).thenApply(apiHttpResponse -> {
037            if (apiHttpResponse.getStatusCode() < 200 || apiHttpResponse.getStatusCode() > 299) {
038                if (apiHttpResponse.getStatusCode() == 405) {
039                    throw new CompletionException(new AuthException(apiHttpResponse.getStatusCode(),
040                        new String(apiHttpResponse.getBody()), apiHttpRequest.getHeaders(),
041                        apiHttpResponse.getMessage()
042                                + " : auth token URI may be incorrect e.g. https://auth.europe-west1.gcp.commercetools.com/oauth/token",
043                        apiHttpResponse));
044                }
045                throw new CompletionException(
046                    new AuthException(apiHttpResponse.getStatusCode(), new String(apiHttpResponse.getBody()),
047                        apiHttpRequest.getHeaders(), apiHttpResponse.getMessage(), apiHttpResponse));
048            }
049            return apiHttpResponse;
050        })
051                .thenApply(Utils.wrapToCompletionException((ApiHttpResponse<byte[]> response) -> JsonUtils
052                        .fromJsonByteArray(response.getBody(), AuthenticationToken.class)));
053    }
054
055    static String urlEncode(String value) {
056        try {
057            return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
058        }
059        catch (UnsupportedEncodingException e) {
060            throw new IllegalArgumentException(e.getMessage(), e);
061        }
062    }
063
064    @Override
065    protected void internalClose() {
066        if (vrapHttpClient instanceof AutoCloseable)
067            closeQuietly((AutoCloseable) vrapHttpClient);
068    }
069}