diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl index 3b93114541d3ac242b051e71f5f38bf2923e68f9..d685d2f2f6e3d11c509d72e774789fa2532649b4 100644 --- a/docker/config/application.tmpl +++ b/docker/config/application.tmpl @@ -82,3 +82,8 @@ keycloak: # cors-exposed-headers: "*" # logoutUrl: {{ .Env.LOGOUT_URL }} + +# Files are imported when building the docker image +files: + pathologies_json: "file:/opt/portal/api/pathologies.json" + disabledAlgorithms_json: "file:/opt/portal/api/disabledAlgorithms.json" diff --git a/pom.xml b/pom.xml index 5292dffd056dbb97d42ea3f766101386b0c9149f..a21e63e379243642933f3042bd6700734633b1a2 100644 --- a/pom.xml +++ b/pom.xml @@ -278,6 +278,15 @@ </includes> <filtering>true</filtering> </resource> + + <!-- Used for development. Docker/config folder files added as resources --> + <resource> + <directory>config</directory> + <includes> + <include>*.json</include> + </includes> + <filtering>true</filtering> + </resource> </resources> <plugins> diff --git a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java index bca25598a6e59827a6a938e30fc9db1b9b5d5614..909d2c1c81dc040c78bba7c29d4f43bcb1e925ca 100644 --- a/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/PersistenceConfiguration.java @@ -29,7 +29,6 @@ public class PersistenceConfiguration { return DataSourceBuilder.create().build(); } - @Bean(name = "entityManagerFactory") @DependsOn("flyway") public LocalContainerEntityManagerFactoryBean entityManagerFactory() { diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java index 22f904af5f97e70d45925434940e594f772df498..8617e2270a5903a872c4ec432fb5016b71cb9b14 100644 --- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java @@ -1,21 +1,16 @@ package eu.hbp.mip.configuration; import eu.hbp.mip.configuration.SecurityUtils.CORSFilter; -import eu.hbp.mip.configuration.SecurityUtils.CustomAccessDeniedHandler; -import eu.hbp.mip.configuration.SecurityUtils.CustomLoginUrlAuthenticationEntryPoint; import org.keycloak.adapters.KeycloakConfigResolver; import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; -import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter; -import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -24,25 +19,18 @@ import org.springframework.security.core.session.SessionRegistryImpl; import org.springframework.security.web.access.channel.ChannelProcessingFilter; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -import org.springframework.security.web.csrf.CsrfFilter; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; -import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.WebUtils; -import javax.net.ssl.*; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; // Reference for OAuth2 login: https://spring.io/guides/tutorials/spring-boot-oauth2/ @@ -132,8 +120,8 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter // ).permitAll() // .antMatchers("/galaxy*", "/galaxy/*").hasRole("DATA MANAGER") // .anyRequest().hasRole("RESEARCHER") - // .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl)) - // .accessDeniedHandler(new CustomAccessDeniedHandler()) + // .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl)) + // .accessDeniedHandler(new CustomAccessDeniedHandler()) // .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository()) // .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class).csrf(); // .and().logout().logoutSuccessUrl("/logout"); @@ -141,7 +129,7 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter // // // TODO .and().logout().addLogoutHandler(authLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl) // .and().logout().permitAll() - // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); + // TODO ?? .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); } else { http.antMatcher("/**") .authorizeRequests() @@ -150,7 +138,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter } } - // @Bean // public FilterRegistrationBean corsFilter() { // UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); @@ -223,7 +210,6 @@ public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter return repository; } - // @Bean // public AuthoritiesExtractor keycloakAuthoritiesExtractor() { // return new KeycloakAuthoritiesExtractor(); diff --git a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java index 51fc1b4857ad777bcfb7461e0314b09537e37559..72dff716a5fb388806e50282df756039d3058458 100644 --- a/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java +++ b/src/main/java/eu/hbp/mip/controllers/AlgorithmsApi.java @@ -17,6 +17,7 @@ import eu.hbp.mip.utils.Logging; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.http.ResponseEntity; @@ -53,6 +54,9 @@ public class AlgorithmsApi { @Value("#{'${services.galaxy.galaxyApiKey}'}") private String galaxyApiKey; + @Value("#{'${files.disabledAlgorithms_json}'}") + private String disabledAlgorithmsFilePath; + @ApiOperation(value = "List all algorithms", response = String.class) @RequestMapping(method = RequestMethod.GET) public ResponseEntity<List<AlgorithmDTO>> getAlgorithms() { @@ -195,7 +199,7 @@ public class AlgorithmsApi { */ List<String> getDisabledAlgorithms() throws IOException { - Resource resource = resourceLoader.getResource("file:/opt/portal/api/disabledAlgorithms.json"); + Resource resource = resourceLoader.getResource(disabledAlgorithmsFilePath); List<String> response = gson.fromJson(convertInputStreamToString( resource.getInputStream()), diff --git a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java index 055b04b2363e5522f244d5319197275993b79643..0f3f3c2bb5f4216e92f4863a93c1999d02c0d469 100644 --- a/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java +++ b/src/main/java/eu/hbp/mip/controllers/PathologiesApi.java @@ -1,7 +1,3 @@ -/** - * Created by mirco on 04.12.15. - */ - package eu.hbp.mip.controllers; import com.google.gson.Gson; @@ -42,32 +38,37 @@ public class PathologiesApi { @Value("#{'${authentication.enabled}'}") private boolean authenticationIsEnabled; + @Value("#{'${files.pathologies_json}'}") + private String pathologiesFilePath; + @Autowired private CustomResourceLoader resourceLoader; @RequestMapping(name = "/pathologies", method = RequestMethod.GET) public ResponseEntity<String> getPathologies(Authentication authentication) { - Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Loading pathologies ..."); + String endpoint = "(GET) /pathologies"; + String username = activeUserService.getActiveUser().getUsername(); + Logging.LogUserAction(username, endpoint, "Loading pathologies ..."); // Load pathologies from file - Resource resource = resourceLoader.getResource("file:/opt/portal/api/pathologies.json"); + Resource resource = resourceLoader.getResource(pathologiesFilePath); List<PathologyDTO> allPathologies; try { allPathologies = gson.fromJson(InputStreamConverter.convertInputStreamToString(resource.getInputStream()), new TypeToken<List<PathologyDTO>>() { }.getType()); } catch (IOException e) { - Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Unable to load pathologies"); + Logging.LogUserAction(username, endpoint, "Unable to load pathologies"); throw new BadRequestException("The pathologies could not be loaded."); } // If authentication is disabled return everything if (!authenticationIsEnabled) { - Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Successfully loaded " + allPathologies.size() + " pathologies"); + Logging.LogUserAction(username, endpoint, "Successfully loaded " + allPathologies.size() + " pathologies"); return ResponseEntity.ok().body(gson.toJson(allPathologies)); } - Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /pathologies", "Successfully loaded all authorized pathologies"); + Logging.LogUserAction(username, endpoint, "Successfully loaded all authorized pathologies"); return ResponseEntity.ok().body(ClaimUtils.getAuthorizedPathologies( - activeUserService.getActiveUser().getUsername(), authentication.getAuthorities(), allPathologies)); + username, authentication.getAuthorities(), allPathologies)); } } diff --git a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java index 696fac039275ae760711ac6d9ee7350c15691f47..7bc4fb7b7a82c385d62f4a56428b13a61a575753 100644 --- a/src/main/java/eu/hbp/mip/controllers/SecurityApi.java +++ b/src/main/java/eu/hbp/mip/controllers/SecurityApi.java @@ -31,13 +31,11 @@ public class SecurityApi { @Autowired private SecurityConfiguration securityConfiguration; - // TODO How to redirect? keycloak off? @RequestMapping(path = "/login/hbp", method = RequestMethod.GET) @ConditionalOnExpression("${authentication.enabled:0}") public void noLogin(HttpServletResponse httpServletResponse) throws IOException { Logging.LogUserAction(activeUserService.getActiveUser().getUsername(), "(GET) /user/login/hbp", "Unauthorized login."); - httpServletResponse.sendRedirect(securityConfiguration.getFrontendRedirectAfterLogin()); } @@ -47,7 +45,7 @@ public class SecurityApi { @Value("#{'${services.galaxy.galaxyPassword:password}'}") private String galaxyPassword; - @Value("#{'${services.galaxy.galaxyContext:nativeGalaxy}'}") + @Value("#{'${services.galaxy.galaxpathoyContext:nativeGalaxy}'}") private String galaxyContext; /** diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java index 7ffffc7ebfca5f53cbd840cf259b8643667fa335..3f6bb87b00683c13ea8684c4464a135c337f7ff6 100644 --- a/src/main/java/eu/hbp/mip/services/ExperimentService.java +++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java @@ -474,8 +474,8 @@ public class ExperimentService { * @return the experiment information that was retrieved from exareme */ public ExperimentDTO createExaremeExperiment(ExperimentDTO experimentDTO, String endpoint) { - UserDAO user = activeUserService.getActiveUser(); + Logging.LogUserAction(user.getUsername(), endpoint, "Running the algorithm..."); ExperimentDAO experimentDAO = createExperimentInTheDatabase(experimentDTO, endpoint); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 65ab563a91ca742cb81d154592a5e2f8bf81e26e..fb4e06de77f68567e992054cc6ea66a447d673f7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -82,3 +82,8 @@ keycloak: # cors-exposed-headers: "*" # logoutUrl: {{ .Env.LOGOUT_URL }} + +# Files are loaded from the resources +files: + pathologies_json: "classPath:/pathologies.json" + disabledAlgorithms_json: "classPath:/disabledAlgorithms.json"