001
002package io.vrap.rmf.base.client.oauth2;
003
004import static io.vrap.rmf.base.client.ApiHttpHeaders.headerEntry;
005
006import java.net.URI;
007import java.nio.charset.StandardCharsets;
008import java.time.Duration;
009import java.util.Base64;
010import java.util.concurrent.CompletableFuture;
011
012import io.vrap.rmf.base.client.*;
013import io.vrap.rmf.base.client.utils.ClientUtils;
014
015public class AnonymousFlowTokenSupplier extends BaseAuthTokenSupplier implements RefreshableTokenSupplier {
016    private final RefreshFlowTokenSupplier refreshFlowTokenSupplier;
017
018    public AnonymousFlowTokenSupplier(final String clientId, final String clientSecret, final String scope,
019            final String tokenEndpoint, final RefreshFlowTokenSupplier refreshFlowTokenSupplier,
020            final VrapHttpClient vrapHttpClient) {
021        super(vrapHttpClient, constructApiHttpRequest(clientId, clientSecret, scope, tokenEndpoint));
022        this.refreshFlowTokenSupplier = refreshFlowTokenSupplier;
023    }
024
025    @Override
026    public CompletableFuture<AuthenticationToken> refreshToken() {
027        return refreshFlowTokenSupplier.refreshToken().exceptionally(throwable -> {
028            logger.error(() -> throwable);
029            return ClientUtils.blockingWait(getToken(), Duration.ofSeconds(5));
030        });
031    }
032
033    private static ApiHttpRequest constructApiHttpRequest(final String clientId, final String clientSecret,
034            final String scope, final String tokenEndpoint) {
035        String auth = Base64.getEncoder()
036                .encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
037        final ApiHttpHeaders apiHttpHeaders = new ApiHttpHeaders(
038            headerEntry(ApiHttpHeaders.AUTHORIZATION, String.format("Basic %s", auth)),
039            headerEntry(ApiHttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded"));
040        final String body;
041        if (scope == null || scope.isEmpty()) {
042            body = "grant_type=client_credentials";
043        }
044        else {
045            body = String.format("grant_type=client_credentials&scope=%s", urlEncode(scope));
046        }
047        return new ApiHttpRequest(ApiHttpMethod.POST, URI.create(tokenEndpoint), apiHttpHeaders,
048            body.getBytes(StandardCharsets.UTF_8));
049    }
050}