opinionated-vertx/src/de/pzzz/vertx/oauth/OAuthWebClient.java

96 lines
3.5 KiB
Java
Executable file

package de.pzzz.vertx.oauth;
import java.util.logging.Logger;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.codec.BodyCodec;
public class OAuthWebClient {
private static final Logger LOG = Logger.getLogger(OAuthWebClient.class.getName());
private final WebClient webClient;
private final OAuthConfig config;
private OAuthToken token;
public OAuthWebClient(final Vertx vertx, final OAuthConfig config) {
this.webClient = WebClient.create(vertx, new WebClientOptions()
.setLogActivity(true).setSsl(true).setTrustAll(config.isTrustAllCertificates()).setVerifyHost(false));
this.config = config;
}
public Future<HttpRequest<Buffer>> prepareAuthenticatedPut(final String requestPath) {
return prepareAuthenticatedRequest(HttpMethod.PUT, requestPath);
}
public Future<HttpRequest<Buffer>> prepareAuthenticatedGet(final String requestPath) {
return prepareAuthenticatedRequest(HttpMethod.GET, requestPath);
}
public Future<HttpRequest<Buffer>> prepareAuthenticatedPost(final String requestPath) {
return prepareAuthenticatedRequest(HttpMethod.POST, requestPath);
}
public Future<HttpRequest<Buffer>> prepareAuthenticatedDelete(final String requestPath) {
return prepareAuthenticatedRequest(HttpMethod.DELETE, requestPath);
}
public Future<HttpRequest<Buffer>> prepareAuthenticatedRequest(final HttpMethod method, final String requestPath) {
Promise<HttpRequest<Buffer>> promise = Promise.promise();
ensureIsAuthenticated().andThen(v ->
promise.complete(webClient.requestAbs(method, config.getBaseUrl() + requestPath)
.bearerTokenAuthentication(token.getToken()))
).onFailure(promise::fail);
return promise.future();
}
private Future<Void> ensureIsAuthenticated() {
if (null != token && token.isValid()) {
LOG.finest("keeping token...");
return Future.succeededFuture();
}
LOG.finest("Requesting new token...");
return getToken();
}
private Future<Void> getToken() {
String baseErrorMessage = "Failed to login! ";
Promise<Void> promise = Promise.promise();
MultiMap form = MultiMap.caseInsensitiveMultiMap();
form.set("grant_type", "client_credentials");
LOG.fine("Requesting new token...");
webClient.postAbs(config.getOauthTokenUrl())
.basicAuthentication(config.getOauthClientId(), config.getOauthClientSecret())
.as(BodyCodec.json(OAuthToken.class))
.sendForm(form)
.onSuccess(response -> {
if (response.statusCode() == 200) {
token = response.body();
LOG.finest("Got new token...");
promise.complete();
} else {
String errorMessage = baseErrorMessage + response.statusCode() + " - "
+ response.statusMessage();
handleTokenError(errorMessage, promise);
}
})
.onFailure(error -> {
String errorMessage = baseErrorMessage + error.getMessage();
handleTokenError(errorMessage, promise);
});
return promise.future();
}
private void handleTokenError(final String errorMessage, final Promise<Void> promise) {
LOG.severe(errorMessage);
token = null;
promise.fail(errorMessage);
}
}