diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/InMemoryUserManagementConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/InMemoryUserManagementConfiguration.java new file mode 100644 index 000000000..fc979fd67 --- /dev/null +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/InMemoryUserManagementConfiguration.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.autoconfigure.security; + +import java.util.ArrayList; + +import org.eclipse.hawkbit.im.authentication.MultitenancyIndicator; +import org.eclipse.hawkbit.im.authentication.PermissionUtils; +import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; + +/** + * Auto-configuration for the in-memory-user-management. + * + */ +@Configuration +@ConditionalOnMissingBean(UserDetailsService.class) +public class InMemoryUserManagementConfiguration extends GlobalAuthenticationConfigurerAdapter { + + @Override + public void configure(final AuthenticationManagerBuilder auth) throws Exception { + final DaoAuthenticationProvider userDaoAuthenticationProvider = new TenantDaoAuthenticationProvider(); + userDaoAuthenticationProvider.setUserDetailsService(userDetailsService()); + auth.authenticationProvider(userDaoAuthenticationProvider); + } + + /** + * @return the user details service to load a user from memory user manager. + */ + @Bean + @ConditionalOnMissingBean + public UserDetailsService userDetailsService() { + final InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(new ArrayList<>()); + inMemoryUserDetailsManager.setAuthenticationManager(null); + inMemoryUserDetailsManager.createUser(new User("admin", "admin", PermissionUtils.createAllAuthorityList())); + return inMemoryUserDetailsManager; + } + + /** + * @return the multi-tenancy indicator to disallow multi-tenancy + */ + @Bean + @ConditionalOnMissingBean + public MultitenancyIndicator multiTenancyIndicator() { + return () -> false; + } + + private static class TenantDaoAuthenticationProvider extends DaoAuthenticationProvider { + + @Override + protected Authentication createSuccessAuthentication(final Object principal, + final Authentication authentication, final UserDetails user) { + final UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal, + authentication.getCredentials(), user.getAuthorities()); + result.setDetails(new TenantAwareAuthenticationDetails("DEFAULT", false)); + return result; + } + } +} diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java index 8c44f0496..d74b27dc8 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java @@ -8,43 +8,17 @@ */ package org.eclipse.hawkbit.autoconfigure.security; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.hawkbit.im.authentication.MultitenancyIndicator; import org.eclipse.hawkbit.im.authentication.PermissionService; -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.im.authentication.UserAuthenticationFilter; import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SpringSecurityAuditorAware; import org.eclipse.hawkbit.tenancy.TenantAware; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.AuditorAware; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; -import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; /** * {@link EnableAutoConfiguration Auto-configuration} for security. @@ -88,119 +62,4 @@ public class SecurityAutoConfiguration { return new SpringSecurityAuditorAware(); } - /** - * Auto-configuration for the in-memory-user-management. - * - * - * - */ - @Configuration - @ConditionalOnMissingBean(value = { UserAuthenticationFilter.class }) - public static class InMemoryUserManagementConfiguration extends GlobalAuthenticationConfigurerAdapter { - - private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryUserManagementConfiguration.class); - - @Autowired - private AuthenticationConfiguration configuration; - - /* - * (non-Javadoc) - * - * @see org.springframework.security.config.annotation.authentication. - * configurers. GlobalAuthenticationConfigurerAdapter - * #configure(org.springframework.security.config.annotation. - * authentication.builders.AuthenticationManagerBuilder) - */ - @Override - public void configure(final AuthenticationManagerBuilder auth) throws Exception { - final DaoAuthenticationProvider userDaoAuthenticationProvider = new TenantDaoAuthenticationProvider(); - userDaoAuthenticationProvider.setUserDetailsService(userDetailsService()); - auth.authenticationProvider(userDaoAuthenticationProvider); - } - - /** - * @return the user details service to load a user from memory user - * manager. - */ - @Bean - public UserDetailsService userDetailsService() { - final InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager( - new ArrayList<>()); - inMemoryUserDetailsManager.setAuthenticationManager(null); - inMemoryUserDetailsManager.createUser(new User("admin", "admin", getAllAuthorities())); - return inMemoryUserDetailsManager; - } - - /** - * @return the multi-tenancy indicator to disallow multi-tenancy - */ - @Bean - public MultitenancyIndicator multiTenancyIndicator() { - return new MultitenancyIndicator() { - @Override - public boolean isMultiTenancySupported() { - return false; - } - }; - } - - private Collection getAllAuthorities() { - final List allPermissions = new ArrayList<>(); - final Field[] declaredFields = SpPermission.class.getDeclaredFields(); - for (final Field field : declaredFields) { - if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { - field.setAccessible(true); - try { - final String permissionName = (String) field.get(null); - allPermissions.add(new SimpleGrantedAuthority(permissionName)); - } catch (final IllegalAccessException e) { - LOGGER.error(e.getMessage(), e); - } - } - } - return allPermissions; - } - - private static class TenantDaoAuthenticationProvider extends DaoAuthenticationProvider { - /* - * (non-Javadoc) - * - * @see org.springframework.security.authentication.dao. - * AbstractUserDetailsAuthenticationProvider - * #createSuccessAuthentication(java.lang.Object, - * org.springframework.security.core.Authentication, - * org.springframework.security.core.userdetails.UserDetails) - */ - @Override - protected Authentication createSuccessAuthentication(final Object principal, - final Authentication authentication, final UserDetails user) { - final UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal, - authentication.getCredentials(), user.getAuthorities()); - result.setDetails(new TenantAwareAuthenticationDetails("DEFAULT", false)); - return result; - } - } - - /** - * @return the {@link UserAuthenticationFilter} to include into the SP - * security configuration. - * @throws Exception - * lazy bean exception maybe if the authentication manager - * cannot be instantiated - */ - @Bean - public UserAuthenticationFilter userAuthenticationFilter() throws Exception { - return new UserAuthenticationFilterBasicAuth(configuration.getAuthenticationManager()); - } - - private static final class UserAuthenticationFilterBasicAuth extends BasicAuthenticationFilter - implements UserAuthenticationFilter { - - private UserAuthenticationFilterBasicAuth(final AuthenticationManager authenticationManager) { - super(authenticationManager); - } - - } - } - } diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index 825e21c12..fc7a0a1e4 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -8,6 +8,10 @@ */ package org.eclipse.hawkbit.autoconfigure.security; +import static com.google.common.collect.Lists.newArrayList; +import static org.springframework.context.annotation.AdviceMode.ASPECTJ; +import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; + import java.io.IOException; import java.net.URI; @@ -46,18 +50,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.boot.context.embedded.ServletListenerRegistrationBean; import org.springframework.cache.Cache; -import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.WebSecurityConfigurer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -72,6 +77,8 @@ import org.springframework.security.web.access.intercept.FilterSecurityIntercept import org.springframework.security.web.authentication.AnonymousAuthenticationFilter; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy; import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter; import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode; @@ -83,30 +90,49 @@ import org.vaadin.spring.security.web.VaadinRedirectStrategy; import org.vaadin.spring.security.web.authentication.VaadinAuthenticationSuccessHandler; import org.vaadin.spring.security.web.authentication.VaadinUrlAuthenticationSuccessHandler; -import com.google.common.collect.Lists; - /** - * All configurations related to SP authentication and authorization layer. - * - * - * + * All configurations related to HawkBit's authentication and authorization + * layer. */ @Configuration @EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true) +@EnableGlobalMethodSecurity(prePostEnabled = true, mode = ASPECTJ, proxyTargetClass = true, securedEnabled = true) @EnableWebMvcSecurity -@Order(value = Ordered.HIGHEST_PRECEDENCE) +@Order(value = HIGHEST_PRECEDENCE) public class SecurityManagedConfiguration { + private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class); @Autowired private HawkbitSecurityProperties securityProperties; + @Autowired + private AuthenticationConfiguration configuration; + + /** + * @return the {@link UserAuthenticationFilter} to include into the SP + * security configuration. + * @throws Exception + * lazy bean exception maybe if the authentication manager + * cannot be instantiated + */ + @Bean + @ConditionalOnMissingBean + public UserAuthenticationFilter userAuthenticationFilter() throws Exception { + return new UserAuthenticationFilterBasicAuth(configuration.getAuthenticationManager()); + } + + private static final class UserAuthenticationFilterBasicAuth extends BasicAuthenticationFilter + implements UserAuthenticationFilter { + + private UserAuthenticationFilterBasicAuth(final AuthenticationManager authenticationManager) { + super(authenticationManager); + } + + } + /** * {@link WebSecurityConfigurer} for the internal SP controller API. - * - * - * */ @Configuration @Order(300) @@ -114,19 +140,25 @@ public class SecurityManagedConfiguration { @Autowired private ControllerManagement controllerManagement; + @Autowired private TenantConfigurationManagement tenantConfigurationManagement; + @Autowired private TenantAware tenantAware; + @Autowired private DdiSecurityProperties ddiSecurityConfiguration; + @Autowired private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties; + @Autowired private SystemSecurityContext systemSecurityContext; @Override protected void configure(final HttpSecurity http) throws Exception { + final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource(); final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter( @@ -164,16 +196,19 @@ public class SecurityManagedConfiguration { } if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) { + LOG.info( - "******************\n** Anonymous controller security enabled, should only use for developing purposes **\n******************"); + "******************\n** Anonymous controller security enabled, should only be used for developing purposes **\n******************"); + final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter( "controllerAnonymousFilter", "anonymous", - Lists.newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), + newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE))); anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource); httpSec.requestMatchers().antMatchers("/*/controller/v1/**", "/*/controller/artifacts/v1/**").and() .securityContext().disable().anonymous().authenticationFilter(anoymousFilter); } else { + httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter) .addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter) .antMatcher("/*/controller/**").anonymous().disable().authorizeRequests().anyRequest() @@ -186,6 +221,7 @@ public class SecurityManagedConfiguration { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider( ddiSecurityConfiguration.getRp().getTrustedIPs())); } @@ -200,6 +236,7 @@ public class SecurityManagedConfiguration { @Bean @Order(50) public FilterRegistrationBean dosFilter() { + final FilterRegistrationBean filterRegBean = new FilterRegistrationBean(); filterRegBean.setFilter(new DosFilter(securityProperties.getDos().getFilter().getMaxRead(), @@ -207,6 +244,7 @@ public class SecurityManagedConfiguration { securityProperties.getDos().getFilter().getWhitelist(), securityProperties.getClients().getBlacklist(), securityProperties.getClients().getRemoteIpHeader())); filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*"); + return filterRegBean; } @@ -219,22 +257,21 @@ public class SecurityManagedConfiguration { @Bean @Order(100) public FilterRegistrationBean eTagFilter() { + final FilterRegistrationBean filterRegBean = new FilterRegistrationBean(); - // eclude the URLs for downloading artifacts, so no eTag is generated in - // the - // ShallowEtagHeaderFilter, just using the SH1 hash of the artifact - // itself as 'ETag', because - // otherwise the file will be copied in memory! + // Exclude the URLs for downloading artifacts, so no eTag is generated + // in the ShallowEtagHeaderFilter, just using the SH1 hash of the + // artifact itself as 'ETag', because otherwise the file will be copied + // in memory! filterRegBean.setFilter(new ExcludePathAwareShallowETagFilter( "/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download", "/{tenant}/controller/artifacts/**", "/{targetid}/softwaremodules/{softwareModuleId}/artifacts/**")); + return filterRegBean; } /** * Security configuration for the REST management API of the health url. - * - * */ @Configuration @Order(310) @@ -249,28 +286,34 @@ public class SecurityManagedConfiguration { /** * Security configuration for the REST management API. - * - * */ @Configuration @Order(350) public static class RestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + @Autowired private UserAuthenticationFilter userAuthenticationFilter; + @Autowired private SystemManagement systemManagement; + @Autowired private TenantAware tenantAware; + @Autowired - private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties; + private SecurityProperties springSecurityProperties; @Override protected void configure(final HttpSecurity http) throws Exception { + final BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint(); + basicAuthEntryPoint.setRealmName(springSecurityProperties.getBasic().getRealm()); + HttpSecurity httpSec = http.regexMatcher("\\/rest.*|\\/system.*").csrf().disable(); if (springSecurityProperties.isRequireSsl()) { httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and(); } + httpSec.addFilterBefore(new Filter() { @Override public void init(final FilterConfig filterConfig) throws ServletException { @@ -296,12 +339,13 @@ public class SecurityManagedConfiguration { .hasAnyAuthority(SpPermission.SYSTEM_ADMIN) .antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/**") .hasAnyAuthority(SpPermission.SYSTEM_DIAG); + + httpSec.httpBasic().and().exceptionHandling().authenticationEntryPoint(basicAuthEntryPoint); } } /** * {@link WebSecurityConfigurer} for external (management) access. - * */ @Configuration @Order(400) @@ -311,10 +355,13 @@ public class SecurityManagedConfiguration { private static final String XFRAME_OPTION_DENY = "DENY"; private static final String XFRAME_OPTION_SAMEORIGIN = "SAMEORIGIN"; private static final String XFAME_OPTION_ALLOW_FROM = "ALLOW-FROM"; + @Autowired private VaadinSecurityContext vaadinSecurityContext; + @Autowired private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties; + @Autowired private HawkbitSecurityProperties securityProperties; @@ -346,10 +393,13 @@ public class SecurityManagedConfiguration { */ @Bean public VaadinAuthenticationSuccessHandler redirectSaveHandler() { + final VaadinUrlAuthenticationSuccessHandler handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler(); + handler.setRedirectStrategy(vaadinRedirectStrategy()); handler.setDefaultTargetUrl("/UI/"); handler.setTargetUrlParameter("r"); + return handler; } @@ -371,7 +421,8 @@ public class SecurityManagedConfiguration { // configuration xframe-option final String confXframeOption = securityProperties.getXframe().getOption(); final String confAllowFromUri = securityProperties.getXframe().getAllowfrom(); - if (confXframeOption.equals(XFAME_OPTION_ALLOW_FROM) && confAllowFromUri.isEmpty()) { + + if (XFAME_OPTION_ALLOW_FROM.equals(confXframeOption) && confAllowFromUri.isEmpty()) { // if allow-from option is specified but no allowFromUri throw // exception throw new IllegalStateException("hawkbit.server.security.xframe.option has been specified as ALLOW-FROM" @@ -380,9 +431,8 @@ public class SecurityManagedConfiguration { } // workaround regex: we need to exclude the URL /UI/HEARTBEAT here - // because we bound the - // vaadin application to /UI and not to root, described in - // vaadin-forum: + // because we bound the vaadin application to /UI and not to root, + // described in vaadin-forum: // https://vaadin.com/forum#!/thread/3200565. HttpSecurity httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/UI.*$") // disable as CSRF is handled by Vaadin @@ -391,8 +441,9 @@ public class SecurityManagedConfiguration { if (springSecurityProperties.isRequireSsl()) { httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and(); } else { + LOG.info( - "\"******************\\n** Requires HTTPS Security has been disabled for UI, should only use for developing purposes **\\n******************\""); + "\"******************\\n** Requires HTTPS Security has been disabled for UI, should only be used for developing purposes **\\n******************\""); } // for UI integrator we allow frame integration on same origin @@ -441,9 +492,6 @@ public class SecurityManagedConfiguration { /** * A Websecruity config to handle and filter the download ids. - * - * - * */ @Configuration @EnableWebSecurity @@ -459,6 +507,7 @@ public class SecurityManagedConfiguration { @Override protected void configure(final HttpSecurity http) throws Exception { + final HttpDownloadAuthenticationFilter downloadIdAuthenticationFilter = new HttpDownloadAuthenticationFilter( downloadIdCache); downloadIdAuthenticationFilter.setAuthenticationManager(authenticationManager()); @@ -476,32 +525,21 @@ public class SecurityManagedConfiguration { auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider( ddiSecurityConfiguration.getRp().getTrustedIPs())); } - } - } /** * After a successful login on the UI we need to ensure to create the tenant * meta data within SP. - * - * */ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends VaadinUrlAuthenticationSuccessHandler { @Autowired private SystemManagement systemManagement; - /* - * (non-Javadoc) - * - * @see org.vaadin.spring.security.web.authentication. - * SavedRequestAwareVaadinAuthenticationSuccessHandler - * #onAuthenticationSuccess(org.springframework.security.core. - * Authentication) - */ @Override public void onAuthenticationSuccess(final Authentication authentication) throws Exception { + if (authentication.getClass().equals(TenantUserPasswordAuthenticationToken.class)) { systemManagement .getTenantMetadata(((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString()); @@ -515,14 +553,13 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends // has been fixed. systemManagement.getTenantMetadata("DEFAULT"); } + super.onAuthenticationSuccess(authentication); } } /** * Sevletfilter to create metadata after successful authentication over RESTful. - * - * */ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { @@ -543,11 +580,13 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { + final String currentTenant = tenantAware.getCurrentTenant(); if (currentTenant != null) { // lazy initialize tenant meta data after successful authentication systemManagement.getTenantMetadata(currentTenant); } + chain.doFilter(request, response); } diff --git a/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories b/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories index 335054585..7df1f5ed2 100644 --- a/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/hawkbit-autoconfigure/src/main/resources/META-INF/spring.factories @@ -11,4 +11,5 @@ org.eclipse.hawkbit.autoconfigure.eventbus.EventBusAutoConfiguration,\ org.eclipse.hawkbit.autoconfigure.scheduling.AsyncConfigurerAutoConfiguration,\ org.eclipse.hawkbit.autoconfigure.cache.RedisAutoConfiguration,\ org.eclipse.hawkbit.autoconfigure.scheduling.ExecutorAutoConfiguration,\ -org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration +org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration,\ +org.eclipse.hawkbit.autoconfigure.security.InMemoryUserManagementConfiguration diff --git a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties index 488559383..9c197fbb3 100644 --- a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties +++ b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties @@ -7,6 +7,9 @@ # http://www.eclipse.org/legal/epl-v10.html # +# Displayed basic auth realm +security.basic.realm=HawkBit + # JPA / Datasource spring.jpa.eclipselink.eclipselink.weaving=false spring.jpa.database=H2 diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 50207037a..469e84681 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -11,8 +11,36 @@ package org.eclipse.hawkbit; import java.util.HashMap; import java.util.Map; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.ControllerManagement; +import org.eclipse.hawkbit.repository.DeploymentManagement; +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.ReportManagement; +import org.eclipse.hawkbit.repository.RolloutGroupManagement; +import org.eclipse.hawkbit.repository.RolloutManagement; +import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TagManagement; +import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; +import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.TenantStatsManagement; +import org.eclipse.hawkbit.repository.jpa.JpaArtifactManagement; +import org.eclipse.hawkbit.repository.jpa.JpaControllerManagement; +import org.eclipse.hawkbit.repository.jpa.JpaDeploymentManagement; +import org.eclipse.hawkbit.repository.jpa.JpaDistributionSetManagement; +import org.eclipse.hawkbit.repository.jpa.JpaEntityFactory; +import org.eclipse.hawkbit.repository.jpa.JpaReportManagement; +import org.eclipse.hawkbit.repository.jpa.JpaRolloutGroupManagement; +import org.eclipse.hawkbit.repository.jpa.JpaRolloutManagement; +import org.eclipse.hawkbit.repository.jpa.JpaSoftwareManagement; +import org.eclipse.hawkbit.repository.jpa.JpaSystemManagement; +import org.eclipse.hawkbit.repository.jpa.JpaTagManagement; +import org.eclipse.hawkbit.repository.jpa.JpaTargetFilterQueryManagement; +import org.eclipse.hawkbit.repository.jpa.JpaTargetManagement; +import org.eclipse.hawkbit.repository.jpa.JpaTenantConfigurationManagement; +import org.eclipse.hawkbit.repository.jpa.JpaTenantStatsManagement; import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler; import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager; import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; @@ -26,6 +54,7 @@ import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -35,6 +64,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; +import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; @@ -50,6 +80,7 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess @Configuration @ComponentScan @EnableAutoConfiguration +@EnableScheduling public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { /** * @return the {@link SystemSecurityContext} singleton bean which make it @@ -173,4 +204,170 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { public PlatformTransactionManager transactionManager() { return new MultiTenantJpaTransactionManager(); } + + /** + * {@link JpaSystemManagement} bean. + * + * @return a new {@link SystemManagement} + */ + @Bean + @ConditionalOnMissingBean + public SystemManagement systemManagement() { + return new JpaSystemManagement(); + } + + /** + * {@link JpaReportManagement} bean. + * + * @return a new {@link ReportManagement} + */ + @Bean + @ConditionalOnMissingBean + public ReportManagement reportManagement() { + return new JpaReportManagement(); + } + + /** + * {@link JpaDistributionSetManagement} bean. + * + * @return a new {@link DistributionSetManagement} + */ + @Bean + @ConditionalOnMissingBean + public DistributionSetManagement distributionSetManagement() { + return new JpaDistributionSetManagement(); + } + + /** + * {@link JpaTenantStatsManagement} bean. + * + * @return a new {@link TenantStatsManagement} + */ + @Bean + @ConditionalOnMissingBean + public TenantStatsManagement tenantStatsManagement() { + return new JpaTenantStatsManagement(); + } + + /** + * {@link JpaTenantConfigurationManagement} bean. + * + * @return a new {@link TenantConfigurationManagement} + */ + @Bean + @ConditionalOnMissingBean + public TenantConfigurationManagement tenantConfigurationManagement() { + return new JpaTenantConfigurationManagement(); + } + + /** + * {@link JpaTenantConfigurationManagement} bean. + * + * @return a new {@link TenantConfigurationManagement} + */ + @Bean + @ConditionalOnMissingBean + public TargetManagement targetManagement() { + return new JpaTargetManagement(); + } + + /** + * {@link JpaTargetFilterQueryManagement} bean. + * + * @return a new {@link TargetFilterQueryManagement} + */ + @Bean + @ConditionalOnMissingBean + public TargetFilterQueryManagement targetFilterQueryManagement() { + return new JpaTargetFilterQueryManagement(); + } + + /** + * {@link JpaTagManagement} bean. + * + * @return a new {@link TagManagement} + */ + @Bean + @ConditionalOnMissingBean + public TagManagement tagManagement() { + return new JpaTagManagement(); + } + + /** + * {@link JpaSoftwareManagement} bean. + * + * @return a new {@link SoftwareManagement} + */ + @Bean + @ConditionalOnMissingBean + public SoftwareManagement softwareManagement() { + return new JpaSoftwareManagement(); + } + + /** + * {@link JpaRolloutManagement} bean. + * + * @return a new {@link RolloutManagement} + */ + @Bean + @ConditionalOnMissingBean + public RolloutManagement rolloutManagement() { + return new JpaRolloutManagement(); + } + + /** + * {@link JpaRolloutGroupManagement} bean. + * + * @return a new {@link RolloutGroupManagement} + */ + @Bean + @ConditionalOnMissingBean + public RolloutGroupManagement rolloutGroupManagement() { + return new JpaRolloutGroupManagement(); + } + + /** + * {@link JpaDeploymentManagement} bean. + * + * @return a new {@link DeploymentManagement} + */ + @Bean + @ConditionalOnMissingBean + public DeploymentManagement deploymentManagement() { + return new JpaDeploymentManagement(); + } + + /** + * {@link JpaControllerManagement} bean. + * + * @return a new {@link ControllerManagement} + */ + @Bean + @ConditionalOnMissingBean + public ControllerManagement controllerManagement() { + return new JpaControllerManagement(); + } + + /** + * {@link JpaArtifactManagement} bean. + * + * @return a new {@link ArtifactManagement} + */ + + @Bean + @ConditionalOnMissingBean + public ArtifactManagement artifactManagement() { + return new JpaArtifactManagement(); + } + + /** + * {@link JpaEntityFactory} bean. + * + * @return a new {@link EntityFactory} + */ + @Bean + @ConditionalOnMissingBean + public EntityFactory entityFactory() { + return new JpaEntityFactory(); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java index ea0e5c34f..3c94d885b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java @@ -41,7 +41,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -52,7 +51,6 @@ import org.springframework.validation.annotation.Validated; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaArtifactManagement implements ArtifactManagement { private static final Logger LOG = LoggerFactory.getLogger(JpaArtifactManagement.class); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index 77b71e661..255fef2ae 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -54,7 +54,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -65,7 +64,6 @@ import org.springframework.validation.annotation.Validated; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaControllerManagement implements ControllerManagement { private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class); private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos"); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index 4739f16a7..6236e8d6f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -96,7 +96,6 @@ import com.google.common.eventbus.EventBus; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaDeploymentManagement implements DeploymentManagement { private static final Logger LOG = LoggerFactory.getLogger(JpaDeploymentManagement.class); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index f3ecbcf1b..0e97d6ff5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -60,7 +60,6 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -74,7 +73,6 @@ import com.google.common.eventbus.EventBus; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java index afa3b4dc6..a3792de54 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java @@ -42,13 +42,11 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetTag; -import org.springframework.stereotype.Service; /** * JPA Implementation of {@link EntityFactory}. * */ -@Service public class JpaEntityFactory implements EntityFactory { @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java index 76eb04a34..c6795f600 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaReportManagement.java @@ -45,7 +45,6 @@ import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -56,7 +55,6 @@ import org.springframework.validation.annotation.Validated; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaReportManagement implements ReportManagement { @Value("${spring.jpa.database}") diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java index 7d176d40a..9f63204b1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutGroupManagement.java @@ -47,7 +47,6 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -56,7 +55,6 @@ import org.springframework.validation.annotation.Validated; * JPA implementation of {@link RolloutGroupManagement}. */ @Validated -@Service @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public class JpaRolloutGroupManagement implements RolloutGroupManagement { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index d412d2164..239302a70 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -60,8 +60,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Isolation; @@ -76,8 +74,6 @@ import org.springframework.validation.annotation.Validated; * JPA implementation of {@link RolloutManagement}. */ @Validated -@Service -@EnableScheduling @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public class JpaRolloutManagement implements RolloutManagement { private static final Logger LOGGER = LoggerFactory.getLogger(RolloutManagement.class); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 2fc057aec..50127e227 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -60,7 +60,6 @@ import org.springframework.data.domain.SliceImpl; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -74,7 +73,6 @@ import com.google.common.collect.Sets; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaSoftwareManagement implements SoftwareManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java index 3fed3d858..ea6c99708 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.repository.jpa; -import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.List; import java.util.stream.Collectors; @@ -34,10 +33,8 @@ import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.interceptor.KeyGenerator; -import org.springframework.cache.interceptor.SimpleKeyGenerator; -import org.springframework.context.annotation.Bean; +import org.springframework.context.ApplicationContext; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -49,7 +46,6 @@ import org.springframework.validation.annotation.Validated; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement { @Autowired private EntityManager entityManager; @@ -108,7 +104,11 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst @Autowired private TenancyCacheManager cacheManager; - private final ThreadLocal createInitialTenant = new ThreadLocal<>(); + @Autowired + private SystemManagementCacheKeyGenerator currentTenantCacheKeyGenerator; + + @Autowired + private ApplicationContext applicationContext; @Override public SystemUsageReport getSystemUsageStatistics() { @@ -154,9 +154,8 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst @Override @Transactional(propagation = Propagation.SUPPORTS) - @Bean public KeyGenerator currentTenantKeyGenerator() { - return new CurrentTenantKeyGenerator(); + return currentTenantCacheKeyGenerator.currentTenantKeyGenerator(); } @Override @@ -169,11 +168,12 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst // Create if it does not exist if (result == null) { try { - createInitialTenant.set(tenant); + currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant); cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null)); + applicationContext.getBean("currentTenantKeyGenerator"); return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant)); } finally { - createInitialTenant.remove(); + currentTenantCacheKeyGenerator.getCreateInitialTenant().remove(); } } @@ -239,7 +239,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst // tenant is not cached anyway already. @Transactional(propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED) public String currentTenant() { - final String initialTenantCreation = createInitialTenant.get(); + final String initialTenantCreation = currentTenantCacheKeyGenerator.getCreateInitialTenant().get(); if (initialTenantCreation == null) { final TenantMetaData findByTenant = tenantMetaDataRepository .findByTenantIgnoreCase(tenantAware.getCurrentTenant()); @@ -260,29 +260,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst return tenantMetaDataRepository.save((JpaTenantMetaData) metaData); } - /** - * A implementation of the {@link KeyGenerator} to generate a key based on - * either the {@code createInitialTenant} thread local and the - * {@link TenantAware}, but in case we are in a tenant creation with its - * default types we need to use the tenant the current tenant which is - * currently created and not the one currently in the {@link TenantAware}. - * - */ - public class CurrentTenantKeyGenerator implements KeyGenerator { - @Override - // Exception squid:S923 - override - @SuppressWarnings({ "squid:S923" }) - public Object generate(final Object target, final Method method, final Object... params) { - final String initialTenantCreation = createInitialTenant.get(); - if (initialTenantCreation == null) { - return SimpleKeyGenerator.generateKey(tenantAware.getCurrentTenant().toUpperCase(), - tenantAware.getCurrentTenant().toUpperCase()); - } - return SimpleKeyGenerator.generateKey(initialTenantCreation.toUpperCase(), - initialTenantCreation.toUpperCase()); - } - } - private DistributionSetType createStandardSoftwareDataSetup() { final SoftwareModuleType app = softwareModuleTypeRepository .save(new JpaSoftwareModuleType(Constants.SMT_DEFAULT_APP_KEY, Constants.SMT_DEFAULT_APP_NAME, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java index 29fbb8a2b..e881d8ef8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java @@ -39,7 +39,6 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -52,7 +51,6 @@ import com.google.common.eventbus.EventBus; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaTagManagement implements TagManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java index f418f5f4b..65ed6faa4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java @@ -40,7 +40,6 @@ import com.google.common.base.Strings; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 892ddc771..b7a2facc8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -59,7 +59,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; @@ -75,7 +74,6 @@ import com.google.common.eventbus.EventBus; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaTargetManagement implements TargetManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java index 9f65091a4..d5d6a5540 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java @@ -23,7 +23,6 @@ import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -33,7 +32,6 @@ import org.springframework.validation.annotation.Validated; */ @Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated -@Service public class JpaTenantConfigurationManagement implements EnvironmentAware, TenantConfigurationManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java index e3866a8ad..75f99d886 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java @@ -24,7 +24,6 @@ import org.springframework.validation.annotation.Validated; * */ @Validated -@Service public class JpaTenantStatsManagement implements TenantStatsManagement { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SystemManagementCacheKeyGenerator.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SystemManagementCacheKeyGenerator.java new file mode 100644 index 000000000..2bed4aeff --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SystemManagementCacheKeyGenerator.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa; + +import java.lang.reflect.Method; + +import org.eclipse.hawkbit.tenancy.TenantAware; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.cache.interceptor.SimpleKeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Service; + +/** + * Implementation of {@link CurrentTenantCacheKeyGenerator}. + * + */ +@Service +public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyGenerator { + + @Autowired + private TenantAware tenantAware; + + private final ThreadLocal createInitialTenant = new ThreadLocal<>(); + + /** + * A implementation of the {@link KeyGenerator} to generate a key based on + * either the {@code createInitialTenant} thread local and the + * {@link TenantAware}, but in case we are in a tenant creation with its + * default types we need to use the tenant the current tenant which is + * currently created and not the one currently in the {@link TenantAware}. + * + */ + public class CurrentTenantKeyGenerator implements KeyGenerator { + @Override + // Exception squid:S923 - override + @SuppressWarnings({ "squid:S923" }) + public Object generate(final Object target, final Method method, final Object... params) { + final String initialTenantCreation = createInitialTenant.get(); + if (initialTenantCreation == null) { + return SimpleKeyGenerator.generateKey(tenantAware.getCurrentTenant().toUpperCase(), + tenantAware.getCurrentTenant().toUpperCase()); + } + return SimpleKeyGenerator.generateKey(initialTenantCreation.toUpperCase(), + initialTenantCreation.toUpperCase()); + } + } + + @Override + @Bean + public KeyGenerator currentTenantKeyGenerator() { + return new CurrentTenantKeyGenerator(); + } + + ThreadLocal getCreateInitialTenant() { + return createInitialTenant; + } + +} diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java new file mode 100644 index 000000000..cb3f5476f --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.test.matcher; + +import org.eclipse.hawkbit.repository.model.BaseEntity; +import org.hamcrest.Factory; +import org.hamcrest.FeatureMatcher; +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; + +/** + * Matcher for {@link BaseEntity}. + */ +public class BaseEntityMatcher { + + private BaseEntityMatcher() { + } + + @Factory + public static Matcher hasId(final Long id) { + return new HasIdMatcher(Matchers.equalTo(id)); + } + + private static class HasIdMatcher extends FeatureMatcher { + + public HasIdMatcher(final Matcher subMatcher) { + super(subMatcher, "getId()", "id"); + } + + @Override + protected Long featureValueOf(final BaseEntity baseEntity) { + return baseEntity.getId(); + } + } + +} diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionService.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionService.java index bad24e6c4..2cbadd02d 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionService.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionService.java @@ -17,7 +17,7 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; /** - * + * Service to check permissions. * */ public class PermissionService { diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java new file mode 100644 index 000000000..ae8b604bb --- /dev/null +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.im.authentication; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +/** + * Utility method for creation of GrantedAuthority collections etc. + */ +public final class PermissionUtils { + + private PermissionUtils() { + + } + + /** + * Create {@link GrantedAuthority} by a special role. + * + * @param roles + * the roles + * @return a list of {@link GrantedAuthority} + */ + public static List createAuthorityList(final Collection roles) { + final List authorities = new ArrayList<>(roles.size()); + + for (final String role : roles) { + authorities.add(new SimpleGrantedAuthority(role)); + } + + return authorities; + } + + /** + * Returns all authorities. + * + * @return a list of {@link GrantedAuthority} + */ + public static List createAllAuthorityList() { + return createAuthorityList(SpPermission.getAllAuthorities()); + } +} diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index bcd44e510..ce6bc7c40 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -9,7 +9,16 @@ package org.eclipse.hawkbit.im.authentication; import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.GrantedAuthority; @@ -35,6 +44,8 @@ import org.springframework.security.core.GrantedAuthority; */ public final class SpPermission { + private static final Logger LOGGER = LoggerFactory.getLogger(SpPermission.class); + /** * Permission to read the targets from the * {@link ProvisioningTargetRepository} including their meta information, @@ -139,6 +150,53 @@ public final class SpPermission { // Constants only } + /** + * Return all permission. + * + * @return all permission + */ + public static Collection getAllAuthorities() { + return getAllAuthorities(Collections.emptyList()); + } + + /** + * Return all permission. + * + * @param exclusionRoles + * roles which will excluded + * @return all permissions + */ + public static Collection getAllAuthorities(final String... exclusionRoles) { + return getAllAuthorities(Arrays.asList(exclusionRoles)); + } + + /** + * Return all permission. + * + * @param exclusionRoles + * roles which will excluded + * @return all permissions + */ + public static Collection getAllAuthorities(final Collection exclusionRoles) { + final List allPermissions = new ArrayList<>(); + final Field[] declaredFields = SpPermission.class.getDeclaredFields(); + for (final Field field : declaredFields) { + if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { + field.setAccessible(true); + try { + final String role = (String) field.get(null); + if (!(exclusionRoles.contains(role))) { + allPermissions.add(role); + } + } catch (final IllegalAccessException e) { + LOGGER.error(e.getMessage(), e); + } + + } + } + return allPermissions; + } + /** * Contains all the spring security evaluation expressions for the * {@link PreAuthorize} annotation for method security. diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java index 961b418a0..008aa3e95 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java @@ -8,8 +8,10 @@ */ package org.eclipse.hawkbit.security; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.eclipse.hawkbit.security.SecurityConstants.SECURITY_LOG_PREFIX; + import java.io.IOException; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -31,25 +33,21 @@ import com.google.common.cache.CacheBuilder; /** * Filter for protection against denial of service attacks. It reduces the * maximum number of request per seconds which can be separately configured for - * read (GET) and write (PUT/POST/DELETE) requests. requests - * - * - * - * + * read (GET) and write (PUT/POST/DELETE) requests. */ public class DosFilter extends OncePerRequestFilter { private static final Logger LOG = LoggerFactory.getLogger(DosFilter.class); - private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos"); - private static final Logger LOG_BLACKLIST = LoggerFactory.getLogger("server-security.blacklist"); + private static final Logger LOG_DOS = LoggerFactory.getLogger(SECURITY_LOG_PREFIX + ".dos"); + private static final Logger LOG_BLACKLIST = LoggerFactory.getLogger(SECURITY_LOG_PREFIX + ".blacklist"); private final Pattern ipAdressBlacklist; - private final Cache readCountCache = CacheBuilder.newBuilder() - .expireAfterAccess(1, TimeUnit.SECONDS).build(); + private final Cache readCountCache = CacheBuilder.newBuilder().expireAfterAccess(1, SECONDS) + .build(); - private final Cache writeCountCache = CacheBuilder.newBuilder() - .expireAfterAccess(1, TimeUnit.SECONDS).build(); + private final Cache writeCountCache = CacheBuilder.newBuilder().expireAfterAccess(1, SECONDS) + .build(); private final Integer maxRead; private final Integer maxWrite; @@ -78,7 +76,7 @@ public class DosFilter extends OncePerRequestFilter { */ public DosFilter(final Integer maxRead, final Integer maxWrite, final String ipDosWhiteListPattern, final String ipBlackListPattern, final String forwardHeader) { - super(); + this.maxRead = maxRead; this.maxWrite = maxWrite; this.forwardHeader = forwardHeader; @@ -96,14 +94,6 @@ public class DosFilter extends OncePerRequestFilter { } } - /* - * (non-Javadoc) - * - * @see - * org.springframework.web.filter.OncePerRequestFilter#doFilterInternal( - * javax.servlet.http. HttpServletRequest, - * javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain) - */ @Override protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException { @@ -152,11 +142,9 @@ public class DosFilter extends OncePerRequestFilter { } private static boolean handleMissingIpAddress(final HttpServletResponse response) { - boolean processChain; LOG.error("Failed to get peer IP adress"); response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); - processChain = false; - return processChain; + return false; } private boolean handleWriteRequest(final HttpServletResponse response, final String ip) { diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityConstants.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityConstants.java new file mode 100644 index 000000000..7285404a8 --- /dev/null +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityConstants.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.security; + +/** + * Constants related to security. + */ +public final class SecurityConstants { + + /** + * Logger prefix used for security logging. + */ + public static final String SECURITY_LOG_PREFIX = "server-security"; + + private SecurityConstants() { + + } +} diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java index 2d225c1dc..472e32493 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SpringSecurityAuditorAware.java @@ -14,12 +14,8 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; /** - * Auditor class that allows {@link BaseEntity}s to insert currenlt logged in - * user for repository changes. - * - * - * - * + * Auditor class that allows BaseEntitys to insert current logged in user for + * repository changes. * */ public class SpringSecurityAuditorAware implements AuditorAware { @@ -29,16 +25,21 @@ public class SpringSecurityAuditorAware implements AuditorAware { final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication == null || !authentication.isAuthenticated()) { + if (isAuthenticationInvalid(authentication)) { return null; } - if (authentication.getPrincipal() != null) { - if (authentication.getPrincipal() instanceof UserDetails) { - return ((UserDetails) authentication.getPrincipal()).getUsername(); - } - return authentication.getPrincipal().toString(); + return getCurrentAuditor(authentication); + } + + private String getCurrentAuditor(final Authentication authentication) { + if (authentication.getPrincipal() instanceof UserDetails) { + return ((UserDetails) authentication.getPrincipal()).getUsername(); } - return null; + return authentication.getPrincipal().toString(); + } + + private static boolean isAuthenticationInvalid(final Authentication authentication) { + return authentication == null || !authentication.isAuthenticated() || authentication.getPrincipal() == null; } } diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java new file mode 100644 index 000000000..bca7fd1c1 --- /dev/null +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.im.authentication; + +import static org.fest.assertions.api.Assertions.assertThat; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; +import org.springframework.context.annotation.Description; +import org.springframework.security.core.GrantedAuthority; + +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +/** + * Test {@link SpPermission}. + */ +@Features("Unit Tests - Security") +@Stories("Permission Test") +public final class PermissionTest { + + @Test + @Description("Verify the get permission function") + public void testGetPermissions() { + final int allPermission = 15; + final int permissionWithoutSystem = allPermission - 3; + final Collection allAuthorities = SpPermission.getAllAuthorities(); + final List allAuthoritiesList = PermissionUtils.createAllAuthorityList(); + assertThat(allAuthorities).hasSize(allPermission); + assertThat(allAuthoritiesList).hasSize(allPermission); + assertThat(allAuthoritiesList.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList())) + .containsAll(allAuthorities); + + final Collection authoritiesWithoutSystem = SpPermission.getAllAuthorities(SpPermission.SYSTEM_ADMIN, + SpPermission.SYSTEM_DIAG, SpPermission.SYSTEM_MONITOR); + final List authoritiesListWithoutSystem = PermissionUtils.createAuthorityList(SpPermission + .getAllAuthorities(SpPermission.SYSTEM_ADMIN, SpPermission.SYSTEM_DIAG, SpPermission.SYSTEM_MONITOR)); + + assertThat(authoritiesWithoutSystem).hasSize(permissionWithoutSystem); + assertThat(authoritiesListWithoutSystem).hasSize(permissionWithoutSystem); + assertThat(authoritiesListWithoutSystem.stream().map(authority -> authority.getAuthority()) + .collect(Collectors.toList())).containsAll(authoritiesWithoutSystem); + + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java index 8fb5a8b42..d9a964b04 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java @@ -175,11 +175,7 @@ public final class UserDetailsFormatter { private static UserDetails loadUserByUsername(final String username) { final UserDetailsService userDetailsService = SpringContextHelper.getBean(UserDetailsService.class); try { - final UserDetails loadUserByUsername = userDetailsService.loadUserByUsername(username); - if (loadUserByUsername == null) { - throw new UsernameNotFoundException("User not found " + username); - } - return loadUserByUsername; + return userDetailsService.loadUserByUsername(username); } catch (final UsernameNotFoundException e) { return new User(username, "", Collections.emptyList()); } diff --git a/pom.xml b/pom.xml index 27990b715..f50afa0ab 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,6 @@ examples - ${release.scm.connection} ${release.scm.developerConnection} @@ -88,6 +87,10 @@ 4.5 + 3.1.0 + 2.17 + 1.9.4 + 1.1.0.Final 1.4 @@ -154,6 +157,15 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + -Xlint:all + true + true + + com.mycila license-maven-plugin @@ -184,7 +196,7 @@ maven-scm-plugin - 1.9.4 + ${maven.scm.plugin.version} ${project.version} @@ -192,7 +204,6 @@ org.jacoco jacoco-maven-plugin - ${jacoco.version} prepare-ut-agent @@ -233,6 +244,7 @@ + @@ -276,7 +288,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.17 + ${maven.surefire.plugin.version} true 1 @@ -350,9 +362,13 @@ org.jacoco jacoco-maven-plugin - ${jacoco.maven.version} + ${jacoco.version} + + + org.bsc.maven + maven-processor-plugin + ${maven.processor.plugin.version} -