diff --git a/pom.xml b/pom.xml
index 5b8eb62..c400667 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,11 +14,17 @@
scm:git:gitea@code-repo.d4science.org:MaDgIK/developers-api.git
HEAD
+
+ UTF-8
+ UTF-8
+ ${maven.build.timestamp}
+ E MMM dd HH:mm:ss z yyyy
+
eu.dnetlib
uoa-login-core
- 2.0.2
+ 2.0.3
diff --git a/src/main/java/eu/dnetlib/developers/DevelopersAPIApplication.java b/src/main/java/eu/dnetlib/developers/DevelopersAPIApplication.java
index 3833942..c77984f 100644
--- a/src/main/java/eu/dnetlib/developers/DevelopersAPIApplication.java
+++ b/src/main/java/eu/dnetlib/developers/DevelopersAPIApplication.java
@@ -1,6 +1,8 @@
package eu.dnetlib.developers;
import eu.dnetlib.authentication.configuration.AuthenticationConfiguration;
+import eu.dnetlib.developers.configuration.APIProperties;
+import eu.dnetlib.developers.configuration.GlobalVars;
import eu.dnetlib.developers.configuration.Properties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -16,7 +18,7 @@ import org.springframework.context.annotation.PropertySources;
@PropertySource(value = "classpath:dnet-override.properties", ignoreResourceNotFound = true)
})
@Import({AuthenticationConfiguration.class})
-@EnableConfigurationProperties({Properties.class})
+@EnableConfigurationProperties({Properties.class, APIProperties.class, GlobalVars.class})
public class DevelopersAPIApplication {
public static void main(String[] args) {
diff --git a/src/main/java/eu/dnetlib/developers/configuration/APIProperties.java b/src/main/java/eu/dnetlib/developers/configuration/APIProperties.java
new file mode 100644
index 0000000..31bbfc0
--- /dev/null
+++ b/src/main/java/eu/dnetlib/developers/configuration/APIProperties.java
@@ -0,0 +1,38 @@
+package eu.dnetlib.developers.configuration;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("api")
+public class APIProperties {
+
+ private String title;
+ private String description;
+ private String version;
+
+ public APIProperties() {
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+}
diff --git a/src/main/java/eu/dnetlib/developers/configuration/GlobalVars.java b/src/main/java/eu/dnetlib/developers/configuration/GlobalVars.java
new file mode 100644
index 0000000..df679ff
--- /dev/null
+++ b/src/main/java/eu/dnetlib/developers/configuration/GlobalVars.java
@@ -0,0 +1,31 @@
+package eu.dnetlib.developers.configuration;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.Date;
+
+@ConfigurationProperties("developers-api.globalVars")
+public class GlobalVars {
+ public static Date date = new Date();
+ private Date buildDate;
+ private String version;
+
+ public String getBuildDate() {
+ if(buildDate == null) {
+ return null;
+ }
+ return buildDate.toString();
+ }
+
+ public void setBuildDate(Date buildDate) {
+ this.buildDate = buildDate;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+}
diff --git a/src/main/java/eu/dnetlib/developers/configuration/SwaggerConfig.java b/src/main/java/eu/dnetlib/developers/configuration/SwaggerConfig.java
index 494327a..a95385a 100644
--- a/src/main/java/eu/dnetlib/developers/configuration/SwaggerConfig.java
+++ b/src/main/java/eu/dnetlib/developers/configuration/SwaggerConfig.java
@@ -1,6 +1,4 @@
package eu.dnetlib.developers.configuration;
-
-import eu.dnetlib.authentication.configuration.APIProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/src/main/java/eu/dnetlib/developers/controllers/APIController.java b/src/main/java/eu/dnetlib/developers/controllers/APIController.java
index 8fdd952..f2532b7 100644
--- a/src/main/java/eu/dnetlib/developers/controllers/APIController.java
+++ b/src/main/java/eu/dnetlib/developers/controllers/APIController.java
@@ -1,7 +1,8 @@
package eu.dnetlib.developers.controllers;
-import eu.dnetlib.developers.dto.RegisteredAT;
import eu.dnetlib.developers.dto.API;
+import eu.dnetlib.developers.dto.APIsByIssuer;
+import eu.dnetlib.developers.dto.CopyServices;
import eu.dnetlib.developers.dto.ServiceForm;
import eu.dnetlib.developers.services.APIService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,14 +27,14 @@ public class APIController {
@PreAuthorize("hasAnyAuthority('PORTAL_ADMINISTRATOR')")
@RequestMapping(value = "/all", method = RequestMethod.GET)
- public ResponseEntity> getAll() {
+ public ResponseEntity> getAll() {
return ResponseEntity.ok(this.service.getAll());
}
@PreAuthorize("hasAnyAuthority('PORTAL_ADMINISTRATOR')")
- @RequestMapping(value = "/migrate/accessToken", method = RequestMethod.POST)
- public ResponseEntity> migrateAccessToken(@RequestBody List registeredATS) {
- return ResponseEntity.ok(this.service.migrateAccessToken(registeredATS));
+ @RequestMapping(value = "/copy", method = RequestMethod.POST)
+ public ResponseEntity> copyServices(@RequestBody CopyServices services) {
+ return ResponseEntity.ok(this.service.copyServices(services));
}
@@ -55,7 +56,7 @@ public class APIController {
return ResponseEntity.ok(this.service.save(form, id));
}
- @PreAuthorize("hasAnyAuthority('REGISTERED_USER') && @AuthorizationService.hasPersonalInfo() && @AuthorizationService.isMyService(#id)")
+ @PreAuthorize("hasAnyAuthority('PORTAL_ADMINISTRATOR') || (hasAnyAuthority('REGISTERED_USER') && @AuthorizationService.hasPersonalInfo() && @AuthorizationService.isMyService(#id))")
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
public ResponseEntity> delete(@PathVariable Long id) {
this.service.delete(id);
diff --git a/src/main/java/eu/dnetlib/developers/controllers/HealthController.java b/src/main/java/eu/dnetlib/developers/controllers/HealthController.java
index 0bd9fdb..bf152b6 100644
--- a/src/main/java/eu/dnetlib/developers/controllers/HealthController.java
+++ b/src/main/java/eu/dnetlib/developers/controllers/HealthController.java
@@ -1,6 +1,7 @@
package eu.dnetlib.developers.controllers;
-import eu.dnetlib.authentication.configuration.AuthenticationConfiguration;
+import eu.dnetlib.developers.configuration.GlobalVars;
+import eu.dnetlib.developers.configuration.Properties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@@ -9,16 +10,19 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
+import java.util.HashMap;
import java.util.Map;
@RestController
public class HealthController {
private final Logger log = LogManager.getLogger(this.getClass());
- private final AuthenticationConfiguration configuration;
+ private final Properties properties;
+ private final GlobalVars globalVars;
@Autowired
- public HealthController(AuthenticationConfiguration configuration) {
- this.configuration = configuration;
+ public HealthController(Properties properties, GlobalVars globalVars) {
+ this.properties = properties;
+ this.globalVars = globalVars;
}
@RequestMapping(value = {"", "/health_check"}, method = RequestMethod.GET)
@@ -30,7 +34,21 @@ public class HealthController {
@PreAuthorize("hasAnyAuthority('PORTAL_ADMINISTRATOR')")
@RequestMapping(value = "/health_check/advanced", method = RequestMethod.GET)
public Map checkEverything() {
- Map response = configuration.getProperties();
+ Map response = new HashMap<>();
+ response.put("developers.datasource.driver", properties.getDatasource().getDriver());
+ response.put("developers.datasource.url", properties.getDatasource().getUrl());
+ response.put("developers.datasource.username", properties.getDatasource().getUsername());
+ response.put("developers.datasource.password", properties.getDatasource().getPassword());
+ response.put("developers.issuer", properties.getIssuer());
+ if(eu.dnetlib.authentication.configuration.GlobalVars.date != null) {
+ response.put("Date of deploy", eu.dnetlib.authentication.configuration.GlobalVars.date.toString());
+ }
+ if(globalVars.getBuildDate() != null) {
+ response.put("Date of build", globalVars.getBuildDate());
+ }
+ if (globalVars.getVersion() != null) {
+ response.put("Version", globalVars.getVersion());
+ }
return response;
}
}
diff --git a/src/main/java/eu/dnetlib/developers/dto/APIsByIssuer.java b/src/main/java/eu/dnetlib/developers/dto/APIsByIssuer.java
new file mode 100644
index 0000000..0c0037b
--- /dev/null
+++ b/src/main/java/eu/dnetlib/developers/dto/APIsByIssuer.java
@@ -0,0 +1,31 @@
+package eu.dnetlib.developers.dto;
+
+import java.util.List;
+
+public class APIsByIssuer {
+ String issuer;
+ List apis;
+
+ public APIsByIssuer() {
+ }
+
+ public APIsByIssuer(String issuer) {
+ this.issuer = issuer;
+ }
+
+ public String getIssuer() {
+ return issuer;
+ }
+
+ public void setIssuer(String issuer) {
+ this.issuer = issuer;
+ }
+
+ public List getApis() {
+ return apis;
+ }
+
+ public void setApis(List apis) {
+ this.apis = apis;
+ }
+}
diff --git a/src/main/java/eu/dnetlib/developers/dto/RegisteredAT.java b/src/main/java/eu/dnetlib/developers/dto/CopyService.java
similarity index 92%
rename from src/main/java/eu/dnetlib/developers/dto/RegisteredAT.java
rename to src/main/java/eu/dnetlib/developers/dto/CopyService.java
index 7e12e4c..27e0f15 100644
--- a/src/main/java/eu/dnetlib/developers/dto/RegisteredAT.java
+++ b/src/main/java/eu/dnetlib/developers/dto/CopyService.java
@@ -2,13 +2,13 @@ package eu.dnetlib.developers.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
-public class RegisteredAT {
+public class CopyService {
@JsonProperty("client_id")
private String clientId;
@JsonProperty("registration_access_token")
private String registrationAccessToken;
- public RegisteredAT() {
+ public CopyService() {
}
public String getClientId() {
diff --git a/src/main/java/eu/dnetlib/developers/dto/CopyServices.java b/src/main/java/eu/dnetlib/developers/dto/CopyServices.java
new file mode 100644
index 0000000..7474bd9
--- /dev/null
+++ b/src/main/java/eu/dnetlib/developers/dto/CopyServices.java
@@ -0,0 +1,27 @@
+package eu.dnetlib.developers.dto;
+
+import java.util.List;
+
+public class CopyServices {
+ public String issuer;
+ public List services;
+
+ public CopyServices() {
+ }
+
+ public String getIssuer() {
+ return issuer;
+ }
+
+ public void setIssuer(String issuer) {
+ this.issuer = issuer;
+ }
+
+ public List getServices() {
+ return services;
+ }
+
+ public void setServices(List services) {
+ this.services = services;
+ }
+}
diff --git a/src/main/java/eu/dnetlib/developers/entities/RegisteredService.java b/src/main/java/eu/dnetlib/developers/entities/RegisteredService.java
index 69a658b..42c7f19 100644
--- a/src/main/java/eu/dnetlib/developers/entities/RegisteredService.java
+++ b/src/main/java/eu/dnetlib/developers/entities/RegisteredService.java
@@ -39,6 +39,20 @@ public class RegisteredService {
this.creationDate = new Date();
}
+ public RegisteredService(RegisteredService service, String registrationAccessToken, String issuer) {
+ this.clientId = service.getClientId();
+ this.owner = service.getOwner();
+ this.name = service.getName();
+ this.creationDate = new Date();
+ this.registrationAccessToken = registrationAccessToken;
+ this.keyType = service.getKeyType();
+ this.url = service.getUrl();
+ this.description = service.getDescription();
+ this.frequency = service.getFrequency();
+ this.target = service.getTarget();
+ this.issuer = issuer;
+ }
+
public void setService(ServiceForm form, ServiceResponse response) {
this.clientId = response.getClientId();
this.name = form.getName();
diff --git a/src/main/java/eu/dnetlib/developers/repositories/RegisteredServiceDAO.java b/src/main/java/eu/dnetlib/developers/repositories/RegisteredServiceDAO.java
index 9ee45f7..285a3ce 100644
--- a/src/main/java/eu/dnetlib/developers/repositories/RegisteredServiceDAO.java
+++ b/src/main/java/eu/dnetlib/developers/repositories/RegisteredServiceDAO.java
@@ -1,7 +1,9 @@
package eu.dnetlib.developers.repositories;
import eu.dnetlib.developers.entities.RegisteredService;
+import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@@ -12,9 +14,14 @@ public interface RegisteredServiceDAO extends CrudRepository findAll();
+ @Query("select distinct rs.issuer from RegisteredService rs where rs.issuer != :#{#issuer}")
+ List findAllIssuersExceptActive(@Param("issuer") String issuer);
+
Optional findById(Long id);
- Optional findByClientId(String clientId);
+ Optional findByClientIdAndIssuer(String clientId, String issuer);
+
+ List findAllByIssuerOrderByOwnerAsc(String issuer);
List findAllByOwnerAndIssuerOrderByCreationDateAsc(String owner, String issuer);
}
diff --git a/src/main/java/eu/dnetlib/developers/services/APIService.java b/src/main/java/eu/dnetlib/developers/services/APIService.java
index 4d7d496..82066a0 100644
--- a/src/main/java/eu/dnetlib/developers/services/APIService.java
+++ b/src/main/java/eu/dnetlib/developers/services/APIService.java
@@ -16,16 +16,15 @@ 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.*;
import java.util.stream.Collectors;
@Service()
public class APIService {
- private RegisteredServiceDAO dao;
- private RestTemplate template;
- private String issuer;
+ private final RegisteredServiceDAO dao;
+ private final RestTemplate template;
+ private final String issuer;
@Autowired
public APIService(RegisteredServiceDAO dao, RestTemplate template, Properties properties) {
@@ -34,12 +33,18 @@ public class APIService {
this.issuer = properties.getIssuer();
}
- public List 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;
+ public List getAll() {
+ List issuers = new ArrayList<>(Collections.singletonList(this.issuer));
+ issuers.addAll(this.dao.findAllIssuersExceptActive(this.issuer));
+ return issuers.stream().map(issuer -> {
+ APIsByIssuer api = new APIsByIssuer(issuer);
+ api.setApis(this.dao.findAllByIssuerOrderByOwnerAsc(issuer).stream().map(service -> {
+ API details = new API();
+ details.setService(service);
+ details.setDetails(this.readService(service.getClientId(), service.getRegistrationAccessToken()));
+ return details;
+ }).collect(Collectors.toList()));
+ return api;
}).collect(Collectors.toList());
}
@@ -53,15 +58,21 @@ public class APIService {
}).collect(Collectors.toList());
}
- public List migrateAccessToken(List registeredAT) {
- List apis = new ArrayList<>();
- registeredAT.forEach( element -> {
- RegisteredService service = this.dao.findByClientId(element.getClientId()).orElse(null);
- if(service != null) {
- service.setRegistrationAccessToken(element.getRegistrationAccessToken());
+ public List copyServices(CopyServices services) {
+ List apis = this.dao.findAllByIssuerOrderByOwnerAsc(this.issuer).stream().map(service -> {
+ API details = new API();
+ details.setService(service);
+ details.setDetails(this.readService(service.getClientId(), service.getRegistrationAccessToken()));
+ return details;
+ }).collect(Collectors.toList());
+ services.getServices().forEach(element -> {
+ RegisteredService service = this.dao.findByClientIdAndIssuer(element.getClientId(), services.getIssuer()).orElse(null);
+ RegisteredService newService = this.dao.findByClientIdAndIssuer(element.getClientId(), this.issuer).orElse(null);
+ if (service != null && newService == null) {
+ newService = new RegisteredService(service, element.getRegistrationAccessToken(), this.issuer);
API api = new API();
- api.setService(this.dao.save(service));
- api.setDetails(this.readService(service.getClientId(), service.getRegistrationAccessToken()));
+ api.setService(this.dao.save(newService));
+ api.setDetails(this.readService(newService.getClientId(), service.getRegistrationAccessToken()));
apis.add(api);
}
});
@@ -72,9 +83,9 @@ public class APIService {
ServiceRequest request;
API api = new API();
OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
- if(id != null) {
+ if (id != null) {
RegisteredService service = this.dao.findById(id).orElse(null);
- if(service == null) {
+ if (service == null) {
throw new EntityNotFoundException("Service with id " + id + " does not exist.");
}
api.setService(service);
@@ -83,16 +94,16 @@ public class APIService {
api.setService(new RegisteredService(authentication.getSub(), issuer));
}
String keyType = form.getKeyType();
- if(keyType != null && keyType.equals("uri")) {
- if(form.getUri() == null) {
+ 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")) {
+ } 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()) {
+ 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());
@@ -100,10 +111,10 @@ public class APIService {
request = ServiceRequest.createServiceRequest(api.getService().getClientId(), form.getName(), form.getLogoURL(), authentication.getUserInfo().getEmail());
}
ServiceResponse response;
- if(api.getService().getClientId() != null) {
+ if (api.getService().getClientId() != null) {
response = this.updateService(api.getService().getClientId(), request, api.getService().getRegistrationAccessToken());
} else {
- if(this.dao.findAllByOwnerAndIssuerOrderByCreationDateAsc(authentication.getSub(), issuer).size() < 5) {
+ if (this.dao.findAllByOwnerAndIssuerOrderByCreationDateAsc(authentication.getSub(), issuer).size() < 5) {
response = this.createService(request);
} else {
throw new ForbiddenException("You are not allowed to own more than 5 services.");
@@ -121,10 +132,12 @@ public class APIService {
public void delete(Long id) {
RegisteredService service = this.dao.findById(id).orElse(null);
- if(service == null) {
+ if (service == null) {
throw new EntityNotFoundException("Service with id " + id + " does not exist.");
} else {
- this.deleteService(service.getClientId(), service.getRegistrationAccessToken());
+ if(readService(service.getClientId(), service.getRegistrationAccessToken()) != null) {
+ this.deleteService(service.getClientId(), service.getRegistrationAccessToken());
+ }
this.dao.delete(id);
}
}
diff --git a/src/main/resources/developers.properties b/src/main/resources/developers.properties
index 12c5a2d..2efc849 100644
--- a/src/main/resources/developers.properties
+++ b/src/main/resources/developers.properties
@@ -10,3 +10,6 @@ spring.jpa.hibernate.ddl-auto=none
api.title = Developers API
api.description = Developers API includes authentication methods and provides functionalities to manage OpenAIRE Dynamic AAI APIs.
api.version = ${project.version}
+
+developers-api.global-vars.buildDate=@timestamp@
+developers-api.global-vars.version=@project.version@