Merge pull request #210 from bsinno/feature_rollouts_credentials
Refactoring
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,43 +8,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.autoconfigure.security;
|
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.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.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||||
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
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.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.domain.AuditorAware;
|
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.
|
* {@link EnableAutoConfiguration Auto-configuration} for security.
|
||||||
@@ -88,119 +62,4 @@ public class SecurityAutoConfiguration {
|
|||||||
return new SpringSecurityAuditorAware();
|
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<SimpleGrantedAuthority> getAllAuthorities() {
|
|
||||||
final List<SimpleGrantedAuthority> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.autoconfigure.security;
|
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.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
@@ -46,18 +50,19 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
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.FilterRegistrationBean;
|
||||||
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
|
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.context.annotation.AdviceMode;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.Ordered;
|
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
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.method.configuration.EnableGlobalMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
|
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
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.AnonymousAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter;
|
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.StaticAllowFromStrategy;
|
||||||
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
|
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
|
||||||
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode;
|
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.VaadinAuthenticationSuccessHandler;
|
||||||
import org.vaadin.spring.security.web.authentication.VaadinUrlAuthenticationSuccessHandler;
|
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
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
|
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = ASPECTJ, proxyTargetClass = true, securedEnabled = true)
|
||||||
@EnableWebMvcSecurity
|
@EnableWebMvcSecurity
|
||||||
@Order(value = Ordered.HIGHEST_PRECEDENCE)
|
@Order(value = HIGHEST_PRECEDENCE)
|
||||||
public class SecurityManagedConfiguration {
|
public class SecurityManagedConfiguration {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class);
|
private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HawkbitSecurityProperties securityProperties;
|
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.
|
* {@link WebSecurityConfigurer} for the internal SP controller API.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@Order(300)
|
@Order(300)
|
||||||
@@ -114,19 +140,25 @@ public class SecurityManagedConfiguration {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ControllerManagement controllerManagement;
|
private ControllerManagement controllerManagement;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TenantConfigurationManagement tenantConfigurationManagement;
|
private TenantConfigurationManagement tenantConfigurationManagement;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DdiSecurityProperties ddiSecurityConfiguration;
|
private DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemSecurityContext systemSecurityContext;
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(final HttpSecurity http) throws Exception {
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
|
final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
|
||||||
|
|
||||||
final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
|
final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
|
||||||
@@ -164,16 +196,19 @@ public class SecurityManagedConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
|
if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
|
||||||
|
|
||||||
LOG.info(
|
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(
|
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
||||||
"controllerAnonymousFilter", "anonymous",
|
"controllerAnonymousFilter", "anonymous",
|
||||||
Lists.newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS),
|
newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS),
|
||||||
new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)));
|
new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)));
|
||||||
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
httpSec.requestMatchers().antMatchers("/*/controller/v1/**", "/*/controller/artifacts/v1/**").and()
|
httpSec.requestMatchers().antMatchers("/*/controller/v1/**", "/*/controller/artifacts/v1/**").and()
|
||||||
.securityContext().disable().anonymous().authenticationFilter(anoymousFilter);
|
.securityContext().disable().anonymous().authenticationFilter(anoymousFilter);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
||||||
.addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
|
.addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
|
||||||
.antMatcher("/*/controller/**").anonymous().disable().authorizeRequests().anyRequest()
|
.antMatcher("/*/controller/**").anonymous().disable().authorizeRequests().anyRequest()
|
||||||
@@ -186,6 +221,7 @@ public class SecurityManagedConfiguration {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
|
||||||
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
|
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
|
||||||
ddiSecurityConfiguration.getRp().getTrustedIPs()));
|
ddiSecurityConfiguration.getRp().getTrustedIPs()));
|
||||||
}
|
}
|
||||||
@@ -200,6 +236,7 @@ public class SecurityManagedConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@Order(50)
|
@Order(50)
|
||||||
public FilterRegistrationBean dosFilter() {
|
public FilterRegistrationBean dosFilter() {
|
||||||
|
|
||||||
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
||||||
|
|
||||||
filterRegBean.setFilter(new DosFilter(securityProperties.getDos().getFilter().getMaxRead(),
|
filterRegBean.setFilter(new DosFilter(securityProperties.getDos().getFilter().getMaxRead(),
|
||||||
@@ -207,6 +244,7 @@ public class SecurityManagedConfiguration {
|
|||||||
securityProperties.getDos().getFilter().getWhitelist(), securityProperties.getClients().getBlacklist(),
|
securityProperties.getDos().getFilter().getWhitelist(), securityProperties.getClients().getBlacklist(),
|
||||||
securityProperties.getClients().getRemoteIpHeader()));
|
securityProperties.getClients().getRemoteIpHeader()));
|
||||||
filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*");
|
filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*");
|
||||||
|
|
||||||
return filterRegBean;
|
return filterRegBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,22 +257,21 @@ public class SecurityManagedConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@Order(100)
|
@Order(100)
|
||||||
public FilterRegistrationBean eTagFilter() {
|
public FilterRegistrationBean eTagFilter() {
|
||||||
|
|
||||||
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
||||||
// eclude the URLs for downloading artifacts, so no eTag is generated in
|
// Exclude the URLs for downloading artifacts, so no eTag is generated
|
||||||
// the
|
// in the ShallowEtagHeaderFilter, just using the SH1 hash of the
|
||||||
// ShallowEtagHeaderFilter, just using the SH1 hash of the artifact
|
// artifact itself as 'ETag', because otherwise the file will be copied
|
||||||
// itself as 'ETag', because
|
// in memory!
|
||||||
// otherwise the file will be copied in memory!
|
|
||||||
filterRegBean.setFilter(new ExcludePathAwareShallowETagFilter(
|
filterRegBean.setFilter(new ExcludePathAwareShallowETagFilter(
|
||||||
"/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download", "/{tenant}/controller/artifacts/**",
|
"/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download", "/{tenant}/controller/artifacts/**",
|
||||||
"/{targetid}/softwaremodules/{softwareModuleId}/artifacts/**"));
|
"/{targetid}/softwaremodules/{softwareModuleId}/artifacts/**"));
|
||||||
|
|
||||||
return filterRegBean;
|
return filterRegBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Security configuration for the REST management API of the health url.
|
* Security configuration for the REST management API of the health url.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@Order(310)
|
@Order(310)
|
||||||
@@ -249,28 +286,34 @@ public class SecurityManagedConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Security configuration for the REST management API.
|
* Security configuration for the REST management API.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@Order(350)
|
@Order(350)
|
||||||
public static class RestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
|
public static class RestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserAuthenticationFilter userAuthenticationFilter;
|
private UserAuthenticationFilter userAuthenticationFilter;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemManagement systemManagement;
|
private SystemManagement systemManagement;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
private SecurityProperties springSecurityProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(final HttpSecurity http) throws Exception {
|
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();
|
HttpSecurity httpSec = http.regexMatcher("\\/rest.*|\\/system.*").csrf().disable();
|
||||||
if (springSecurityProperties.isRequireSsl()) {
|
if (springSecurityProperties.isRequireSsl()) {
|
||||||
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
|
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
|
||||||
}
|
}
|
||||||
|
|
||||||
httpSec.addFilterBefore(new Filter() {
|
httpSec.addFilterBefore(new Filter() {
|
||||||
@Override
|
@Override
|
||||||
public void init(final FilterConfig filterConfig) throws ServletException {
|
public void init(final FilterConfig filterConfig) throws ServletException {
|
||||||
@@ -296,12 +339,13 @@ public class SecurityManagedConfiguration {
|
|||||||
.hasAnyAuthority(SpPermission.SYSTEM_ADMIN)
|
.hasAnyAuthority(SpPermission.SYSTEM_ADMIN)
|
||||||
.antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/**")
|
.antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/**")
|
||||||
.hasAnyAuthority(SpPermission.SYSTEM_DIAG);
|
.hasAnyAuthority(SpPermission.SYSTEM_DIAG);
|
||||||
|
|
||||||
|
httpSec.httpBasic().and().exceptionHandling().authenticationEntryPoint(basicAuthEntryPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link WebSecurityConfigurer} for external (management) access.
|
* {@link WebSecurityConfigurer} for external (management) access.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@Order(400)
|
@Order(400)
|
||||||
@@ -311,10 +355,13 @@ public class SecurityManagedConfiguration {
|
|||||||
private static final String XFRAME_OPTION_DENY = "DENY";
|
private static final String XFRAME_OPTION_DENY = "DENY";
|
||||||
private static final String XFRAME_OPTION_SAMEORIGIN = "SAMEORIGIN";
|
private static final String XFRAME_OPTION_SAMEORIGIN = "SAMEORIGIN";
|
||||||
private static final String XFAME_OPTION_ALLOW_FROM = "ALLOW-FROM";
|
private static final String XFAME_OPTION_ALLOW_FROM = "ALLOW-FROM";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private VaadinSecurityContext vaadinSecurityContext;
|
private VaadinSecurityContext vaadinSecurityContext;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HawkbitSecurityProperties securityProperties;
|
private HawkbitSecurityProperties securityProperties;
|
||||||
|
|
||||||
@@ -346,10 +393,13 @@ public class SecurityManagedConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public VaadinAuthenticationSuccessHandler redirectSaveHandler() {
|
public VaadinAuthenticationSuccessHandler redirectSaveHandler() {
|
||||||
|
|
||||||
final VaadinUrlAuthenticationSuccessHandler handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler();
|
final VaadinUrlAuthenticationSuccessHandler handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler();
|
||||||
|
|
||||||
handler.setRedirectStrategy(vaadinRedirectStrategy());
|
handler.setRedirectStrategy(vaadinRedirectStrategy());
|
||||||
handler.setDefaultTargetUrl("/UI/");
|
handler.setDefaultTargetUrl("/UI/");
|
||||||
handler.setTargetUrlParameter("r");
|
handler.setTargetUrlParameter("r");
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +421,8 @@ public class SecurityManagedConfiguration {
|
|||||||
// configuration xframe-option
|
// configuration xframe-option
|
||||||
final String confXframeOption = securityProperties.getXframe().getOption();
|
final String confXframeOption = securityProperties.getXframe().getOption();
|
||||||
final String confAllowFromUri = securityProperties.getXframe().getAllowfrom();
|
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
|
// if allow-from option is specified but no allowFromUri throw
|
||||||
// exception
|
// exception
|
||||||
throw new IllegalStateException("hawkbit.server.security.xframe.option has been specified as ALLOW-FROM"
|
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
|
// workaround regex: we need to exclude the URL /UI/HEARTBEAT here
|
||||||
// because we bound the
|
// because we bound the vaadin application to /UI and not to root,
|
||||||
// vaadin application to /UI and not to root, described in
|
// described in vaadin-forum:
|
||||||
// vaadin-forum:
|
|
||||||
// https://vaadin.com/forum#!/thread/3200565.
|
// https://vaadin.com/forum#!/thread/3200565.
|
||||||
HttpSecurity httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/UI.*$")
|
HttpSecurity httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/UI.*$")
|
||||||
// disable as CSRF is handled by Vaadin
|
// disable as CSRF is handled by Vaadin
|
||||||
@@ -391,8 +441,9 @@ public class SecurityManagedConfiguration {
|
|||||||
if (springSecurityProperties.isRequireSsl()) {
|
if (springSecurityProperties.isRequireSsl()) {
|
||||||
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
|
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
LOG.info(
|
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
|
// 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.
|
* A Websecruity config to handle and filter the download ids.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@@ -459,6 +507,7 @@ public class SecurityManagedConfiguration {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(final HttpSecurity http) throws Exception {
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
final HttpDownloadAuthenticationFilter downloadIdAuthenticationFilter = new HttpDownloadAuthenticationFilter(
|
final HttpDownloadAuthenticationFilter downloadIdAuthenticationFilter = new HttpDownloadAuthenticationFilter(
|
||||||
downloadIdCache);
|
downloadIdCache);
|
||||||
downloadIdAuthenticationFilter.setAuthenticationManager(authenticationManager());
|
downloadIdAuthenticationFilter.setAuthenticationManager(authenticationManager());
|
||||||
@@ -476,32 +525,21 @@ public class SecurityManagedConfiguration {
|
|||||||
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
|
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
|
||||||
ddiSecurityConfiguration.getRp().getTrustedIPs()));
|
ddiSecurityConfiguration.getRp().getTrustedIPs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After a successful login on the UI we need to ensure to create the tenant
|
* After a successful login on the UI we need to ensure to create the tenant
|
||||||
* meta data within SP.
|
* meta data within SP.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends VaadinUrlAuthenticationSuccessHandler {
|
class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends VaadinUrlAuthenticationSuccessHandler {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SystemManagement systemManagement;
|
private SystemManagement systemManagement;
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.vaadin.spring.security.web.authentication.
|
|
||||||
* SavedRequestAwareVaadinAuthenticationSuccessHandler
|
|
||||||
* #onAuthenticationSuccess(org.springframework.security.core.
|
|
||||||
* Authentication)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticationSuccess(final Authentication authentication) throws Exception {
|
public void onAuthenticationSuccess(final Authentication authentication) throws Exception {
|
||||||
|
|
||||||
if (authentication.getClass().equals(TenantUserPasswordAuthenticationToken.class)) {
|
if (authentication.getClass().equals(TenantUserPasswordAuthenticationToken.class)) {
|
||||||
systemManagement
|
systemManagement
|
||||||
.getTenantMetadata(((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString());
|
.getTenantMetadata(((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString());
|
||||||
@@ -515,14 +553,13 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends
|
|||||||
// has been fixed.
|
// has been fixed.
|
||||||
systemManagement.getTenantMetadata("DEFAULT");
|
systemManagement.getTenantMetadata("DEFAULT");
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onAuthenticationSuccess(authentication);
|
super.onAuthenticationSuccess(authentication);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sevletfilter to create metadata after successful authentication over RESTful.
|
* Sevletfilter to create metadata after successful authentication over RESTful.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
||||||
|
|
||||||
@@ -543,11 +580,13 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
|||||||
@Override
|
@Override
|
||||||
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
|
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
final String currentTenant = tenantAware.getCurrentTenant();
|
final String currentTenant = tenantAware.getCurrentTenant();
|
||||||
if (currentTenant != null) {
|
if (currentTenant != null) {
|
||||||
// lazy initialize tenant meta data after successful authentication
|
// lazy initialize tenant meta data after successful authentication
|
||||||
systemManagement.getTenantMetadata(currentTenant);
|
systemManagement.getTenantMetadata(currentTenant);
|
||||||
}
|
}
|
||||||
|
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ org.eclipse.hawkbit.autoconfigure.eventbus.EventBusAutoConfiguration,\
|
|||||||
org.eclipse.hawkbit.autoconfigure.scheduling.AsyncConfigurerAutoConfiguration,\
|
org.eclipse.hawkbit.autoconfigure.scheduling.AsyncConfigurerAutoConfiguration,\
|
||||||
org.eclipse.hawkbit.autoconfigure.cache.RedisAutoConfiguration,\
|
org.eclipse.hawkbit.autoconfigure.cache.RedisAutoConfiguration,\
|
||||||
org.eclipse.hawkbit.autoconfigure.scheduling.ExecutorAutoConfiguration,\
|
org.eclipse.hawkbit.autoconfigure.scheduling.ExecutorAutoConfiguration,\
|
||||||
org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration
|
org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration,\
|
||||||
|
org.eclipse.hawkbit.autoconfigure.security.InMemoryUserManagementConfiguration
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Displayed basic auth realm
|
||||||
|
security.basic.realm=HawkBit
|
||||||
|
|
||||||
# JPA / Datasource
|
# JPA / Datasource
|
||||||
spring.jpa.eclipselink.eclipselink.weaving=false
|
spring.jpa.eclipselink.eclipselink.weaving=false
|
||||||
spring.jpa.database=H2
|
spring.jpa.database=H2
|
||||||
|
|||||||
@@ -11,8 +11,36 @@ package org.eclipse.hawkbit;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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.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.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.aspects.ExceptionMappingAspectHandler;
|
||||||
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
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.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
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.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
|
||||||
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||||
@@ -50,6 +80,7 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess
|
|||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan
|
@ComponentScan
|
||||||
@EnableAutoConfiguration
|
@EnableAutoConfiguration
|
||||||
|
@EnableScheduling
|
||||||
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||||
/**
|
/**
|
||||||
* @return the {@link SystemSecurityContext} singleton bean which make it
|
* @return the {@link SystemSecurityContext} singleton bean which make it
|
||||||
@@ -173,4 +204,170 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
public PlatformTransactionManager transactionManager() {
|
public PlatformTransactionManager transactionManager() {
|
||||||
return new MultiTenantJpaTransactionManager();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import org.springframework.data.domain.Page;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -52,7 +51,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaArtifactManagement implements ArtifactManagement {
|
public class JpaArtifactManagement implements ArtifactManagement {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(JpaArtifactManagement.class);
|
private static final Logger LOG = LoggerFactory.getLogger(JpaArtifactManagement.class);
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -65,7 +64,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaControllerManagement implements ControllerManagement {
|
public class JpaControllerManagement implements ControllerManagement {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class);
|
||||||
private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos");
|
private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos");
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ import com.google.common.eventbus.EventBus;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaDeploymentManagement implements DeploymentManagement {
|
public class JpaDeploymentManagement implements DeploymentManagement {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(JpaDeploymentManagement.class);
|
private static final Logger LOG = LoggerFactory.getLogger(JpaDeploymentManagement.class);
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ import org.springframework.data.domain.PageImpl;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -74,7 +73,6 @@ import com.google.common.eventbus.EventBus;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaDistributionSetManagement implements DistributionSetManagement {
|
public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -42,13 +42,11 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA Implementation of {@link EntityFactory}.
|
* JPA Implementation of {@link EntityFactory}.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Service
|
|
||||||
public class JpaEntityFactory implements EntityFactory {
|
public class JpaEntityFactory implements EntityFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ import org.eclipse.hawkbit.tenancy.TenantAware;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -56,7 +55,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaReportManagement implements ReportManagement {
|
public class JpaReportManagement implements ReportManagement {
|
||||||
|
|
||||||
@Value("${spring.jpa.database}")
|
@Value("${spring.jpa.database}")
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ import org.springframework.data.domain.PageImpl;
|
|||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -56,7 +55,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
* JPA implementation of {@link RolloutGroupManagement}.
|
* JPA implementation of {@link RolloutGroupManagement}.
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ import org.springframework.data.domain.Sort;
|
|||||||
import org.springframework.data.domain.Sort.Direction;
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
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.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
@@ -76,8 +74,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
* JPA implementation of {@link RolloutManagement}.
|
* JPA implementation of {@link RolloutManagement}.
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
@EnableScheduling
|
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
public class JpaRolloutManagement implements RolloutManagement {
|
public class JpaRolloutManagement implements RolloutManagement {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RolloutManagement.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(RolloutManagement.class);
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ import org.springframework.data.domain.SliceImpl;
|
|||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -74,7 +73,6 @@ import com.google.common.collect.Sets;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaSoftwareManagement implements SoftwareManagement {
|
public class JpaSoftwareManagement implements SoftwareManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa;
|
package org.eclipse.hawkbit.repository.jpa;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
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.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -49,7 +46,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement {
|
public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement {
|
||||||
@Autowired
|
@Autowired
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
@@ -108,7 +104,11 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TenancyCacheManager cacheManager;
|
private TenancyCacheManager cacheManager;
|
||||||
|
|
||||||
private final ThreadLocal<String> createInitialTenant = new ThreadLocal<>();
|
@Autowired
|
||||||
|
private SystemManagementCacheKeyGenerator currentTenantCacheKeyGenerator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SystemUsageReport getSystemUsageStatistics() {
|
public SystemUsageReport getSystemUsageStatistics() {
|
||||||
@@ -154,9 +154,8 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
@Bean
|
|
||||||
public KeyGenerator currentTenantKeyGenerator() {
|
public KeyGenerator currentTenantKeyGenerator() {
|
||||||
return new CurrentTenantKeyGenerator();
|
return currentTenantCacheKeyGenerator.currentTenantKeyGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -169,11 +168,12 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
// Create if it does not exist
|
// Create if it does not exist
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
try {
|
try {
|
||||||
createInitialTenant.set(tenant);
|
currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant);
|
||||||
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
||||||
|
applicationContext.getBean("currentTenantKeyGenerator");
|
||||||
return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant));
|
return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant));
|
||||||
} finally {
|
} finally {
|
||||||
createInitialTenant.remove();
|
currentTenantCacheKeyGenerator.getCreateInitialTenant().remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
// tenant is not cached anyway already.
|
// tenant is not cached anyway already.
|
||||||
@Transactional(propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
public String currentTenant() {
|
public String currentTenant() {
|
||||||
final String initialTenantCreation = createInitialTenant.get();
|
final String initialTenantCreation = currentTenantCacheKeyGenerator.getCreateInitialTenant().get();
|
||||||
if (initialTenantCreation == null) {
|
if (initialTenantCreation == null) {
|
||||||
final TenantMetaData findByTenant = tenantMetaDataRepository
|
final TenantMetaData findByTenant = tenantMetaDataRepository
|
||||||
.findByTenantIgnoreCase(tenantAware.getCurrentTenant());
|
.findByTenantIgnoreCase(tenantAware.getCurrentTenant());
|
||||||
@@ -260,29 +260,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
return tenantMetaDataRepository.save((JpaTenantMetaData) metaData);
|
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() {
|
private DistributionSetType createStandardSoftwareDataSetup() {
|
||||||
final SoftwareModuleType app = softwareModuleTypeRepository
|
final SoftwareModuleType app = softwareModuleTypeRepository
|
||||||
.save(new JpaSoftwareModuleType(Constants.SMT_DEFAULT_APP_KEY, Constants.SMT_DEFAULT_APP_NAME,
|
.save(new JpaSoftwareModuleType(Constants.SMT_DEFAULT_APP_KEY, Constants.SMT_DEFAULT_APP_NAME,
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import org.springframework.data.domain.PageImpl;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -52,7 +51,6 @@ import com.google.common.eventbus.EventBus;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaTagManagement implements TagManagement {
|
public class JpaTagManagement implements TagManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import com.google.common.base.Strings;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement {
|
public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ import org.springframework.data.domain.Sort;
|
|||||||
import org.springframework.data.domain.Sort.Direction;
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
@@ -75,7 +74,6 @@ import com.google.common.eventbus.EventBus;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaTargetManagement implements TargetManagement {
|
public class JpaTargetManagement implements TargetManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.springframework.core.convert.support.ConfigurableConversionService;
|
|||||||
import org.springframework.core.convert.support.DefaultConversionService;
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -33,7 +32,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaTenantConfigurationManagement implements EnvironmentAware, TenantConfigurationManagement {
|
public class JpaTenantConfigurationManagement implements EnvironmentAware, TenantConfigurationManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
|
||||||
public class JpaTenantStatsManagement implements TenantStatsManagement {
|
public class JpaTenantStatsManagement implements TenantStatsManagement {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -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<String> 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<String> getCreateInitialTenant() {
|
||||||
|
return createInitialTenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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<BaseEntity> hasId(final Long id) {
|
||||||
|
return new HasIdMatcher(Matchers.equalTo(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HasIdMatcher extends FeatureMatcher<BaseEntity, Long> {
|
||||||
|
|
||||||
|
public HasIdMatcher(final Matcher<Long> subMatcher) {
|
||||||
|
super(subMatcher, "getId()", "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Long featureValueOf(final BaseEntity baseEntity) {
|
||||||
|
return baseEntity.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import org.springframework.security.core.context.SecurityContext;
|
|||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Service to check permissions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PermissionService {
|
public class PermissionService {
|
||||||
|
|||||||
@@ -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 <tt>GrantedAuthority</tt> 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<GrantedAuthority> createAuthorityList(final Collection<String> roles) {
|
||||||
|
final List<GrantedAuthority> 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<GrantedAuthority> createAllAuthorityList() {
|
||||||
|
return createAuthorityList(SpPermission.getAllAuthorities());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,16 @@
|
|||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.im.authentication;
|
||||||
|
|
||||||
import java.lang.annotation.Target;
|
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.access.prepost.PreAuthorize;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
@@ -35,6 +44,8 @@ import org.springframework.security.core.GrantedAuthority;
|
|||||||
*/
|
*/
|
||||||
public final class SpPermission {
|
public final class SpPermission {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SpPermission.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to read the targets from the
|
* Permission to read the targets from the
|
||||||
* {@link ProvisioningTargetRepository} including their meta information,
|
* {@link ProvisioningTargetRepository} including their meta information,
|
||||||
@@ -139,6 +150,53 @@ public final class SpPermission {
|
|||||||
// Constants only
|
// Constants only
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all permission.
|
||||||
|
*
|
||||||
|
* @return all permission
|
||||||
|
*/
|
||||||
|
public static Collection<String> getAllAuthorities() {
|
||||||
|
return getAllAuthorities(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all permission.
|
||||||
|
*
|
||||||
|
* @param exclusionRoles
|
||||||
|
* roles which will excluded
|
||||||
|
* @return all permissions
|
||||||
|
*/
|
||||||
|
public static Collection<String> getAllAuthorities(final String... exclusionRoles) {
|
||||||
|
return getAllAuthorities(Arrays.asList(exclusionRoles));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all permission.
|
||||||
|
*
|
||||||
|
* @param exclusionRoles
|
||||||
|
* roles which will excluded
|
||||||
|
* @return all permissions
|
||||||
|
*/
|
||||||
|
public static Collection<String> getAllAuthorities(final Collection<String> exclusionRoles) {
|
||||||
|
final List<String> 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
|
* Contains all the spring security evaluation expressions for the
|
||||||
* {@link PreAuthorize} annotation for method security.
|
* {@link PreAuthorize} annotation for method security.
|
||||||
|
|||||||
@@ -8,8 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
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.io.IOException;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.regex.Pattern;
|
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
|
* Filter for protection against denial of service attacks. It reduces the
|
||||||
* maximum number of request per seconds which can be separately configured for
|
* 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 {
|
public class DosFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DosFilter.class);
|
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_DOS = LoggerFactory.getLogger(SECURITY_LOG_PREFIX + ".dos");
|
||||||
private static final Logger LOG_BLACKLIST = LoggerFactory.getLogger("server-security.blacklist");
|
private static final Logger LOG_BLACKLIST = LoggerFactory.getLogger(SECURITY_LOG_PREFIX + ".blacklist");
|
||||||
|
|
||||||
private final Pattern ipAdressBlacklist;
|
private final Pattern ipAdressBlacklist;
|
||||||
|
|
||||||
private final Cache<String, AtomicInteger> readCountCache = CacheBuilder.newBuilder()
|
private final Cache<String, AtomicInteger> readCountCache = CacheBuilder.newBuilder().expireAfterAccess(1, SECONDS)
|
||||||
.expireAfterAccess(1, TimeUnit.SECONDS).build();
|
.build();
|
||||||
|
|
||||||
private final Cache<String, AtomicInteger> writeCountCache = CacheBuilder.newBuilder()
|
private final Cache<String, AtomicInteger> writeCountCache = CacheBuilder.newBuilder().expireAfterAccess(1, SECONDS)
|
||||||
.expireAfterAccess(1, TimeUnit.SECONDS).build();
|
.build();
|
||||||
|
|
||||||
private final Integer maxRead;
|
private final Integer maxRead;
|
||||||
private final Integer maxWrite;
|
private final Integer maxWrite;
|
||||||
@@ -78,7 +76,7 @@ public class DosFilter extends OncePerRequestFilter {
|
|||||||
*/
|
*/
|
||||||
public DosFilter(final Integer maxRead, final Integer maxWrite, final String ipDosWhiteListPattern,
|
public DosFilter(final Integer maxRead, final Integer maxWrite, final String ipDosWhiteListPattern,
|
||||||
final String ipBlackListPattern, final String forwardHeader) {
|
final String ipBlackListPattern, final String forwardHeader) {
|
||||||
super();
|
|
||||||
this.maxRead = maxRead;
|
this.maxRead = maxRead;
|
||||||
this.maxWrite = maxWrite;
|
this.maxWrite = maxWrite;
|
||||||
this.forwardHeader = forwardHeader;
|
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
|
@Override
|
||||||
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
|
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
|
||||||
final FilterChain filterChain) throws ServletException, IOException {
|
final FilterChain filterChain) throws ServletException, IOException {
|
||||||
@@ -152,11 +142,9 @@ public class DosFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean handleMissingIpAddress(final HttpServletResponse response) {
|
private static boolean handleMissingIpAddress(final HttpServletResponse response) {
|
||||||
boolean processChain;
|
|
||||||
LOG.error("Failed to get peer IP adress");
|
LOG.error("Failed to get peer IP adress");
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
processChain = false;
|
return false;
|
||||||
return processChain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleWriteRequest(final HttpServletResponse response, final String ip) {
|
private boolean handleWriteRequest(final HttpServletResponse response, final String ip) {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,12 +14,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auditor class that allows {@link BaseEntity}s to insert currenlt logged in
|
* Auditor class that allows BaseEntitys to insert current logged in user for
|
||||||
* user for repository changes.
|
* repository changes.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpringSecurityAuditorAware implements AuditorAware<String> {
|
public class SpringSecurityAuditorAware implements AuditorAware<String> {
|
||||||
@@ -29,16 +25,21 @@ public class SpringSecurityAuditorAware implements AuditorAware<String> {
|
|||||||
|
|
||||||
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
if (authentication == null || !authentication.isAuthenticated()) {
|
if (isAuthenticationInvalid(authentication)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authentication.getPrincipal() != null) {
|
return getCurrentAuditor(authentication);
|
||||||
if (authentication.getPrincipal() instanceof UserDetails) {
|
}
|
||||||
return ((UserDetails) authentication.getPrincipal()).getUsername();
|
|
||||||
}
|
private String getCurrentAuditor(final Authentication authentication) {
|
||||||
return authentication.getPrincipal().toString();
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<String> allAuthorities = SpPermission.getAllAuthorities();
|
||||||
|
final List<GrantedAuthority> 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<String> authoritiesWithoutSystem = SpPermission.getAllAuthorities(SpPermission.SYSTEM_ADMIN,
|
||||||
|
SpPermission.SYSTEM_DIAG, SpPermission.SYSTEM_MONITOR);
|
||||||
|
final List<GrantedAuthority> 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -175,11 +175,7 @@ public final class UserDetailsFormatter {
|
|||||||
private static UserDetails loadUserByUsername(final String username) {
|
private static UserDetails loadUserByUsername(final String username) {
|
||||||
final UserDetailsService userDetailsService = SpringContextHelper.getBean(UserDetailsService.class);
|
final UserDetailsService userDetailsService = SpringContextHelper.getBean(UserDetailsService.class);
|
||||||
try {
|
try {
|
||||||
final UserDetails loadUserByUsername = userDetailsService.loadUserByUsername(username);
|
return userDetailsService.loadUserByUsername(username);
|
||||||
if (loadUserByUsername == null) {
|
|
||||||
throw new UsernameNotFoundException("User not found " + username);
|
|
||||||
}
|
|
||||||
return loadUserByUsername;
|
|
||||||
} catch (final UsernameNotFoundException e) {
|
} catch (final UsernameNotFoundException e) {
|
||||||
return new User(username, "", Collections.emptyList());
|
return new User(username, "", Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|||||||
28
pom.xml
28
pom.xml
@@ -45,7 +45,6 @@
|
|||||||
<module>examples</module>
|
<module>examples</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>${release.scm.connection}</connection>
|
<connection>${release.scm.connection}</connection>
|
||||||
<developerConnection>${release.scm.developerConnection}</developerConnection>
|
<developerConnection>${release.scm.developerConnection}</developerConnection>
|
||||||
@@ -88,6 +87,10 @@
|
|||||||
<vaadin.addon.contextmenu.version>4.5</vaadin.addon.contextmenu.version>
|
<vaadin.addon.contextmenu.version>4.5</vaadin.addon.contextmenu.version>
|
||||||
<!-- Vaadin versions - END -->
|
<!-- Vaadin versions - END -->
|
||||||
|
|
||||||
|
<maven.processor.plugin.version>3.1.0</maven.processor.plugin.version>
|
||||||
|
<maven.surefire.plugin.version>2.17</maven.surefire.plugin.version>
|
||||||
|
<maven.scm.plugin.version>1.9.4</maven.scm.plugin.version>
|
||||||
|
|
||||||
<!-- Misc libraries versions - START -->
|
<!-- Misc libraries versions - START -->
|
||||||
<validation-api.version>1.1.0.Final</validation-api.version>
|
<validation-api.version>1.1.0.Final</validation-api.version>
|
||||||
<fest-assert.version>1.4</fest-assert.version>
|
<fest-assert.version>1.4</fest-assert.version>
|
||||||
@@ -154,6 +157,15 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<compilerArgument>-Xlint:all</compilerArgument>
|
||||||
|
<showWarnings>true</showWarnings>
|
||||||
|
<showDeprecation>true</showDeprecation>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mycila</groupId>
|
<groupId>com.mycila</groupId>
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
@@ -184,7 +196,7 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-scm-plugin</artifactId>
|
<artifactId>maven-scm-plugin</artifactId>
|
||||||
<version>1.9.4</version>
|
<version>${maven.scm.plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tag>${project.version}</tag>
|
<tag>${project.version}</tag>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -192,7 +204,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>${jacoco.version}</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>prepare-ut-agent</id>
|
<id>prepare-ut-agent</id>
|
||||||
@@ -233,6 +244,7 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -276,7 +288,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.17</version>
|
<version>${maven.surefire.plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<reuseForks>true</reuseForks>
|
<reuseForks>true</reuseForks>
|
||||||
<forkCount>1</forkCount>
|
<forkCount>1</forkCount>
|
||||||
@@ -350,9 +362,13 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>${jacoco.maven.version}</version>
|
<version>${jacoco.version}</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.bsc.maven</groupId>
|
||||||
|
<artifactId>maven-processor-plugin</artifactId>
|
||||||
|
<version>${maven.processor.plugin.version}</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
|
|||||||
Reference in New Issue
Block a user