[Trunk | Orcid Service]: Initial commit in trunk folder. The API is already partially implemented and running (configuration, controllers, services, DAOs, entities, handlers, responses, properties).

This commit is contained in:
Konstantina Galouni 2021-01-14 11:31:25 +00:00
parent cb05250ee5
commit 93acb15d2d
31 changed files with 1971 additions and 0 deletions

113
pom.xml Normal file
View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.dnetlib</groupId>
<artifactId>uoa-orcid-service</artifactId>
<version>2.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>uoa-orcid-service</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>20030203.000550</version>
</dependency>
<dependency>
<groupId>eu.dnetlib</groupId>
<artifactId>uoa-authorization-library</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.httpcomponents</groupId>-->
<!-- <artifactId>httpclient</artifactId>-->
<!-- </dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--3d answer: https://stackoverflow.com/questions/23260057/the-forked-vm-terminated-without-saying-properly-goodbye-vm-crash-or-system-exi-->
<!--If you use openjdk there might be a problem with surfire plugin - uncomment following lines-->
<!--<plugin>-->
<!--<groupId>org.apache.maven.plugins</groupId>-->
<!--<artifactId>maven-surefire-plugin</artifactId>-->
<!--<version>2.19.1</version>-->
<!--<configuration>-->
<!--&lt;!&ndash;<testFailureIgnore>true</testFailureIgnore>&ndash;&gt;-->
<!--<useSystemClassLoader>false</useSystemClassLoader>-->
<!--</configuration>-->
<!--</plugin>-->
</plugins>
<finalName>uoa-orcid-service</finalName>
</build>
</project>

View File

@ -0,0 +1,13 @@
package eu.dnetlib.uoaorcidservice;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(UoaOrcidServiceApplication.class);
}
}

View File

@ -0,0 +1,26 @@
package eu.dnetlib.uoaorcidservice;
import eu.dnetlib.uoaauthorizationlibrary.configuration.AuthorizationConfiguration;
import eu.dnetlib.uoaorcidservice.configuration.properties.MongoConfig;
//import eu.dnetlib.uoaauthorizationlibrary.configuration.AuthorizationConfiguration;
import eu.dnetlib.uoaorcidservice.handlers.utils.AESUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
@SpringBootApplication(scanBasePackages = {"eu.dnetlib.uoaorcidservice"})
@PropertySources({
@PropertySource("classpath:orcidservice.properties"),
@PropertySource(value = "classpath:dnet-override.properties", ignoreResourceNotFound = true)
})
@EnableConfigurationProperties({MongoConfig.class, AESUtils.class})
@Import(AuthorizationConfiguration.class)
public class UoaOrcidServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UoaOrcidServiceApplication.class, args);
}
}

View File

@ -0,0 +1,26 @@
package eu.dnetlib.uoaorcidservice;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class UoaOrcidServiceConfiguration extends WebMvcConfigurerAdapter {
private final Logger log = Logger.getLogger(this.getClass());
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(new AuthorizationHandler(securityConfig.getUserInfoUrl(), securityConfig.getOriginServer(), securityConfig.getPostsAllowed()))
// .addPathPatterns("/**");
}
}

View File

@ -0,0 +1,46 @@
package eu.dnetlib.uoaorcidservice.configuration.mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import eu.dnetlib.uoaorcidservice.configuration.properties.MongoConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Collections;
@Configuration
@EnableMongoRepositories(basePackages = {"eu.dnetlib.uoaorcidservice.dao"})
public class MongoConnection {
@Autowired
private MongoConfig mongoConfig;
@Bean
@Primary
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(getMongoClient(), mongoConfig.getDatabase());
}
@Bean(name = "mongoTemplate")
@Primary
public MongoTemplate getMongoTemplate() {
return new MongoTemplate(mongoDbFactory());
}
private MongoClient getMongoClient() {
if(mongoConfig.getUsername() != null && mongoConfig.getPassword() != null){
return new MongoClient(Collections.singletonList(
new ServerAddress(mongoConfig.getHost(), mongoConfig.getPort())),
Collections.singletonList(MongoCredential.createCredential(mongoConfig.getUsername(), mongoConfig.getDatabase(), mongoConfig.getPassword().toCharArray())));
} else {
return new MongoClient(Collections.singletonList(new ServerAddress(mongoConfig.getHost(), mongoConfig.getPort())));
}
}
}

View File

@ -0,0 +1,54 @@
package eu.dnetlib.uoaorcidservice.configuration.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("orcidservice.mongodb")
public class MongoConfig {
private String host;
private String database;
private String username;
private String password;
private int port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}

View File

@ -0,0 +1,83 @@
package eu.dnetlib.uoaorcidservice.controllers;
import eu.dnetlib.uoaorcidservice.services.UserTokensService;
import org.apache.log4j.Logger;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
@RestController
@RequestMapping("/orcid")
@CrossOrigin(origins = "*")
public class RecordController {
private final Logger log = Logger.getLogger(this.getClass());
@Autowired
UserTokensService userTokensService;
@RequestMapping(value = {"/record"}, method = RequestMethod.GET)
public String getRecord() throws BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException, IOException {
String testingUserToken = userTokensService.getUserAccessToken(null);
String testingUserOrcid = userTokensService.getCurrentUserOrcid();
String url = "https://api.sandbox.orcid.org/v3.0/"+testingUserOrcid;//+"/record";
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
protected boolean hasError(HttpStatus statusCode) {
return false;
}});
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "application/json");
headers.add("Authorization", "Bearer "+testingUserToken);
headers.add("Content-Type","application/orcid+json");
HttpEntity<String> request = new HttpEntity<>(headers);
//logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request, String.class);
if(response.getStatusCode() != HttpStatus.OK) {
log.debug("Getting orcid record response code is: " + response.getStatusCode());
return null;
} else {
log.debug(response);
return response.getBody().toString();
}
// try {
// URL obj = new URL(url);
//
// HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// con.setRequestProperty("Accept", "application/json");
// con.setRequestProperty("Content-Type", "application/json");
// con.setRequestProperty("Authorization", "Bearer "+testingUserToken);
//
// if (con.getResponseCode() != 200) {
// log.debug("User record response code is: " + con.getResponseCode());
// return null;
// }
// BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
// StringBuilder response = new StringBuilder();
// String inputLine;
// while ((inputLine = in.readLine()) != null) {
// response.append(inputLine).append("\n");
// }
// in.close();
// log.debug(response);
// return response;
// } catch (Exception e) {
// log.error("An error occured while trying to fetch user record ", e);
// return null;
// }
}
}

View File

@ -0,0 +1,94 @@
package eu.dnetlib.uoaorcidservice.controllers;
import eu.dnetlib.uoaorcidservice.responses.ExceptionResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
//public class SimpleErrorController {}
@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/error")
public class SimpleErrorController implements ErrorController {
private final Logger log = Logger.getLogger(this.getClass());
private final ErrorAttributes errorAttributes;
@Autowired
public SimpleErrorController(ErrorAttributes errorAttributes) {
Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
this.errorAttributes = errorAttributes;
}
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping
public ResponseEntity<ExceptionResponse> error(HttpServletRequest aRequest){
Map<String, Object> body = getErrorAttributes(aRequest,getTraceParameter(aRequest));
// String trace = (String) body.get("trace");
// log.debug(trace);
// if(trace != null){
// String[] lines = trace.split("\n\t");
// log.debug(lines);
// body.put("trace", lines);
// }
// log.debug(body);
// {timestamp=Mon Jan 04 14:29:25 EET 2021,
// status=500,
// error=Internal Server Error,
// exception=org.springframework.web.client.UnknownHttpStatusCodeException,
// message=Unknown status code [525] Origin SSL Handshake Error,
// path=/uoa-orcid-service/orcid/work/save}
log.debug(body);
log.debug(body.get("status"));
Integer status = (Integer)body.get("status");
log.debug("status: "+status);
HttpStatus statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
if (status != null) {
statusCode = HttpStatus.valueOf(status);
log.debug(statusCode);
}
ExceptionResponse response = new ExceptionResponse();
response.setErrorCode((String)body.get("error"));
response.setErrorMessage((String)body.get("exception"));
response.setErrors((String)body.get("message"));
response.setStatus(statusCode);
log.error((String)body.get("exception")+" : "+ (String)body.get("message"));
return new ResponseEntity<ExceptionResponse>(response, statusCode);
// return body;
}
private boolean getTraceParameter(HttpServletRequest request) {
String parameter = request.getParameter("trace");
if (parameter == null) {
return false;
}
return !"false".equals(parameter.toLowerCase());
}
private Map<String, Object> getErrorAttributes(HttpServletRequest aRequest, boolean includeStackTrace) {
RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest);
return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
}
}

View File

@ -0,0 +1,159 @@
package eu.dnetlib.uoaorcidservice.controllers;
import eu.dnetlib.uoaorcidservice.entities.UserTokens;
import eu.dnetlib.uoaorcidservice.handlers.utils.AESUtils;
import eu.dnetlib.uoaorcidservice.services.UserTokensService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/orcid")
@CrossOrigin(origins = "*")
public class UserTokensController {
private final Logger log = Logger.getLogger(this.getClass());
@Autowired
private UserTokensService userTokensService;
// @RequestMapping(value = "/tokens", method = RequestMethod.GET)
// public List<UserTokens> getAllUserTokens() {
// return userTokensService.getAllUserTokens();
// }
// @RequestMapping(value = "/token/access_token", method = RequestMethod.GET)
// public String getUserAccessTokenByOrcid(@RequestParam String orcid) {
// return "\""+userTokensService.getUserAccessToken(orcid)+"\"";
// }
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/token/save", method = RequestMethod.GET)
public String saveUserTokens(@RequestParam String code) throws BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException {
log.debug("saveUserTokens: code="+code);
String url = "https://sandbox.orcid.org/oauth/token";
String clientId = "APP-A5M3KTX6NCN67L91";
String clientSecret = "96b20d71-ae06-4286-bb00-9172536c1ad4";
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
protected boolean hasError(HttpStatus statusCode) {
return false;
}});
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type","application/x-www-form-urlencoded");
headers.add("Accept","application/json");
String inputString =
"client_id="+clientId
+"&client_secret="+clientSecret
+"&grant_type=authorization_code"
+"&code="+code
+"&redirect_uri=http://duffy.di.uoa.gr:4300/orcid";
log.debug(inputString);
HttpEntity<String> request = new HttpEntity<>(inputString, headers);
//logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
if(response.getStatusCode() != HttpStatus.OK) {
log.debug("User tokens response code is: " + response.getStatusCode());
log.debug(response.getBody());
return null;
} else {
log.debug(response);
UserTokens userTokens = userTokensService.json2UserTokens(response.getBody().toString());
userTokensService.saveUserTokens(userTokens);
return "\""+userTokens.getAccessToken()+"\"";
}
// try {
// URL obj = new URL(url);
//
// HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// con.setRequestMethod("POST");
// con.setDoOutput(true);
// con.setInstanceFollowRedirects(true);
// con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// con.setRequestProperty("Accept", "application/json");
//
// String inputString =
// "client_id="+clientId
// +"&client_secret="+clientSecret
// +"&grant_type=authorization_code"
// +"&code="+code
// +"&redirect_uri=http://duffy.di.uoa.gr:4300/orcid";
//
// log.debug(inputString);
//
// try(OutputStream os = con.getOutputStream()) {
//// byte[] input = inputString.getBytes();
//// os.write(inputString, 0, inputString.length());
//
// OutputStreamWriter osw = new OutputStreamWriter(os);
// osw.write(inputString);
// osw.flush();
// osw.close();
//
// os.close(); //don't forget to close the OutputStream
// log.debug("http request body added");
// } catch (Exception e) {
// log.error("Failed to add http request body", e);
// }
//
// con.connect();
//
//// log.debug(con.getRequestMethod());
//// log.debug(con.getErrorStream());
//// log.debug(con.getContent());
//
//
// if (con.getResponseCode() != 200) {
// log.debug("User tokens response code is: " + con.getResponseCode());
// return null;
// } else {
// BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
// StringBuilder response = new StringBuilder();
// String inputLine;
// while ((inputLine = in.readLine()) != null) {
// response.append(inputLine).append("\n");
// }
// in.close();
// log.debug(response);
//
// UserTokens userTokens = userTokensService.json2UserTokens(response.toString());
// userTokensService.saveUserTokens(userTokens);
//
// return "\""+userTokens.getAccessToken()+"\"";
// }
//
// } catch (Exception e) {
// log.error("An error occured while trying to fetch user tokens ", e);
// return null;
// }
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/tokens/decrypt", method = RequestMethod.GET)
public UserTokens decryptToken(@RequestParam String aaiId) throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException, IOException {
return userTokensService.getUserTokensByAai(aaiId);
}
}

View File

@ -0,0 +1,486 @@
package eu.dnetlib.uoaorcidservice.controllers;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.dnetlib.uoaorcidservice.entities.ResultIdAndWork;
import eu.dnetlib.uoaorcidservice.entities.UserTokens;
import eu.dnetlib.uoaorcidservice.entities.Work;
import eu.dnetlib.uoaorcidservice.handlers.ConflictException;
import eu.dnetlib.uoaorcidservice.handlers.ForbiddenException;
import eu.dnetlib.uoaorcidservice.services.UserTokensService;
import eu.dnetlib.uoaorcidservice.services.WorkService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.access.AuthorizationServiceException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/orcid")
@CrossOrigin(origins = "*")
public class WorkController {
private final Logger log = Logger.getLogger(this.getClass());
@Autowired
private UserTokensService userTokensService;
@Autowired
private WorkService workService;
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "put-code", method = RequestMethod.GET)
public List<String> getPutCode(@RequestParam String[] pids) {
String userOrcid = userTokensService.getCurrentUserOrcid();
List<Work> works = workService.getWorks(pids, userOrcid);
if(works != null) {
List<String> putCodes = new ArrayList<>();
for(Work work : works) {
putCodes.add(work.getPutCode());
}
return putCodes;
}
return null;
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "put-codes", method = RequestMethod.POST)
public List<List<String>> getPutCodes(@RequestBody String[][] pids) {
String userOrcid = userTokensService.getCurrentUserOrcid();
List<List<String>> putCodes = new ArrayList();
for(int i=0; i<pids.length; i++) {
List<Work> works = workService.getWorks(pids[i], userOrcid);
if (works != null) {
List<String> putCodesOfOneRecord = new ArrayList<>();
for(Work work : works) {
putCodesOfOneRecord.add(work.getPutCode());
}
putCodes.add(putCodesOfOneRecord);
} else {
putCodes.add(null);
}
}
return putCodes;
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/work/save", method = RequestMethod.POST)
public String saveWork(@RequestBody String resultString) throws IOException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
log.debug("saveWork: result = " + resultString);
Gson gson = new GsonBuilder().create();
ResultIdAndWork result = gson.fromJson(resultString, ResultIdAndWork.class);
UserTokens userTokens = userTokensService.getUserTokens();
if(userTokens == null) {
throw new AuthorizationServiceException("User is not registered");
}
String userOrcid = userTokens.getOrcid();
String userAccessToken = userTokens.getAccessToken();
if(userOrcid == null || userAccessToken == null) {
throw new AuthorizationServiceException("User is not registered");
}
log.debug("Access token: " + userAccessToken);
log.debug("User orcid: " + userOrcid);
String url = "https://api.sandbox.orcid.org/v3.0/" + userOrcid + "/work";
RestTemplate restTemplate = new RestTemplate();
// restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
protected boolean hasError(HttpStatus statusCode) {
if(statusCode == HttpStatus.UNAUTHORIZED) {
throw new AuthorizationServiceException("User is not registered");
}
return false;
}
});
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + userAccessToken);
headers.add("Content-Type", "application/orcid+json;charset=UTF-8");
log.debug(headers.get("Authorization"));
HttpEntity<String> request = new HttpEntity<>(gson.toJson(result.getWork()), headers);
//logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
if (response.getStatusCode() != HttpStatus.CREATED) {
log.debug("Saving work response code is: " + response.getStatusCode());
log.debug(response.getBody());
if(response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
throw new AuthorizationServiceException("You are not allowed to save work");
}
if(response.getStatusCode() == HttpStatus.CONFLICT) {
throw new ConflictException("Work is already saved");
}
return null;
} else {
log.debug("[success] Saving work response code is: " + response.getStatusCode());
log.debug(response.toString());
Work workToSave = new Work();
workToSave.setPids(result.getPids());
workToSave.setOrcid(userOrcid);
workToSave.setCreationDate(new Date());
HttpHeaders responseHeaders = response.getHeaders();
String locationPath = responseHeaders.getLocation().toString();
String[] locationPathArray = locationPath.split("/");
workToSave.setPutCode(locationPathArray[locationPathArray.length - 1]);
log.debug(gson.toJson(result.getPids()));
log.debug(responseHeaders.getLocation().toString());
log.debug(gson.toJson(workToSave));
workService.saveWork(workToSave);
return "\""+workToSave.getPutCode()+"\"";
}
}
// @RequestMapping(value = "/{orcid}/work/{putCode}", method = RequestMethod.PUT)
// public String updateWork(@PathVariable String orcid,
// @PathVariable String putCode,
// @RequestBody String work) throws AccessDeniedException {
// log.debug("updateWork: orcid = " + orcid + " - putCode = " + putCode);
//
// String userAccessToken = userTokensService.getUserAccessToken(orcid);
// log.debug("Access token: " + userAccessToken);
//
//// String url = "https://sandbox.orcid.org/v3.0/" + orcid.toString() + "/works";
// String url = "https://api.sandbox.orcid.org/v3.0/" + orcid + "/work/" + putCode;
//
// RestTemplate restTemplate = new RestTemplate();
// restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
// protected boolean hasError(HttpStatus statusCode) {
// return false;
// }
// });
// HttpHeaders headers = new HttpHeaders();
//// headers.add("Accept", "application/json");
// headers.add("Authorization", "Bearer " + userAccessToken);
// headers.add("Content-Type","application/orcid+json");
//
// HttpEntity<String> request = new HttpEntity<>(work, headers);
// //logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
// ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, request, String.class);
// if (response.getStatusCode() != HttpStatus.OK) {
// log.debug("Updating work response code is: " + response.getStatusCode());
// return null;
// } else {
// log.debug(response);
//
// return null;
// }
//
// }
// @RequestMapping(value = "/works/save", method = RequestMethod.POST)
// public String saveWorks(@RequestBody String works) {
// log.debug("saveWorks");
//
// String userAccessToken = userTokensService.getUserAccessToken(null);
// log.debug("Access token: " + userAccessToken);
// log.debug(works);
//
// String url = "https://api.sandbox.orcid.org/v3.0/0000-0001-9541-4617/work";
//
// RestTemplate restTemplate = new RestTemplate();
// restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
// protected boolean hasError(HttpStatus statusCode) {
// return false;
// }
// });
// HttpHeaders headers = new HttpHeaders();
// headers.add("Authorization", "Bearer " + userAccessToken);
// headers.add("Content-Type", "application/json");
//// List<MediaType> list = new ArrayList();
//// list.add(MediaType.TEXT_HTML);
//// headers.setAccept(list);
//
//
// HttpEntity<String> request = new HttpEntity<>(works.toString(), headers);
//
//// log.debug(restTemplate.exchange(url, HttpMethod.POST, request, Object.class));
//
// ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
// if (response.getStatusCode() != HttpStatus.OK) {
// log.debug("Saving works response code is: " + response.getStatusCode());
// log.debug(response.getBody().toString());
// return null;
// } else {
// log.debug("[success] Saving works response code is: " + response.getStatusCode());
// log.debug(response.toString());
//
// return response.toString();
// }
// }
// @RequestMapping(value = "/works", method = RequestMethod.GET)
// public String getAllWorks(@RequestParam String orcid) {
// log.debug("getAllWorks: orcid = |" + orcid + "|");
//
// String userAccessToken = userTokensService.getUserAccessToken(orcid);
// log.debug("Access token: " + userAccessToken);
//
//// String url = "https://sandbox.orcid.org/v3.0/" + orcid.toString() + "/works";
// String url = "https://api.sandbox.orcid.org/v3.0/"+orcid+"/works";
//
// RestTemplate restTemplate = new RestTemplate();
// restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
// protected boolean hasError(HttpStatus statusCode) {
// return false;
// }
// });
// HttpHeaders headers = new HttpHeaders();
// headers.add("Accept", "application/json");
// headers.add("Authorization", "Bearer " + userAccessToken);
// headers.add("Content-Type", "application/orcid+json");
// log.debug(headers.get("Authorization"));
// HttpEntity<String> request = new HttpEntity<>(headers);
// //logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
// ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request, String.class);
// if (response.getStatusCode() != HttpStatus.OK) {
// log.debug("Getting works response code is: " + response.getStatusCode());
// return null;
// } else {
// log.debug(response);
// return response.getBody().toString();
// }
//
//// try {
//// URL obj = new URL(url);
////
//// HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//// con.setRequestProperty("Accept", "application/json");
//// con.setRequestProperty("Content-Type", "application/orcid+json");
//// con.setRequestProperty("Authorization", "Bearer "+userAccessToken);
////
//// if (con.getResponseCode() != 200) {
//// log.debug("Getting works response code is: " + con.getResponseCode());
//// return null;
//// }
//// BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
//// StringBuilder response = new StringBuilder();
//// String inputLine;
//// while ((inputLine = in.readLine()) != null) {
//// response.append(inputLine).append("\n");
//// }
//// in.close();
//// log.debug(response);
//// return response;
//// } catch (Exception e) {
//// log.error("An error occured while trying to fetch works for orcid: "+orcid, e);
//// return null;
//// }
// }
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/work/{putCode}/delete", method = RequestMethod.DELETE)
public String deleteWork(@PathVariable String putCode) throws IOException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
log.debug("deleteWork: putCode = " + putCode);
UserTokens userTokens = userTokensService.getUserTokens();
if(userTokens == null) {
throw new AuthorizationServiceException("User is not registered");
}
String userOrcid = userTokens.getOrcid();
String userAccessToken = userTokens.getAccessToken();
if(userOrcid == null || userAccessToken == null) {
throw new AuthorizationServiceException("User is not registered");
}
log.debug("Access token: " + userAccessToken);
log.debug("User orcid: " + userOrcid);
// String url = "https://sandbox.orcid.org/v3.0/" + orcid.toString() + "/works";
String url = "https://api.sandbox.orcid.org/v3.0/"+userOrcid+"/work/" + putCode;
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
HttpHeaders headers = new HttpHeaders();
// headers.add("Accept", "application/json");
headers.add("Authorization", "Bearer " + userAccessToken);
headers.add("Content-Type","application/orcid+json");
HttpEntity<String> request = new HttpEntity<>(headers);
//logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, request, String.class);
if (response.getStatusCode() != HttpStatus.NO_CONTENT) {
log.debug("Deleting work response code is: " + response.getStatusCode());
if(response.getStatusCode() == HttpStatus.NOT_FOUND) {
workService.deleteWork(putCode);
return putCode;
}
if(response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
throw new AuthorizationServiceException("You are not allowed to delete work");
}
return null;
} else {
log.debug(response);
workService.deleteWork(putCode);
return putCode;
}
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/works/delete", method = RequestMethod.POST)
public List<String> deleteWorks(@RequestBody List<String> putCodes) throws IOException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
log.debug("deleteWorks: putCodes = " + putCodes);
UserTokens userTokens = userTokensService.getUserTokens();
if(userTokens == null) {
throw new AuthorizationServiceException("User is not registered");
}
String userOrcid = userTokens.getOrcid();
String userAccessToken = userTokens.getAccessToken();
if(userOrcid == null || userAccessToken == null) {
throw new AuthorizationServiceException("User is not registered");
}
log.debug("Access token: " + userAccessToken);
log.debug("User orcid: " + userOrcid);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
HttpHeaders headers = new HttpHeaders();
// headers.add("Accept", "application/json");
headers.add("Authorization", "Bearer " + userAccessToken);
headers.add("Content-Type","application/orcid+json");
HttpEntity<String> request = new HttpEntity<>(headers);
//logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
List<String> deletedPutCodes = new ArrayList<>();
int index = 0;
for(String putCode : putCodes) {
String url = "https://api.sandbox.orcid.org/v3.0/"+userOrcid+"/work/" + putCode;
// UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, request, String.class);
if (response.getStatusCode() != HttpStatus.NO_CONTENT) {
log.debug("Deleting work response code is: " + response.getStatusCode());
if(index == 0 && response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
throw new AuthorizationServiceException("You are not allowed to delete work");
}
if (response.getStatusCode() == HttpStatus.NOT_FOUND) {
workService.deleteWork(putCode);
deletedPutCodes.add(putCode);
} else {
deletedPutCodes.add(null);
}
} else {
log.debug(response);
workService.deleteWork(putCode);
deletedPutCodes.add(putCode);
}
index++;
}
return deletedPutCodes;
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/work", method = RequestMethod.GET)
public List<String> getWorksOfReuslt(@RequestParam String[] pids, @RequestParam String orcid) throws BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException, IOException {
log.debug("getWorks: pids = " + pids + " - orcid = "+orcid);
List<Work> works = workService.getWorks(pids, orcid);
String userAccessToken = userTokensService.getUserAccessToken(orcid);
log.debug("Access token: " + userAccessToken);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "application/json");
headers.add("Authorization", "Bearer " + userAccessToken);
headers.add("Content-Type", "application/orcid+json");
log.debug(headers.get("Authorization"));
HttpEntity<String> request = new HttpEntity<>(headers);
List<String> responseValues = new ArrayList<>();
for(Work work : works) {
// String url = "https://api.sandbox.orcid.org/v3.0/0000-0001-9541-4617/work/"+work.getPutCode();
String url = "https://api.sandbox.orcid.org/v3.0/" + orcid + "/work/" + work.getPutCode();
log.debug(url);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
//logger.info(restTemplate.exchange(fooResourceUrl, HttpMethod.GET, request, Object.class));
ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, request, String.class);
// ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request, String.class);
if (response.getStatusCode() != HttpStatus.OK) {
log.debug("Getting work response code is: " + response.getStatusCode());
if (response.getStatusCode() == HttpStatus.NOT_FOUND) {
// work.setPutCode(null);
// workService.saveWork(work);
workService.deleteWork(work.getPutCode());
}
responseValues.add(null);
} else {
log.debug(response);
responseValues.add(response.getBody().toString());
}
}
return responseValues;
}
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/works/local", method = RequestMethod.GET)
public List<Work> getLocalWorks() throws BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException, IOException {
log.debug("getWorks");
UserTokens userTokens = userTokensService.getUserTokens();
if(userTokens == null) {
throw new AuthorizationServiceException("User is not registered");
}
String userOrcid = userTokens.getOrcid();
if(userOrcid == null) {
throw new AuthorizationServiceException("User is not registered");
}
return workService.getLocalWorks(userOrcid);
}
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.uoaorcidservice.dao.MongoDBDAOs;
import eu.dnetlib.uoaorcidservice.dao.UserTokensDAO;
import eu.dnetlib.uoaorcidservice.entities.UserTokens;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface MongoDBUserTokensDAO extends UserTokensDAO, MongoRepository<UserTokens, String> {
List<UserTokens> findAll();
UserTokens findByAaiId(String AaiId);
UserTokens findByOrcid(String Orcid);
UserTokens save(UserTokens userTokens);
void deleteAll();
void deleteByAaiId(String AaiId);
void deleteByOrcid(String Orcid);
}

View File

@ -0,0 +1,29 @@
package eu.dnetlib.uoaorcidservice.dao.MongoDBDAOs;
import eu.dnetlib.uoaorcidservice.dao.WorkDAO;
import eu.dnetlib.uoaorcidservice.entities.Work;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface MongoDBWorkDAO extends WorkDAO, MongoRepository<Work, String> {
List<Work> findAll();
Work findById(String Id);
// List<Work> findByPidsContaining(String Pid);
// Work findByPidsContainingAndOrcid(String Pid, String Orcid);
List<Work> findByPidsInAndOrcid(List<String> Pids, String Orcid);
List<Work> findByOrcid(String Orcid);
Work save(Work work);
void deleteAll();
void deleteById(String Id);
void deleteByPutCode(String PutCode);
}

View File

@ -0,0 +1,22 @@
package eu.dnetlib.uoaorcidservice.dao;
import eu.dnetlib.uoaorcidservice.entities.UserTokens;
import java.util.List;
public interface UserTokensDAO {
List<UserTokens> findAll();
UserTokens findByAaiId(String AaiId);
UserTokens findByOrcid(String Orcid);
UserTokens save(UserTokens userTokens);
void deleteAll();
void deleteByAaiId(String AaiId);
void deleteByOrcid(String Orcid);
}

View File

@ -0,0 +1,27 @@
package eu.dnetlib.uoaorcidservice.dao;
import eu.dnetlib.uoaorcidservice.entities.Work;
import java.util.List;
public interface WorkDAO {
List<Work> findAll();
Work findById(String Id);
// List<Work> findByPidsContaining(String Pid);
// Work findByPidsContainingAndOrcid(String Pid, String Orcid);
List<Work> findByPidsInAndOrcid(String[] Pids, String Orcid);
List<Work> findByOrcid(String Orcid);
Work save(Work work);
void deleteAll();
void deleteById(String Id);
void deleteByPutCode(String PutCode);
}

View File

@ -0,0 +1,24 @@
package eu.dnetlib.uoaorcidservice.entities;
import java.util.List;
public class ResultIdAndWork {
String[] pids;
Object work;
public String[] getPids() {
return pids;
}
public void setPids(String[] pids) {
this.pids = pids;
}
public Object getWork() {
return work;
}
public void setWork(Object work) {
this.work = work;
}
}

View File

@ -0,0 +1,92 @@
package eu.dnetlib.uoaorcidservice.entities;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.data.annotation.Id;
public class UserTokens {
@Id
//@JsonProperty("_id")
//private String id;
@JsonProperty("aaiId")
private String aaiId;
private String orcid;
private String name;
private String access_token;
private String token_type;
private String refresh_token;
private String expires_in;
private String scope;
// public String getId() {
// return id;
// }
//
// public void setId(String id) {
// this.id = id;
// }
public String getAaiId() {
return aaiId;
}
public void setAaiId(String aaiId) {
this.aaiId = aaiId;
}
public String getOrcid() {
return orcid;
}
public void setOrcid(String orcid) {
this.orcid = orcid;
}
public String getAccessToken() {
return access_token;
}
public void setAccessToken(String access_token) {
this.access_token = access_token;
}
public String getTokenType() {
return token_type;
}
public void setTokenType(String token_type) {
this.token_type = token_type;
}
public String getRefreshToken() {
return refresh_token;
}
public void setRefreshToken(String refresh_token) {
this.refresh_token = refresh_token;
}
public String getExpiresIn() {
return expires_in;
}
public void setExpiresIn(String expires_in) {
this.expires_in = expires_in;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,57 @@
package eu.dnetlib.uoaorcidservice.entities;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.data.annotation.Id;
import java.util.Date;
public class Work {
@Id
@JsonProperty("_id")
private String id;
private String[] pids;
private String putCode;
private String orcid;
private Date creationDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String[] getPids() {
return pids;
}
public void setPids(String[] pids) {
this.pids = pids;
}
public String getPutCode() {
return putCode;
}
public void setPutCode(String putCode) {
this.putCode = putCode;
}
public String getOrcid() {
return orcid;
}
public void setOrcid(String orcid) {
this.orcid = orcid;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}

View File

@ -0,0 +1,12 @@
package eu.dnetlib.uoaorcidservice.handlers;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NO_CONTENT)
public class CommunityNotFoundException extends RuntimeException {
public CommunityNotFoundException(String message){
super(message);
}
}

View File

@ -0,0 +1,11 @@
package eu.dnetlib.uoaorcidservice.handlers;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.CONFLICT)
public class ConflictException extends RuntimeException {
public ConflictException(String message){
super(message);
}
}

View File

@ -0,0 +1,17 @@
package eu.dnetlib.uoaorcidservice.handlers;
import java.util.Date;
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}
}

View File

@ -0,0 +1,98 @@
package eu.dnetlib.uoaorcidservice.handlers;
//import eu.dnetlib.uoaadmintoolslibrary.responses.ExceptionResponse;
//import eu.dnetlib.uoaadmintoolslibrary.handlers.InvalidReCaptchaException;
import com.google.gson.JsonSyntaxException;
import eu.dnetlib.uoaorcidservice.responses.ExceptionResponse;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AuthorizationServiceException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.nio.file.AccessDeniedException;
@ControllerAdvice
public class ExceptionsHandler {
private final Logger log = Logger.getLogger(this.getClass());
// @ExceptionHandler(MissingServletRequestParameterException.class)
// public ResponseEntity<ExceptionResponse> invalidInput(Exception ex) {
// ExceptionResponse response = new ExceptionResponse();
// response.setErrorCode("Validation Error");
// response.setErrorMessage("Invalid inputs.");
// response.setErrors(ex.getMessage());
// log.debug("invalidInput exception");
//
// return new ResponseEntity<ExceptionResponse>(response, HttpStatus.BAD_REQUEST);
// }
//
// @ExceptionHandler(NullPointerException.class)
// public ResponseEntity<ExceptionResponse> nullPointerException(Exception ex) {
// ExceptionResponse response = new ExceptionResponse();
// response.setErrorCode("Null pointer Exception");
// response.setErrorMessage("Null pointer Exception");
// response.setErrors(ex.getMessage());
// log.debug("nullPointerException exception");
// return new ResponseEntity<ExceptionResponse>(response, HttpStatus.BAD_REQUEST);
// }
// @ExceptionHandler(AccessDeniedException.class)
// public ResponseEntity<ExceptionResponse> accessDeniedException(Exception ex) {
// ExceptionResponse response = new ExceptionResponse();
// response.setErrorCode("Forbidden Exception");
// response.setErrorMessage("Access Denied Exception");
// response.setErrors(ex.getMessage());
// response.setStatus(HttpStatus.FORBIDDEN);
// log.error("accessDeniedException exception : "+ ex.getMessage());
// return new ResponseEntity<ExceptionResponse>(response, HttpStatus.FORBIDDEN);
// }
@ExceptionHandler(ForbiddenException.class)
public ResponseEntity<ExceptionResponse> forbiddenException(Exception ex) {
ExceptionResponse response = new ExceptionResponse();
response.setErrorCode("Forbidden Exception");
response.setErrorMessage("Forbidden Exception");
response.setErrors(ex.getMessage());
response.setStatus(HttpStatus.FORBIDDEN);
log.error("forbiddenException exception : "+ ex.getMessage());
return new ResponseEntity<ExceptionResponse>(response, HttpStatus.FORBIDDEN);
}
@ExceptionHandler(AuthorizationServiceException.class)
public ResponseEntity<ExceptionResponse> authorizationServiceException(Exception ex) {
ExceptionResponse response = new ExceptionResponse();
response.setErrorCode("User not registered");
response.setErrorMessage("Authorization Service Exception");
response.setErrors(ex.getMessage());
response.setStatus(HttpStatus.UNAUTHORIZED);
log.error("authorizationServiceException exception : "+ ex.getMessage());
return new ResponseEntity<ExceptionResponse>(response, HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(JsonSyntaxException.class)
public ResponseEntity<ExceptionResponse> jsonSyntaxException(Exception ex) {
ExceptionResponse response = new ExceptionResponse();
response.setErrorCode("Json syntax is not valid");
response.setErrorMessage("Json Syntax Exception");
response.setErrors(ex.getMessage());
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
log.error("jsonSyntaxException exception : "+ ex.getMessage());
return new ResponseEntity<ExceptionResponse>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
// @ExceptionHandler(Exception.class)
// public ResponseEntity<ExceptionResponse> exception(Exception ex) {
// ExceptionResponse response = new ExceptionResponse();
// response.setErrorCode();
// response.setErrorMessage("Exception");
// response.setErrors(ex.getMessage());
// response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
// log.error("Exception exception : "+ ex.getMessage());
// return new ResponseEntity<ExceptionResponse>(response, HttpStatus.INTERNAL_SERVER_ERROR);
// }
}

View File

@ -0,0 +1,11 @@
package eu.dnetlib.uoaorcidservice.handlers;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {
public ForbiddenException(String message){
super(message);
}
}

View File

@ -0,0 +1,112 @@
package eu.dnetlib.uoaorcidservice.handlers.utils;
import org.apache.log4j.Logger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.BadPaddingException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SealedObject;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;
@ConfigurationProperties("orcidservice.encryption")
public class AESUtils {
private static final Logger log = Logger.getLogger(AESUtils.class);
private static String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static SecretKey generateKey(int n) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(n);
SecretKey key = keyGenerator.generateKey();
return key;
}
public static SecretKey getKeyFromPassword(String password, String salt)
throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey secret = new SecretKeySpec(factory.generateSecret(spec)
.getEncoded(), "AES");
return secret;
}
public static IvParameterSpec generateIv() {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
public static String encryptPasswordBased(String plainText, String salt)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException, InvalidKeySpecException {
IvParameterSpec iv = generateIv();
SecretKey key = AESUtils.getKeyFromPassword(password,salt);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
log.debug("password: "+password);
log.debug("salt: "+salt);
log.debug("encrypt: "+plainText);
log.debug("key: "+key);
log.debug("encrypted: |"+Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes()))+"|");
// concatenate salt + iv + ciphertext
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(iv.getIV());
outputStream.write(cipher.doFinal(plainText.getBytes()));
// properly encode the complete ciphertext
// return DatatypeConverter.printBase64Binary(outputStream.toByteArray());
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
}
public static String decryptPasswordBased(String cipherTextStr, String salt/*, IvParameterSpec iv*/)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException {
SecretKey key = getKeyFromPassword(password,salt);
byte[] ciphertext = Base64.getDecoder().decode(cipherTextStr);
// if (ciphertext.length < 48) {
// return null;
// }
// byte[] salt = Arrays.copyOfRange(ciphertext, 0, 16);
byte[] iv = Arrays.copyOfRange(ciphertext, 0, 16);
byte[] ct = Arrays.copyOfRange(ciphertext, 16, ciphertext.length);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
log.debug("decrypt: |"+ct+"|");
log.debug("key: "+key);
log.debug("decrypted: "+new String(cipher.doFinal(ct)));
return new String(cipher.doFinal(ct));
}
}

View File

@ -0,0 +1,32 @@
package eu.dnetlib.uoaorcidservice.handlers.utils;
import eu.dnetlib.uoaauthorizationlibrary.security.AuthorizationService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class RolesUtils {
@Autowired
private AuthorizationService authorizationService;
private final Logger log = Logger.getLogger(this.getClass());
public List<String> getRoles() {
return authorizationService.getRoles();
}
public String getAaiId() {
return authorizationService.getAaiId();
}
public boolean isLoggedIn(List<String> roles) {
if(roles == null || roles.contains(authorizationService.ANONYMOUS_USER)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,40 @@
package eu.dnetlib.uoaorcidservice.responses;
import org.springframework.http.HttpStatus;
public class ExceptionResponse {
private HttpStatus status;
private String errorCode;
private String errorMessage;
private String errors;
public ExceptionResponse() {}
public HttpStatus getStatus() { return status; }
public void setStatus(HttpStatus status) { this.status = status; }
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrors() {
return errors;
}
public void setErrors(String errors) {
this.errors = errors;
}
}

View File

@ -0,0 +1,18 @@
package eu.dnetlib.uoaorcidservice.responses;
public class SingleValueWrapperResponse<T> {
private T value = null;
public SingleValueWrapperResponse() { }
public SingleValueWrapperResponse(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}

View File

@ -0,0 +1,163 @@
package eu.dnetlib.uoaorcidservice.services;
import com.google.gson.Gson;
import eu.dnetlib.uoaorcidservice.dao.UserTokensDAO;
import eu.dnetlib.uoaorcidservice.entities.UserTokens;
import eu.dnetlib.uoaorcidservice.handlers.utils.AESUtils;
import eu.dnetlib.uoaorcidservice.handlers.utils.RolesUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.List;
@Service
public class UserTokensService {
private final Logger log = Logger.getLogger(this.getClass());
@Autowired
private UserTokensDAO userTokensDAO;
@Autowired
private RolesUtils rolesUtils;
public List<UserTokens> getAllUserTokens() {
return userTokensDAO.findAll();
}
public String getUserAccessToken(String orcid) throws BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException {
log.debug("getUserAccessToken: orcid="+orcid);
// String aaiId = "3";
String aaiId = rolesUtils.getAaiId();
UserTokens userTokens = userTokensDAO.findByAaiId(aaiId);
if(userTokens == null) {
return null;
}
userTokens = decryptTokens(userTokens);
log.debug("userTokens.getAccessToken(): "+userTokens.getAccessToken());
return userTokens.getAccessToken();
}
public String getCurrentUserOrcid() {
log.debug("getCurrentUserOrcid");
// String aaiId = "1";
String aaiId = rolesUtils.getAaiId();
UserTokens userTokens = userTokensDAO.findByAaiId(aaiId);
if(userTokens == null) {
return null;
}
log.debug("userTokens.getOrcidId(): "+userTokens.getOrcid());
return userTokens.getOrcid();
}
public UserTokens getUserTokens() throws BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException {
log.debug("getUserTokens");
String aaiId = rolesUtils.getAaiId();
UserTokens userTokens = userTokensDAO.findByAaiId(aaiId);
return decryptTokens(userTokens);
}
public UserTokens json2UserTokens(String json) {
log.debug("json2UserTokens: "+json);
if (json == null) {
return null;
}
BufferedReader br = new BufferedReader(new StringReader(json));
//convert the json string back to object
Gson gson = new Gson();
UserTokens userTokens = null;
try {
userTokens = gson.fromJson(br, UserTokens.class);
} catch (Exception e) {
log.debug("Error in parsing json response. Given json is : " + json, e);
}
return userTokens;
}
public void saveUserTokens(UserTokens userTokens) throws InvalidKeySpecException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
userTokens.setAaiId(rolesUtils.getAaiId());
userTokens = encryptTokens(userTokens);
userTokensDAO.save(userTokens);
}
public UserTokens encryptTokens(UserTokens userTokens) throws InvalidKeySpecException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
// String password = "mypassword";
// String salt = "034131145430079";//userTokens.getAaiId();
// IvParameterSpec ivParameterSpec = AESUtils.generateIv();
// SecretKey key = AESUtils.getKeyFromPassword(password,salt);
//
// log.debug("password: "+password);
// log.debug("salt: "+salt);
// String cipherText = AESUtils.encryptPasswordBased("test0", key, ivParameterSpec);
String cipherText = AESUtils.encryptPasswordBased(userTokens.getAccessToken(), userTokens.getAaiId());
userTokens.setAccessToken(cipherText);
cipherText = AESUtils.encryptPasswordBased(userTokens.getRefreshToken(), userTokens.getAaiId());
userTokens.setRefreshToken(cipherText);
// String decryptedCipherText = AESUtils.decryptPasswordBased(cipherText, key, ivParameterSpec);
return userTokens;
}
public UserTokens decryptTokens(UserTokens userTokens) throws InvalidKeySpecException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
if(userTokens == null) {
return null;
}
// String password = "mypassword";
// String salt = "034131145430079";//userTokens.getAaiId();
// IvParameterSpec ivParameterSpec = AESUtils.generateIv();
// SecretKey key = AESUtils.getKeyFromPassword(password,salt);
// log.debug("password: "+password);
// log.debug("salt: "+salt);
String token = AESUtils.decryptPasswordBased(userTokens.getAccessToken(), userTokens.getAaiId());
userTokens.setAccessToken(token);
token = AESUtils.decryptPasswordBased(userTokens.getRefreshToken(), userTokens.getAaiId());
userTokens.setRefreshToken(token);
// String plainText = "www.baeldung.com";
// String password2 = "mypassword";
// String salt2 = "034131145430079";
// IvParameterSpec ivParameterSpec2 = AESUtils.generateIv();
// SecretKey key2 = AESUtils.getKeyFromPassword(password2,salt2);
// String cipherText = AESUtils.encryptPasswordBased(plainText, );
// IvParameterSpec ivParameterSpec3 = AESUtils.generateIv();
// SecretKey key3 = AESUtils.getKeyFromPassword(password2,salt2);
// String decryptedCipherText = AESUtils.decryptPasswordBased(cipherText, key3);
// log.debug("test decrypted text: "+decryptedCipherText);
return userTokens;
}
public UserTokens getUserTokensByAai(String aaiId) throws BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException {
log.debug("getUserTokens");
UserTokens userTokens = userTokensDAO.findByAaiId(aaiId);
return decryptTokens(userTokens);
}
}

View File

@ -0,0 +1,40 @@
package eu.dnetlib.uoaorcidservice.services;
import eu.dnetlib.uoaorcidservice.dao.WorkDAO;
import eu.dnetlib.uoaorcidservice.entities.Work;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class WorkService {
private final Logger log = Logger.getLogger(this.getClass());
@Autowired
private WorkDAO workDAO;
public List<Work> getAllWorks() {
return workDAO.findAll();
}
public List<Work> getWorks(String[] pids, String orcid) {
// return workDAO.findByPidsContainingAndOrcid(pid, orcid);
return workDAO.findByPidsInAndOrcid(pids, orcid);
}
public void saveWork(Work work) {
log.debug("Save in DB work with pids: "+work.getPids() + " - for ORCID iD: "+work.getOrcid());
workDAO.save(work);
}
public void deleteWork(String putCode) {
log.debug("Delete from DB work with putCode: "+putCode);
workDAO.deleteByPutCode(putCode);
}
public List<Work> getLocalWorks(String orcid) {
return workDAO.findByOrcid(orcid);
}
}

View File

@ -0,0 +1,20 @@
log4j.rootLogger = DEBUG, R
log4j.logger.eu.dnetlib = DEBUG
log4j.logger.org.springframework = DEBUG, S
log4j.additivity.org.springframework = false
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/var/log/dnet/uoa-orcid-service/uoa-orcid-service.log
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern= %d %p %t [%c] - %m%n
log4j.appender.S=org.apache.log4j.RollingFileAppender
log4j.appender.S.File=/var/log/dnet/uoa-orcid-service/uoa-orcid-service-spring.log
log4j.appender.S.MaxFileSize=10MB
log4j.appender.S.MaxBackupIndex=10
log4j.appender.S.layout=org.apache.log4j.PatternLayout
log4j.appender.S.layout.ConversionPattern= %d %p %t [%c] - %m%n

View File

@ -0,0 +1,22 @@
#dev
orcidservice.mongodb.host=localhost
orcidservice.mongodb.port=27017
orcidservice.mongodb.database=openaire_orcid
#orcidservice.encryption.password=...
#beta
#orcidservice.google.secret =...
#orcidservice.mongodb.host=beta.services.openaire.eu
#orcidservice.mongodb.port=27017
#orcidservice.mongodb.database=openaire_orcid
#orcidservice.encryption.password=...
#production
#orcidservice.google.secret =...
#orcidservice.mongodb.host=localhost
#orcidservice.mongodb.port=27017
#orcidservice.mongodb.database=openaire_orcid
#orcidservice.encryption.password=...
#orcidservice.mongodb.username=dnet8480
#orcidservice.mongodb.password=