dev.fitko.fitconnect.core.auth.DefaultOAuthApiService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of client Show documentation
Show all versions of client Show documentation
Library that provides client access to the FIT-Connect api-endpoints for sending, subscribing and
routing
package dev.fitko.fitconnect.core.auth;
import dev.fitko.fitconnect.api.domain.auth.OAuthToken;
import dev.fitko.fitconnect.api.exceptions.internal.RestApiException;
import dev.fitko.fitconnect.api.services.auth.OAuthService;
import dev.fitko.fitconnect.api.services.http.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import static dev.fitko.fitconnect.core.http.HttpHeaders.ACCEPT;
import static dev.fitko.fitconnect.core.http.HttpHeaders.ACCEPT_CHARSET;
import static dev.fitko.fitconnect.core.http.HttpHeaders.CONTENT_TYPE;
import static dev.fitko.fitconnect.core.http.MimeTypes.APPLICATION_FORM_URLENCODED;
import static dev.fitko.fitconnect.core.http.MimeTypes.APPLICATION_JSON;
import static java.util.stream.Collectors.joining;
public class DefaultOAuthApiService implements OAuthService {
public static final String AUTH_TOKEN_PATH = "/token";
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultOAuthApiService.class);
private final HttpClient httpClient;
private final String authBaseUrl;
private final String clientId;
private final String clientSecret;
private OAuthToken currentToken;
private LocalDateTime tokenExpirationTime;
public DefaultOAuthApiService(final HttpClient httpClient, final String clientId, final String clientSecret, final String authBaseUrl) {
this.httpClient = httpClient;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.authBaseUrl = authBaseUrl;
resetExistingToken();
}
@Override
public OAuthToken getCurrentToken() throws RestApiException {
if (tokenExpired()) {
LOGGER.info("Current token is expired, authenticating ...");
authenticate();
}
return currentToken;
}
private boolean tokenExpired() {
if (currentToken == null || tokenExpirationTime == null) {
return true;
}
return tokenExpirationTime.isBefore(LocalDateTime.now());
}
private void resetExistingToken() {
currentToken = null;
tokenExpirationTime = null;
}
private void authenticate() {
final String requestBody = buildRequestBody(clientId, clientSecret);
currentToken = performTokenRequest(requestBody);
tokenExpirationTime = LocalDateTime.now().plusSeconds(currentToken.getExpiresIn());
}
private String buildRequestBody(final String clientId, final String clientSecret) {
final var data = new HashMap();
data.put("grant_type", "client_credentials");
data.put("client_id", clientId);
data.put("client_secret", clientSecret);
return joinRequestParams(data);
}
private String joinRequestParams(final HashMap data) {
return data.entrySet()
.stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(joining("&"));
}
private OAuthToken performTokenRequest(final String requestBody) throws RestApiException {
try {
LOGGER.info("Sending authentication request");
return httpClient.post(authBaseUrl + AUTH_TOKEN_PATH, getHeaders(), requestBody, OAuthToken.class).getBody();
} catch (final RestApiException e) {
LOGGER.error(e.getMessage(), e);
throw new RestApiException("Could not retrieve OAuth token", e);
}
}
private Map getHeaders() {
return new HashMap<>(Map.of(
ACCEPT, APPLICATION_JSON,
CONTENT_TYPE, APPLICATION_FORM_URLENCODED,
ACCEPT_CHARSET, StandardCharsets.UTF_8.toString()));
}
}