Skip to content
RapClient.java 4.22 KiB
Newer Older
Sonia Zorba's avatar
Sonia Zorba committed
package it.inaf.ia2.gms.rap;

import it.inaf.ia2.gms.authn.SessionData;
import it.inaf.ia2.gms.model.RapUser;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Sonia Zorba's avatar
Sonia Zorba committed
import java.util.Map;
Sonia Zorba's avatar
Sonia Zorba committed
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
Sonia Zorba's avatar
Sonia Zorba committed
import org.springframework.http.ResponseEntity;
Sonia Zorba's avatar
Sonia Zorba committed
import org.springframework.stereotype.Component;
Sonia Zorba's avatar
Sonia Zorba committed
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
Sonia Zorba's avatar
Sonia Zorba committed

@Component
public class RapClient {

    @Value("${rap.ws-url}")
    private String rapBaseUrl;

Sonia Zorba's avatar
Sonia Zorba committed
    @Value("${security.oauth2.client.access-token-uri}")
    private String accessTokenUri;

    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Value("${security.oauth2.client.scope}")
    private String scope;

    private final SessionData sessionData;

    private final RestTemplate rapRestTemplate;

    private final RestTemplate refreshTokenRestTemplate;
Sonia Zorba's avatar
Sonia Zorba committed
    public RapClient(SessionData sessionData, RestTemplate rapRestTemplate) {
        this.sessionData = sessionData;
        this.rapRestTemplate = rapRestTemplate;
        this.refreshTokenRestTemplate = new RestTemplate();
    }

    public List<RapUser> getUsers(Set<String> identifiers) {

        if (identifiers.isEmpty()) {
            return new ArrayList<>();
        }

        String url = rapBaseUrl + "/user?identifiers=" + String.join(",", identifiers);
Sonia Zorba's avatar
Sonia Zorba committed

        return httpCall(entity -> {
            return rapRestTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<List<RapUser>>() {
            }).getBody();
        });
    public List<RapUser> searchUsers(String searchText) {

        if (searchText == null || searchText.trim().isEmpty()) {
            return new ArrayList<>();
        }

        String url = rapBaseUrl + "/user?search=" + searchText;
Sonia Zorba's avatar
Sonia Zorba committed

        return httpCall(entity -> {
            return rapRestTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<List<RapUser>>() {
            }).getBody();
        });
    }

    private <R> R httpCall(Function<HttpEntity<?>, R> function) {
        return httpCall(function, null);
Sonia Zorba's avatar
Sonia Zorba committed
    private <R, T> R httpCall(Function<HttpEntity<?>, R> function, T body) {
        try {
            return function.apply(getEntity(body));
        } catch (HttpClientErrorException.Unauthorized ex) {
            refreshToken();
            return function.apply(getEntity(body));
        }
    }

    private <T> HttpEntity<T> getEntity(T body) {

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

        headers.add("Authorization", "Bearer " + sessionData.getAccessToken());

        return new HttpEntity<>(body, headers);
    }
Sonia Zorba's avatar
Sonia Zorba committed

    private void refreshToken() {

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        headers.setBasicAuth(clientId, clientSecret);

        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("grant_type", "refresh_token");
        map.add("refresh_token", sessionData.getRefreshToken());
        map.add("scope", scope.replace(",", " "));

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

        ResponseEntity<Map> response = refreshTokenRestTemplate.postForEntity(accessTokenUri, request, Map.class);

        Map<String, String> values = response.getBody();

        sessionData.setAccessToken(values.get("access_token"));
        sessionData.setRefreshToken(values.get("refresh_token"));
    }