diff --git a/Dockerfile b/Dockerfile
index d11797a..12f26b7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,17 @@
+### Build using Maven ###
+FROM maven:3.8-jdk-11-slim AS maven
+
+COPY pom.xml /tmp/
+COPY . /tmp/
+
+WORKDIR /tmp/
+
+## run maven package ##
+RUN mvn package -U -DskipTests
+
+
FROM openjdk:11
-ARG JAR_FILE=target/*.jar
-COPY ${JAR_FILE} intelcomp-catalogue.jar
+
+COPY --from=maven /tmp/target/*.jar /intelcomp-catalogue.jar
ENTRYPOINT ["java","-jar","/intelcomp-catalogue.jar"]
diff --git a/pom.xml b/pom.xml
index 3955ac8..343c6fa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,18 +5,19 @@
org.springframework.boot
spring-boot-starter-parent
- 2.5.6
+ 2.5.7
eu.intelcomp
catalogue
- 1.0.0-SNAPSHOT
+ 2.0.0-SNAPSHOT
jar
intelcomp
Intelcomp Catalogue Project
11
- 2.3.7
+ 2.7.3
+ 7.17.14
@@ -46,16 +47,35 @@
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
org.springframework.boot
spring-boot-starter-oauth2-client
- 2.6.1
org.springframework.boot
spring-boot-starter-oauth2-resource-server
- 2.6.1
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ org.springframework.session
+ spring-session-data-redis
@@ -78,7 +98,7 @@
gr.athenarc
catalogue
- 3.0.0
+ 5.0.2
@@ -92,9 +112,9 @@
- omtd-snapshots
+ madgik-snapshots
default
- https://repo.openminted.eu/content/repositories/snapshots/
+ https://repo.madgik.di.uoa.gr/content/repositories/snapshots/
false
@@ -103,9 +123,9 @@
- omtd-releases
+ madgik-releases
default
- https://repo.openminted.eu/content/repositories/releases
+ https://repo.madgik.di.uoa.gr/content/repositories/releases
true
@@ -165,14 +185,46 @@
+
+ cz.habarta.typescript-generator
+ typescript-generator-maven-plugin
+ 2.16.538
+
+
+ generate
+
+ generate
+
+ process-classes
+
+
+
+ jackson2
+
+ eu.intelcomp.xsd2java.**
+ eu.intelcomp.catalogue.domain.**
+
+
+ function(name, simpleName) { return name; }
+
+ target/domain.ts
+ module
+ implementationFile
+ asEnum
+ asClasses
+
+
src/main/resources
true
+
+ **/application.yml
+ **/resourceTypes/
+
- **/application.yml
- **/registry.properties
+ **/application.properties
diff --git a/src/main/java/eu/intelcomp/catalogue/IntelcompApplication.java b/src/main/java/eu/intelcomp/catalogue/IntelcompApplication.java
index fe815ca..6a4083a 100644
--- a/src/main/java/eu/intelcomp/catalogue/IntelcompApplication.java
+++ b/src/main/java/eu/intelcomp/catalogue/IntelcompApplication.java
@@ -2,13 +2,12 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@SpringBootApplication
public class IntelcompApplication {
- public static void main(String[] args) {
- SpringApplication.run(IntelcompApplication.class, args);
- }
+ public static void main(String[] args) {
+ SpringApplication.run(IntelcompApplication.class, args);
+ }
}
diff --git a/src/main/java/eu/intelcomp/catalogue/aspects/SecurityAspect.java b/src/main/java/eu/intelcomp/catalogue/aspects/SecurityAspect.java
new file mode 100644
index 0000000..759bc3c
--- /dev/null
+++ b/src/main/java/eu/intelcomp/catalogue/aspects/SecurityAspect.java
@@ -0,0 +1,80 @@
+package eu.intelcomp.catalogue.aspects;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+
+@Aspect
+@Component
+public class SecurityAspect {
+
+ private static final Logger logger = LoggerFactory.getLogger(SecurityAspect.class);
+
+ public SecurityAspect() {
+ }
+
+ @Before(value = "execution(* gr.athenarc.catalogue.controller.GenericItemController.create(String,..)) && args(resourceType)", argNames = "resourceType")
+ void beforeCreate(String resourceType) {
+ authorize(resourceType);
+ }
+
+ @Before(value = "(execution(* gr.athenarc.catalogue.controller.GenericItemController.update(String, String, ..)) ||" +
+ "execution(* gr.athenarc.catalogue.controller.GenericItemController.delete(String, String, ..))) " +
+ "&& args(id, resourceType,..)", argNames = "id,resourceType")
+ void beforeUpdate_Delete(String id, String resourceType) {
+ authorize(resourceType);
+ }
+
+ void authorize(String resourceType) {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ boolean authorized = false;
+ if (authentication.getAuthorities().contains(new SimpleGrantedAuthority("ADMIN"))) {
+ return;
+ }
+ switch (resourceType) {
+ case "tool":
+ authorized = authorizeAiTool(authentication);
+ break;
+ case "ai_model":
+ authorized = authorizeAiModel(authentication);
+ break;
+ case "dataset_type":
+ authorized = authorizeDatasetType(authentication);
+ break;
+ case "dataset_instance":
+ authorized = authorizeDatasetInstance(authentication);
+ break;
+ default:
+ authorized = authentication.getAuthorities().contains(new SimpleGrantedAuthority("ADMIN"));
+ }
+ if (!authorized) {
+ throw new AccessDeniedException("Forbidden");
+ }
+ }
+
+ boolean authorizeDatasetType(Authentication authentication) {
+ SimpleGrantedAuthority[] authorities = {new SimpleGrantedAuthority("OPERATOR_DATASET-INGESTOR")};
+ return Arrays.stream(authorities).anyMatch(authority -> authentication.getAuthorities().contains(authority));
+ }
+
+ boolean authorizeDatasetInstance(Authentication authentication) {
+ return authentication.getAuthorities().contains(new SimpleGrantedAuthority("OPERATOR_DATASET-INGESTOR"));
+ }
+
+ boolean authorizeAiTool(Authentication authentication) {
+ return authentication.getAuthorities().contains(new SimpleGrantedAuthority("OPERATOR_DEVELOPER"));
+ }
+
+ boolean authorizeAiModel(Authentication authentication) {
+ return authentication.getAuthorities().contains(new SimpleGrantedAuthority("OPERATOR_DEVELOPER"));
+ }
+}
diff --git a/src/main/java/eu/intelcomp/catalogue/config/AuthSuccessHandler.java b/src/main/java/eu/intelcomp/catalogue/config/AuthSuccessHandler.java
index 815549d..6886150 100644
--- a/src/main/java/eu/intelcomp/catalogue/config/AuthSuccessHandler.java
+++ b/src/main/java/eu/intelcomp/catalogue/config/AuthSuccessHandler.java
@@ -1,10 +1,10 @@
package eu.intelcomp.catalogue.config;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
@@ -14,19 +14,18 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.time.Instant;
-import java.util.Date;
@Component
public class AuthSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(AuthSuccessHandler.class);
- private final ApplicationProperties applicationProperties;
+ private final IntelcompProperties intelcompProperties;
+ private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired
- public AuthSuccessHandler(ApplicationProperties applicationProperties) {
- this.applicationProperties = applicationProperties;
+ public AuthSuccessHandler(IntelcompProperties intelcompProperties) {
+ this.intelcompProperties = intelcompProperties;
}
@Override
@@ -36,28 +35,13 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
- Cookie cookie = new Cookie("AccessToken", ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue());
- cookie.setMaxAge(createCookieMaxAge(authentication));
+ Cookie cookie = new Cookie("AccessToken", "deprecated");
cookie.setPath("/");
-// cookie.setSecure(true);
+ logger.debug("Assigning Cookie: {}", objectMapper.writeValueAsString(cookie));
response.addCookie(cookie);
- response.sendRedirect(applicationProperties.getLoginRedirect());
- }
-
- private int createCookieMaxAge(Authentication authentication) {
- Integer age = getExp(authentication);
- return age != null ? age : 3600;
- }
-
- private Integer getExp(Authentication authentication) {
- OidcUser user = ((OidcUser) authentication.getPrincipal());
- if (user.getAttribute("exp") instanceof Instant) {
- Instant exp = user.getAttribute("exp");
- int age = (int) (exp.getEpochSecond() - (new Date().getTime() / 1000));
- return age;
- }
- return null;
+ logger.debug("Authentication Successful - Redirecting to: {}", intelcompProperties.getLoginRedirect());
+ response.sendRedirect(intelcompProperties.getLoginRedirect());
}
}
diff --git a/src/main/java/eu/intelcomp/catalogue/config/CompleteLogoutSuccessHandler.java b/src/main/java/eu/intelcomp/catalogue/config/CompleteLogoutSuccessHandler.java
index b4ee3bb..b27f369 100644
--- a/src/main/java/eu/intelcomp/catalogue/config/CompleteLogoutSuccessHandler.java
+++ b/src/main/java/eu/intelcomp/catalogue/config/CompleteLogoutSuccessHandler.java
@@ -23,12 +23,12 @@ public class CompleteLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler
private final String OPENID_CONFIGURATION = "/.well-known/openid-configuration";
private final String END_SESSION_ENDPOINT = "end_session_endpoint";
- private final ApplicationProperties applicationProperties;
+ private final IntelcompProperties intelcompProperties;
private final RestTemplate restTemplate = new RestTemplate();
@Autowired
- public CompleteLogoutSuccessHandler(ApplicationProperties applicationProperties) {
- this.applicationProperties = applicationProperties;
+ public CompleteLogoutSuccessHandler(IntelcompProperties intelcompProperties) {
+ this.intelcompProperties = intelcompProperties;
}
@Override
@@ -44,9 +44,9 @@ public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse resp
String logoutEndpoint = getLogoutEndpoint(url);
String logoutUrl;
if (logoutEndpoint != null) {
- logoutUrl = String.format("%s?redirect_uri=%s", logoutEndpoint, applicationProperties.getLogoutRedirect());
+ logoutUrl = String.format("%s?redirect_uri=%s", logoutEndpoint, intelcompProperties.getLogoutRedirect());
} else {
- logoutUrl = applicationProperties.getLogoutRedirect();
+ logoutUrl = intelcompProperties.getLogoutRedirect();
}
response.sendRedirect(logoutUrl);
super.onLogoutSuccess(request, response, authentication);
diff --git a/src/main/java/eu/intelcomp/catalogue/config/IntelcompConfiguration.java b/src/main/java/eu/intelcomp/catalogue/config/IntelcompConfiguration.java
index 838fb42..5b77c3d 100644
--- a/src/main/java/eu/intelcomp/catalogue/config/IntelcompConfiguration.java
+++ b/src/main/java/eu/intelcomp/catalogue/config/IntelcompConfiguration.java
@@ -1,29 +1,12 @@
package eu.intelcomp.catalogue.config;
-import eu.openminted.registry.core.controllers.ResourceSyncController;
-import gr.athenarc.catalogue.CatalogueApplication;
-import gr.athenarc.catalogue.config.CatalogueLibConfiguration;
-import gr.athenarc.catalogue.config.LibConfiguration;
-import gr.athenarc.catalogue.config.RegistryCoreConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
-@ComponentScan(value = {
- "gr.athenarc",
- "eu.openminted.registry.core",
-},
-excludeFilters = {
- @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CatalogueApplication.class),
- @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = LibConfiguration.class), // TODO: remove if lib is fixed
- @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = RegistryCoreConfiguration.class),
- @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ResourceSyncController.class)
-})
-public class IntelcompConfiguration implements CatalogueLibConfiguration {
-
- @Override
- public String generatedClassesPackageName() {
- return "eu.intelcomp.xsd2java";
- }
+@EnableConfigurationProperties(IntelcompProperties.class)
+@ComponentScan(value = {"eu.openminted.registry.core"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = eu.openminted.registry.core.controllers.GenericController.class)})
+public class IntelcompConfiguration {
}
diff --git a/src/main/java/eu/intelcomp/catalogue/config/ApplicationProperties.java b/src/main/java/eu/intelcomp/catalogue/config/IntelcompProperties.java
similarity index 89%
rename from src/main/java/eu/intelcomp/catalogue/config/ApplicationProperties.java
rename to src/main/java/eu/intelcomp/catalogue/config/IntelcompProperties.java
index 9641a85..6ee1702 100644
--- a/src/main/java/eu/intelcomp/catalogue/config/ApplicationProperties.java
+++ b/src/main/java/eu/intelcomp/catalogue/config/IntelcompProperties.java
@@ -1,13 +1,11 @@
package eu.intelcomp.catalogue.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
import java.util.Set;
-@Component
@ConfigurationProperties(prefix = "intelcomp")
-public class ApplicationProperties {
+public class IntelcompProperties {
private Set