From 14528d8db0bbf392f8c20c6c92c79359d9fff7c9 Mon Sep 17 00:00:00 2001 From: Kristina Date: Thu, 20 Oct 2022 15:58:26 +0200 Subject: [PATCH 01/10] Working around keycloak authentication --- klab.hub/pom.xml | 5 + .../hub/api/EngineAuthResponeFactory.java | 14 +- .../klab/hub/config/OAuth2Config.java | 112 ++--- .../hub/config/WebSecurityConfiguration.java | 111 +++++ .../hub/config/dev/DevMongoModelsConfig.java | 3 +- .../controllers/EngineLicenseController.java | 8 +- .../security/TokenAuthenticationFilter.java | 3 +- .../klab/hub/security/WebSecurityConfig.java | 402 +++++++++--------- .../OAuth2AuthenticationSuccessHandler.java | 120 +++--- .../tokens/services/UserAuthTokenService.java | 32 +- .../services/UserAuthTokenServiceImpl.java | 230 +++++----- .../UserAuthenticationController.java | 40 +- klab.hub/src/main/resources/application.yml | 40 +- 13 files changed, 626 insertions(+), 494 deletions(-) create mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java diff --git a/klab.hub/pom.xml b/klab.hub/pom.xml index 438b4d26ba..68c65be1c7 100644 --- a/klab.hub/pom.xml +++ b/klab.hub/pom.xml @@ -260,6 +260,11 @@ 1.34.0 + + org.keycloak + keycloak-spring-boot-starter + 19.0.2 + \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/EngineAuthResponeFactory.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/EngineAuthResponeFactory.java index a3c9bd70c0..a23c16b954 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/EngineAuthResponeFactory.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/EngineAuthResponeFactory.java @@ -15,7 +15,7 @@ import org.integratedmodelling.klab.hub.licenses.services.LicenseConfigService; import org.integratedmodelling.klab.hub.repository.MongoGroupRepository; import org.integratedmodelling.klab.hub.network.NodeNetworkManager; -import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; +//import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; import org.integratedmodelling.klab.hub.users.services.UserProfileService; import org.integratedmodelling.klab.rest.AuthenticatedIdentity; import org.integratedmodelling.klab.rest.EngineAuthenticationRequest; @@ -37,16 +37,16 @@ public class EngineAuthResponeFactory { private LicenseConfigService configService; - private UserAuthTokenService tokenService; +// private UserAuthTokenService tokenService; public EngineAuthResponeFactory(UserProfileService profileService, MongoGroupRepository groupRepository, - LicenseConfigService configService, - UserAuthTokenService tokenService) { + LicenseConfigService configService/*, + UserAuthTokenService tokenService*/) { this.profileService = profileService; this.groupRepository = groupRepository; this.configService = configService; - this.tokenService = tokenService; +// this.tokenService = tokenService; } public EngineAuthenticationResponse getRespone(EngineAuthenticationRequest request, String remoteAddr) @@ -76,8 +76,8 @@ public EngineAuthenticationResponse getRespone(EngineAuthenticationRequest reque config = null; } EngineAuthenticationResponse response = remoteEngine(profile, request.getCertificate(), config); - TokenAuthentication token = tokenService.createToken(profile.getUsername(), TokenType.auth); - response.setAuthentication(token.getTokenString()); +// TokenAuthentication token = tokenService.createToken(profile.getUsername(), TokenType.auth); +// response.setAuthentication(token.getTokenString()); profile.setLastConnection(DateTime.now()); profileService.updateUserByProfile(profile); return response; diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/OAuth2Config.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/OAuth2Config.java index b85f455ba0..f839d4f6e4 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/OAuth2Config.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/OAuth2Config.java @@ -1,56 +1,56 @@ -package org.integratedmodelling.klab.hub.config; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConfigurationProperties(prefix = "app") -public class OAuth2Config { - private final Auth auth = new Auth(); - private final OAuth2 oauth2 = new OAuth2(); - - public static class Auth { - private String tokenSecret; - private long tokenExpirationMsec; - - public String getTokenSecret() { - return tokenSecret; - } - - public void setTokenSecret(String tokenSecret) { - this.tokenSecret = tokenSecret; - } - - public long getTokenExpirationMsec() { - return tokenExpirationMsec; - } - - public void setTokenExpirationMsec(long tokenExpirationMsec) { - this.tokenExpirationMsec = tokenExpirationMsec; - } - } - - public static final class OAuth2 { - private List authorizedRedirectUris = new ArrayList<>(); - - public List getAuthorizedRedirectUris() { - return authorizedRedirectUris; - } - - public OAuth2 authorizedRedirectUris(List authorizedRedirectUris) { - this.authorizedRedirectUris = authorizedRedirectUris; - return this; - } - } - - public Auth getAuth() { - return auth; - } - - public OAuth2 getOauth2() { - return oauth2; - } -} +//package org.integratedmodelling.klab.hub.config; +// +//import java.util.ArrayList; +//import java.util.List; +// +//import org.springframework.boot.context.properties.ConfigurationProperties; +//import org.springframework.context.annotation.Configuration; +// +//@Configuration +//@ConfigurationProperties(prefix = "app") +//public class OAuth2Config { +// private final Auth auth = new Auth(); +// private final OAuth2 oauth2 = new OAuth2(); +// +// public static class Auth { +// private String tokenSecret; +// private long tokenExpirationMsec; +// +// public String getTokenSecret() { +// return tokenSecret; +// } +// +// public void setTokenSecret(String tokenSecret) { +// this.tokenSecret = tokenSecret; +// } +// +// public long getTokenExpirationMsec() { +// return tokenExpirationMsec; +// } +// +// public void setTokenExpirationMsec(long tokenExpirationMsec) { +// this.tokenExpirationMsec = tokenExpirationMsec; +// } +// } +// +// public static final class OAuth2 { +// private List authorizedRedirectUris = new ArrayList<>(); +// +// public List getAuthorizedRedirectUris() { +// return authorizedRedirectUris; +// } +// +// public OAuth2 authorizedRedirectUris(List authorizedRedirectUris) { +// this.authorizedRedirectUris = authorizedRedirectUris; +// return this; +// } +// } +// +// public Auth getAuth() { +// return auth; +// } +// +// public OAuth2 getOauth2() { +// return oauth2; +// } +//} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java new file mode 100644 index 0000000000..473ad8616c --- /dev/null +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java @@ -0,0 +1,111 @@ +package org.integratedmodelling.klab.hub.config; + +import java.util.Arrays; +import java.util.Collections; + +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.config.KeycloakWebSecurityConfigurerAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.crypto.password.LdapShaPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import com.google.common.collect.ImmutableList; +import com.google.common.net.HttpHeaders; + +@KeycloakConfiguration +//@Order(95) +public class WebSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + KeycloakAuthenticationProvider keycloakAuthenticationProvider = + keycloakAuthenticationProvider(); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + auth.authenticationProvider(keycloakAuthenticationProvider); + } + + @Bean + @Override + protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new NullAuthenticatedSessionStrategy(); + } + + @Bean + public KeycloakConfigResolver KeycloakConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + super.configure(http); + http.cors() + .and() + .csrf() + .disable() + .authorizeRequests() + .anyRequest() + .authenticated() + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + + @Bean + CorsConfigurationSource corsConfigurationSource() { + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + final CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(false); + config.setAllowedOrigins(ImmutableList.of( + "https://integratedmodelling.org", + "http://localhost:8080", + "https://localhost:8080", + "http://localhost:8081", + "https://localhost:8081", + "http://localhost:8284", + "https://localhost:8284")); + config.setAllowedHeaders(Collections.singletonList("*")); + config.addExposedHeader("Content-disposition"); + config.addExposedHeader(HttpHeaders.LOCATION); + config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "HEAD")); + source.registerCorsConfiguration("/**", config); + return source; + } + + /** + * The allows our password encoder to have multiple entries. Allowing us to upgrade user + * passwords without needing to do some serious migration effort. It is possible that + * we will need to have users set a new password, or force the system to rehash the password + * when the user logs in. + * + * In the end there are limited possibilities in the options here. The better way would be + * to use a proper encoder and not some deprecated methodm but crowd can only handle one type + * of encrcyption at a time. + * + * + * String encodingId = "bcrypt"; Map encoders = new + * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); + * encoders.put("SHA512", new LdapShaPasswordEncoder()); + * DelegatingPasswordEncoder delegatingPasswordEncoder = new + * DelegatingPasswordEncoder(encodingId, encoders); + * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new + * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new LdapShaPasswordEncoder(); + } +} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java index ac8492f074..3fc9f008a7 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java @@ -50,7 +50,8 @@ public void onApplicationEvent(ContextRefreshedEvent event) { groupRepo, userRepository, ldapUserDetailsManager, - passwordEncoder).execute(); + passwordEncoder + ).execute(); new CreateInitialLevers(leverRepo).execute(); new CreateIntialNodes(nodeRepo, groupRepo).execute(); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java index 06be654935..821d219844 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java @@ -21,7 +21,7 @@ import org.integratedmodelling.klab.hub.exception.LicenseGenerationError; import org.integratedmodelling.klab.hub.licenses.services.LicenseConfigService; import org.integratedmodelling.klab.hub.repository.MongoGroupRepository; -import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; +//import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; import org.integratedmodelling.klab.hub.users.services.UserProfileService; import org.integratedmodelling.klab.rest.EngineAuthenticationRequest; import org.integratedmodelling.klab.rest.EngineAuthenticationResponse; @@ -53,9 +53,9 @@ public class EngineLicenseController extends LicenseController token = tokenRepository.findByTokenString(tokenString); if(token.isPresent()) { diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java index 24068c7fbd..7f52d611d6 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java @@ -1,202 +1,202 @@ -package org.integratedmodelling.klab.hub.security; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.config.BeanIds; -import org.integratedmodelling.klab.exceptions.KlabAuthorizationException; -import org.integratedmodelling.klab.hub.security.oauth2.HttpCookieOAuth2AuthorizationRequestRepository; -import org.integratedmodelling.klab.hub.security.oauth2.OAuth2AuthenticationFailureHandler; -import org.integratedmodelling.klab.hub.security.oauth2.OAuth2AuthenticationSuccessHandler; -import org.integratedmodelling.klab.hub.service.OAuth2UserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.password.LdapShaPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.CorsConfigurationSource; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; -import com.google.common.collect.ImmutableList; -import com.google.common.net.HttpHeaders; - -@SuppressWarnings("deprecation") -@Configuration -@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true) -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - UserDetailsService userDetailsService; - - @Autowired - private JwtAuthenticationEntryPoint unauthorizedHandler; - - @Autowired - private OAuth2UserService oAuth2UserService; - - @Autowired - private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler; - - @Autowired - private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler; - - @Bean - public TokenAuthenticationFilter tokenAuthenticationFilter() { - return new TokenAuthenticationFilter(); - } - - - public static final String AUTHENTICATION_TOKEN_HEADER_NAME = "Authentication"; - - /** - * TODO incorporate this where? this allows us to assign our own HTTP response - * status code, by using an exception class which is annotated with it directly. - * (otherwise we would rely on Spring's container logic to assign a 'redirect' - * or other default status.) - */ - AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler() { - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, - AuthenticationException e) throws IOException, ServletException { - throw new KlabAuthorizationException("Authentication failed."); - } - }; - - @Bean - public HttpCookieOAuth2AuthorizationRequestRepository cookieAuthorizationRequestRepository() { - return new HttpCookieOAuth2AuthorizationRequestRepository(); - } - - /** - * this is necessary so that HubAuthenticationManager injection points can be - * populated. - */ - @Bean(BeanIds.AUTHENTICATION_MANAGER) - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - - @Override - public void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); - } - - - /** - * The allows our password encoder to have multiple entries. Allowing us to upgrade user - * passwords without needing to do some serious migration effort. It is possible that - * we will need to have users set a new password, or force the system to rehash the password - * when the user logs in. - * - * In the end there are limited possibilities in the options here. The better way would be - * to use a proper encoder and not some deprecated methodm but crowd can only handle one type - * of encrcyption at a time. - * - * - * String encodingId = "bcrypt"; Map encoders = new - * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); - * encoders.put("SHA512", new LdapShaPasswordEncoder()); - * DelegatingPasswordEncoder delegatingPasswordEncoder = new - * DelegatingPasswordEncoder(encodingId, encoders); - * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new - * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; - */ - @Bean - public PasswordEncoder passwordEncoder() { - return new LdapShaPasswordEncoder(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .cors() - .and() - .csrf() - .disable() - .exceptionHandling() - .authenticationEntryPoint(unauthorizedHandler) - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() - .antMatchers(HttpMethod.POST, HubRequestMatchers.getAuthentication()) - .permitAll() - .regexMatchers(HttpMethod.POST, HubRequestMatchers.getUsers()) - .permitAll() - .anyRequest() - .authenticated() - .and() - .oauth2Login() - .authorizationEndpoint() - .baseUri("/oauth2/authorize") - .authorizationRequestRepository(cookieAuthorizationRequestRepository()) - .and() - .redirectionEndpoint() - .baseUri("/oauth2/callback/*") - .and() - .userInfoEndpoint() - .userService(oAuth2UserService) - .and() - .successHandler(oAuth2AuthenticationSuccessHandler) - .failureHandler(oAuth2AuthenticationFailureHandler); - - http.csrf().disable().antMatcher("/api/**") - .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); - //.addFilterBefore(WebSecurityCorsFilter(), ChannelProcessingFilter.class); - } - -// Left here as a last resort -// public class WebSecurityCorsFilter implements Filter { -// @Override -// public void init(FilterConfig filterConfig) throws ServletException { -// } -// @Override -// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { -// HttpServletResponse res = (HttpServletResponse) response; -// res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control"); -// chain.doFilter(request, res); -// } -// @Override -// public void destroy() { -// } +//package org.integratedmodelling.klab.hub.security; +// +//import java.io.IOException; +//import java.util.Arrays; +//import java.util.Collections; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.springframework.security.config.BeanIds; +//import org.integratedmodelling.klab.exceptions.KlabAuthorizationException; +//import org.integratedmodelling.klab.hub.security.oauth2.HttpCookieOAuth2AuthorizationRequestRepository; +//import org.integratedmodelling.klab.hub.security.oauth2.OAuth2AuthenticationFailureHandler; +//import org.integratedmodelling.klab.hub.security.oauth2.OAuth2AuthenticationSuccessHandler; +//import org.integratedmodelling.klab.hub.service.OAuth2UserService; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.http.HttpMethod; +//import org.springframework.security.authentication.AuthenticationManager; +//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +//import org.springframework.security.config.annotation.web.builders.HttpSecurity; +//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +//import org.springframework.security.config.http.SessionCreationPolicy; +//import org.springframework.security.core.AuthenticationException; +//import org.springframework.security.core.userdetails.UserDetailsService; +//import org.springframework.security.crypto.password.LdapShaPasswordEncoder; +//import org.springframework.security.crypto.password.PasswordEncoder; +//import org.springframework.security.web.authentication.AuthenticationFailureHandler; +//import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +//import org.springframework.web.cors.CorsConfiguration; +//import org.springframework.web.cors.CorsConfigurationSource; +//import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +//import com.google.common.collect.ImmutableList; +//import com.google.common.net.HttpHeaders; +// +//@SuppressWarnings("deprecation") +//@Configuration +////@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true) +//public class WebSecurityConfig { +// +// @Autowired +// UserDetailsService userDetailsService; +// +// @Autowired +// private JwtAuthenticationEntryPoint unauthorizedHandler; +// +// @Autowired +// private OAuth2UserService oAuth2UserService; +// +// @Autowired +// private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler; +// +// @Autowired +// private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler; +// +// @Bean +// public TokenAuthenticationFilter tokenAuthenticationFilter() { +// return new TokenAuthenticationFilter(); // } - - @Bean - CorsConfigurationSource corsConfigurationSource() { - final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - final CorsConfiguration config = new CorsConfiguration(); - config.setAllowCredentials(false); - config.setAllowedOrigins(ImmutableList.of( - "https://integratedmodelling.org", - "http://localhost:8080", - "https://localhost:8080", - "http://localhost:8081", - "https://localhost:8081", - "http://localhost:8284", - "https://localhost:8284")); - config.setAllowedHeaders(Collections.singletonList("*")); - config.addExposedHeader("Content-disposition"); - config.addExposedHeader(HttpHeaders.LOCATION); - config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "HEAD")); - source.registerCorsConfiguration("/**", config); - return source; - } - -} \ No newline at end of file +// +// +// public static final String AUTHENTICATION_TOKEN_HEADER_NAME = "Authentication"; +// +// /** +// * TODO incorporate this where? this allows us to assign our own HTTP response +// * status code, by using an exception class which is annotated with it directly. +// * (otherwise we would rely on Spring's container logic to assign a 'redirect' +// * or other default status.) +// */ +// AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler() { +// @Override +// public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, +// AuthenticationException e) throws IOException, ServletException { +// throw new KlabAuthorizationException("Authentication failed."); +// } +// }; +// +// @Bean +// public HttpCookieOAuth2AuthorizationRequestRepository cookieAuthorizationRequestRepository() { +// return new HttpCookieOAuth2AuthorizationRequestRepository(); +// } +// +// /** +// * this is necessary so that HubAuthenticationManager injection points can be +// * populated. +// */ +//// @Bean(BeanIds.AUTHENTICATION_MANAGER) +//// @Override +//// public AuthenticationManager authenticationManagerBean() throws Exception { +//// return super.authenticationManagerBean(); +//// } +//// +//// @Override +//// public void configure(AuthenticationManagerBuilder auth) throws Exception { +//// auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); +//// } +// +// +// /** +// * The allows our password encoder to have multiple entries. Allowing us to upgrade user +// * passwords without needing to do some serious migration effort. It is possible that +// * we will need to have users set a new password, or force the system to rehash the password +// * when the user logs in. +// * +// * In the end there are limited possibilities in the options here. The better way would be +// * to use a proper encoder and not some deprecated methodm but crowd can only handle one type +// * of encrcyption at a time. +// * +// * +// * String encodingId = "bcrypt"; Map encoders = new +// * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); +// * encoders.put("SHA512", new LdapShaPasswordEncoder()); +// * DelegatingPasswordEncoder delegatingPasswordEncoder = new +// * DelegatingPasswordEncoder(encodingId, encoders); +// * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new +// * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; +// */ +// @Bean +// public PasswordEncoder passwordEncoder() { +// return new LdapShaPasswordEncoder(); +// } +// +//// @Override +//// protected void configure(HttpSecurity http) throws Exception { +//// http +//// .cors() +//// .and() +//// .csrf() +//// .disable() +//// .exceptionHandling() +//// .authenticationEntryPoint(unauthorizedHandler) +//// .and() +//// .sessionManagement() +//// .sessionCreationPolicy(SessionCreationPolicy.STATELESS) +//// .and() +//// .authorizeRequests() +//// .antMatchers(HttpMethod.POST, HubRequestMatchers.getAuthentication()) +//// .permitAll() +//// .regexMatchers(HttpMethod.POST, HubRequestMatchers.getUsers()) +//// .permitAll() +//// .anyRequest() +//// .authenticated() +//// .and() +//// .oauth2Login() +//// .authorizationEndpoint() +//// .baseUri("/oauth2/authorize") +//// .authorizationRequestRepository(cookieAuthorizationRequestRepository()) +//// .and() +//// .redirectionEndpoint() +//// .baseUri("/oauth2/callback/*") +//// .and() +//// .userInfoEndpoint() +//// .userService(oAuth2UserService) +//// .and() +//// .successHandler(oAuth2AuthenticationSuccessHandler) +//// .failureHandler(oAuth2AuthenticationFailureHandler); +//// +//// http.csrf().disable().antMatcher("/api/**") +//// .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); +//// //.addFilterBefore(WebSecurityCorsFilter(), ChannelProcessingFilter.class); +//// } +// +//// Left here as a last resort +//// public class WebSecurityCorsFilter implements Filter { +//// @Override +//// public void init(FilterConfig filterConfig) throws ServletException { +//// } +//// @Override +//// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { +//// HttpServletResponse res = (HttpServletResponse) response; +//// res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control"); +//// chain.doFilter(request, res); +//// } +//// @Override +//// public void destroy() { +//// } +//// } +// +//// @Bean +//// CorsConfigurationSource corsConfigurationSource() { +//// final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); +//// final CorsConfiguration config = new CorsConfiguration(); +//// config.setAllowCredentials(false); +//// config.setAllowedOrigins(ImmutableList.of( +//// "https://integratedmodelling.org", +//// "http://localhost:8080", +//// "https://localhost:8080", +//// "http://localhost:8081", +//// "https://localhost:8081", +//// "http://localhost:8284", +//// "https://localhost:8284")); +//// config.setAllowedHeaders(Collections.singletonList("*")); +//// config.addExposedHeader("Content-disposition"); +//// config.addExposedHeader(HttpHeaders.LOCATION); +//// config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "HEAD")); +//// source.registerCorsConfiguration("/**", config); +//// return source; +//// } +// +//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java index b537eea1b7..285b22275a 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java @@ -1,60 +1,60 @@ -package org.integratedmodelling.klab.hub.security.oauth2; - -import java.io.IOException; -import java.io.PrintWriter; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.integratedmodelling.klab.hub.api.TokenAuthentication; -import org.integratedmodelling.klab.hub.api.TokenType; -import org.integratedmodelling.klab.hub.api.ProfileResource; -import org.integratedmodelling.klab.hub.config.LinkConfig; -import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.stereotype.Component; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Component -public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler { - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - UserAuthTokenService userAuthTokenService; - - @Autowired - LinkConfig tokenClickbackConfig; - - @Autowired - OAuth2AuthenticationSuccessHandler(MappingJackson2HttpMessageConverter messageConverter) { - this.objectMapper = messageConverter.getObjectMapper(); - } - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) throws IOException, ServletException { - OAuth2AuthenticationToken oAuthToken = (OAuth2AuthenticationToken) authentication; - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - ProfileResource profile = (ProfileResource) authentication.getPrincipal(); - TokenAuthentication token = userAuthTokenService.createToken(profile.getUsername(), TokenType.auth); - String profileString = objectMapper.writeValueAsString(profile); - response.setHeader("Authorization", token.getTokenString()); - String redirect = String.format( - "%s/%s?token=%s", - tokenClickbackConfig.getCallbackUrl().toString(), - oAuthToken.getAuthorizedClientRegistrationId(), - token.getTokenString()); - response.sendRedirect(redirect); - PrintWriter out = response.getWriter(); - out.print(profileString); - out.flush(); - } - -} \ No newline at end of file +//package org.integratedmodelling.klab.hub.security.oauth2; +// +//import java.io.IOException; +//import java.io.PrintWriter; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.integratedmodelling.klab.hub.api.TokenAuthentication; +//import org.integratedmodelling.klab.hub.api.TokenType; +//import org.integratedmodelling.klab.hub.api.ProfileResource; +//import org.integratedmodelling.klab.hub.config.LinkConfig; +//import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +//import org.springframework.security.core.Authentication; +//import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +//import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +//import org.springframework.stereotype.Component; +//import com.fasterxml.jackson.databind.ObjectMapper; +// +//@Component +//public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler { +// +// @Autowired +// private ObjectMapper objectMapper; +// +// @Autowired +// UserAuthTokenService userAuthTokenService; +// +// @Autowired +// LinkConfig tokenClickbackConfig; +// +// @Autowired +// OAuth2AuthenticationSuccessHandler(MappingJackson2HttpMessageConverter messageConverter) { +// this.objectMapper = messageConverter.getObjectMapper(); +// } +// +// @Override +// public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, +// Authentication authentication) throws IOException, ServletException { +// OAuth2AuthenticationToken oAuthToken = (OAuth2AuthenticationToken) authentication; +// response.setStatus(HttpServletResponse.SC_OK); +// response.setContentType("application/json"); +// ProfileResource profile = (ProfileResource) authentication.getPrincipal(); +// TokenAuthentication token = userAuthTokenService.createToken(profile.getUsername(), TokenType.auth); +// String profileString = objectMapper.writeValueAsString(profile); +// response.setHeader("Authorization", token.getTokenString()); +// String redirect = String.format( +// "%s/%s?token=%s", +// tokenClickbackConfig.getCallbackUrl().toString(), +// oAuthToken.getAuthorizedClientRegistrationId(), +// token.getTokenString()); +// response.sendRedirect(redirect); +// PrintWriter out = response.getWriter(); +// out.print(profileString); +// out.flush(); +// } +// +//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java index 4a8e724fd5..a2cf773de9 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java @@ -1,16 +1,16 @@ -package org.integratedmodelling.klab.hub.tokens.services; - -import org.integratedmodelling.klab.hub.api.TokenAuthentication; -import org.integratedmodelling.klab.hub.payload.LoginResponse; -import org.integratedmodelling.klab.hub.payload.LogoutResponse; -import org.springframework.stereotype.Service; - -@Service -public interface UserAuthTokenService extends TokenBaseService { - public TokenAuthentication getUserAuthenticationToken(String username, String password); - - public LoginResponse getAuthResponse(String username, String password); - - public LogoutResponse getLogoutResponse(String token); - -} +//package org.integratedmodelling.klab.hub.tokens.services; +// +//import org.integratedmodelling.klab.hub.api.TokenAuthentication; +//import org.integratedmodelling.klab.hub.payload.LoginResponse; +//import org.integratedmodelling.klab.hub.payload.LogoutResponse; +//import org.springframework.stereotype.Service; +// +//@Service +//public interface UserAuthTokenService extends TokenBaseService { +// public TokenAuthentication getUserAuthenticationToken(String username, String password); +// +// public LoginResponse getAuthResponse(String username, String password); +// +// public LogoutResponse getLogoutResponse(String token); +// +//} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java index 159c6d8ca2..1a7d1063ba 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java @@ -1,115 +1,115 @@ -package org.integratedmodelling.klab.hub.tokens.services; - -import java.util.List; - -import java.util.Optional; - -import org.integratedmodelling.klab.exceptions.KlabException; -import org.integratedmodelling.klab.hub.api.TokenAuthentication; -import org.integratedmodelling.klab.hub.api.ProfileResource; -import org.integratedmodelling.klab.hub.api.TokenType; -import org.integratedmodelling.klab.hub.api.User; -import org.integratedmodelling.klab.hub.commands.CreateUserAuthenticationToken; -import org.integratedmodelling.klab.hub.commands.DeleteAuthenticationToken; -import org.integratedmodelling.klab.hub.commands.GetUserProfile; -import org.integratedmodelling.klab.hub.exception.AuthenticationFailedException; -import org.integratedmodelling.klab.hub.exception.LoginFailedExcepetion; -import org.integratedmodelling.klab.hub.payload.LoginResponse; -import org.integratedmodelling.klab.hub.payload.LogoutResponse; -import org.integratedmodelling.klab.hub.repository.TokenRepository; -import org.integratedmodelling.klab.hub.repository.UserRepository; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.stereotype.Service; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@Service -public class UserAuthTokenServiceImpl implements UserAuthTokenService{ - - private AuthenticationManager authenticationManager; - - private UserRepository userRepository; - - private TokenRepository tokenRepository; - - private ObjectMapper objectMapper; - - public UserAuthTokenServiceImpl(AuthenticationManager authenticationManager, UserRepository userRepository, - TokenRepository tokenRepository, ObjectMapper objectMapper) { - super(); - this.authenticationManager = authenticationManager; - this.userRepository = userRepository; - this.tokenRepository = tokenRepository; - this.objectMapper = objectMapper; - } - - @Override - public TokenAuthentication createToken(String username, TokenType type) { - if(TokenType.auth == type) { - TokenAuthentication token = null; - Optional user = userRepository.findByNameIgnoreCase(username); - if(user.isPresent()) { - token = new CreateUserAuthenticationToken(tokenRepository, user.get()).execute(); - } - return token; - } else { - throw new AuthenticationFailedException("Incorrect workflow for creating token"); - } - } - - - @Override - public void deleteToken(String tokenString) { - new DeleteAuthenticationToken(tokenRepository, tokenString).execute(); - } - - private void deleteExpiredTokens(String username) { - List dbTokens = tokenRepository.findByUsername(username); - for (TokenAuthentication dbToken : dbTokens) { - if (dbToken.isExpired()) { - deleteToken(dbToken.getTokenString()); - } - } - } - - @Override - public TokenAuthentication getUserAuthenticationToken(String username, String password) { - Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password); - try { - authRequest = authenticationManager.authenticate(authRequest); - } catch (AuthenticationException e) { - throw new LoginFailedExcepetion(username); - } - if (!authRequest.isAuthenticated()) { - String msg = "Something went wrong with authentication. Result.isAuthenticated() == false, but no exception was thrown."; - throw new KlabException(msg); - } else { - deleteExpiredTokens(username); - TokenAuthentication result = createToken(username, TokenType.auth); - PreAuthenticatedAuthenticationToken secureToken = new PreAuthenticatedAuthenticationToken(result.getPrincipal(),result.getCredentials(),result.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(secureToken); - return result; - } - } - - @Override - public LoginResponse getAuthResponse(String username, String password) { - TokenAuthentication token = getUserAuthenticationToken(username, password); - ProfileResource profile = new GetUserProfile(userRepository, username, objectMapper).execute(); - LoginResponse response = new LoginResponse(token, profile.getSafeProfile()); - return response; - } - - @Override - public LogoutResponse getLogoutResponse(String token) { - deleteToken(token); - String username = SecurityContextHolder.getContext().getAuthentication().getName(); - return new LogoutResponse(username); - } - -} +//package org.integratedmodelling.klab.hub.tokens.services; +// +//import java.util.List; +// +//import java.util.Optional; +// +//import org.integratedmodelling.klab.exceptions.KlabException; +//import org.integratedmodelling.klab.hub.api.TokenAuthentication; +//import org.integratedmodelling.klab.hub.api.ProfileResource; +//import org.integratedmodelling.klab.hub.api.TokenType; +//import org.integratedmodelling.klab.hub.api.User; +//import org.integratedmodelling.klab.hub.commands.CreateUserAuthenticationToken; +//import org.integratedmodelling.klab.hub.commands.DeleteAuthenticationToken; +//import org.integratedmodelling.klab.hub.commands.GetUserProfile; +//import org.integratedmodelling.klab.hub.exception.AuthenticationFailedException; +//import org.integratedmodelling.klab.hub.exception.LoginFailedExcepetion; +//import org.integratedmodelling.klab.hub.payload.LoginResponse; +//import org.integratedmodelling.klab.hub.payload.LogoutResponse; +//import org.integratedmodelling.klab.hub.repository.TokenRepository; +//import org.integratedmodelling.klab.hub.repository.UserRepository; +//import org.springframework.security.authentication.AuthenticationManager; +//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +//import org.springframework.security.core.Authentication; +//import org.springframework.security.core.AuthenticationException; +//import org.springframework.security.core.context.SecurityContextHolder; +//import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +//import org.springframework.stereotype.Service; +// +//import com.fasterxml.jackson.databind.ObjectMapper; +// +//@Service +//public class UserAuthTokenServiceImpl implements UserAuthTokenService{ +// +// private AuthenticationManager authenticationManager; +// +// private UserRepository userRepository; +// +// private TokenRepository tokenRepository; +// +// private ObjectMapper objectMapper; +// +// public UserAuthTokenServiceImpl(AuthenticationManager authenticationManager, UserRepository userRepository, +// TokenRepository tokenRepository, ObjectMapper objectMapper) { +// super(); +// this.authenticationManager = authenticationManager; +// this.userRepository = userRepository; +// this.tokenRepository = tokenRepository; +// this.objectMapper = objectMapper; +// } +// +// @Override +// public TokenAuthentication createToken(String username, TokenType type) { +// if(TokenType.auth == type) { +// TokenAuthentication token = null; +// Optional user = userRepository.findByNameIgnoreCase(username); +// if(user.isPresent()) { +// token = new CreateUserAuthenticationToken(tokenRepository, user.get()).execute(); +// } +// return token; +// } else { +// throw new AuthenticationFailedException("Incorrect workflow for creating token"); +// } +// } +// +// +// @Override +// public void deleteToken(String tokenString) { +// new DeleteAuthenticationToken(tokenRepository, tokenString).execute(); +// } +// +// private void deleteExpiredTokens(String username) { +// List dbTokens = tokenRepository.findByUsername(username); +// for (TokenAuthentication dbToken : dbTokens) { +// if (dbToken.isExpired()) { +// deleteToken(dbToken.getTokenString()); +// } +// } +// } +// +// @Override +// public TokenAuthentication getUserAuthenticationToken(String username, String password) { +// Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password); +// try { +// authRequest = authenticationManager.authenticate(authRequest); +// } catch (AuthenticationException e) { +// throw new LoginFailedExcepetion(username); +// } +// if (!authRequest.isAuthenticated()) { +// String msg = "Something went wrong with authentication. Result.isAuthenticated() == false, but no exception was thrown."; +// throw new KlabException(msg); +// } else { +// deleteExpiredTokens(username); +// TokenAuthentication result = createToken(username, TokenType.auth); +// PreAuthenticatedAuthenticationToken secureToken = new PreAuthenticatedAuthenticationToken(result.getPrincipal(),result.getCredentials(),result.getAuthorities()); +// SecurityContextHolder.getContext().setAuthentication(secureToken); +// return result; +// } +// } +// +// @Override +// public LoginResponse getAuthResponse(String username, String password) { +// TokenAuthentication token = getUserAuthenticationToken(username, password); +// ProfileResource profile = new GetUserProfile(userRepository, username, objectMapper).execute(); +// LoginResponse response = new LoginResponse(token, profile.getSafeProfile()); +// return response; +// } +// +// @Override +// public LogoutResponse getLogoutResponse(String token) { +// deleteToken(token); +// String username = SecurityContextHolder.getContext().getAuthentication().getName(); +// return new LogoutResponse(username); +// } +// +//} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java index 783771841c..73c224605a 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java @@ -3,7 +3,7 @@ import org.integratedmodelling.klab.api.API; import org.integratedmodelling.klab.hub.payload.LoginResponse; import org.integratedmodelling.klab.hub.payload.LogoutResponse; -import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; +//import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; import org.integratedmodelling.klab.rest.UserAuthenticationRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -14,24 +14,34 @@ @RestController public class UserAuthenticationController { + + - private UserAuthTokenService userAuthService; +// private UserAuthTokenService userAuthService; +// +// @Autowired +// UserAuthenticationController(UserAuthTokenService userAuthService) { +// this.userAuthService = userAuthService; +// } - @Autowired - UserAuthenticationController(UserAuthTokenService userAuthService) { - this.userAuthService = userAuthService; - } +// @PostMapping(API.HUB.AUTHENTICATE_USER) +// public ResponseEntity loginResponse(@RequestBody UserAuthenticationRequest request) { +// LoginResponse response = userAuthService.getAuthResponse(request.getUsername(), request.getPassword()); +// return response.getResponse(); +// } @PostMapping(API.HUB.AUTHENTICATE_USER) - public ResponseEntity loginResponse(@RequestBody UserAuthenticationRequest request) { - LoginResponse response = userAuthService.getAuthResponse(request.getUsername(), request.getPassword()); - return response.getResponse(); - } + public ResponseEntity loginResponse() { + System.out.println("holis"); +// LoginResponse response = userAuthService.getAuthResponse("", ""); +// return response.getResponse(); + return null; + } - @PostMapping(API.HUB.DEAUTHENTICATE_USER) - public ResponseEntity logoutResponse(@RequestHeader("Authentication") String token) { - LogoutResponse response = userAuthService.getLogoutResponse(token); - return response.getResponse(); - } +// @PostMapping(API.HUB.DEAUTHENTICATE_USER) +// public ResponseEntity logoutResponse(@RequestHeader("Authentication") String token) { +// LogoutResponse response = userAuthService.getLogoutResponse(token); +// return response.getResponse(); +// } } diff --git a/klab.hub/src/main/resources/application.yml b/klab.hub/src/main/resources/application.yml index 4df68014a9..159cc5c752 100644 --- a/klab.hub/src/main/resources/application.yml +++ b/klab.hub/src/main/resources/application.yml @@ -1,7 +1,7 @@ server: port: 8284 servlet: - contextPath: /hub + contextPath: /hub spring: cloud: @@ -29,25 +29,25 @@ spring: enabled: true profiles: default: true - security: - oauth2: - client: - registration: - google: - clientId: 395263683724-koqd6u0bh04c44fal2darevl1p7717g0.apps.googleusercontent.com - clientSecret: M1OCx0qI_HbXmes0J26oCzXV - redirectUriTemplate: '{baseUrl}/oauth2/callback/{registrationId}' - scope: - - email - - profile - + #security: + # oauth2: + # client: + # registration: + # google: + # clientId: 395263683724-koqd6u0bh04c44fal2darevl1p7717g0.apps.googleusercontent.com + # clientSecret: M1OCx0qI_HbXmes0J26oCzXV + # redirectUriTemplate: '{baseUrl}/oauth2/callback/{registrationId}' + # scope: + # - email + # - profile + mongo: hostname: localhost port: 27017 - + logging: file: hub.log - + site: callback: http://localhost:8080/#/callback clickback: "/clickback/{tokenString}" @@ -56,7 +56,7 @@ site: url: http://localhost/hub/ server: id: im - + engine: url: https://localhost:8287 @@ -76,7 +76,7 @@ email: emailaddress: Admin noreply: emailaddress: No reply - + license: userId: "Klab Hub (This is the key for the Dev Hub) " password: password @@ -92,4 +92,8 @@ license: filename: "keyring/PubRing.pgp" digest: "cad134cc3dfcb0e96acb90af56532a96171f858c4c30335541932c0e00a66c9deab764805d9b9f08a49619af211b96305b512d4cf256e8a9c29877d06d207c72" - \ No newline at end of file +keycloak: + realm: SpringBootKleycloak + auth-server-url: https://login.integratedmodelling.org + resource: spring-boot-keycloack-client + bearer-only: true From 175daa61f8a35836872a1719cac2c64900149b87 Mon Sep 17 00:00:00 2001 From: kristina Date: Mon, 14 Nov 2022 12:03:29 +0100 Subject: [PATCH 02/10] Add Keycloak @PreAuthorized and Keycloak management --- .../klab/hub/commands/CreateInitialUsers.java | 225 +++++++++--------- .../klab/hub/config/KeycloakConfig.java | 23 ++ ...CustomMethodSecurityExpressionHandler.java | 10 + .../klab/hub/security/HubRequestMatchers.java | 64 ++--- .../security/TokenAuthenticationFilter.java | 134 +++++------ .../klab/hub/security/WebSecurityConfig.java | 202 ---------------- .../WebSecurityConfiguration.java | 9 +- .../KeycloakMethodSecurityExpression.java | 62 +++++ ...ycloakMethodSecurityExpressionHandler.java | 58 +++++ .../service/KeycloakSecurityService.java | 39 +++ .../klab/hub/service/OAuth2UserService.java | 194 +++++++-------- .../controllers/ModifyGroupsController.java | 4 +- .../tasks/controllers/TasksController.java | 6 +- .../tokens/services/UserAuthTokenService.java | 28 +-- .../UserAuthenticationController.java | 55 ++++- .../controllers/UserProfileController.java | 87 ++++--- .../services/UserProfileServiceImpl.java | 21 +- klab.hub/src/main/resources/application.yml | 3 + 18 files changed, 640 insertions(+), 584 deletions(-) create mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/KeycloakConfig.java create mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/CustomMethodSecurityExpressionHandler.java delete mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java rename klab.hub/src/main/java/org/integratedmodelling/klab/hub/{config => security}/WebSecurityConfiguration.java (92%) create mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/method/KeycloakMethodSecurityExpression.java create mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/methodHandler/KeycloakMethodSecurityExpressionHandler.java create mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/service/KeycloakSecurityService.java diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java index 91415342c7..76526d085b 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java @@ -20,46 +20,44 @@ import org.springframework.security.ldap.userdetails.LdapUserDetailsManager; public class CreateInitialUsers { - - private MongoGroupRepository groupRepository; - private UserRepository userRepository; - private LdapUserDetailsManager ldapUserDetailsManager; - private PasswordEncoder passwordEncoder; - - public CreateInitialUsers(MongoGroupRepository groupRepository, - UserRepository userRepository, - LdapUserDetailsManager ldapUserDetailsManager, - PasswordEncoder passwordEncoder) { - this.groupRepository = groupRepository; - this.userRepository = userRepository; - this.ldapUserDetailsManager = ldapUserDetailsManager; - this.passwordEncoder = passwordEncoder; - } - - public void execute() { - createInitialUsers(); - } - - private static final List initialUsers = new ArrayList(100); - - private static final User system = testUser("system", "password", "test.bc3@integratedmodelling.org", "Joe", - "Robot", Role.ROLE_USER, Role.ROLE_ADMINISTRATOR, Role.ROLE_SYSTEM); - - private static final User hades = testUser("hades", "password", "hades@integratedmodelling.org", "Hades", - "of Greece", Role.ROLE_USER, Role.ROLE_ADMINISTRATOR); - - private static final User developerS = testUser("srwohl", "password", "steven.wohl@bc3research.org", - "Hercules", "of Rome", Role.ROLE_USER); - - private static final User developerE = testUser("enrico", "password", "enrico.girotto@bc3research.org", - "Enrico", "of Venice", Role.ROLE_USER); - - private static final User achilles_activeMissingLdap = testUser("achilles", "password", - "achilles@integratedmodelling.org", "Achilles", "of Greece", Role.ROLE_USER); - - private static final User triton_pendingMissingLdap = testUser("triton", "password", - "triton@integratedmodelling.org", "Triton", "of Greece", Role.ROLE_USER); - + + private MongoGroupRepository groupRepository; + private UserRepository userRepository; + private LdapUserDetailsManager ldapUserDetailsManager; + private PasswordEncoder passwordEncoder; + + public CreateInitialUsers(MongoGroupRepository groupRepository, UserRepository userRepository, + LdapUserDetailsManager ldapUserDetailsManager, PasswordEncoder passwordEncoder) { + this.groupRepository = groupRepository; + this.userRepository = userRepository; + this.ldapUserDetailsManager = ldapUserDetailsManager; + this.passwordEncoder = passwordEncoder; + } + + public void execute() { + createInitialUsers(); + } + + private static final List initialUsers = new ArrayList(100); + + private static final User system = testUser("system", "password", "test.bc3@integratedmodelling.org", "Joe", "Robot", + Role.ROLE_USER, Role.ROLE_ADMINISTRATOR, Role.ROLE_SYSTEM); + + private static final User hades = testUser("hades", "password", "hades@integratedmodelling.org", "Hades", "of Greece", + Role.ROLE_USER, Role.ROLE_ADMINISTRATOR); + + private static final User developerS = testUser("kristina", "kristina", "kristina.sanchez@bc3research.org", "Hercules", + "of Rome", Role.ROLE_USER, Role.ROLE_ADMINISTRATOR); + + private static final User developerE = testUser("enrico", "password", "enrico.girotto@bc3research.org", "Enrico", "of Venice", + Role.ROLE_USER); + + private static final User achilles_activeMissingLdap = testUser("achilles", "password", "achilles@integratedmodelling.org", + "Achilles", "of Greece", Role.ROLE_USER); + + private static final User triton_pendingMissingLdap = testUser("triton", "password", "triton@integratedmodelling.org", + "Triton", "of Greece", Role.ROLE_USER); + private static User testUser(String username, String password, String email, String firstName, String lastName, Role... roles) { User result = new User(); @@ -74,9 +72,9 @@ private static User testUser(String username, String password, String email, Str result.setPasswordHash(password); return result; } - + private static final DateTime generateRandomDate(DateTime from) { - GregorianCalendar gc = new GregorianCalendar(); + GregorianCalendar gc = new GregorianCalendar(); int year = randBetween(from != null ? from.getYear() : 2015, 2019); gc.set(Calendar.YEAR, year); int dayOfYear = randBetween(from != null ? from.getDayOfYear() : 1, gc.getActualMaximum(Calendar.DAY_OF_YEAR)); @@ -87,61 +85,64 @@ private static final DateTime generateRandomDate(DateTime from) { gc.set(Calendar.MINUTE, minute); return new DateTime(gc); } - + private static int randBetween(int start, int end) { - return start + (int)Math.round(Math.random() * (end - start)); + return start + (int) Math.round(Math.random() * (end - start)); } - + private List getInitialUsers() { - GroupEntry im = new GroupEntry(new GetMongoGroupByName("IM", groupRepository).execute()); - GroupEntry aries = new GroupEntry(new GetMongoGroupByName("ARIES", groupRepository).execute(), DateTime.now().minusDays(20)); - GroupEntry alice = new GroupEntry(new GetMongoGroupByName("ALICE", groupRepository).execute()); - GroupEntry seea = new GroupEntry(new GetMongoGroupByName("SEEA", groupRepository).execute(), DateTime.now().plusDays(10)); - Set entries = new HashSet(); - entries.add(im); - entries.add(aries); - entries.add(alice); - for (int i = 0; i<100; i++) { - User u = testUser("User-"+i, "password", "user-"+i+"@integratedmodelling.org", "Name"+i, "Last"+i, Role.ROLE_USER); - int x = (int)(Math.random()*100+1); - if (x < 2) - u.addRoles(Role.ROLE_SYSTEM); // less than 2% are system - if (x < 5) - u.addRoles(Role.ROLE_ADMINISTRATOR); // less than 5% are administrator - if (x < 7) - u.addRoles(Role.ROLE_DATA_MANAGER); // less than 7% are data manager - x = (int)(Math.random()*100+1); - if (x <= 80) { - u.addGroupEntries(im); // 80% has IM and ARIES. If no IM and ARIES, no groups for now - u.addGroupEntries(aries); - x = (int)(Math.random()*100+1); - if (x < 22) { - for (int j = 0; j<=x; j++) { - u.addGroupEntries(alice); // multiple groups - } - } - } - x = (int)(Math.random()*100+1); - if (x <= 5) { // 5% pending activation - u.setAccountStatus(AccountStatus.pendingActivation); - u.setLastLogin(null); - u.setRegistrationDate(null); - } - if (x >= 6 && x <= 8) { // not pending but no registration date (legacy problem) - u.setRegistrationDate(null); - } - if (u.getAccountStatus() != AccountStatus.pendingActivation) { - x = (int)(Math.random()*100+1); - if (x < 5) { // less than 5% with no last login - u.setLastLogin(null); - } - } - x = (int)(Math.random()*100+1); - if (x<=20) { - u.setSendUpdates(false); - } - initialUsers.add(u); - } + GroupEntry im = new GroupEntry(new GetMongoGroupByName("IM", groupRepository).execute()); + GroupEntry aries = new GroupEntry(new GetMongoGroupByName("ARIES", groupRepository).execute(), + DateTime.now().minusDays(20)); + GroupEntry alice = new GroupEntry(new GetMongoGroupByName("ALICE", groupRepository).execute()); + GroupEntry seea = new GroupEntry(new GetMongoGroupByName("SEEA", groupRepository).execute(), DateTime.now().plusDays(10)); + Set entries = new HashSet(); + entries.add(im); + entries.add(aries); + entries.add(alice); + for(int i = 0; i < 100; i++) { + User u = testUser("user" + i, "password", "user-" + i + "@integratedmodelling.org", "Name" + i, "Last" + i, + Role.ROLE_USER); + int x = (int) (Math.random() * 100 + 1); + if (x < 2) + u.addRoles(Role.ROLE_SYSTEM); // less than 2% are system + if (x < 5) + u.addRoles(Role.ROLE_ADMINISTRATOR); // less than 5% are administrator + if (x < 7) + u.addRoles(Role.ROLE_DATA_MANAGER); // less than 7% are data manager + x = (int) (Math.random() * 100 + 1); + if (x <= 80) { + u.addGroupEntries(im); // 80% has IM and ARIES. If no IM and ARIES, no groups for + // now + u.addGroupEntries(aries); + x = (int) (Math.random() * 100 + 1); + if (x < 22) { + for(int j = 0; j <= x; j++) { + u.addGroupEntries(alice); // multiple groups + } + } + } + x = (int) (Math.random() * 100 + 1); + if (x <= 5) { // 5% pending activation + u.setAccountStatus(AccountStatus.pendingActivation); + u.setLastLogin(null); + u.setRegistrationDate(null); + } + if (x >= 6 && x <= 8) { // not pending but no registration date (legacy problem) + u.setRegistrationDate(null); + } + if (u.getAccountStatus() != AccountStatus.pendingActivation) { + x = (int) (Math.random() * 100 + 1); + if (x < 5) { // less than 5% with no last login + u.setLastLogin(null); + } + } + x = (int) (Math.random() * 100 + 1); + if (x <= 20) { + u.setSendUpdates(false); + } + initialUsers.add(u); + } system.addGroupEntries(aries); system.addGroupEntries(im); system.addGroupEntries(alice); @@ -164,24 +165,24 @@ private List getInitialUsers() { initialUsers.add(triton_pendingMissingLdap); return initialUsers; } - + private void createInitialUsers() { - List users = getInitialUsers(); - for(User user : users) { - try { - //This is our legacy password encoding - user = new SetUserPasswordHash(user, user.getPasswordHash(),this.passwordEncoder).execute(); - User newUser = new CreateUserWithRolesAndStatus(user, userRepository, ldapUserDetailsManager).execute(); - if (newUser.getLastLogin() != null) { - int x = (int)(Math.random()*100+1); - if (x>=5) // less than 5% not connected - newUser.setLastConnection(generateRandomDate(newUser.getLastLogin())); - } - new UpdateUser(user, userRepository).execute(); - } catch (Exception e) { - Logging.INSTANCE.error(e); - } - } - } + List users = getInitialUsers(); + for(User user : users) { + try { + // This is our legacy password encoding + user = new SetUserPasswordHash(user, user.getPasswordHash(), this.passwordEncoder).execute(); + User newUser = new CreateUserWithRolesAndStatus(user, userRepository, ldapUserDetailsManager).execute(); + if (newUser.getLastLogin() != null) { + int x = (int) (Math.random() * 100 + 1); + if (x >= 5) // less than 5% not connected + newUser.setLastConnection(generateRandomDate(newUser.getLastLogin())); + } + new UpdateUser(user, userRepository).execute(); + } catch (Exception e) { + Logging.INSTANCE.error(e); + } + } + } } diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/KeycloakConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/KeycloakConfig.java new file mode 100644 index 0000000000..275c3f5d77 --- /dev/null +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/KeycloakConfig.java @@ -0,0 +1,23 @@ +package org.integratedmodelling.klab.hub.config; + +import org.integratedmodelling.klab.hub.security.keycloak.methodHandler.KeycloakMethodSecurityExpressionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true, +securedEnabled= true) +public class KeycloakConfig extends GlobalMethodSecurityConfiguration { + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + KeycloakMethodSecurityExpressionHandler expressionHandler = + new KeycloakMethodSecurityExpressionHandler(); + //expressionHandler.setPermissionEvaluator(new KeycloakMethodSecurityExpressionHandler()); + return expressionHandler; + } + } + diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/CustomMethodSecurityExpressionHandler.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/CustomMethodSecurityExpressionHandler.java new file mode 100644 index 0000000000..a3219e5dd7 --- /dev/null +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/CustomMethodSecurityExpressionHandler.java @@ -0,0 +1,10 @@ +//package org.integratedmodelling.klab.hub.security; +//public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler { +// +// @Override +// protected MethodSecurityExpressionOperations createSecurityExpressionRoot( +// Authentication authentication, MethodInvocation invocation) { +// CustomMethodSecurityExpression custom = new CustomMethodSecurityExpression(authentication); +// return custom; +// } +//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/HubRequestMatchers.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/HubRequestMatchers.java index 3d132205bd..4abf36f0a1 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/HubRequestMatchers.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/HubRequestMatchers.java @@ -1,32 +1,32 @@ -package org.integratedmodelling.klab.hub.security; - -import org.integratedmodelling.klab.api.API; - -public final class HubRequestMatchers { - - private static final String[] authentication = new String[] { - API.HUB.AUTHENTICATE_ENGINE, - API.HUB.AUTHENTICATE_LEVER, - API.HUB.AUTHENTICATE_NODE, - API.HUB.AUTHENTICATE_USER, - API.HUB.LEGACY_AUTHENTICATE_ENGINE - }; - - private static final String[] users = new String[] { - API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_ACTIVATION + ".*", - API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_LOST_PASSWORD + ".*", - API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_SET_PASSWORD + ".*", - API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_VERIFICATION + ".*", - API.HUB.USER_BASE+"$" - }; - - public static String[] getAuthentication() { - return authentication; - } - - public static String[] getUsers() { - return users; - } - - -} +//package org.integratedmodelling.klab.hub.security; +// +//import org.integratedmodelling.klab.api.API; +// +//public final class HubRequestMatchers { +// +// private static final String[] authentication = new String[] { +// API.HUB.AUTHENTICATE_ENGINE, +// API.HUB.AUTHENTICATE_LEVER, +// API.HUB.AUTHENTICATE_NODE, +// API.HUB.AUTHENTICATE_USER, +// API.HUB.LEGACY_AUTHENTICATE_ENGINE +// }; +// +// private static final String[] users = new String[] { +// API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_ACTIVATION + ".*", +// API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_LOST_PASSWORD + ".*", +// API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_SET_PASSWORD + ".*", +// API.HUB.USER_BASE+".*" + API.HUB.PARAMETERS.USER_VERIFICATION + ".*", +// API.HUB.USER_BASE+"$" +// }; +// +// public static String[] getAuthentication() { +// return authentication; +// } +// +// public static String[] getUsers() { +// return users; +// } +// +// +//} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/TokenAuthenticationFilter.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/TokenAuthenticationFilter.java index f8b10a96ac..345572a4aa 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/TokenAuthenticationFilter.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/TokenAuthenticationFilter.java @@ -1,67 +1,67 @@ -package org.integratedmodelling.klab.hub.security; - -import java.io.IOException; -import java.util.Optional; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -import org.integratedmodelling.klab.Logging; -import org.integratedmodelling.klab.hub.api.TokenAuthentication; -import org.integratedmodelling.klab.hub.repository.TokenRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; - - -public class TokenAuthenticationFilter implements Filter { - public static final String AUTHENTICATION_TOKEN_HEADER_NAME = "Authentication"; - - - @Autowired - private TokenRepository tokenRepository; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - try { - - String tokenString = ((HttpServletRequest) request) - .getHeader(AUTHENTICATION_TOKEN_HEADER_NAME); - if (tokenString != null) { - Optional token = tokenRepository.findByTokenString(tokenString); - if(token.isPresent()) { - TokenAuthentication storedToken = token.get(); - if (storedToken.isAuthenticated()) { - PreAuthenticatedAuthenticationToken authToken = new PreAuthenticatedAuthenticationToken(storedToken.getPrincipal() - ,storedToken.getCredentials(),storedToken.getAuthorities()); - // successful match. token should contain everything the security context needs. - SecurityContextHolder.getContext().setAuthentication(authToken); - } - } - } - } catch (Throwable e) { - Logging.INSTANCE.error("Could not set user authentication in security context " + e.toString()); - } finally { - SecurityContextHolder.getContext(); - chain.doFilter(request, response); - } - - } - - @Override - public void destroy() { - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - System.out.println("Initialized TokenHeaderProcessingFilter"); - } - - -} \ No newline at end of file +//package org.integratedmodelling.klab.hub.security; +// +//import java.io.IOException; +//import java.util.Optional; +// +//import javax.servlet.Filter; +//import javax.servlet.FilterChain; +//import javax.servlet.FilterConfig; +//import javax.servlet.ServletException; +//import javax.servlet.ServletRequest; +//import javax.servlet.ServletResponse; +//import javax.servlet.http.HttpServletRequest; +// +//import org.integratedmodelling.klab.Logging; +//import org.integratedmodelling.klab.hub.api.TokenAuthentication; +//import org.integratedmodelling.klab.hub.repository.TokenRepository; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.security.core.context.SecurityContextHolder; +//import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +// +// +//public class TokenAuthenticationFilter implements Filter { +// public static final String AUTHENTICATION_TOKEN_HEADER_NAME = "Authentication"; +// +// +// @Autowired +// private TokenRepository tokenRepository; +// +// @Override +// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) +// throws IOException, ServletException { +// try { +// +// String tokenString = ((HttpServletRequest) request) +// .getHeader(AUTHENTICATION_TOKEN_HEADER_NAME); +// if (tokenString != null) { +// Optional token = tokenRepository.findByTokenString(tokenString); +// if(token.isPresent()) { +// TokenAuthentication storedToken = token.get(); +// if (storedToken.isAuthenticated()) { +// PreAuthenticatedAuthenticationToken authToken = new PreAuthenticatedAuthenticationToken(storedToken.getPrincipal() +// ,storedToken.getCredentials(),storedToken.getAuthorities()); +// // successful match. token should contain everything the security context needs. +// SecurityContextHolder.getContext().setAuthentication(authToken); +// } +// } +// } +// } catch (Throwable e) { +// Logging.INSTANCE.error("Could not set user authentication in security context " + e.toString()); +// } finally { +// SecurityContextHolder.getContext(); +// chain.doFilter(request, response); +// } +// +// } +// +// @Override +// public void destroy() { +// } +// +// @Override +// public void init(FilterConfig filterConfig) throws ServletException { +// System.out.println("Initialized TokenHeaderProcessingFilter"); +// } +// +// +//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java deleted file mode 100644 index 7f52d611d6..0000000000 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfig.java +++ /dev/null @@ -1,202 +0,0 @@ -//package org.integratedmodelling.klab.hub.security; -// -//import java.io.IOException; -//import java.util.Arrays; -//import java.util.Collections; -//import javax.servlet.ServletException; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -// -//import org.springframework.security.config.BeanIds; -//import org.integratedmodelling.klab.exceptions.KlabAuthorizationException; -//import org.integratedmodelling.klab.hub.security.oauth2.HttpCookieOAuth2AuthorizationRequestRepository; -//import org.integratedmodelling.klab.hub.security.oauth2.OAuth2AuthenticationFailureHandler; -//import org.integratedmodelling.klab.hub.security.oauth2.OAuth2AuthenticationSuccessHandler; -//import org.integratedmodelling.klab.hub.service.OAuth2UserService; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.http.HttpMethod; -//import org.springframework.security.authentication.AuthenticationManager; -//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -//import org.springframework.security.config.annotation.web.builders.HttpSecurity; -//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -//import org.springframework.security.config.http.SessionCreationPolicy; -//import org.springframework.security.core.AuthenticationException; -//import org.springframework.security.core.userdetails.UserDetailsService; -//import org.springframework.security.crypto.password.LdapShaPasswordEncoder; -//import org.springframework.security.crypto.password.PasswordEncoder; -//import org.springframework.security.web.authentication.AuthenticationFailureHandler; -//import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -//import org.springframework.web.cors.CorsConfiguration; -//import org.springframework.web.cors.CorsConfigurationSource; -//import org.springframework.web.cors.UrlBasedCorsConfigurationSource; -//import com.google.common.collect.ImmutableList; -//import com.google.common.net.HttpHeaders; -// -//@SuppressWarnings("deprecation") -//@Configuration -////@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true) -//public class WebSecurityConfig { -// -// @Autowired -// UserDetailsService userDetailsService; -// -// @Autowired -// private JwtAuthenticationEntryPoint unauthorizedHandler; -// -// @Autowired -// private OAuth2UserService oAuth2UserService; -// -// @Autowired -// private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler; -// -// @Autowired -// private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler; -// -// @Bean -// public TokenAuthenticationFilter tokenAuthenticationFilter() { -// return new TokenAuthenticationFilter(); -// } -// -// -// public static final String AUTHENTICATION_TOKEN_HEADER_NAME = "Authentication"; -// -// /** -// * TODO incorporate this where? this allows us to assign our own HTTP response -// * status code, by using an exception class which is annotated with it directly. -// * (otherwise we would rely on Spring's container logic to assign a 'redirect' -// * or other default status.) -// */ -// AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler() { -// @Override -// public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, -// AuthenticationException e) throws IOException, ServletException { -// throw new KlabAuthorizationException("Authentication failed."); -// } -// }; -// -// @Bean -// public HttpCookieOAuth2AuthorizationRequestRepository cookieAuthorizationRequestRepository() { -// return new HttpCookieOAuth2AuthorizationRequestRepository(); -// } -// -// /** -// * this is necessary so that HubAuthenticationManager injection points can be -// * populated. -// */ -//// @Bean(BeanIds.AUTHENTICATION_MANAGER) -//// @Override -//// public AuthenticationManager authenticationManagerBean() throws Exception { -//// return super.authenticationManagerBean(); -//// } -//// -//// @Override -//// public void configure(AuthenticationManagerBuilder auth) throws Exception { -//// auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); -//// } -// -// -// /** -// * The allows our password encoder to have multiple entries. Allowing us to upgrade user -// * passwords without needing to do some serious migration effort. It is possible that -// * we will need to have users set a new password, or force the system to rehash the password -// * when the user logs in. -// * -// * In the end there are limited possibilities in the options here. The better way would be -// * to use a proper encoder and not some deprecated methodm but crowd can only handle one type -// * of encrcyption at a time. -// * -// * -// * String encodingId = "bcrypt"; Map encoders = new -// * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); -// * encoders.put("SHA512", new LdapShaPasswordEncoder()); -// * DelegatingPasswordEncoder delegatingPasswordEncoder = new -// * DelegatingPasswordEncoder(encodingId, encoders); -// * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new -// * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; -// */ -// @Bean -// public PasswordEncoder passwordEncoder() { -// return new LdapShaPasswordEncoder(); -// } -// -//// @Override -//// protected void configure(HttpSecurity http) throws Exception { -//// http -//// .cors() -//// .and() -//// .csrf() -//// .disable() -//// .exceptionHandling() -//// .authenticationEntryPoint(unauthorizedHandler) -//// .and() -//// .sessionManagement() -//// .sessionCreationPolicy(SessionCreationPolicy.STATELESS) -//// .and() -//// .authorizeRequests() -//// .antMatchers(HttpMethod.POST, HubRequestMatchers.getAuthentication()) -//// .permitAll() -//// .regexMatchers(HttpMethod.POST, HubRequestMatchers.getUsers()) -//// .permitAll() -//// .anyRequest() -//// .authenticated() -//// .and() -//// .oauth2Login() -//// .authorizationEndpoint() -//// .baseUri("/oauth2/authorize") -//// .authorizationRequestRepository(cookieAuthorizationRequestRepository()) -//// .and() -//// .redirectionEndpoint() -//// .baseUri("/oauth2/callback/*") -//// .and() -//// .userInfoEndpoint() -//// .userService(oAuth2UserService) -//// .and() -//// .successHandler(oAuth2AuthenticationSuccessHandler) -//// .failureHandler(oAuth2AuthenticationFailureHandler); -//// -//// http.csrf().disable().antMatcher("/api/**") -//// .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); -//// //.addFilterBefore(WebSecurityCorsFilter(), ChannelProcessingFilter.class); -//// } -// -//// Left here as a last resort -//// public class WebSecurityCorsFilter implements Filter { -//// @Override -//// public void init(FilterConfig filterConfig) throws ServletException { -//// } -//// @Override -//// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { -//// HttpServletResponse res = (HttpServletResponse) response; -//// res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control"); -//// chain.doFilter(request, res); -//// } -//// @Override -//// public void destroy() { -//// } -//// } -// -//// @Bean -//// CorsConfigurationSource corsConfigurationSource() { -//// final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); -//// final CorsConfiguration config = new CorsConfiguration(); -//// config.setAllowCredentials(false); -//// config.setAllowedOrigins(ImmutableList.of( -//// "https://integratedmodelling.org", -//// "http://localhost:8080", -//// "https://localhost:8080", -//// "http://localhost:8081", -//// "https://localhost:8081", -//// "http://localhost:8284", -//// "https://localhost:8284")); -//// config.setAllowedHeaders(Collections.singletonList("*")); -//// config.addExposedHeader("Content-disposition"); -//// config.addExposedHeader(HttpHeaders.LOCATION); -//// config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "HEAD")); -//// source.registerCorsConfiguration("/**", config); -//// return source; -//// } -// -//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java similarity index 92% rename from klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java rename to klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java index 473ad8616c..c4ea7410f5 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/WebSecurityConfiguration.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java @@ -1,8 +1,9 @@ -package org.integratedmodelling.klab.hub.config; +package org.integratedmodelling.klab.hub.security; import java.util.Arrays; import java.util.Collections; +import org.integratedmodelling.klab.hub.security.keycloak.method.KeycloakMethodSecurityExpression; import org.keycloak.adapters.KeycloakConfigResolver; import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; @@ -11,7 +12,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.core.annotation.Order; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; @@ -27,7 +30,7 @@ import com.google.common.net.HttpHeaders; @KeycloakConfiguration -//@Order(95) +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled= true) public class WebSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { @Autowired @@ -48,7 +51,7 @@ protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { public KeycloakConfigResolver KeycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } - + @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/method/KeycloakMethodSecurityExpression.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/method/KeycloakMethodSecurityExpression.java new file mode 100644 index 0000000000..8c0384277f --- /dev/null +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/method/KeycloakMethodSecurityExpression.java @@ -0,0 +1,62 @@ +package org.integratedmodelling.klab.hub.security.keycloak.method; + +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; +import org.springframework.security.access.expression.SecurityExpressionRoot; +import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +public class KeycloakMethodSecurityExpression extends SecurityExpressionRoot implements MethodSecurityExpressionOperations { + + private Object filterObject; + private Object returnObject; + private Object target; + + public KeycloakMethodSecurityExpression(Authentication authentication) { + super(authentication); + } + + public boolean isUser(String userName) { + KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) this.authentication; + KeycloakPrincipal principal = (KeycloakPrincipal) token.getPrincipal(); + + String preferredUsername = principal.getKeycloakSecurityContext().getToken().getPreferredUsername(); + if (preferredUsername != null) { + return preferredUsername.equals(userName); + } + + return false; + } + + @Override + public void setFilterObject(Object filterObject) { + this.filterObject = filterObject; + } + + @Override + public Object getFilterObject() { + return this.filterObject; + } + + @Override + public void setReturnObject(Object returnObject) { + this.returnObject = returnObject; + + } + + @Override + public Object getReturnObject() { + return this.returnObject; + } + + @Override + public Object getThis() { + return target; + } + + void setThis(Object target) { + this.target = target; + } +} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/methodHandler/KeycloakMethodSecurityExpressionHandler.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/methodHandler/KeycloakMethodSecurityExpressionHandler.java new file mode 100644 index 0000000000..a25518ebc8 --- /dev/null +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/methodHandler/KeycloakMethodSecurityExpressionHandler.java @@ -0,0 +1,58 @@ +package org.integratedmodelling.klab.hub.security.keycloak.methodHandler; + +import java.io.Serializable; + +import org.aopalliance.intercept.MethodInvocation; +import org.integratedmodelling.klab.hub.security.keycloak.method.KeycloakMethodSecurityExpression; +import org.springframework.security.access.PermissionEvaluator; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; +import org.springframework.security.authentication.AuthenticationTrustResolverImpl; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; + +public class KeycloakMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler implements PermissionEvaluator { + + @Override + protected MethodSecurityExpressionOperations createSecurityExpressionRoot( + Authentication authentication, MethodInvocation invocation) { + KeycloakMethodSecurityExpression root = new KeycloakMethodSecurityExpression(authentication); + + root.setPermissionEvaluator(getPermissionEvaluator()); + root.setTrustResolver(new AuthenticationTrustResolverImpl()); + root.setRoleHierarchy(getRoleHierarchy()); + return root; + } + + @Override + public boolean hasPermission( + Authentication auth, Object targetDomainObject, Object permission) { + if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)){ + return false; + } + String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase(); + + return hasPrivilege(auth, targetType, permission.toString().toUpperCase()); + } + + @Override + public boolean hasPermission( + Authentication auth, Serializable targetId, String targetType, Object permission) { + if ((auth == null) || (targetType == null) || !(permission instanceof String)) { + return false; + } + return hasPrivilege(auth, targetType.toUpperCase(), + permission.toString().toUpperCase()); + } + + private boolean hasPrivilege(Authentication auth, String targetType, String permission) { + for (GrantedAuthority grantedAuth : auth.getAuthorities()) { + if (grantedAuth.getAuthority().startsWith(targetType) && + grantedAuth.getAuthority().contains(permission)) { + return true; + } + } + return false; + } + +} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/service/KeycloakSecurityService.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/service/KeycloakSecurityService.java new file mode 100644 index 0000000000..5528463c60 --- /dev/null +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/keycloak/service/KeycloakSecurityService.java @@ -0,0 +1,39 @@ +package org.integratedmodelling.klab.hub.security.keycloak.service; + +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +@Service("securityService") +public class KeycloakSecurityService { + + public boolean isUser(String userName) { + KeycloakAuthenticationToken authentication = + (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication; + KeycloakPrincipal principal = (KeycloakPrincipal) token.getPrincipal(); + + String preferredUsername = principal.getKeycloakSecurityContext().getToken().getPreferredUsername(); + if (preferredUsername != null) { + return preferredUsername.equals(userName); + } + + return false; + } + + public boolean isUserId(String userId) { + String id = SecurityContextHolder.getContext().getAuthentication().getName(); +// KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication; +// KeycloakPrincipal principal = (KeycloakPrincipal) token.getPrincipal(); +// +// String preferredUsername = principal.getKeycloakSecurityContext().getToken().getPreferredUsername(); + if (id != null) { + return id.equals(userId); + } + + return false; + } + +} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/service/OAuth2UserService.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/service/OAuth2UserService.java index e44ffc2816..ad5d8f7dc0 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/service/OAuth2UserService.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/service/OAuth2UserService.java @@ -1,97 +1,97 @@ -package org.integratedmodelling.klab.hub.service; - -import org.integratedmodelling.klab.hub.security.oauth2.OAuth2UserInfo; -import org.integratedmodelling.klab.hub.security.oauth2.OAuth2UserInfoFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.InternalAuthenticationServiceException; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.integratedmodelling.klab.hub.api.AuthProvider; -import org.integratedmodelling.klab.hub.api.ProfileResource; -import org.integratedmodelling.klab.hub.api.Role; -import org.integratedmodelling.klab.hub.api.User; -import org.integratedmodelling.klab.hub.api.User.AccountStatus; -import org.integratedmodelling.klab.hub.commands.CreateUserWithRolesAndStatus; -import org.integratedmodelling.klab.hub.exception.OAuth2AuthenticationProcessingException; -import org.integratedmodelling.klab.hub.repository.UserRepository; - -@Service -public class OAuth2UserService extends DefaultOAuth2UserService { - - @Autowired - UserRepository userRepository; - - @Autowired - protected ObjectMapper objectMapper; - - @Override - public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException { - OAuth2User oAuth2User = super.loadUser(oAuth2UserRequest); - try { - return processOAuth2User(oAuth2UserRequest, oAuth2User); - } catch (AuthenticationException e) { - throw e; - } catch (Exception e) { - throw new InternalAuthenticationServiceException(e.getMessage(), e.getCause()); - } - } - - private OAuth2User processOAuth2User(OAuth2UserRequest oAuth2UserRequest, OAuth2User oAuth2User) { - OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(oAuth2UserRequest.getClientRegistration().getRegistrationId(), oAuth2User.getAttributes()); - if(StringUtils.isEmpty(oAuth2UserInfo.getEmail())) { - throw new OAuth2AuthenticationProcessingException("Email not found from OAuth2 provider"); - } - //lets check to see if the user exists in our database, we may have a problem with duplicated email addresses - //how can we respond to an email check for example when an engine and a user are both using the same email address? who do I match? - //We need to indicate where this verification comes from, ldap, google, or whatever. - Optional userOptional = userRepository - .findByNameIgnoreCaseOrEmailIgnoreCase(oAuth2UserInfo.getName(), oAuth2UserInfo.getEmail()); - User user; - if(userOptional.isPresent()) { - user = userOptional.get(); - if(!user.getProvider().equals(AuthProvider.valueOf(oAuth2UserRequest.getClientRegistration().getRegistrationId()))) { - throw new OAuth2AuthenticationProcessingException("Looks like you're signed up with " + - user.getProvider() + " account. Please use your " + user.getProvider() + - " account to login."); - } - user = updateExistingUser(user, oAuth2UserInfo); - } else { - user = registerNewUser(oAuth2UserRequest, oAuth2UserInfo); - } - - ProfileResource profielResource = objectMapper.convertValue(user, ProfileResource.class); - profielResource.setAttributes(oAuth2User.getAttributes()); - return profielResource; - } - - private User registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo) { - Set roles = new HashSet<>(); - roles.add(Role.ROLE_USER); - User user = new User(); - user.setProvider(AuthProvider.valueOf(oAuth2UserRequest.getClientRegistration().getRegistrationId())); - user.setProviderId(oAuth2UserInfo.getId()); - user.setFirstName(oAuth2UserInfo.getName()); - user.setEmail(oAuth2UserInfo.getEmail()); - user.setUsername(oAuth2UserInfo.getEmail()); - user.setRoles(roles); - user.setAccountStatus(AccountStatus.active); - user = new CreateUserWithRolesAndStatus(user, userRepository, null).execute(); - return user; - } - - private User updateExistingUser(User existingUser, OAuth2UserInfo oAuth2UserInfo) { - //TODO need some user update system for when if oauth info changes - return null; - } -} +//package org.integratedmodelling.klab.hub.service; +// +//import org.integratedmodelling.klab.hub.security.oauth2.OAuth2UserInfo; +//import org.integratedmodelling.klab.hub.security.oauth2.OAuth2UserInfoFactory; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.security.authentication.InternalAuthenticationServiceException; +//import org.springframework.security.core.AuthenticationException; +//import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +//import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +//import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +//import org.springframework.security.oauth2.core.user.OAuth2User; +//import org.springframework.stereotype.Service; +// +//import com.fasterxml.jackson.databind.ObjectMapper; +//import java.util.HashSet; +//import java.util.Optional; +//import java.util.Set; +// +//import org.apache.commons.lang3.StringUtils; +//import org.integratedmodelling.klab.hub.api.AuthProvider; +//import org.integratedmodelling.klab.hub.api.ProfileResource; +//import org.integratedmodelling.klab.hub.api.Role; +//import org.integratedmodelling.klab.hub.api.User; +//import org.integratedmodelling.klab.hub.api.User.AccountStatus; +//import org.integratedmodelling.klab.hub.commands.CreateUserWithRolesAndStatus; +//import org.integratedmodelling.klab.hub.exception.OAuth2AuthenticationProcessingException; +//import org.integratedmodelling.klab.hub.repository.UserRepository; +// +//@Service +//public class OAuth2UserService extends DefaultOAuth2UserService { +// +// @Autowired +// UserRepository userRepository; +// +// @Autowired +// protected ObjectMapper objectMapper; +// +// @Override +// public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException { +// OAuth2User oAuth2User = super.loadUser(oAuth2UserRequest); +// try { +// return processOAuth2User(oAuth2UserRequest, oAuth2User); +// } catch (AuthenticationException e) { +// throw e; +// } catch (Exception e) { +// throw new InternalAuthenticationServiceException(e.getMessage(), e.getCause()); +// } +// } +// +// private OAuth2User processOAuth2User(OAuth2UserRequest oAuth2UserRequest, OAuth2User oAuth2User) { +// OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo(oAuth2UserRequest.getClientRegistration().getRegistrationId(), oAuth2User.getAttributes()); +// if(StringUtils.isEmpty(oAuth2UserInfo.getEmail())) { +// throw new OAuth2AuthenticationProcessingException("Email not found from OAuth2 provider"); +// } +// //lets check to see if the user exists in our database, we may have a problem with duplicated email addresses +// //how can we respond to an email check for example when an engine and a user are both using the same email address? who do I match? +// //We need to indicate where this verification comes from, ldap, google, or whatever. +// Optional userOptional = userRepository +// .findByNameIgnoreCaseOrEmailIgnoreCase(oAuth2UserInfo.getName(), oAuth2UserInfo.getEmail()); +// User user; +// if(userOptional.isPresent()) { +// user = userOptional.get(); +// if(!user.getProvider().equals(AuthProvider.valueOf(oAuth2UserRequest.getClientRegistration().getRegistrationId()))) { +// throw new OAuth2AuthenticationProcessingException("Looks like you're signed up with " + +// user.getProvider() + " account. Please use your " + user.getProvider() + +// " account to login."); +// } +// user = updateExistingUser(user, oAuth2UserInfo); +// } else { +// user = registerNewUser(oAuth2UserRequest, oAuth2UserInfo); +// } +// +// ProfileResource profielResource = objectMapper.convertValue(user, ProfileResource.class); +// profielResource.setAttributes(oAuth2User.getAttributes()); +// return profielResource; +// } +// +// private User registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo oAuth2UserInfo) { +// Set roles = new HashSet<>(); +// roles.add(Role.ROLE_USER); +// User user = new User(); +// user.setProvider(AuthProvider.valueOf(oAuth2UserRequest.getClientRegistration().getRegistrationId())); +// user.setProviderId(oAuth2UserInfo.getId()); +// user.setFirstName(oAuth2UserInfo.getName()); +// user.setEmail(oAuth2UserInfo.getEmail()); +// user.setUsername(oAuth2UserInfo.getEmail()); +// user.setRoles(roles); +// user.setAccountStatus(AccountStatus.active); +// user = new CreateUserWithRolesAndStatus(user, userRepository, null).execute(); +// return user; +// } +// +// private User updateExistingUser(User existingUser, OAuth2UserInfo oAuth2UserInfo) { +// //TODO need some user update system for when if oauth info changes +// return null; +// } +//} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/ModifyGroupsController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/ModifyGroupsController.java index 9de04ee47e..f1b89c12e8 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/ModifyGroupsController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/ModifyGroupsController.java @@ -36,7 +36,7 @@ public class ModifyGroupsController { TaskService service; @PostMapping(value= API.HUB.TASK_BASE, produces = "application/json", params=API.HUB.PARAMETERS.USER_REQUEST_GROUPS) - @PreAuthorize("authentication.principal == #username or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") + @PreAuthorize("@securityService.isUser(#username) or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") public ResponseEntity requestGroupsResponse( @RequestParam(API.HUB.PARAMETERS.USER_REQUEST_GROUPS) String username, @RequestBody List groupNames, @@ -49,7 +49,7 @@ public ResponseEntity requestGroupsResponse( } @PostMapping(value= API.HUB.TASK_BASE, produces = "application/json", params=API.HUB.PARAMETERS.USER_REMOVE_GROUPS) - @PreAuthorize("authentication.principal == #username or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") + @PreAuthorize("@securityService.isUser(#username) or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") public ResponseEntity removeGroupsResponse( @RequestParam(API.HUB.PARAMETERS.USER_REMOVE_GROUPS) String username, @RequestBody List groupNames, diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/TasksController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/TasksController.java index f0fff1650f..d7a7cd3254 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/TasksController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tasks/controllers/TasksController.java @@ -14,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; @@ -39,8 +40,9 @@ public ResponseEntity getTask(@PathVariable("id") String id) { return resp; } - @GetMapping(value=API.HUB.TASK_BASE, produces = "application/json") - @RolesAllowed({ "ROLE_ADMINISTRATOR", "ROLE_SYSTEM" }) + @GetMapping(value = API.HUB.TASK_BASE, produces = "application/json") + //@RolesAllowed({ "ROLE_ADMINISTRATOR", "ROLE_SYSTEM" }) + @PreAuthorize("hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") public ResponseEntity getTasks(@RequestParam("type") Optional type, @RequestParam("status") Optional status) { List tasks = new ArrayList<>(); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java index a2cf773de9..dcc5355803 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java @@ -1,16 +1,16 @@ -//package org.integratedmodelling.klab.hub.tokens.services; -// -//import org.integratedmodelling.klab.hub.api.TokenAuthentication; -//import org.integratedmodelling.klab.hub.payload.LoginResponse; -//import org.integratedmodelling.klab.hub.payload.LogoutResponse; -//import org.springframework.stereotype.Service; -// -//@Service -//public interface UserAuthTokenService extends TokenBaseService { +package org.integratedmodelling.klab.hub.tokens.services; + +import org.integratedmodelling.klab.hub.api.TokenAuthentication; +import org.integratedmodelling.klab.hub.payload.LoginResponse; +import org.integratedmodelling.klab.hub.payload.LogoutResponse; +import org.springframework.stereotype.Service; + +@Service +public interface UserAuthTokenService { // public TokenAuthentication getUserAuthenticationToken(String username, String password); -// -// public LoginResponse getAuthResponse(String username, String password); -// + + public LoginResponse getAuthResponse(String username, String password); + // public LogoutResponse getLogoutResponse(String token); -// -//} + +} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java index 73c224605a..0335ff4264 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java @@ -1,17 +1,27 @@ package org.integratedmodelling.klab.hub.users.controllers; +import java.security.Principal; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + import org.integratedmodelling.klab.api.API; -import org.integratedmodelling.klab.hub.payload.LoginResponse; -import org.integratedmodelling.klab.hub.payload.LogoutResponse; -//import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; -import org.integratedmodelling.klab.rest.UserAuthenticationRequest; -import org.springframework.beans.factory.annotation.Autowired; +import org.integratedmodelling.klab.hub.api.ProfileResource; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; +import org.keycloak.common.Profile; +import org.keycloak.representations.AccessToken; +import org.keycloak.representations.AccessToken.Access; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; +import net.minidev.json.JSONObject; + @RestController public class UserAuthenticationController { @@ -35,7 +45,38 @@ public ResponseEntity loginResponse() { System.out.println("holis"); // LoginResponse response = userAuthService.getAuthResponse("", ""); // return response.getResponse(); - return null; +// Principal hola = request.getUserPrincipal(); +// KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) request.getUserPrincipal(); +// KeycloakPrincipal principal=(KeycloakPrincipal)token.getPrincipal(); +// KeycloakSecurityContext session = principal.getKeycloakSecurityContext(); +// AccessToken accessToken = session.getToken(); +// String username = accessToken.getPreferredUsername(); +// String emailID = accessToken.getEmail(); +// String lastname = accessToken.getFamilyName(); +// String firstname = accessToken.getGivenName(); +// String realmName = accessToken.getIssuer(); +// Access realmAccess = accessToken.getRealmAccess(); +// Set roles = realmAccess.getRoles(); +// LoginResponse response = userAuthService.getAuthResponse(username, accessToken.getAccessTokenHash()); +// JSONObject resp = new JSONObject(); +// ProfileResource profile = new ProfileResource(); +// profile.setUsername("user_id"); +// +// resp.appendField("Profile", profile.getSafeProfile()); +// resp.appendField("Authentication", ); +// HttpHeaders headers = new HttpHeaders(); +// headers.add("Authentication", ); +// return new ResponseEntity(resp, headers, HttpStatus.OK); +// return response.getResponse(); + return new ResponseEntity<>("hemos entrado con el token", HttpStatus.OK); + } + + @PostMapping(API.HUB.AUTHENTICATE_USER+"2") + public ResponseEntity loginResponse2() { + System.out.println("holis"); +// LoginResponse response = userAuthService.getAuthResponse("", ""); +// return response.getResponse(); + return new ResponseEntity<>("hemos entrado con el token", HttpStatus.OK); } // @PostMapping(API.HUB.DEAUTHENTICATE_USER) diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java index a68d4b88f8..8858e52b85 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java @@ -18,49 +18,48 @@ @RestController public class UserProfileController { - - private UserProfileService userService; - - @Autowired - UserProfileController(UserProfileService userService) { - this.userService = userService; - } - - @GetMapping(API.HUB.USER_BASE) - @PreAuthorize("hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") - public ResponseEntity getAllUserProfiles() { - JSONObject profiles = new JSONObject().appendField("profiles", userService.getAllUserProfiles()); - return new ResponseEntity<>(profiles,HttpStatus.OK); - } - - @GetMapping(API.HUB.USER_BASE_ID) - @PreAuthorize("authentication.getPrincipal() == #id or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") - public ResponseEntity getUserProfile(@PathVariable String id) { - ProfileResource profile = userService.getUserProfile(id); - return new ResponseEntity<>(profile,HttpStatus.ACCEPTED); - } - - @GetMapping(API.HUB.CURRENT_PROFILE) - // TODO this is call from single user, not need PreAuthorize - // @PreAuthorize("authentication.getPrincipal() == #username or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") - //correct the auth should be caught on the token filter side. - public ResponseEntity getCurrentUserProfile() { - ProfileResource profile = userService.getCurrentUserProfile(); - return new ResponseEntity<>(profile,HttpStatus.ACCEPTED); - } - @PutMapping(API.HUB.USER_BASE_ID) - @PreAuthorize("authentication.getPrincipal() == #id" ) - public ResponseEntity updateUserProfile(@PathVariable String id, @RequestBody UpdateUserRequest updateRequest) { - ProfileResource profile = userService.updateUserByProfile(updateRequest.getProfile()); - return new ResponseEntity<>(profile,HttpStatus.ACCEPTED); - } - - @GetMapping(value= API.HUB.USER_BASE_ID, params = "remote-login") - @PreAuthorize("authentication.getPrincipal() == #id") - public ResponseEntity getFullUserProfile(@PathVariable String id) { - ProfileResource profile = userService.getRawUserProfile(id); - return new ResponseEntity<>(profile,HttpStatus.ACCEPTED); - } - + private UserProfileService userService; + + @Autowired + UserProfileController(UserProfileService userService) { + this.userService = userService; + } + + @GetMapping(API.HUB.USER_BASE) + @PreAuthorize("hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") + public ResponseEntity< ? > getAllUserProfiles() { + JSONObject profiles = new JSONObject().appendField("profiles", userService.getAllUserProfiles()); + return new ResponseEntity<>(profiles, HttpStatus.OK); + } + + @GetMapping(API.HUB.USER_BASE_ID) + @PreAuthorize("authentication.getPrincipal() == #id or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") + public ResponseEntity< ? > getUserProfile(@PathVariable String id) { + ProfileResource profile = userService.getUserProfile(id); + return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); + } + + @GetMapping(API.HUB.CURRENT_PROFILE) + // TODO this is call from single user, not need PreAuthorize + // correct the auth should be caught on the token filter side. + public ResponseEntity< ? > getCurrentUserProfile() { + ProfileResource profile = userService.getCurrentUserProfile(); + return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); + } + + @PutMapping(API.HUB.USER_BASE_ID) + @PreAuthorize("authentication.getPrincipal() == #id") + public ResponseEntity< ? > updateUserProfile(@PathVariable String id, @RequestBody UpdateUserRequest updateRequest) { + ProfileResource profile = userService.updateUserByProfile(updateRequest.getProfile()); + return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); + } + + @GetMapping(value = API.HUB.USER_BASE_ID, params = "remote-login") + @PreAuthorize("authentication.getPrincipal() == #id") + public ResponseEntity< ? > getFullUserProfile(@PathVariable String id) { + ProfileResource profile = userService.getRawUserProfile(id); + return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); + } + } diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java index 98258d2f78..9f77db2f26 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java @@ -1,5 +1,6 @@ package org.integratedmodelling.klab.hub.users.services; +import java.security.Principal; import java.util.HashSet; import java.util.Set; @@ -10,6 +11,11 @@ import org.integratedmodelling.klab.hub.exception.UserByEmailDoesNotExistException; import org.integratedmodelling.klab.hub.exception.UserDoesNotExistException; import org.integratedmodelling.klab.hub.repository.UserRepository; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; +import org.keycloak.representations.AccessToken; +import org.keycloak.representations.IDToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; @@ -59,8 +65,19 @@ public ProfileResource getUserProfile(String username) { @Override public ProfileResource getCurrentUserProfile() { - String username = SecurityContextHolder.getContext().getAuthentication().getName(); - User user = userRepository.findByNameIgnoreCase(username) + KeycloakAuthenticationToken authentication = + (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + + Principal principal = (Principal) authentication.getPrincipal(); + + String preferredUsername = ""; + + if (principal instanceof KeycloakPrincipal) { + KeycloakPrincipal kPrincipal = (KeycloakPrincipal) principal; + AccessToken token = kPrincipal.getKeycloakSecurityContext().getToken(); + preferredUsername = token.getPreferredUsername(); + } + User user = userRepository.findByNameIgnoreCase(preferredUsername) .orElseThrow(() -> new UserDoesNotExistException()); ProfileResource profile = objectMapper.convertValue(user, ProfileResource.class); diff --git a/klab.hub/src/main/resources/application.yml b/klab.hub/src/main/resources/application.yml index 159cc5c752..296595a300 100644 --- a/klab.hub/src/main/resources/application.yml +++ b/klab.hub/src/main/resources/application.yml @@ -3,7 +3,10 @@ server: servlet: contextPath: /hub + spring: + main: + allow-bean-definition-overriding: true cloud: bus: enabled: false From 30fcc6c75622a6e3e49ddb8ffc21aa091f85e687 Mon Sep 17 00:00:00 2001 From: kristina Date: Mon, 14 Nov 2022 15:17:28 +0100 Subject: [PATCH 03/10] Not use LDAP in local mode --- .../klab/hub/commands/CreateInitialUsers.java | 8 ++++---- .../klab/hub/commands/CreateUserWithRolesAndStatus.java | 8 ++++---- .../klab/hub/config/dev/DevMongoModelsConfig.java | 8 ++++---- .../hub/users/services/UserRegistrationServiceImpl.java | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java index 76526d085b..b8e14b4a06 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateInitialUsers.java @@ -23,14 +23,14 @@ public class CreateInitialUsers { private MongoGroupRepository groupRepository; private UserRepository userRepository; - private LdapUserDetailsManager ldapUserDetailsManager; +// private LdapUserDetailsManager ldapUserDetailsManager; private PasswordEncoder passwordEncoder; public CreateInitialUsers(MongoGroupRepository groupRepository, UserRepository userRepository, - LdapUserDetailsManager ldapUserDetailsManager, PasswordEncoder passwordEncoder) { + /*LdapUserDetailsManager ldapUserDetailsManager,*/ PasswordEncoder passwordEncoder) { this.groupRepository = groupRepository; this.userRepository = userRepository; - this.ldapUserDetailsManager = ldapUserDetailsManager; +// this.ldapUserDetailsManager = ldapUserDetailsManager; this.passwordEncoder = passwordEncoder; } @@ -172,7 +172,7 @@ private void createInitialUsers() { try { // This is our legacy password encoding user = new SetUserPasswordHash(user, user.getPasswordHash(), this.passwordEncoder).execute(); - User newUser = new CreateUserWithRolesAndStatus(user, userRepository, ldapUserDetailsManager).execute(); + User newUser = new CreateUserWithRolesAndStatus(user, userRepository/*, ldapUserDetailsManager*/).execute(); if (newUser.getLastLogin() != null) { int x = (int) (Math.random() * 100 + 1); if (x >= 5) // less than 5% not connected diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateUserWithRolesAndStatus.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateUserWithRolesAndStatus.java index 2a0db8055b..294fcc30d3 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateUserWithRolesAndStatus.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/commands/CreateUserWithRolesAndStatus.java @@ -9,14 +9,14 @@ public class CreateUserWithRolesAndStatus implements UserCommand { private UserRepository userRepository; private User user; - private LdapUserDetailsManager ldapUserDetailsManager; +// private LdapUserDetailsManager ldapUserDetailsManager; public CreateUserWithRolesAndStatus(User user, - UserRepository userRepository, LdapUserDetailsManager ldapUserDetailsManager) { + UserRepository userRepository/*, LdapUserDetailsManager ldapUserDetailsManager*/) { super(); this.userRepository = userRepository; this.user = user; - this.ldapUserDetailsManager = ldapUserDetailsManager; +// this.ldapUserDetailsManager = ldapUserDetailsManager; } @Override @@ -25,7 +25,7 @@ public User execute() { if (newUser.getProvider() != null && newUser.getProvider() != AuthProvider.local) { return newUser; } - new CreateLdapUser(newUser, ldapUserDetailsManager).execute(); +// new CreateLdapUser(newUser, ldapUserDetailsManager).execute(); return newUser; } diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java index 3fc9f008a7..f6e15bb716 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java @@ -20,7 +20,7 @@ public class DevMongoModelsConfig implements ApplicationListener Date: Mon, 14 Nov 2022 16:20:40 +0100 Subject: [PATCH 04/10] Request group with Keycloak --- .../java/org/integratedmodelling/klab/hub/api/Task.java | 5 ++++- klab.hub/src/main/resources/application.yml | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java index fa26a32657..ec624c45fe 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java @@ -6,6 +6,9 @@ import javax.servlet.http.HttpServletRequest; import org.joda.time.DateTime; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Reference; import org.springframework.data.annotation.Transient; @@ -69,7 +72,7 @@ protected Task(TaskStatus parentStatus) { this(null, parentStatus); } protected Task(Role roleRequirement, TaskStatus parentStatus) { - this.setUser(SecurityContextHolder.getContext().getAuthentication().getName()); + this.setUser(((KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getKeycloakSecurityContext().getToken().getPreferredUsername()); this.setRoleRequirement(roleRequirement);; this.setIssued(); this.setStatus(TaskStatus.pending); diff --git a/klab.hub/src/main/resources/application.yml b/klab.hub/src/main/resources/application.yml index 296595a300..c336b4db72 100644 --- a/klab.hub/src/main/resources/application.yml +++ b/klab.hub/src/main/resources/application.yml @@ -65,10 +65,10 @@ engine: email: server: - hostname: localhost - port: 3025 - username: system - password: password + hostname: mail.privateemail.com + port: 587 + username: noreply@integratedmodelling.org + password: huntalloyhuggingtoes replyable: replyable: general: From 241e43d9755dd3e605e43e34184a4fea03bfd0a7 Mon Sep 17 00:00:00 2001 From: Kristina Date: Wed, 16 Nov 2022 08:06:37 +0100 Subject: [PATCH 05/10] Working around CORS in error in getCertificate --- .../hub/license/controllers/EngineLicenseController.java | 9 +++++++-- .../klab/hub/security/WebSecurityConfiguration.java | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java index 821d219844..f313002177 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java @@ -29,6 +29,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -61,9 +62,13 @@ public class EngineLicenseController extends LicenseController Date: Thu, 17 Nov 2022 08:27:11 +0100 Subject: [PATCH 06/10] Change authentication in backend, for using openID with Keycloak. Front-end hub. --- .../hub/license/controllers/EngineLicenseController.java | 6 ++---- .../klab/hub/security/WebSecurityConfiguration.java | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java index f313002177..db1c56121d 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java @@ -64,11 +64,9 @@ public class EngineLicenseController extends LicenseController Date: Thu, 25 Apr 2024 10:00:30 +0200 Subject: [PATCH 07/10] IM-347 First approach to use keycloak instead ldap --- klab.hub/.settings/org.eclipse.jdt.core.prefs | 8 +- .../klab/hub/api/Task.java | 360 ++++++++-------- .../klab/hub/config/MongoConfig.java | 41 +- .../hub/config/dev/DevMongoModelsConfig.java | 69 ++- .../controllers/EngineLicenseController.java | 130 ------ .../controllers/EngineLicenseController.java | 23 +- .../dto/EngineAuthResponeFactory.java | 24 +- .../klab/hub/security/HubRequestMatchers.java | 33 +- .../klab/hub/security/WebSecurityConfig.java | 400 +++++++++--------- .../security/WebSecurityConfiguration.java | 71 ++-- .../OAuth2AuthenticationSuccessHandler.java | 29 +- .../klab/hub/tags/dto/MongoTag.java | 2 - .../tokens/services/UserAuthTokenService.java | 32 +- .../services/UserAuthTokenServiceImpl.java | 210 ++++----- .../UserAuthenticationController.java | 40 +- .../controllers/UserProfileController.java | 131 ++---- .../UserRegistrationController.java | 2 +- .../services/UserProfileServiceImpl.java | 47 +- .../services/UserRegistrationServiceImpl.java | 101 +---- 19 files changed, 715 insertions(+), 1038 deletions(-) delete mode 100644 klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java diff --git a/klab.hub/.settings/org.eclipse.jdt.core.prefs b/klab.hub/.settings/org.eclipse.jdt.core.prefs index d089a9b734..29fe717b87 100644 --- a/klab.hub/.settings/org.eclipse.jdt.core.prefs +++ b/klab.hub/.settings/org.eclipse.jdt.core.prefs @@ -1,11 +1,11 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java index 98649400d6..59b9bc3852 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/api/Task.java @@ -6,13 +6,10 @@ import javax.servlet.http.HttpServletRequest; -import org.joda.time.DateTime; -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.integratedmodelling.klab.auth.Role; import org.integratedmodelling.klab.hub.tasks.enums.TaskStatus; import org.integratedmodelling.klab.hub.tasks.enums.TaskType; +import org.keycloak.KeycloakPrincipal; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Reference; import org.springframework.data.annotation.Transient; @@ -27,208 +24,209 @@ @Document(collection = "Tasks") public abstract class Task { - @Id - String id; - - String user; - - LocalDateTime issued; - - LocalDateTime closed; - + @Id + String id; + + String user; + + LocalDateTime issued; + + LocalDateTime closed; + @Enumerated(EnumType.STRING) Role roleRequirement; - + @Enumerated(EnumType.STRING) TaskStatus status; - + @Enumerated(EnumType.STRING) TaskStatus parentStatus; - + List log = new ArrayList(); - + LocalDateTime expirationDate; - + /** * The next task to be accepted or deny */ @Reference List next = new ArrayList(); - - /** + + /** * If true, after create, we do accept */ boolean autoAccepted; - + @JsonInclude() @Transient private TaskType type; - + public Task() { - this(null, null); + this(null, null); } - + public Task(Role roleRequirement) { - this(roleRequirement, null); + this(roleRequirement, null); } - + public Task(TaskStatus parentStatus) { - this(null, parentStatus); + this(null, parentStatus); } protected Task(Role roleRequirement, TaskStatus parentStatus) { - this.setUser(((KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getKeycloakSecurityContext().getToken().getPreferredUsername()); - this.setRoleRequirement(roleRequirement);; - this.setIssued(); - this.setStatus(TaskStatus.pending); - this.setParentStatus(parentStatus); - this.setType(); // force to set the type - // this.setDescription(this.getType().name()); - } - - public String getId() { - return id; - } - - /** - * @return the user - */ - public String getUser() { - return user; - } - - /** - * @param user the user to set - */ - public void setUser(String user) { - this.user = user; - } - - public void setId(String id) { - this.id = id; - } - - public LocalDateTime getIssued() { - return issued; - } - - public void setIssued() { - this.issued = LocalDateTime.now(); - } - - public LocalDateTime getClosed() { - return closed; - } - - public void setClosed() { - this.closed = LocalDateTime.now(); - } - - public TaskStatus getStatus() { - return status; - } - - public void setStatus(TaskStatus status) { - this.status = status; - } - - public LocalDateTime getExpirationDate() { - return expirationDate; - } - - public void setExpirationDate(LocalDateTime expirationDate) { - this.expirationDate = expirationDate; - } - - public String getRoleRequirement() { - return roleRequirement.toString(); - } - - public void setRoleRequirement(Role role) { - this.roleRequirement = role; - } - - public boolean isAutoAccepted() { - return this.autoAccepted; - } - - public void setAutoAccepted(boolean autoAccepted) { - this.autoAccepted = autoAccepted; - } - - /** - * @return the parentStatus - */ - public TaskStatus getParentStatus() { - return parentStatus; - } - - /** - * @param parentStatus the parentStatus to set - */ - public void setParentStatus(TaskStatus parentStatus) { - this.parentStatus = parentStatus; - } - - /** - * @return the deniedMessage - */ - public List getLog() { - return log; - } - - /** - * @param deniedMessage the deniedMessage to set - */ - public void addToLog(String message) { - this.log.add(message); - } - - /** - * @return the next - */ - public List getNext() { - return next; - } - - /** - * @param next task to add to next - */ - public void add(Task next) { - this.next.add(next); - } - - /** - * Specific code for accept action - * The status of task after this operation is the final one, it will be change inside the method - * The new status is not persisted - * @param request the request, used if needed to check roles - * @throws DeniedException - */ - abstract public void acceptTaskAction(HttpServletRequest request); - /** - * Specific code for deny action - * The status of task after this operation is the final one, it must be changed inside the method - * The new status is not persisted - * @param request the request, used if needed to check roles - * @return message is necessary or null - */ - abstract public void denyTaskAction(HttpServletRequest request, String message); - - /** - * Return the type - * @return the TaskType, - */ - public TaskType getType() { - return type; - } - - public void setType(TaskType type) { - this.type = type; - } - - /** - * Added to force implementation to set the type, is called in constructor - */ - public abstract void setType(); + this.setUser(((KeycloakPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal()) + .getKeycloakSecurityContext().getToken().getPreferredUsername()); + this.setRoleRequirement(roleRequirement);; + this.setIssued(); + this.setStatus(TaskStatus.pending); + this.setParentStatus(parentStatus); + this.setType(); // force to set the type + // this.setDescription(this.getType().name()); + } + + public String getId() { + return id; + } + + /** + * @return the user + */ + public String getUser() { + return user; + } + + /** + * @param user the user to set + */ + public void setUser(String user) { + this.user = user; + } + + public void setId(String id) { + this.id = id; + } + + public LocalDateTime getIssued() { + return issued; + } + + public void setIssued() { + this.issued = LocalDateTime.now(); + } + + public LocalDateTime getClosed() { + return closed; + } + + public void setClosed() { + this.closed = LocalDateTime.now(); + } + + public TaskStatus getStatus() { + return status; + } + + public void setStatus(TaskStatus status) { + this.status = status; + } + + public LocalDateTime getExpirationDate() { + return expirationDate; + } + + public void setExpirationDate(LocalDateTime expirationDate) { + this.expirationDate = expirationDate; + } + + public String getRoleRequirement() { + return roleRequirement.toString(); + } + + public void setRoleRequirement(Role role) { + this.roleRequirement = role; + } + + public boolean isAutoAccepted() { + return this.autoAccepted; + } + + public void setAutoAccepted(boolean autoAccepted) { + this.autoAccepted = autoAccepted; + } + + /** + * @return the parentStatus + */ + public TaskStatus getParentStatus() { + return parentStatus; + } + + /** + * @param parentStatus the parentStatus to set + */ + public void setParentStatus(TaskStatus parentStatus) { + this.parentStatus = parentStatus; + } + + /** + * @return the deniedMessage + */ + public List getLog() { + return log; + } + + /** + * @param deniedMessage the deniedMessage to set + */ + public void addToLog(String message) { + this.log.add(message); + } + + /** + * @return the next + */ + public List getNext() { + return next; + } + + /** + * @param next task to add to next + */ + public void add(Task next) { + this.next.add(next); + } + + /** + * Specific code for accept action + * The status of task after this operation is the final one, it will be change inside the method + * The new status is not persisted + * @param request the request, used if needed to check roles + * @throws DeniedException + */ + abstract public void acceptTaskAction(HttpServletRequest request); + /** + * Specific code for deny action + * The status of task after this operation is the final one, it must be changed inside the method + * The new status is not persisted + * @param request the request, used if needed to check roles + * @return message is necessary or null + */ + abstract public void denyTaskAction(HttpServletRequest request, String message); + + /** + * Return the type + * @return the TaskType, + */ + public TaskType getType() { + return type; + } + + public void setType(TaskType type) { + this.type = type; + } + + /** + * Added to force implementation to set the type, is called in constructor + */ + public abstract void setType(); } diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/MongoConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/MongoConfig.java index 21085979c4..501bed3eab 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/MongoConfig.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/MongoConfig.java @@ -1,6 +1,5 @@ package org.integratedmodelling.klab.hub.config; - import java.util.Arrays; import java.util.Collection; @@ -11,7 +10,6 @@ import org.springframework.context.annotation.Profile; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration; -import org.springframework.data.mongodb.config.EnableMongoAuditing; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -22,24 +20,23 @@ import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; - @Profile("production") @Configuration @EnableMongoRepositories(basePackages = "org.integratedmodelling.klab.hub.repository") public class MongoConfig extends AbstractMongoClientConfiguration { - + @Value("${mongo.hostname}") private String HOSTNAME; @Value("${mongo.port}") private int PORT; - @Autowired + @Autowired private MappingMongoConverter mongoConverter; - + @Bean public MongoTemplate mongoTemplate(MongoClient mongoClient) { - this.mongoConverter.setMapKeyDotReplacement("#"); + this.mongoConverter.setMapKeyDotReplacement("#"); return new MongoTemplate(mongoDbFactory(mongoClient), this.mongoConverter); } @@ -47,7 +44,7 @@ public MongoTemplate mongoTemplate(MongoClient mongoClient) { public MongoDatabaseFactory mongoDbFactory(MongoClient mongoClient) { return new SimpleMongoClientDatabaseFactory(mongoClient, getDatabaseName()); } - + @Bean public ValidatingMongoEventListener validatingMongoEventListener() { return new ValidatingMongoEventListener(validator()); @@ -57,21 +54,21 @@ public ValidatingMongoEventListener validatingMongoEventListener() { public LocalValidatorFactoryBean validator() { return new LocalValidatorFactoryBean(); } - + @Override - protected Collection getMappingBasePackages(){ - return Arrays.asList("org.integratedmodelling.klab.hub.api","org.integratedmodelling.klab.hub.tokens.dto","org.integratedmodelling.klab.hub.licenses.dto" - ); + protected Collection getMappingBasePackages() { + return Arrays.asList("org.integratedmodelling.klab.hub.api", "org.integratedmodelling.klab.hub.tokens.dto", + "org.integratedmodelling.klab.hub.licenses.dto"); } - - @Override - protected String getDatabaseName() { - return "hub"; - } - @Override - public MongoClient mongoClient() { - String con = "mongodb://" + HOSTNAME + ":" + PORT; - return MongoClients.create(con); - } + @Override + protected String getDatabaseName() { + return "hub"; + } + + @Override + public MongoClient mongoClient() { + String con = "mongodb://" + HOSTNAME + ":" + PORT; + return MongoClients.create(con); + } } \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java index 6646df431e..adf15f97ea 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/config/dev/DevMongoModelsConfig.java @@ -17,46 +17,37 @@ @Profile("development") @Configuration -public class DevMongoModelsConfig implements ApplicationListener{ - - private MongoGroupRepository groupRepo; - private UserRepository userRepository; -// private LdapUserDetailsManager ldapUserDetailsManager; - private PasswordEncoder passwordEncoder; - private MongoLeverRepository leverRepo; - private MongoNodeRepository nodeRepo; - - @Autowired - public DevMongoModelsConfig(MongoGroupRepository groupRepo, - UserRepository userRepository, +public class DevMongoModelsConfig implements ApplicationListener { + + private MongoGroupRepository groupRepo; + private UserRepository userRepository; + private LdapUserDetailsManager ldapUserDetailsManager; + private PasswordEncoder passwordEncoder; + private MongoLeverRepository leverRepo; + private MongoNodeRepository nodeRepo; + + @Autowired + public DevMongoModelsConfig(MongoGroupRepository groupRepo, UserRepository userRepository, // LdapUserDetailsManager ldapUserDetailsManager, - PasswordEncoder passwordEncoder, - MongoLeverRepository leverRepo, - MongoNodeRepository nodeRepo) { - super(); - this.groupRepo = groupRepo; - this.userRepository = userRepository; + PasswordEncoder passwordEncoder, MongoLeverRepository leverRepo, MongoNodeRepository nodeRepo) { + super(); + this.groupRepo = groupRepo; + this.userRepository = userRepository; // this.ldapUserDetailsManager = ldapUserDetailsManager; - this.passwordEncoder = passwordEncoder; - this.leverRepo = leverRepo; - this.nodeRepo = nodeRepo; - } - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - URL url = DevMongoModelsConfig.class.getClassLoader().getResource("initial-groups.json"); - new CreateIntialGroups(url, groupRepo).execute(); - - new CreateInitialUsers( - groupRepo, - userRepository, -// ldapUserDetailsManager, - passwordEncoder - ).execute(); - - new CreateInitialLevers(leverRepo).execute(); - new CreateIntialNodes(nodeRepo, groupRepo).execute(); - } - + this.passwordEncoder = passwordEncoder; + this.leverRepo = leverRepo; + this.nodeRepo = nodeRepo; + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + URL url = DevMongoModelsConfig.class.getClassLoader().getResource("initial-groups.json"); + new CreateIntialGroups(url, groupRepo).execute(); + + new CreateInitialUsers(groupRepo, userRepository, ldapUserDetailsManager, passwordEncoder).execute(); + + new CreateInitialLevers(leverRepo).execute(); + new CreateIntialNodes(nodeRepo, groupRepo).execute(); + } } diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java deleted file mode 100644 index db1c56121d..0000000000 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/license/controllers/EngineLicenseController.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.integratedmodelling.klab.hub.license.controllers; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.charset.Charset; -import java.security.NoSuchProviderException; -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.io.IOUtils; -import org.bouncycastle.openpgp.PGPException; -import org.integratedmodelling.klab.api.API; -import org.integratedmodelling.klab.api.auth.ICertificate; -import org.integratedmodelling.klab.auth.KlabCertificate; -import org.integratedmodelling.klab.hub.api.EngineAuthResponeFactory; -import org.integratedmodelling.klab.hub.api.LicenseGenerator; -import org.integratedmodelling.klab.hub.api.ProfileResource; -import org.integratedmodelling.klab.hub.emails.services.EmailManager; -import org.integratedmodelling.klab.hub.exception.LicenseExpiredException; -import org.integratedmodelling.klab.hub.exception.LicenseGenerationError; -import org.integratedmodelling.klab.hub.licenses.services.LicenseConfigService; -import org.integratedmodelling.klab.hub.repository.MongoGroupRepository; -//import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; -import org.integratedmodelling.klab.hub.users.services.UserProfileService; -import org.integratedmodelling.klab.rest.EngineAuthenticationRequest; -import org.integratedmodelling.klab.rest.EngineAuthenticationResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -@RestController -public class EngineLicenseController extends LicenseController{ - - private EmailManager emailManager; - - private EngineAuthResponeFactory authFactory; - - private UserProfileService userProfileService; - - private LicenseGenerator licenseGenerator; - - @Autowired - EngineLicenseController(UserProfileService userProfileService, - LicenseConfigService configService, - MongoGroupRepository groupRepository, - EmailManager emailManager/*, - UserAuthTokenService authTokenService*/) { - this.authFactory = new EngineAuthResponeFactory(userProfileService, groupRepository, configService/*, authTokenService*/); - this.licenseGenerator = new LicenseGenerator(configService); - this.userProfileService = userProfileService; - this.emailManager = emailManager; - } - - - - @GetMapping(value= API.HUB.USER_BASE_ID, params = "certificate") - @PreAuthorize("@securityService.isUser(#id)") - public void generateCertFile(@PathVariable("id") String id, HttpServletResponse response) throws IOException { - - ProfileResource profile = userProfileService.getCurrentUserProfile(); - byte[] certFileContent = licenseGenerator.generate(profile, null); - String certFileString = String.format("attachment; filename=%s", KlabCertificate.DEFAULT_ENGINE_CERTIFICATE_FILENAME); - response.setHeader("Content-disposition", certFileString); - response.setContentType("text/plain;charset=utf-8"); - response.setContentLength(certFileContent.length); - try { - IOUtils.copy(new ByteArrayInputStream(certFileContent), response.getOutputStream()); - response.flushBuffer(); - } finally { - response.getOutputStream().close(); - } - - } - - @PostMapping(value= API.HUB.AUTHENTICATE_ENGINE) - public ResponseEntity processCertificate( - @RequestBody EngineAuthenticationRequest request, - HttpServletRequest httpRequest) throws MessagingException { - String remoteAddr = ""; - - if (httpRequest != null) { - remoteAddr = httpRequest.getHeader("X-FORWARDED-FOR"); - if (remoteAddr == null || "".equals(remoteAddr)) { - remoteAddr = httpRequest.getRemoteAddr(); - } - } - - if(httpRequest.getHeader("test") != null) { - remoteAddr = "128.0.0.1"; - } - - EngineAuthenticationResponse response = null; - - try { - response = authFactory - .getRespone(request, remoteAddr); - } catch (NoSuchProviderException | IOException | PGPException e) { - throw new LicenseGenerationError("Issue in authenticating certificate."); - } catch (LicenseExpiredException e) { - emailManager.expiredLicenseEmail(request.getEmail()); - } - - return new ResponseEntity<>(response, HttpStatus.OK); - } - - @PostMapping(value= API.HUB.LEGACY_AUTHENTICATE_ENGINE) - public ResponseEntity processLegacyEndpoint(HttpServletRequest request) throws IOException, MessagingException { - final String str = IOUtils.toString(request.getInputStream(), Charset.defaultCharset()); - JsonObject translate = new Gson().fromJson(str, JsonObject.class); - EngineAuthenticationRequest newRequest = new EngineAuthenticationRequest(); - newRequest.setCertificate(translate.get("certificate").getAsString()); - newRequest.setName(translate.get("username").getAsString()); - newRequest.setKey(translate.get("userKey").getAsString()); - newRequest.setUserType(translate.get("userType").getAsString()); - newRequest.setLevel(ICertificate.Level.USER); - return processCertificate(newRequest, request); - } - -} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/licenses/controllers/EngineLicenseController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/licenses/controllers/EngineLicenseController.java index 3a2322b777..cc855d7f06 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/licenses/controllers/EngineLicenseController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/licenses/controllers/EngineLicenseController.java @@ -23,7 +23,6 @@ import org.integratedmodelling.klab.hub.repository.MongoGroupRepository; import org.integratedmodelling.klab.hub.tags.enums.TagNameEnum; import org.integratedmodelling.klab.hub.tags.services.TagNotificationService; -import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; import org.integratedmodelling.klab.hub.users.dto.ProfileResource; import org.integratedmodelling.klab.hub.users.services.UserProfileService; import org.integratedmodelling.klab.rest.EngineAuthenticationRequest; @@ -53,12 +52,24 @@ public class EngineLicenseController extends LicenseController encoders = new - * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); - * encoders.put("SHA512", new LdapShaPasswordEncoder()); - * DelegatingPasswordEncoder delegatingPasswordEncoder = new - * DelegatingPasswordEncoder(encodingId, encoders); - * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new - * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; - */ - @Bean - public PasswordEncoder passwordEncoder() { - return new LdapShaPasswordEncoder(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .cors() - .and() - .csrf() - .disable() - .exceptionHandling() - .authenticationEntryPoint(unauthorizedHandler) - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() - .antMatchers(HttpMethod.GET, HubRequestMatchers.getAgreements()) - .permitAll() - .antMatchers(HttpMethod.POST, HubRequestMatchers.getAuthentication()) - .permitAll() - .regexMatchers(HttpMethod.POST, HubRequestMatchers.getUsersPost()) - .permitAll() - .regexMatchers(HttpMethod.GET, HubRequestMatchers.getUsersGet()) - .permitAll() - .regexMatchers(HttpMethod.PUT, HubRequestMatchers.getUsersPut()) - .permitAll() - .anyRequest() - .authenticated() - .and() - .oauth2Login() - .authorizationEndpoint() - .baseUri("/oauth2/authorize") - .authorizationRequestRepository(cookieAuthorizationRequestRepository()) - .and() - .redirectionEndpoint() - .baseUri("/oauth2/callback/*") - .and() - .userInfoEndpoint() - .userService(oAuth2UserService) - .and() - .successHandler(oAuth2AuthenticationSuccessHandler) - .failureHandler(oAuth2AuthenticationFailureHandler); - - - http.csrf().disable().antMatcher("/api/**") - .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); - //.addFilterBefore(WebSecurityCorsFilter(), ChannelProcessingFilter.class); - } - -// Left here as a last resort -// public class WebSecurityCorsFilter implements Filter { -// @Override -// public void init(FilterConfig filterConfig) throws ServletException { -// } -// @Override -// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { -// HttpServletResponse res = (HttpServletResponse) response; -// res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control"); -// chain.doFilter(request, res); -// } -// @Override -// public void destroy() { -// } -// } - - @Bean - CorsConfigurationSource corsConfigurationSource() { - final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - final CorsConfiguration config = new CorsConfiguration(); - config.setAllowCredentials(false); - config.setAllowedOrigins(ImmutableList.of( - "https://integratedmodelling.org", - "https://test.integratedmodelling.org", - "http://localhost:8080", - "https://localhost:8080", - "http://localhost:8081", - "https://localhost:8081", - "http://localhost:8284", - "https://localhost:8284")); - config.setAllowedHeaders(Collections.singletonList("*")); - config.addExposedHeader("Content-disposition"); - config.addExposedHeader(HttpHeaders.LOCATION); - config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "HEAD")); - source.registerCorsConfiguration("/**", config); - return source; - } - -} \ No newline at end of file +//package org.integratedmodelling.klab.hub.security; +// +//import java.util.Arrays; +//import java.util.Collections; +// +//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.config.KeycloakWebSecurityConfigurerAdapter; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Bean; +//import org.springframework.http.HttpMethod; +//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +//import org.springframework.security.config.annotation.web.builders.HttpSecurity; +//import org.springframework.security.config.http.SessionCreationPolicy; +//import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +//import org.springframework.security.crypto.password.LdapShaPasswordEncoder; +//import org.springframework.security.crypto.password.PasswordEncoder; +//import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; +//import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +//import org.springframework.web.cors.CorsConfiguration; +//import org.springframework.web.cors.CorsConfigurationSource; +//import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +// +//import com.google.common.collect.ImmutableList; +//import com.google.common.net.HttpHeaders; +// +////@SuppressWarnings("deprecation") +////@Configuration +////@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true) +//@KeycloakConfiguration +//@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +//public class WebSecurityConfig extends KeycloakWebSecurityConfigurerAdapter { +// +//// @Autowired +//// UserDetailsService userDetailsService; +//// +//// @Autowired +//// private JwtAuthenticationEntryPoint unauthorizedHandler; +//// +//// @Autowired +//// private OAuth2UserService oAuth2UserService; +// +//// @Autowired +//// private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler; +// +//// @Autowired +//// private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler; +// +//// @Bean +//// public TokenAuthenticationFilter tokenAuthenticationFilter() { +//// return new TokenAuthenticationFilter(); +//// } +// +// @Bean +// @Override +// protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { +// return new NullAuthenticatedSessionStrategy(); +// } +// +// @Bean +// public KeycloakConfigResolver KeycloakConfigResolver() { +// return new KeycloakSpringBootConfigResolver(); +// } +// +// // public static final String AUTHENTICATION_TOKEN_HEADER_NAME = "Authentication"; +// +// @Autowired +// public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { +// KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); +// keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); +// auth.authenticationProvider(keycloakAuthenticationProvider); +// } +// +// /** +// * TODO incorporate this where? this allows us to assign our own HTTP response +// * status code, by using an exception class which is annotated with it directly. +// * (otherwise we would rely on Spring's container logic to assign a 'redirect' +// * or other default status.) +// */ +//// AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler(){ +//// @Override +//// public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) +//// throws IOException, ServletException { +//// throw new KlabAuthorizationException("Authentication failed."); +//// } +//// }; +// +//// @Bean +//// public HttpCookieOAuth2AuthorizationRequestRepository cookieAuthorizationRequestRepository() { +//// return new HttpCookieOAuth2AuthorizationRequestRepository(); +//// } +// +// /** +// * this is necessary so that HubAuthenticationManager injection points can be +// * populated. +// */ +//// @Bean(BeanIds.AUTHENTICATION_MANAGER) +//// @Override +//// public AuthenticationManager authenticationManagerBean() throws Exception { +//// return super.authenticationManagerBean(); +//// } +// +//// @Override +//// public void configure(AuthenticationManagerBuilder auth) throws Exception { +//// auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); +//// } +// +// /** +// * The allows our password encoder to have multiple entries. Allowing us to upgrade user +// * passwords without needing to do some serious migration effort. It is possible that +// * we will need to have users set a new password, or force the system to rehash the password +// * when the user logs in. +// * +// * In the end there are limited possibilities in the options here. The better way would be +// * to use a proper encoder and not some deprecated methodm but crowd can only handle one type +// * of encrcyption at a time. +// * +// * +// * String encodingId = "bcrypt"; Map encoders = new +// * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); +// * encoders.put("SHA512", new LdapShaPasswordEncoder()); +// * DelegatingPasswordEncoder delegatingPasswordEncoder = new +// * DelegatingPasswordEncoder(encodingId, encoders); +// * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new +// * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; +// */ +// @Bean +// public PasswordEncoder passwordEncoder() { +// return new LdapShaPasswordEncoder(); +// } +// +// @Override +// protected void configure(HttpSecurity http) throws Exception { +// http.cors().and().csrf().disable().exceptionHandling() +//// .authenticationEntryPoint(unauthorizedHandler) +// .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() +// .antMatchers(HttpMethod.GET, HubRequestMatchers.getAgreements()).permitAll() +// .antMatchers(HttpMethod.POST, HubRequestMatchers.getAuthentication()).permitAll() +// .regexMatchers(HttpMethod.POST, HubRequestMatchers.getUsersPost()).permitAll() +// .regexMatchers(HttpMethod.GET, HubRequestMatchers.getUsersGet()).permitAll() +// .regexMatchers(HttpMethod.PUT, HubRequestMatchers.getUsersPut()).permitAll().anyRequest().authenticated().and() +// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); +//// .oauth2Login().authorizationEndpoint().baseUri("/oauth2/authorize") +//// .authorizationRequestRepository(cookieAuthorizationRequestRepository()).and().redirectionEndpoint() +//// .baseUri("/oauth2/callback/*").and().userInfoEndpoint(); +//// .userService(oAuth2UserService).and() +//// .successHandler(oAuth2AuthenticationSuccessHandler) +//// .failureHandler(oAuth2AuthenticationFailureHandler); +// +// http.csrf().disable().antMatcher("/api/**"); +//// .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); +// // .addFilterBefore(WebSecurityCorsFilter(), ChannelProcessingFilter.class); +// } +// +//// Left here as a last resort +//// public class WebSecurityCorsFilter implements Filter { +//// @Override +//// public void init(FilterConfig filterConfig) throws ServletException { +//// } +//// @Override +//// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { +//// HttpServletResponse res = (HttpServletResponse) response; +//// res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control"); +//// chain.doFilter(request, res); +//// } +//// @Override +//// public void destroy() { +//// } +//// } +// +// @Bean +// CorsConfigurationSource corsConfigurationSource() { +// final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); +// final CorsConfiguration config = new CorsConfiguration(); +// config.setAllowCredentials(false); +// config.setAllowedOrigins(ImmutableList.of("https://integratedmodelling.org", "https://test.integratedmodelling.org", +// "http://localhost:8080", "https://localhost:8080", "http://localhost:8081", "https://localhost:8081", +// "http://localhost:8284", "https://localhost:8284")); +// config.setAllowedHeaders(Collections.singletonList("*")); +// config.addExposedHeader("Content-disposition"); +// config.addExposedHeader(HttpHeaders.LOCATION); +// config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH", "HEAD")); +// source.registerCorsConfiguration("/**", config); +// return source; +// } +// +//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java index c4ea7410f5..ad12de3847 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/WebSecurityConfiguration.java @@ -3,7 +3,6 @@ import java.util.Arrays; import java.util.Collections; -import org.integratedmodelling.klab.hub.security.keycloak.method.KeycloakMethodSecurityExpression; import org.keycloak.adapters.KeycloakConfigResolver; import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; import org.keycloak.adapters.springsecurity.KeycloakConfiguration; @@ -11,8 +10,6 @@ import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.core.annotation.Order; -import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -30,13 +27,12 @@ import com.google.common.net.HttpHeaders; @KeycloakConfiguration -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled= true) +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) public class WebSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - KeycloakAuthenticationProvider keycloakAuthenticationProvider = - keycloakAuthenticationProvider(); + KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(keycloakAuthenticationProvider); } @@ -46,40 +42,27 @@ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new NullAuthenticatedSessionStrategy(); } - + @Bean public KeycloakConfigResolver KeycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } - + @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); - http.cors() - .and() - .csrf() - .disable() - .authorizeRequests() - .anyRequest() - .authenticated() - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); + http.cors().and().csrf().disable().authorizeRequests().anyRequest().authenticated().and().sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } - + @Bean CorsConfigurationSource corsConfigurationSource() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(false); - config.setAllowedOrigins(ImmutableList.of( - "https://integratedmodelling.org", - "http://localhost:8080", - "https://localhost:8080", - "http://localhost:8081", - "https://localhost:8081", - "http://localhost:8284", - "https://localhost:8284")); + config.setAllowedOrigins( + ImmutableList.of("https://integratedmodelling.org", "http://localhost:8080", "https://localhost:8080", + "http://localhost:8081", "https://localhost:8081", "http://localhost:8284", "https://localhost:8284")); config.setAllowedHeaders(Collections.singletonList("*")); config.addExposedHeader("Content-disposition"); config.addExposedHeader(HttpHeaders.LOCATION); @@ -87,18 +70,18 @@ CorsConfigurationSource corsConfigurationSource() { source.registerCorsConfiguration("/**", config); return source; } - - /** - * The allows our password encoder to have multiple entries. Allowing us to upgrade user - * passwords without needing to do some serious migration effort. It is possible that - * we will need to have users set a new password, or force the system to rehash the password - * when the user logs in. - * - * In the end there are limited possibilities in the options here. The better way would be - * to use a proper encoder and not some deprecated methodm but crowd can only handle one type - * of encrcyption at a time. - * - * + + /** + * The allows our password encoder to have multiple entries. Allowing us to upgrade user + * passwords without needing to do some serious migration effort. It is possible that + * we will need to have users set a new password, or force the system to rehash the password + * when the user logs in. + * + * In the end there are limited possibilities in the options here. The better way would be + * to use a proper encoder and not some deprecated methodm but crowd can only handle one type + * of encrcyption at a time. + * + * * String encodingId = "bcrypt"; Map encoders = new * HashMap<>(); encoders.put(encodingId, new BCryptPasswordEncoder()); * encoders.put("SHA512", new LdapShaPasswordEncoder()); @@ -106,9 +89,9 @@ CorsConfigurationSource corsConfigurationSource() { * DelegatingPasswordEncoder(encodingId, encoders); * delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(new * LdapShaPasswordEncoder()); return delegatingPasswordEncoder; - */ - @Bean - public PasswordEncoder passwordEncoder() { - return new LdapShaPasswordEncoder(); - } + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new LdapShaPasswordEncoder(); + } } \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java index 285b22275a..6bb2d6b22e 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/security/oauth2/OAuth2AuthenticationSuccessHandler.java @@ -2,21 +2,23 @@ // //import java.io.IOException; //import java.io.PrintWriter; +// //import javax.servlet.ServletException; //import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletResponse; // -//import org.integratedmodelling.klab.hub.api.TokenAuthentication; -//import org.integratedmodelling.klab.hub.api.TokenType; -//import org.integratedmodelling.klab.hub.api.ProfileResource; //import org.integratedmodelling.klab.hub.config.LinkConfig; +//import org.integratedmodelling.klab.hub.tokens.dto.TokenAuthentication; +//import org.integratedmodelling.klab.hub.tokens.enums.TokenType; //import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; +//import org.integratedmodelling.klab.hub.users.dto.ProfileResource; //import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; //import org.springframework.security.core.Authentication; //import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; //import org.springframework.security.web.authentication.AuthenticationSuccessHandler; //import org.springframework.stereotype.Component; +// //import com.fasterxml.jackson.databind.ObjectMapper; // //@Component @@ -24,33 +26,30 @@ // // @Autowired // private ObjectMapper objectMapper; -// +// // @Autowired // UserAuthTokenService userAuthTokenService; -// +// // @Autowired // LinkConfig tokenClickbackConfig; -// +// // @Autowired // OAuth2AuthenticationSuccessHandler(MappingJackson2HttpMessageConverter messageConverter) { // this.objectMapper = messageConverter.getObjectMapper(); // } -// +// // @Override -// public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, -// Authentication authentication) throws IOException, ServletException { -// OAuth2AuthenticationToken oAuthToken = (OAuth2AuthenticationToken) authentication; +// public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) +// throws IOException, ServletException { +// OAuth2AuthenticationToken oAuthToken = (OAuth2AuthenticationToken) authentication; // response.setStatus(HttpServletResponse.SC_OK); // response.setContentType("application/json"); // ProfileResource profile = (ProfileResource) authentication.getPrincipal(); // TokenAuthentication token = userAuthTokenService.createToken(profile.getUsername(), TokenType.auth); // String profileString = objectMapper.writeValueAsString(profile); // response.setHeader("Authorization", token.getTokenString()); -// String redirect = String.format( -// "%s/%s?token=%s", -// tokenClickbackConfig.getCallbackUrl().toString(), -// oAuthToken.getAuthorizedClientRegistrationId(), -// token.getTokenString()); +// String redirect = String.format("%s/%s?token=%s", tokenClickbackConfig.getCallbackUrl().toString(), +// oAuthToken.getAuthorizedClientRegistrationId(), token.getTokenString()); // response.sendRedirect(redirect); // PrintWriter out = response.getWriter(); // out.print(profileString); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java index fe43bc5d09..1281439316 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java @@ -13,11 +13,9 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import lombok.Getter; import lombok.NoArgsConstructor; @Builder -@Getter @Data @AllArgsConstructor @NoArgsConstructor diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java index ce0c03df56..1db725e421 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenService.java @@ -1,16 +1,16 @@ -package org.integratedmodelling.klab.hub.tokens.services; - -import org.integratedmodelling.klab.hub.tokens.dto.TokenAuthentication; -import org.integratedmodelling.klab.hub.users.payload.LoginResponse; -import org.integratedmodelling.klab.hub.users.payload.LogoutResponse; -import org.springframework.stereotype.Service; - -@Service -public interface UserAuthTokenService { -// public TokenAuthentication getUserAuthenticationToken(String username, String password); - - public LoginResponse getAuthResponse(String username, String password, boolean jwtToken); - -// public LogoutResponse getLogoutResponse(String token); - -} +//package org.integratedmodelling.klab.hub.tokens.services; +// +//import org.integratedmodelling.klab.hub.tokens.dto.TokenAuthentication; +//import org.integratedmodelling.klab.hub.users.payload.LoginResponse; +//import org.integratedmodelling.klab.hub.users.payload.LogoutResponse; +//import org.springframework.stereotype.Service; +// +//@Service +//public interface UserAuthTokenService extends TokenBaseService { +// public TokenAuthentication getUserAuthenticationToken(String username, String password); +// +// public LoginResponse< ? > getAuthResponse(String username, String password, boolean jwtToken); +// +// public LogoutResponse getLogoutResponse(String token); +// +//} diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java index 1a7d1063ba..3ec99c4d61 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tokens/services/UserAuthTokenServiceImpl.java @@ -1,23 +1,26 @@ //package org.integratedmodelling.klab.hub.tokens.services; // //import java.util.List; -// //import java.util.Optional; // //import org.integratedmodelling.klab.exceptions.KlabException; -//import org.integratedmodelling.klab.hub.api.TokenAuthentication; -//import org.integratedmodelling.klab.hub.api.ProfileResource; -//import org.integratedmodelling.klab.hub.api.TokenType; -//import org.integratedmodelling.klab.hub.api.User; -//import org.integratedmodelling.klab.hub.commands.CreateUserAuthenticationToken; -//import org.integratedmodelling.klab.hub.commands.DeleteAuthenticationToken; -//import org.integratedmodelling.klab.hub.commands.GetUserProfile; -//import org.integratedmodelling.klab.hub.exception.AuthenticationFailedException; -//import org.integratedmodelling.klab.hub.exception.LoginFailedExcepetion; -//import org.integratedmodelling.klab.hub.payload.LoginResponse; -//import org.integratedmodelling.klab.hub.payload.LogoutResponse; +//import org.integratedmodelling.klab.hub.licenses.dto.JwtToken; +//import org.integratedmodelling.klab.hub.payload.EngineProfileResource; //import org.integratedmodelling.klab.hub.repository.TokenRepository; //import org.integratedmodelling.klab.hub.repository.UserRepository; +//import org.integratedmodelling.klab.hub.tokens.commands.CreateUserAuthenticationToken; +//import org.integratedmodelling.klab.hub.tokens.commands.DeleteAuthenticationToken; +//import org.integratedmodelling.klab.hub.tokens.dto.TokenAuthentication; +//import org.integratedmodelling.klab.hub.tokens.enums.TokenType; +//import org.integratedmodelling.klab.hub.tokens.exceptions.AuthenticationFailedException; +//import org.integratedmodelling.klab.hub.users.commands.GetUserProfile; +//import org.integratedmodelling.klab.hub.users.dto.ProfileResource; +//import org.integratedmodelling.klab.hub.users.dto.User; +//import org.integratedmodelling.klab.hub.users.exceptions.LoginFailedExcepetion; +//import org.integratedmodelling.klab.hub.users.payload.LoginResponse; +//import org.integratedmodelling.klab.hub.users.payload.LogoutResponse; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; //import org.springframework.security.authentication.AuthenticationManager; //import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; //import org.springframework.security.core.Authentication; @@ -27,89 +30,104 @@ //import org.springframework.stereotype.Service; // //import com.fasterxml.jackson.databind.ObjectMapper; +//import com.mongodb.MongoException; // //@Service -//public class UserAuthTokenServiceImpl implements UserAuthTokenService{ -// -// private AuthenticationManager authenticationManager; -// -// private UserRepository userRepository; -// -// private TokenRepository tokenRepository; -// -// private ObjectMapper objectMapper; -// -// public UserAuthTokenServiceImpl(AuthenticationManager authenticationManager, UserRepository userRepository, -// TokenRepository tokenRepository, ObjectMapper objectMapper) { -// super(); -// this.authenticationManager = authenticationManager; -// this.userRepository = userRepository; -// this.tokenRepository = tokenRepository; -// this.objectMapper = objectMapper; -// } -// -// @Override -// public TokenAuthentication createToken(String username, TokenType type) { -// if(TokenType.auth == type) { -// TokenAuthentication token = null; -// Optional user = userRepository.findByNameIgnoreCase(username); -// if(user.isPresent()) { -// token = new CreateUserAuthenticationToken(tokenRepository, user.get()).execute(); -// } -// return token; -// } else { -// throw new AuthenticationFailedException("Incorrect workflow for creating token"); -// } -// } -// -// -// @Override -// public void deleteToken(String tokenString) { -// new DeleteAuthenticationToken(tokenRepository, tokenString).execute(); -// } -// -// private void deleteExpiredTokens(String username) { -// List dbTokens = tokenRepository.findByUsername(username); -// for (TokenAuthentication dbToken : dbTokens) { -// if (dbToken.isExpired()) { -// deleteToken(dbToken.getTokenString()); -// } -// } -// } -// -// @Override -// public TokenAuthentication getUserAuthenticationToken(String username, String password) { -// Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password); -// try { -// authRequest = authenticationManager.authenticate(authRequest); -// } catch (AuthenticationException e) { -// throw new LoginFailedExcepetion(username); -// } -// if (!authRequest.isAuthenticated()) { -// String msg = "Something went wrong with authentication. Result.isAuthenticated() == false, but no exception was thrown."; -// throw new KlabException(msg); -// } else { -// deleteExpiredTokens(username); -// TokenAuthentication result = createToken(username, TokenType.auth); -// PreAuthenticatedAuthenticationToken secureToken = new PreAuthenticatedAuthenticationToken(result.getPrincipal(),result.getCredentials(),result.getAuthorities()); -// SecurityContextHolder.getContext().setAuthentication(secureToken); -// return result; -// } -// } -// -// @Override -// public LoginResponse getAuthResponse(String username, String password) { -// TokenAuthentication token = getUserAuthenticationToken(username, password); -// ProfileResource profile = new GetUserProfile(userRepository, username, objectMapper).execute(); -// LoginResponse response = new LoginResponse(token, profile.getSafeProfile()); -// return response; -// } -// -// @Override -// public LogoutResponse getLogoutResponse(String token) { -// deleteToken(token); -// String username = SecurityContextHolder.getContext().getAuthentication().getName(); -// return new LogoutResponse(username); -// } -// -//} +//public class UserAuthTokenServiceImpl implements UserAuthTokenService { +// +// protected static final Logger logger = LoggerFactory.getLogger(UserAuthTokenServiceImpl.class); +// +// private AuthenticationManager authenticationManager; +// +// private UserRepository userRepository; +// +// private TokenRepository tokenRepository; +// +// private ObjectMapper objectMapper; +// +// public UserAuthTokenServiceImpl(AuthenticationManager authenticationManager, UserRepository userRepository, +// TokenRepository tokenRepository, ObjectMapper objectMapper) { +// super(); +// this.authenticationManager = authenticationManager; +// this.userRepository = userRepository; +// this.tokenRepository = tokenRepository; +// this.objectMapper = objectMapper; +// } +// +// private static final JwtToken JWT_TOKEN_FACTORY = new JwtToken(); +// +// @Override +// public TokenAuthentication createToken(String username, TokenType type) { +// if (TokenType.auth == type) { +// TokenAuthentication token = null; +// Optional user = userRepository.findByNameIgnoreCase(username); +// if (user.isPresent()) { +// token = new CreateUserAuthenticationToken(tokenRepository, user.get()).execute(); +// } +// return token; +// } else { +// throw new AuthenticationFailedException("Incorrect workflow for creating token"); +// } +// } +// +// @Override +// public void deleteToken(String tokenString) { +// try { +// new DeleteAuthenticationToken(tokenRepository, tokenString).execute(); +// } catch (MongoException e) { +// logger.error(e.getMessage(), e); +// throw new KlabException("Error deleting token, " + e.getMessage(), e); +// } +// } +// +// private void deleteExpiredTokens(String username) { +// List dbTokens = tokenRepository.findByUsername(username); +// for(TokenAuthentication dbToken : dbTokens) { +// if (dbToken.isExpired()) { +// deleteToken(dbToken.getTokenString()); +// } +// } +// } +// +// @Override +// public TokenAuthentication getUserAuthenticationToken(String username, String password) { +// Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password); +// try { +// authRequest = authenticationManager.authenticate(authRequest); +// } catch (AuthenticationException e) { +// throw new LoginFailedExcepetion(username); +// } +// if (!authRequest.isAuthenticated()) { +// String msg = "Something went wrong with authentication. Result.isAuthenticated() == false, but no exception was thrown."; +// throw new KlabException(msg); +// } else { +// deleteExpiredTokens(username); +// TokenAuthentication result = createToken(username, TokenType.auth); +// PreAuthenticatedAuthenticationToken secureToken = new PreAuthenticatedAuthenticationToken(result.getPrincipal(), +// result.getCredentials(), result.getAuthorities()); +// SecurityContextHolder.getContext().setAuthentication(secureToken); +// return result; +// } +// } +// +// @SuppressWarnings("rawtypes") +// @Override +// public LoginResponse< ? > getAuthResponse(String username, String password, boolean remote) { +// TokenAuthentication token = getUserAuthenticationToken(username, password); +// ProfileResource profile = new GetUserProfile(userRepository, username, objectMapper).execute(); +// if (remote) { +// profile.setJwtToken(JWT_TOKEN_FACTORY.createEngineJwtToken(profile)); +// return new LoginResponse(token, new EngineProfileResource(profile)); +// } else { +// return new LoginResponse(token, profile.getSafeProfile()); +// } +// } +// +// @Override +// public LogoutResponse getLogoutResponse(String token) { +// deleteToken(token); +// String username = SecurityContextHolder.getContext().getAuthentication().getName(); +// return new LogoutResponse(username); +// } +// +//} \ No newline at end of file diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java index 0335ff4264..c380a03eab 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserAuthenticationController.java @@ -1,48 +1,30 @@ package org.integratedmodelling.klab.hub.users.controllers; -import java.security.Principal; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - import org.integratedmodelling.klab.api.API; -import org.integratedmodelling.klab.hub.api.ProfileResource; -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.keycloak.common.Profile; -import org.keycloak.representations.AccessToken; -import org.keycloak.representations.AccessToken.Access; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; -import net.minidev.json.JSONObject; - @RestController public class UserAuthenticationController { - - - + // private UserAuthTokenService userAuthService; // // @Autowired // UserAuthenticationController(UserAuthTokenService userAuthService) { // this.userAuthService = userAuthService; // } - + // @PostMapping(API.HUB.AUTHENTICATE_USER) // public ResponseEntity loginResponse(@RequestBody UserAuthenticationRequest request) { // LoginResponse response = userAuthService.getAuthResponse(request.getUsername(), request.getPassword()); // return response.getResponse(); // } - - @PostMapping(API.HUB.AUTHENTICATE_USER) - public ResponseEntity loginResponse() { - System.out.println("holis"); + + @PostMapping(API.HUB.AUTHENTICATE_USER) + public ResponseEntity< ? > loginResponse() { + System.out.println("holis"); // LoginResponse response = userAuthService.getAuthResponse("", ""); // return response.getResponse(); // Principal hola = request.getUserPrincipal(); @@ -68,17 +50,17 @@ public ResponseEntity loginResponse() { // headers.add("Authentication", ); // return new ResponseEntity(resp, headers, HttpStatus.OK); // return response.getResponse(); - return new ResponseEntity<>("hemos entrado con el token", HttpStatus.OK); + return new ResponseEntity<>("hemos entrado con el token", HttpStatus.OK); } - - @PostMapping(API.HUB.AUTHENTICATE_USER+"2") - public ResponseEntity loginResponse2() { + + @PostMapping(API.HUB.AUTHENTICATE_USER + "2") + public ResponseEntity< ? > loginResponse2() { System.out.println("holis"); // LoginResponse response = userAuthService.getAuthResponse("", ""); // return response.getResponse(); return new ResponseEntity<>("hemos entrado con el token", HttpStatus.OK); } - + // @PostMapping(API.HUB.DEAUTHENTICATE_USER) // public ResponseEntity logoutResponse(@RequestHeader("Authentication") String token) { // LogoutResponse response = userAuthService.getLogoutResponse(token); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java index 78e20f569b..8d17c02e39 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserProfileController.java @@ -18,10 +18,8 @@ import org.integratedmodelling.klab.hub.tokens.enums.TokenType; import org.integratedmodelling.klab.hub.tokens.exceptions.ActivationTokenFailedException; import org.integratedmodelling.klab.hub.tokens.services.RegistrationTokenService; -import org.integratedmodelling.klab.hub.tokens.services.UserAuthTokenService; import org.integratedmodelling.klab.hub.users.dto.ProfileResource; import org.integratedmodelling.klab.hub.users.dto.User; -import org.integratedmodelling.klab.hub.users.payload.UpdateEmailRequest; import org.integratedmodelling.klab.hub.users.payload.UpdateEmailResponse; import org.integratedmodelling.klab.hub.users.payload.UpdateUserRequest; import org.integratedmodelling.klab.hub.users.services.UserProfileService; @@ -41,72 +39,28 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import net.minidev.json.JSONObject; - @RestController public class UserProfileController { - private UserProfileService userService; - - @Autowired - UserProfileController(UserProfileService userService) { - this.userService = userService; - } - - @GetMapping(API.HUB.USER_BASE) - @PreAuthorize("hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") - public ResponseEntity< ? > getAllUserProfiles() { - JSONObject profiles = new JSONObject().appendField("profiles", userService.getAllUserProfiles()); - return new ResponseEntity<>(profiles, HttpStatus.OK); - } - - @GetMapping(API.HUB.USER_BASE_ID) - @PreAuthorize("authentication.getPrincipal() == #id or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") - public ResponseEntity< ? > getUserProfile(@PathVariable String id) { - ProfileResource profile = userService.getUserProfile(id); - return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); - } - - @GetMapping(API.HUB.CURRENT_PROFILE) - // TODO this is call from single user, not need PreAuthorize - // correct the auth should be caught on the token filter side. - public ResponseEntity< ? > getCurrentUserProfile() { - ProfileResource profile = userService.getCurrentUserProfile(); - return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); - } - - @PutMapping(API.HUB.USER_BASE_ID) - @PreAuthorize("authentication.getPrincipal() == #id") - public ResponseEntity< ? > updateUserProfile(@PathVariable String id, @RequestBody UpdateUserRequest updateRequest) { - ProfileResource profile = userService.updateUserByProfile(updateRequest.getProfile()); - return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); - } - - @GetMapping(value = API.HUB.USER_BASE_ID, params = "remote-login") - @PreAuthorize("authentication.getPrincipal() == #id") - public ResponseEntity< ? > getFullUserProfile(@PathVariable String id) { - ProfileResource profile = userService.getRawUserProfile(id); - return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); - } - private UserProfileService userService; private final GenericPageAndFilterConverter genericPageAndFilterConverter; private final FilterBuilderService filterBuilderService; private RegistrationTokenService tokenService; - private UserAuthTokenService userAuthService; +// private UserAuthTokenService userAuthService; private static final JwtToken JWT_TOKEN_FACTORY = new JwtToken(); private static final String FILTER_NO_GROUPS = "$NO_GROUPS$"; @Autowired UserProfileController(UserProfileService userService, GenericPageAndFilterConverter genericPageAndFilterConverter, - FilterBuilderService filterBuilderService, RegistrationTokenService tokenService, - UserAuthTokenService userAuthService) { + FilterBuilderService filterBuilderService, RegistrationTokenService tokenService +// ,UserAuthTokenService userAuthService + ) { this.userService = userService; this.genericPageAndFilterConverter = genericPageAndFilterConverter; this.filterBuilderService = filterBuilderService; this.tokenService = tokenService; - this.userAuthService = userAuthService; +// this.userAuthService = userAuthService; } @GetMapping(API.HUB.USER_BASE) @@ -166,7 +120,7 @@ public class UserProfileController { } @GetMapping(API.HUB.USER_BASE_ID) - @PreAuthorize("authentication.getPrincipal() == #id or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") + @PreAuthorize("@securityService.isUser(#id) or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") public ResponseEntity< ? > getUserProfile(@PathVariable String id) { ProfileResource profile = userService.getUserProfile(id); return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); @@ -203,14 +157,14 @@ public class UserProfileController { } @PutMapping(API.HUB.USER_BASE_ID) - @PreAuthorize("authentication.getPrincipal() == #id or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") + @PreAuthorize("@securityService.isUser(#id) or hasRole('ROLE_ADMINISTRATOR') or hasRole('ROLE_SYSTEM')") public ResponseEntity< ? > updateUserProfile(@PathVariable String id, @RequestBody UpdateUserRequest updateRequest) { ProfileResource profile = userService.updateUserByProfile(updateRequest.getProfile()); return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); } @PostMapping(value = API.HUB.USER_BASE_ID, params = API.HUB.PARAMETERS.USER_REQUEST_EMAIL) - @PreAuthorize("authentication.getPrincipal() == #id") + @PreAuthorize("@securityService.isUser(#id)") public ResponseEntity< ? > requestNewUserEmail(@PathVariable String id, @RequestParam(API.HUB.PARAMETERS.USER_REQUEST_EMAIL) String requestNewEmail) { ProfileResource profile; @@ -223,42 +177,43 @@ public class UserProfileController { } - @PutMapping(value = API.HUB.USER_BASE_ID, params = API.HUB.PARAMETERS.USER_SET_EMAIL) - public ResponseEntity< ? > updateUserEmail(@PathVariable String id, - @RequestParam(API.HUB.PARAMETERS.USER_SET_EMAIL) String setPassword, - @RequestBody UpdateEmailRequest updateEmailRequest) { - - /* Check user and password are correct */ - try { - userAuthService.getAuthResponse(updateEmailRequest.getUsername(), updateEmailRequest.getPassword(), - updateEmailRequest.isRemote()); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Incorrect password."); - } - - /* Check token is correct */ - TokenVerifyEmailClickback token = (TokenVerifyEmailClickback) tokenService.getAndVerifyToken(id, - updateEmailRequest.getToken(), TokenType.verifyEmail); - if (token == null) { - throw new ActivationTokenFailedException("User Verification token failed"); - } - - /* Update user email */ - try { - userService.updateUserEmail(id, updateEmailRequest.getEmail()); - - tokenService.deleteToken(token.getTokenString()); - - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); - } - - JSONObject resp = new JSONObject(); - return new ResponseEntity(resp, HttpStatus.CREATED); - } + // TODO keycloak +// @PutMapping(value = API.HUB.USER_BASE_ID, params = API.HUB.PARAMETERS.USER_SET_EMAIL) +// public ResponseEntity< ? > updateUserEmail(@PathVariable String id, +// @RequestParam(API.HUB.PARAMETERS.USER_SET_EMAIL) String setPassword, +// @RequestBody UpdateEmailRequest updateEmailRequest) { +// +// /* Check user and password are correct */ +// try { +// userAuthService.getAuthResponse(updateEmailRequest.getUsername(), updateEmailRequest.getPassword(), +// updateEmailRequest.isRemote()); +// } catch (Exception e) { +// return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Incorrect password."); +// } +// +// /* Check token is correct */ +// TokenVerifyEmailClickback token = (TokenVerifyEmailClickback) tokenService.getAndVerifyToken(id, +// updateEmailRequest.getToken(), TokenType.verifyEmail); +// if (token == null) { +// throw new ActivationTokenFailedException("User Verification token failed"); +// } +// +// /* Update user email */ +// try { +// userService.updateUserEmail(id, updateEmailRequest.getEmail()); +// +// tokenService.deleteToken(token.getTokenString()); +// +// } catch (Exception e) { +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); +// } +// +// JSONObject resp = new JSONObject(); +// return new ResponseEntity(resp, HttpStatus.CREATED); +// } @GetMapping(value = API.HUB.USER_BASE_ID, params = "remote-login") - @PreAuthorize("authentication.getPrincipal() == #id") + @PreAuthorize("@securityService.isUser(#id)") public ResponseEntity< ? > getFullUserProfile(@PathVariable String id) { ProfileResource profile = userService.getRawUserProfile(id); return new ResponseEntity<>(profile, HttpStatus.ACCEPTED); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserRegistrationController.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserRegistrationController.java index d2795a9e96..3d00fa432e 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserRegistrationController.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/controllers/UserRegistrationController.java @@ -110,7 +110,7 @@ public ResponseEntity newUserPassword(@PathVariable String id, @RequestParam( } @PostMapping(value=API.HUB.USER_BASE_ID, params = API.HUB.PARAMETERS.USER_REQUEST_PASSWORD) - @PreAuthorize("authentication.getPrincipal() == #id" ) + @PreAuthorize("@securityService.isUser(#id)" ) public ResponseEntity authorizedPasswordChange(@PathVariable String id) { TokenChangePasswordClickback token = (TokenChangePasswordClickback) tokenService.createToken(id, TokenType.password); diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java index 4b5a8613be..1d58745725 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserProfileServiceImpl.java @@ -11,11 +11,6 @@ import org.integratedmodelling.klab.hub.emails.services.EmailManager; import org.integratedmodelling.klab.hub.ldap.LdapServiceImpl; import org.integratedmodelling.klab.hub.repository.UserRepository; -import org.keycloak.KeycloakPrincipal; -import org.keycloak.KeycloakSecurityContext; -import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; -import org.keycloak.representations.AccessToken; -import org.keycloak.representations.IDToken; import org.integratedmodelling.klab.hub.tags.enums.TagNameEnum; import org.integratedmodelling.klab.hub.tags.services.TagNotificationService; import org.integratedmodelling.klab.hub.tokens.dto.TokenVerifyEmailClickback; @@ -26,6 +21,10 @@ import org.integratedmodelling.klab.hub.users.dto.User; import org.integratedmodelling.klab.hub.users.exceptions.UserByEmailDoesNotExistException; import org.integratedmodelling.klab.hub.users.exceptions.UserDoesNotExistException; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; +import org.keycloak.representations.AccessToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; @@ -45,26 +44,7 @@ public class UserProfileServiceImpl implements UserProfileService { private UserRepository userRepository; private LdapServiceImpl ldapServiceImpl; - @Override - public ProfileResource getCurrentUserProfile() { - KeycloakAuthenticationToken authentication = - (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); - - Principal principal = (Principal) authentication.getPrincipal(); - - String preferredUsername = ""; - - if (principal instanceof KeycloakPrincipal) { - KeycloakPrincipal kPrincipal = (KeycloakPrincipal) principal; - AccessToken token = kPrincipal.getKeycloakSecurityContext().getToken(); - preferredUsername = token.getPreferredUsername(); - } - User user = userRepository.findByNameIgnoreCase(preferredUsername) - .orElseThrow(() -> - new UserDoesNotExistException()); - ProfileResource profile = objectMapper.convertValue(user, ProfileResource.class); - return profile.getSafeProfile(); - } + private ObjectMapper objectMapper; private EmailManager emailManager; @@ -114,12 +94,25 @@ public ProfileResource getUserProfile(String username) { @Override public ProfileResource getCurrentUserProfile(boolean remote) { - String username = SecurityContextHolder.getContext().getAuthentication().getName(); - User user = getUser(username); + KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext() + .getAuthentication(); + + Principal principal = (Principal) authentication.getPrincipal(); + + String preferredUsername = ""; + + if (principal instanceof KeycloakPrincipal) { + KeycloakPrincipal kPrincipal = (KeycloakPrincipal) principal; + AccessToken token = kPrincipal.getKeycloakSecurityContext().getToken(); + preferredUsername = token.getPreferredUsername(); + } + User user = userRepository.findByNameIgnoreCase(preferredUsername).orElseThrow(() -> new UserDoesNotExistException()); ProfileResource profile = objectMapper.convertValue(user, ProfileResource.class); + if (remote) { return profile; } + return profile.getSafeProfile(); } diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserRegistrationServiceImpl.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserRegistrationServiceImpl.java index 45aee037c6..c7c2c320b9 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserRegistrationServiceImpl.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/users/services/UserRegistrationServiceImpl.java @@ -33,88 +33,16 @@ public class UserRegistrationServiceImpl implements UserRegistrationService { private UserRepository userRepository; - private PasswordEncoder passwordEncoder; + private PasswordEncoder passwordEncoder; private LdapServiceImpl ldapService; private LdapUserDetailsManager ldapUserDetailsManager; private HubEventPublisher publisher; private AgreementService agreementService; - @Override - public User registerNewUser(String username, String email) { - Optional pendingUser = checkIfUserPending(username, email); - if (pendingUser.isPresent()) { - return pendingUser.get(); - } else { - User newUser = new User(); - newUser.setUsername(username); - newUser.setEmail(email); - newUser = new CreatePendingUser(userRepository, newUser).execute(); - publisher.publish(new NewUserAdded(new Object(), newUser)); - return newUser; - } - - } - - @Override - public User registerUser(User user) { - Optional pendingUser = checkIfUserPending(user.getName(), user.getEmail()); - if (pendingUser.isPresent()) { - return pendingUser.get(); - } else { - User newUser = new CreateUserWithRolesAndStatus(user, userRepository/*, ldapUserDetailsManager*/).execute(); - return newUser; - } - - } - - private Optional checkIfUserPending(String username, String email) { - boolean existInMongo = userRepository. - findByNameIgnoreCaseOrEmailIgnoreCase(username, email) - .isPresent(); - - if(existInMongo) { - boolean usernameExists = userRepository - .findByNameIgnoreCase(username) - .isPresent(); - - boolean emailExists = userRepository - .findByEmailIgnoreCase(email) - .isPresent(); - - boolean ldapExists = ldapUserExists(username, email); - - if(ldapExists && usernameExists && emailExists) { - throw new UserExistsException(username); - } - - if(!ldapExists && usernameExists && emailExists) { - //we need to return a user who has not activated there account and will be asked to - //reactivate with an email. - Optional pendingUser = userRepository.findByNameIgnoreCase(username) - .filter(u -> u.getAccountStatus().equals(AccountStatus.pendingActivation)); - pendingUser - .orElseThrow(()-> new BadRequestException("User exists but has not set a password. " - + "Please make a forgot password request.")); - return pendingUser; - } - - if(usernameExists != emailExists) { - if (usernameExists) - throw new UserExistsException(username); - else - throw new UserEmailExistsException(email); - } - - throw new UserExistsException("How did we get here?"); - - } else { - return Optional.empty(); - } - } @Autowired - public UserRegistrationServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder, LdapServiceImpl ldapServiceImpl, - LdapUserDetailsManager ldapUserDetailsManager, HubEventPublisher publisher, - AgreementService agreementService) { + public UserRegistrationServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder, + LdapServiceImpl ldapServiceImpl, LdapUserDetailsManager ldapUserDetailsManager, + HubEventPublisher publisher, AgreementService agreementService) { super(); this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; @@ -148,16 +76,17 @@ public User addAgreement(User user, Agreement agreement) { } @Override - public User createAndAddAgreement(User user, AgreementType agreementType, AgreementLevel agreementLevel) { - List agreements = user.getAgreements().stream().filter((agreement) -> - agreement.getAgreement().getAgreementType().equals(agreementType) && - agreement.getAgreement().getAgreementLevel().equals(agreementLevel)).toList(); - + public User createAndAddAgreement(User user, AgreementType agreementType, AgreementLevel agreementLevel) { + List agreements = user.getAgreements().stream() + .filter((agreement) -> agreement.getAgreement().getAgreementType().equals(agreementType) + && agreement.getAgreement().getAgreementLevel().equals(agreementLevel)) + .toList(); + if (agreements.isEmpty()) { Agreement agreement = agreementService.createAgreement(agreementType, agreementLevel).stream().findFirst().get(); user = addAgreement(user, agreement); - } - + } + return user; } @@ -178,14 +107,13 @@ private Optional checkIfUserPending(String username, String email) { boolean emailExists = userRepository.findByEmailIgnoreCase(email).isPresent(); if (usernameExists || emailExists) { - + boolean ldapExists = false; try { ldapExists = ldapService.userExists(username, email); } catch (BadRequestException bre) { throw new UserNameOrEmailExistsException(); } - if (ldapExists && usernameExists && emailExists) { throw new UserExistsException(username); @@ -235,7 +163,8 @@ public User setPassword(String username, String password, String confirm) { u -> u.getAccountStatus().equals(AccountStatus.verified) | u.getAccountStatus().equals(AccountStatus.active)) .orElseThrow(() -> new BadRequestException("User not active or verified")); - if (user.getAccountStatus().equals(AccountStatus.verified) | !ldapService.userExists(user.getUsername(), user.getEmail())) { + if (user.getAccountStatus().equals(AccountStatus.verified) + | !ldapService.userExists(user.getUsername(), user.getEmail())) { user = new SetUserPasswordHash(user, password, passwordEncoder).execute(); user = new CreateLdapUser(user, ldapUserDetailsManager).execute(); user.setAccountStatus(AccountStatus.active); From 91af5ebc9274e051b8df3c8845c3e773a10b83c6 Mon Sep 17 00:00:00 2001 From: Kristina Date: Wed, 15 May 2024 16:38:57 +0200 Subject: [PATCH 08/10] IM-333 Add MongoTag getters and setter to avoid lombok polugin --- klab.hub/.classpath | 3 +- klab.hub/.settings/org.eclipse.jdt.core.prefs | 8 ++-- .../klab/hub/tags/dto/MongoTag.java | 44 +++++++++++++++++++ klab.hub/src/main/resources/application.yml | 16 ++++--- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/klab.hub/.classpath b/klab.hub/.classpath index 492fba4207..530c84185a 100644 --- a/klab.hub/.classpath +++ b/klab.hub/.classpath @@ -11,9 +11,8 @@ - + - diff --git a/klab.hub/.settings/org.eclipse.jdt.core.prefs b/klab.hub/.settings/org.eclipse.jdt.core.prefs index d089a9b734..29fe717b87 100644 --- a/klab.hub/.settings/org.eclipse.jdt.core.prefs +++ b/klab.hub/.settings/org.eclipse.jdt.core.prefs @@ -1,11 +1,11 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java index 1281439316..e1945517dc 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java @@ -52,4 +52,48 @@ public void setName(String name) { this.name = name; } + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Period getTimeToExpiration() { + return timeToExpiration; + } + + public void setTimeToExpiration(Period timeToExpiration) { + this.timeToExpiration = timeToExpiration; + } + + public String getTagElementId() { + return tagElementId; + } + + public void setTagElementId(String tagElementId) { + this.tagElementId = tagElementId; + } + + public ITagElement getITagElement() { + return iTagElement; + } + + public void setITagElement(ITagElement iTagElement) { + this.iTagElement = iTagElement; + } + + public Boolean getVisible() { + return visible; + } + + public void setVisible(Boolean visible) { + this.visible = visible; + } + + public String getName() { + return name; + } + } diff --git a/klab.hub/src/main/resources/application.yml b/klab.hub/src/main/resources/application.yml index 05ae7035a0..8f93709e2b 100644 --- a/klab.hub/src/main/resources/application.yml +++ b/klab.hub/src/main/resources/application.yml @@ -5,8 +5,6 @@ server: error: include-message: always spring: - main: - allow-bean-definition-overriding: true cloud: bus: enabled: false @@ -43,7 +41,7 @@ mongo: ldap: partitionSuffix: dc=integratedmodelling,dc=org principal: cn=admin,dc=integratedmodelling,dc=org - password: SuperSecret + password: curd-h0cod port: 389 url: ldap://localhost:389 userGroup: ou=groups @@ -72,10 +70,10 @@ engine: email: server: - hostname: mail.provider.com + hostname: mail.privateemail.com port: 587 - username: email@integratedmodelling.org - password: someRandomPassword + username: noreply@integratedmodelling.org + password: r8UtFl9F3m21 default: domain: integratedmodelling.org @@ -112,3 +110,9 @@ license: pubRing: filename: "keyring/PubRing.pgp" digest: "cad134cc3dfcb0e96acb90af56532a96171f858c4c30335541932c0e00a66c9deab764805d9b9f08a49619af211b96305b512d4cf256e8a9c29877d06d207c72" + +keycloak: + realm: k.Hub + auth-server-url: http://localhost:8078 + resource: spring-boot-keycloack-client + bearer-only: true From 3467815c1844d2f8443e42f5279982503890a802 Mon Sep 17 00:00:00 2001 From: Kristina Date: Wed, 15 May 2024 16:38:57 +0200 Subject: [PATCH 09/10] Revert "IM-333 Add MongoTag getters and setter to avoid lombok polugin" This reverts commit 91af5ebc9274e051b8df3c8845c3e773a10b83c6. --- klab.hub/.classpath | 3 +- klab.hub/.settings/org.eclipse.jdt.core.prefs | 8 ++-- .../klab/hub/tags/dto/MongoTag.java | 44 ------------------- klab.hub/src/main/resources/application.yml | 16 +++---- 4 files changed, 12 insertions(+), 59 deletions(-) diff --git a/klab.hub/.classpath b/klab.hub/.classpath index 530c84185a..492fba4207 100644 --- a/klab.hub/.classpath +++ b/klab.hub/.classpath @@ -11,8 +11,9 @@ - + + diff --git a/klab.hub/.settings/org.eclipse.jdt.core.prefs b/klab.hub/.settings/org.eclipse.jdt.core.prefs index 29fe717b87..d089a9b734 100644 --- a/klab.hub/.settings/org.eclipse.jdt.core.prefs +++ b/klab.hub/.settings/org.eclipse.jdt.core.prefs @@ -1,11 +1,11 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java index e1945517dc..1281439316 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java @@ -52,48 +52,4 @@ public void setName(String name) { this.name = name; } - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Period getTimeToExpiration() { - return timeToExpiration; - } - - public void setTimeToExpiration(Period timeToExpiration) { - this.timeToExpiration = timeToExpiration; - } - - public String getTagElementId() { - return tagElementId; - } - - public void setTagElementId(String tagElementId) { - this.tagElementId = tagElementId; - } - - public ITagElement getITagElement() { - return iTagElement; - } - - public void setITagElement(ITagElement iTagElement) { - this.iTagElement = iTagElement; - } - - public Boolean getVisible() { - return visible; - } - - public void setVisible(Boolean visible) { - this.visible = visible; - } - - public String getName() { - return name; - } - } diff --git a/klab.hub/src/main/resources/application.yml b/klab.hub/src/main/resources/application.yml index 8f93709e2b..05ae7035a0 100644 --- a/klab.hub/src/main/resources/application.yml +++ b/klab.hub/src/main/resources/application.yml @@ -5,6 +5,8 @@ server: error: include-message: always spring: + main: + allow-bean-definition-overriding: true cloud: bus: enabled: false @@ -41,7 +43,7 @@ mongo: ldap: partitionSuffix: dc=integratedmodelling,dc=org principal: cn=admin,dc=integratedmodelling,dc=org - password: curd-h0cod + password: SuperSecret port: 389 url: ldap://localhost:389 userGroup: ou=groups @@ -70,10 +72,10 @@ engine: email: server: - hostname: mail.privateemail.com + hostname: mail.provider.com port: 587 - username: noreply@integratedmodelling.org - password: r8UtFl9F3m21 + username: email@integratedmodelling.org + password: someRandomPassword default: domain: integratedmodelling.org @@ -110,9 +112,3 @@ license: pubRing: filename: "keyring/PubRing.pgp" digest: "cad134cc3dfcb0e96acb90af56532a96171f858c4c30335541932c0e00a66c9deab764805d9b9f08a49619af211b96305b512d4cf256e8a9c29877d06d207c72" - -keycloak: - realm: k.Hub - auth-server-url: http://localhost:8078 - resource: spring-boot-keycloack-client - bearer-only: true From f3feb2d87574a119474951991a964466a1cb2b72 Mon Sep 17 00:00:00 2001 From: Kristina Date: Wed, 15 May 2024 16:41:21 +0200 Subject: [PATCH 10/10] Add MongoTag getters and setters to avoid lombok plugin --- .../klab/hub/tags/dto/MongoTag.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java index 1281439316..e1945517dc 100644 --- a/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java +++ b/klab.hub/src/main/java/org/integratedmodelling/klab/hub/tags/dto/MongoTag.java @@ -52,4 +52,48 @@ public void setName(String name) { this.name = name; } + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Period getTimeToExpiration() { + return timeToExpiration; + } + + public void setTimeToExpiration(Period timeToExpiration) { + this.timeToExpiration = timeToExpiration; + } + + public String getTagElementId() { + return tagElementId; + } + + public void setTagElementId(String tagElementId) { + this.tagElementId = tagElementId; + } + + public ITagElement getITagElement() { + return iTagElement; + } + + public void setITagElement(ITagElement iTagElement) { + this.iTagElement = iTagElement; + } + + public Boolean getVisible() { + return visible; + } + + public void setVisible(Boolean visible) { + this.visible = visible; + } + + public String getName() { + return name; + } + }