188 lines
8.9 KiB
Java
188 lines
8.9 KiB
Java
package eu.dnetlib.developers.services;
|
|
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import eu.dnetlib.developers.configuration.Properties;
|
|
import eu.dnetlib.developers.dto.*;
|
|
import eu.dnetlib.developers.entities.RegisteredService;
|
|
import eu.dnetlib.developers.exceptions.EntityMissingException;
|
|
import eu.dnetlib.developers.exceptions.EntityNotFoundException;
|
|
import eu.dnetlib.developers.exceptions.ForbiddenException;
|
|
import eu.dnetlib.developers.repositories.RegisteredServiceDAO;
|
|
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.*;
|
|
import org.springframework.security.core.context.SecurityContextHolder;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Service()
|
|
public class APIService {
|
|
|
|
private RegisteredServiceDAO dao;
|
|
private RestTemplate template;
|
|
private String issuer;
|
|
|
|
@Autowired
|
|
public APIService(RegisteredServiceDAO dao, RestTemplate template, Properties properties) {
|
|
this.dao = dao;
|
|
this.template = template;
|
|
this.issuer = properties.getIssuer();
|
|
}
|
|
|
|
public List<API> getAll() {
|
|
return this.dao.findAll().stream().map(service -> {
|
|
API details = new API();
|
|
details.setService(service);
|
|
details.setDetails(this.readService(service.getClientId(), service.getRegistrationAccessToken()));
|
|
return details;
|
|
}).collect(Collectors.toList());
|
|
}
|
|
|
|
public List<API> getMyServices() {
|
|
OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
|
return this.dao.findAllByOwnerOrderByCreationDateAsc(authentication.getSub()).stream().map(service -> {
|
|
API details = new API();
|
|
details.setService(service);
|
|
details.setDetails(this.readService(service.getClientId(), service.getRegistrationAccessToken()));
|
|
return details;
|
|
}).collect(Collectors.toList());
|
|
}
|
|
|
|
public List<API> migrateAccessToken(List<RegisteredAT> registeredAT) {
|
|
List<API> apis = new ArrayList<>();
|
|
registeredAT.forEach( element -> {
|
|
RegisteredService service = this.dao.findByClientId(element.getClientId()).orElse(null);
|
|
if(service != null) {
|
|
service.setRegistrationAccessToken(element.getRegistrationAccessToken());
|
|
API api = new API();
|
|
api.setService(this.dao.save(service));
|
|
api.setDetails(this.readService(service.getClientId(), service.getRegistrationAccessToken()));
|
|
apis.add(api);
|
|
}
|
|
});
|
|
return apis;
|
|
}
|
|
|
|
public API save(ServiceForm form, Long id) {
|
|
ServiceRequest request;
|
|
API api = new API();
|
|
OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
|
if(id != null) {
|
|
RegisteredService service = this.dao.findById(id).orElse(null);
|
|
if(service == null) {
|
|
throw new EntityNotFoundException("Service with id " + id + " does not exist.");
|
|
}
|
|
api.setService(service);
|
|
api.setDetails(readService(service.getClientId(), service.getRegistrationAccessToken()));
|
|
} else {
|
|
api.setService(new RegisteredService(authentication.getSub(), form.getName(), form.getUrl(), form.getKeyType()));
|
|
}
|
|
String keyType = form.getKeyType();
|
|
if(keyType != null && keyType.equals("uri")) {
|
|
if(form.getUri() == null) {
|
|
throw new EntityMissingException("Uri is required in this type of key");
|
|
}
|
|
request = ServiceRequest.createServiceRequest(api.getService().getClientId(), form.getName(), form.getLogoURL(), authentication.getUserInfo().getEmail(), form.getUri());
|
|
} else if(keyType != null && keyType.equals("value")) {
|
|
Gson gson = new GsonBuilder().registerTypeAdapter(Jwks.class, new JwksDeserializer()).create();
|
|
String jwksSet = String.format("{\"keys\":[%s]}", form.getValue());
|
|
form.setJwks(gson.fromJson(jwksSet, Jwks.class));
|
|
if(!form.getJwks().isValid()) {
|
|
throw new EntityMissingException("Jwks value is not valid");
|
|
}
|
|
request = ServiceRequest.createServiceRequest(api.getService().getClientId(), form.getName(), form.getLogoURL(), authentication.getUserInfo().getEmail(), form.getJwks());
|
|
} else {
|
|
request = ServiceRequest.createServiceRequest(api.getService().getClientId(), form.getName(), form.getLogoURL(), authentication.getUserInfo().getEmail());
|
|
}
|
|
ServiceResponse response;
|
|
if(api.getService().getClientId() != null) {
|
|
response = this.updateService(api.getService().getClientId(), request, api.getService().getRegistrationAccessToken());
|
|
} else {
|
|
if(this.dao.findAllByOwnerOrderByCreationDateAsc(authentication.getSub()).size() < 5) {
|
|
response = this.createService(request);
|
|
} else {
|
|
throw new ForbiddenException("You are not allowed to own more than 5 services.");
|
|
}
|
|
}
|
|
api.getService().setKeyType(form.getKeyType());
|
|
api.getService().setUrl(form.getUrl());
|
|
api.getService().setName(request.getClientName());
|
|
api.getService().setClientId(response.getClientId());
|
|
api.getService().setRegistrationAccessToken(response.getRegistrationAccessToken());
|
|
api.setService(this.dao.save(api.getService()));
|
|
api.setDetails(response);
|
|
return api;
|
|
}
|
|
|
|
public API save(ServiceForm form) {
|
|
return this.save(form, null);
|
|
}
|
|
|
|
public void delete(Long id) {
|
|
RegisteredService service = this.dao.findById(id).orElse(null);
|
|
if(service == null) {
|
|
throw new EntityNotFoundException("Service with id " + id + " does not exist.");
|
|
} else {
|
|
this.deleteService(service.getClientId(), service.getRegistrationAccessToken());
|
|
this.dao.delete(id);
|
|
}
|
|
}
|
|
|
|
private ServiceResponse createService(ServiceRequest request) {
|
|
HttpHeaders headers = new HttpHeaders();
|
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
HttpEntity<String> requestEntity = new HttpEntity<>(request.toJson(), headers);
|
|
try {
|
|
ResponseEntity<String> response = template.exchange(this.issuer, HttpMethod.POST, requestEntity, String.class);
|
|
return ServiceResponse.fromString(response.getBody());
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
throw new EntityMissingException("Register of this service couldn't be completed. Check again your parameters");
|
|
}
|
|
}
|
|
|
|
private ServiceResponse updateService(String clientId, ServiceRequest request, String token) {
|
|
HttpHeaders headers = new HttpHeaders();
|
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + token);
|
|
HttpEntity<String> requestEntity = new HttpEntity<>(request.toJson(), headers);
|
|
try {
|
|
ResponseEntity<String> response = template.exchange(this.issuer + "/" + clientId, HttpMethod.PUT, requestEntity, String.class);
|
|
return ServiceResponse.fromString(response.getBody());
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
throw new EntityMissingException("Update of service with client id: " + clientId + " couldn't be completed. Check again your parameters");
|
|
}
|
|
}
|
|
|
|
private ServiceResponse readService(String clientId, String token) {
|
|
HttpHeaders headers = new HttpHeaders();
|
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + token);
|
|
HttpEntity<String> requestEntity = new HttpEntity<>(headers);
|
|
try {
|
|
ResponseEntity<String> response = template.exchange(this.issuer + "/" + clientId, HttpMethod.GET, requestEntity, String.class);
|
|
return ServiceResponse.fromString(response.getBody());
|
|
} catch (Exception e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void deleteService(String clientId, String token) {
|
|
HttpHeaders headers = new HttpHeaders();
|
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + token);
|
|
HttpEntity<ServiceRequest> requestEntity = new HttpEntity<>(headers);
|
|
try {
|
|
template.exchange(this.issuer + "/" + clientId, HttpMethod.DELETE, requestEntity, String.class);
|
|
} catch (Exception e) {
|
|
throw new EntityMissingException("Delete of service with client id: " + clientId + " couldn't be completed. Check again your parameters");
|
|
}
|
|
}
|
|
}
|