Completed migration to ConfigurationProperties annotation. Added boot metadata generation to build.

This commit is contained in:
Kai Zimmermann
2016-02-25 17:59:46 +01:00
parent 0b8e693cec
commit ab18e12b69
39 changed files with 348 additions and 200 deletions

3
.gitignore vendored
View File

@@ -16,13 +16,12 @@
*.jar *.jar
*.war *.war
######################
# Sonar # Sonar
######################
.sonar_lock .sonar_lock
# Eclipse IDE # Eclipse IDE
.factorypath
*.pydevproject *.pydevproject
.project .project
.metadata .metadata

9
MIGRATION.md Normal file
View File

@@ -0,0 +1,9 @@
# hawkBit Migration Guides
## Release 0.2
### Configuration Property changes
- hawkbit.server.controller._ have changed to hawkbit.server.ddi._
- info.build._ have changed to hawkbit.server.build._
- hawkbit.server.demo._ have changed to hawkbit.server.ui.demo._
- hawkbit.server.email.support has changed to hawkbit.server.ui.links.support
- hawkbit.server.email.request.account has changed to hawkbit.server.ui.links.requestAccount
- hawkbit.server.im.login.url has changed to hawkbit.server.ui.links.userManagement

View File

@@ -100,7 +100,6 @@
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>19.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.netflix.feign</groupId> <groupId>com.netflix.feign</groupId>
@@ -116,6 +115,11 @@
<groupId>com.jayway.jsonpath</groupId> <groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId> <artifactId>json-path</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>

View File

@@ -9,12 +9,14 @@
package org.eclipse.hawkbit.simulator.amqp; package org.eclipse.hawkbit.simulator.amqp;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Bean which holds the necessary properties for configuring the AMQP * Bean which holds the necessary properties for configuring the AMQP
* connection. * connection.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.device.simulator.amqp") @ConfigurationProperties("hawkbit.device.simulator.amqp")
public class AmqpProperties { public class AmqpProperties {

View File

@@ -7,23 +7,20 @@
# http://www.eclipse.org/legal/epl-v10.html # http://www.eclipse.org/legal/epl-v10.html
# #
# need to re-name these properties in the defaulthawkbit.properties and code! hawkbit.server.ddi.security.authentication.anonymous.enabled=true
hawkbit.server.controller.security.authentication.anonymous.enabled=true hawkbit.server.ddi.security.authentication.targettoken.enabled=false
hawkbit.server.controller.security.authentication.header.enabled=false hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
hawkbit.server.controller.security.authentication.targettoken.enabled=false
hawkbit.server.controller.security.authentication.gatewaytoken.enabled=false
spring.profiles.active=amqp spring.profiles.active=amqp
vaadin.servlet.productionMode=false vaadin.servlet.productionMode=false
vaadin.static.servlet.productionMode=false
## Configuration for RabbitMQ integration ## Configuration for RabbitMQ integration
hawkbit.server.amqp.username=guest spring.rabbitmq.username=guest
hawkbit.server.amqp.password=guest spring.rabbitmq.password=guest
hawkbit.server.amqp.virtualHost=/ spring.rabbitmq.virtualHost=/
hawkbit.server.amqp.host=localhost spring.rabbitmq.host=localhost
hawkbit.server.amqp.port=5672 spring.rabbitmq.port=5672
hawkbit.server.amqp.deadLetterQueue=sp_deadletter hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter
hawkbit.server.amqp.deadLetterExchange=sp.deadletter hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
hawkbit.server.amqp.receiverQueue=sp_receiver hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver

View File

@@ -87,5 +87,10 @@
<artifactId>google-collections</artifactId> <artifactId>google-collections</artifactId>
<version>1.0-rc2</version> <version>1.0-rc2</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -9,12 +9,14 @@
package org.eclipse.hawkbit.mgmt.client; package org.eclipse.hawkbit.mgmt.client;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Configuration bean which holds the configuration of the client e.g. the base * Configuration bean which holds the configuration of the client e.g. the base
* URL of the hawkbit-server and the credentials to use the RESTful Management * URL of the hawkbit-server and the credentials to use the RESTful Management
* API. * API.
*/ */
@Component
@ConfigurationProperties(prefix = "hawkbit") @ConfigurationProperties(prefix = "hawkbit")
public class ClientConfigurationProperties { public class ClientConfigurationProperties {

View File

@@ -11,4 +11,4 @@ hawkbit.url=localhost:8080
hawkbit.username=admin hawkbit.username=admin
hawkbit.password=admin hawkbit.password=admin
spring.main.banner-mode=OFF spring.main.show-banner=false

View File

@@ -72,5 +72,10 @@
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId> <artifactId>spring-context-support</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,27 +0,0 @@
/**
* 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.conf;
import org.eclipse.hawkbit.ControllerPollProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Enable the Controlle Poll.
*
*
*
*/
@Configuration
@ConditionalOnClass(ControllerPollProperties.class)
@EnableConfigurationProperties(ControllerPollProperties.class)
public class ControllerPollAutoConfiguration {
}

View File

@@ -9,11 +9,13 @@
package org.eclipse.hawkbit.autoconfigure.scheduling; package org.eclipse.hawkbit.autoconfigure.scheduling;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Properties for the async configurer. * Properties for the async configurer.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.threadpool") @ConfigurationProperties("hawkbit.threadpool")
public class AsyncConfigurerThreadpoolProperties { public class AsyncConfigurerThreadpoolProperties {

View File

@@ -33,12 +33,12 @@ import org.eclipse.hawkbit.rest.resource.RestConstants;
import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource; import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource;
import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.DosFilter; import org.eclipse.hawkbit.security.DosFilter;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter; import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter; import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter; import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
import org.eclipse.hawkbit.security.HttpDownloadAuthenticationFilter; import org.eclipse.hawkbit.security.HttpDownloadAuthenticationFilter;
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
import org.eclipse.hawkbit.security.SecurityProperties;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -96,7 +96,7 @@ public class SecurityManagedConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class); private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class);
@Autowired @Autowired
private SecurityProperties securityProperties; private HawkbitSecurityProperties securityProperties;
/** /**
* {@link WebSecurityConfigurer} for the internal SP controller API. * {@link WebSecurityConfigurer} for the internal SP controller API.
@@ -124,7 +124,7 @@ public class SecurityManagedConfiguration {
final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource(); final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter( final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
securityConfiguration.getRpCnHeader(), securityConfiguration.getRpSslIssuerHashHeader(), securityConfiguration.getRp().getCnHeader(), securityConfiguration.getRp().getSslIssuerHashHeader(),
systemManagement, tenantAware); systemManagement, tenantAware);
securityHeaderFilter.setAuthenticationManager(authenticationManager()); securityHeaderFilter.setAuthenticationManager(authenticationManager());
securityHeaderFilter.setCheckForPrincipalChanges(true); securityHeaderFilter.setCheckForPrincipalChanges(true);
@@ -150,7 +150,7 @@ public class SecurityManagedConfiguration {
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and(); httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
} }
if (securityConfiguration.getAnonymousEnabled()) { if (securityConfiguration.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 use for developing purposes **\n******************");
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter( final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
@@ -181,7 +181,7 @@ public class SecurityManagedConfiguration {
@Override @Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception { protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider( auth.authenticationProvider(
new PreAuthTokenSourceTrustAuthenticationProvider(securityConfiguration.getRpTrustedIPs())); new PreAuthTokenSourceTrustAuthenticationProvider(securityConfiguration.getRp().getTrustedIPs()));
} }
} }
@@ -197,8 +197,9 @@ public class SecurityManagedConfiguration {
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(),
securityProperties.getDos().getFilter().getMaxWrite(), securityProperties.getDos().getWhitelist(), securityProperties.getDos().getFilter().getMaxWrite(),
securityProperties.getClients().getBlacklist(), securityProperties.getClients().getRemoteIpHeader())); securityProperties.getDos().getFilter().getWhitelist(), securityProperties.getClients().getBlacklist(),
securityProperties.getClients().getRemoteIpHeader()));
filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*"); filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*");
return filterRegBean; return filterRegBean;
} }
@@ -308,7 +309,7 @@ public class SecurityManagedConfiguration {
@Autowired @Autowired
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties; private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
@Autowired @Autowired
private SecurityProperties securityProperties; private HawkbitSecurityProperties securityProperties;
/** /**
* post construct for setting the authentication success handler for the * post construct for setting the authentication success handler for the
@@ -466,7 +467,7 @@ public class SecurityManagedConfiguration {
@Override @Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception { protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider( auth.authenticationProvider(
new PreAuthTokenSourceTrustAuthenticationProvider(securityConfiguration.getRpTrustedIPs())); new PreAuthTokenSourceTrustAuthenticationProvider(securityConfiguration.getRp().getTrustedIPs()));
} }
} }

View File

@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.autoconfigure.url;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import org.eclipse.hawkbit.ServerProperties; import org.eclipse.hawkbit.HawkbitServerProperties;
import org.eclipse.hawkbit.api.HostnameResolver; import org.eclipse.hawkbit.api.HostnameResolver;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -28,11 +28,11 @@ import com.google.common.base.Throwables;
* *
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(ServerProperties.class) @EnableConfigurationProperties(HawkbitServerProperties.class)
public class PropertyHostnameResolverAutoConfiguration { public class PropertyHostnameResolverAutoConfiguration {
@Autowired @Autowired
private ServerProperties serverProperties; private HawkbitServerProperties serverProperties;
/** /**
* @return the default autoconfigure hostname resolver implementation which * @return the default autoconfigure hostname resolver implementation which

View File

@@ -37,6 +37,11 @@
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test --> <!-- Test -->

View File

@@ -9,12 +9,14 @@
package org.eclipse.hawkbit.cache; package org.eclipse.hawkbit.cache;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Bean which holds the necessary properties for configuring the Redis * Bean which holds the necessary properties for configuring the Redis
* connection. * connection.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.server.redis") @ConfigurationProperties("hawkbit.server.redis")
public class RedisProperties { public class RedisProperties {

View File

@@ -43,6 +43,11 @@
<artifactId>allure-junit-adaptor</artifactId> <artifactId>allure-junit-adaptor</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -9,14 +9,13 @@
package org.eclipse.hawkbit; package org.eclipse.hawkbit;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Defines the polling time for the controllers in HH:MM:SS notation. * Defines the polling time for the controllers in HH:MM:SS notation.
* *
*
*
*/ */
@Component
@ConfigurationProperties(prefix = "hawkbit.controller") @ConfigurationProperties(prefix = "hawkbit.controller")
public class ControllerPollProperties { public class ControllerPollProperties {

View File

@@ -9,13 +9,15 @@
package org.eclipse.hawkbit; package org.eclipse.hawkbit;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Properties for the server e.g. the server's URL which must be configured. * Properties for the server e.g. the server's URL which must be configured.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.server") @ConfigurationProperties("hawkbit.server")
public class ServerProperties { public class HawkbitServerProperties {
/** /**
* Defines under which URI the update server can be reached. Used to * Defines under which URI the update server can be reached. Used to
* calculate download URLs for DMF transmitted update actions. * calculate download URLs for DMF transmitted update actions.

View File

@@ -22,35 +22,35 @@ public enum TenantConfigurationKey {
* boolean value {@code true} {@code false}. * boolean value {@code true} {@code false}.
*/ */
AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled",
"hawkbit.server.controller.security.authentication.header.enabled", Boolean.FALSE.toString()), "hawkbit.server.ddi.security.authentication.header.enabled", Boolean.FALSE.toString()),
/** /**
* *
*/ */
AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority",
"hawkbit.server.controller.security.authentication.header.authority", Boolean.FALSE.toString()), "hawkbit.server.ddi.security.authentication.header.authority", Boolean.FALSE.toString()),
/** /**
* boolean value {@code true} {@code false}. * boolean value {@code true} {@code false}.
*/ */
AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled",
"hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.FALSE.toString()), "hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.FALSE.toString()),
/** /**
* boolean value {@code true} {@code false}. * boolean value {@code true} {@code false}.
*/ */
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled",
"hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.FALSE.toString()), "hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.FALSE.toString()),
/** /**
* string value which holds the name of the security token key. * string value which holds the name of the security token key.
*/ */
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name",
"hawkbit.server.controller.security.authentication.gatewaytoken.name", null), "hawkbit.server.ddi.security.authentication.gatewaytoken.name", null),
/** /**
* string value which holds the actual security-key of the gateway security * string value which holds the actual security-key of the gateway security
* token. * token.
*/ */
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key",
"hawkbit.server.controller.security.authentication.gatewaytoken.key", null); "hawkbit.server.ddi.security.authentication.gatewaytoken.key", null);
private final String keyName; private final String keyName;
private final String defaultKeyName; private final String defaultKeyName;

View File

@@ -60,6 +60,11 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test --> <!-- Test -->

View File

@@ -21,9 +21,9 @@ import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
import org.eclipse.hawkbit.security.PreAuthenficationFilter; import org.eclipse.hawkbit.security.PreAuthenficationFilter;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -78,8 +78,8 @@ public class AmqpControllerAuthentfication {
filterChain.add(gatewaySecurityTokenFilter); filterChain.add(gatewaySecurityTokenFilter);
final ControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new ControllerPreAuthenticatedSecurityHeaderFilter( final ControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new ControllerPreAuthenticatedSecurityHeaderFilter(
secruityProperties.getRpCnHeader(), secruityProperties.getRpSslIssuerHashHeader(), systemManagement, secruityProperties.getRp().getCnHeader(), secruityProperties.getRp().getSslIssuerHashHeader(),
tenantAware); systemManagement, tenantAware);
filterChain.add(securityHeaderFilter); filterChain.add(securityHeaderFilter);
final ControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new ControllerPreAuthenticateSecurityTokenFilter( final ControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new ControllerPreAuthenticateSecurityTokenFilter(

View File

@@ -10,12 +10,14 @@ package org.eclipse.hawkbit.amqp;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Bean which holds the necessary properties for configuring the AMQP * Bean which holds the necessary properties for configuring the AMQP
* connection. * connection.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.dmf.rabbitmq") @ConfigurationProperties("hawkbit.dmf.rabbitmq")
public class AmqpProperties { public class AmqpProperties {

View File

@@ -23,8 +23,9 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -68,8 +69,11 @@ public class AmqpControllerAuthentficationTest {
authenticationManager = new AmqpControllerAuthentfication(); authenticationManager = new AmqpControllerAuthentfication();
authenticationManager.setControllerManagement(mock(ControllerManagement.class)); authenticationManager.setControllerManagement(mock(ControllerManagement.class));
final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class); final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class);
when(secruityProperties.getRpSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d"); final Rp rp = mock(Rp.class);
when(secruityProperties.getRp()).thenReturn(rp);
when(rp.getSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d");
authenticationManager.setSecruityProperties(secruityProperties); authenticationManager.setSecruityProperties(secruityProperties);
systemManagement = mock(SystemManagement.class); systemManagement = mock(SystemManagement.class);
authenticationManager.setSystemManagement(systemManagement); authenticationManager.setSystemManagement(systemManagement);

View File

@@ -99,6 +99,11 @@
<groupId>org.flywaydb</groupId> <groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId> <artifactId>flyway-core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>

View File

@@ -0,0 +1,50 @@
/**
* 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;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* Rollout Management properties.
*
*/
@Component
@ConfigurationProperties("hawkbit.rollout")
public class RolloutProperties {
private final Scheduler scheduler = new Scheduler();
public Scheduler getScheduler() {
return scheduler;
}
/**
* Rollout scheduler configuration.
*/
public static class Scheduler {
// used by @Scheduled annotation which needs constant
public static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.rollout.scheduler.fixedDelay:30000}";
/**
* Schedule where the rollout scheduler looks necessary state changes in
* milliseconds.
*/
private long fixedDelay = 30000L;
public long getFixedDelay() {
return fixedDelay;
}
public void setFixedDelay(final long fixedDelay) {
this.fixedDelay = fixedDelay;
}
}
}

View File

@@ -33,7 +33,7 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.Target_; import org.eclipse.hawkbit.repository.model.Target_;
import org.eclipse.hawkbit.security.SecurityProperties; import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.hibernate.validator.constraints.NotEmpty; import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -84,7 +84,7 @@ public class ControllerManagement {
private ActionStatusRepository actionStatusRepository; private ActionStatusRepository actionStatusRepository;
@Autowired @Autowired
private SecurityProperties securityProperties; private HawkbitSecurityProperties securityProperties;
/** /**
* Refreshes the time of the last time the controller has been connected to * Refreshes the time of the last time the controller has been connected to

View File

@@ -10,14 +10,13 @@ package org.eclipse.hawkbit.repository;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.RolloutProperties;
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.slf4j.Logger; 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.context.EnvironmentAware;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -31,15 +30,10 @@ import org.springframework.stereotype.Component;
// don't active the rollout scheduler in test, otherwise it is hard to test // don't active the rollout scheduler in test, otherwise it is hard to test
// rolloutmanagement and leads weird side-effects maybe. // rolloutmanagement and leads weird side-effects maybe.
@Profile("!test") @Profile("!test")
public class RolloutScheduler implements EnvironmentAware { public class RolloutScheduler {
private static final Logger logger = LoggerFactory.getLogger(RolloutScheduler.class); private static final Logger logger = LoggerFactory.getLogger(RolloutScheduler.class);
private static final String PROP_SCHEDULER_DELAY = "hawkbit.rollout.scheduler.fixedDelay";
private static final long DEFAULT_SCHEDULER_DELAY = 30000L;
private static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${" + PROP_SCHEDULER_DELAY + ":"
+ DEFAULT_SCHEDULER_DELAY + "}";
@Autowired @Autowired
private TenantAware tenantAware; private TenantAware tenantAware;
@@ -52,7 +46,8 @@ public class RolloutScheduler implements EnvironmentAware {
@Autowired @Autowired
private SystemSecurityContext systemSecurityContext; private SystemSecurityContext systemSecurityContext;
private long fixedDelay = DEFAULT_SCHEDULER_DELAY; @Autowired
private RolloutProperties rolloutProperties;
/** /**
* Scheduler method called by the spring-async mechanism. Retrieves all * Scheduler method called by the spring-async mechanism. Retrieves all
@@ -60,7 +55,7 @@ public class RolloutScheduler implements EnvironmentAware {
* tenant the {@link RolloutManagement#checkRunningRollouts(long)} in the * tenant the {@link RolloutManagement#checkRunningRollouts(long)} in the
* {@link SystemSecurityContext}. * {@link SystemSecurityContext}.
*/ */
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER) @Scheduled(initialDelayString = RolloutProperties.Scheduler.PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = RolloutProperties.Scheduler.PROP_SCHEDULER_DELAY_PLACEHOLDER)
public void rolloutScheduler() { public void rolloutScheduler() {
logger.debug("rollout schedule checker has been triggered."); logger.debug("rollout schedule checker has been triggered.");
// run this code in system code privileged to have the necessary // run this code in system code privileged to have the necessary
@@ -76,16 +71,11 @@ public class RolloutScheduler implements EnvironmentAware {
logger.info("Checking rollouts for {} tenants", tenants.size()); logger.info("Checking rollouts for {} tenants", tenants.size());
for (final String tenant : tenants) { for (final String tenant : tenants) {
tenantAware.runAsTenant(tenant, () -> { tenantAware.runAsTenant(tenant, () -> {
rolloutManagement.checkRunningRollouts(fixedDelay); rolloutManagement.checkRunningRollouts(rolloutProperties.getScheduler().getFixedDelay());
return null; return null;
}); });
} }
return null; return null;
}); });
} }
@Override
public void setEnvironment(final Environment environment) {
fixedDelay = environment.getProperty(PROP_SCHEDULER_DELAY, Long.class, DEFAULT_SCHEDULER_DELAY);
}
} }

View File

@@ -18,12 +18,10 @@ import org.eclipse.hawkbit.repository.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator; import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator;
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator.DatabaseCleanupUtil; import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator.DatabaseCleanupUtil;
import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
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.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.guava.GuavaCacheManager; import org.springframework.cache.guava.GuavaCacheManager;
import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.AdviceMode;
@@ -47,7 +45,8 @@ import com.mongodb.MongoClientOptions;
*/ */
@Configuration @Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
@EnableConfigurationProperties({ DdiSecurityProperties.class, ControllerPollProperties.class }) // @EnableConfigurationProperties({ DdiSecurityProperties.class,
// ControllerPollProperties.class })
@Profile("test") @Profile("test")
public class TestConfiguration implements AsyncConfigurer { public class TestConfiguration implements AsyncConfigurer {

View File

@@ -10,7 +10,7 @@
spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value} spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value}
spring.data.mongodb.port=28017 spring.data.mongodb.port=28017
hawkbit.server.controller.security.authentication.header.enabled=true hawkbit.server.ddi.security.authentication.header.enabled=true
hawkbit.server.artifact.repo.upload.maxFileSize=5MB hawkbit.server.artifact.repo.upload.maxFileSize=5MB
@@ -29,11 +29,6 @@ flyway.initOnMigrate=true
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
#spring.jpa.show-sql=true #spring.jpa.show-sql=true
# SP Controller configuration # DDI configuration
hawkbit.controller.pollingTime=00:01:00 hawkbit.controller.pollingTime=00:01:00
hawkbit.controller.pollingOverdueTime=00:01:00 hawkbit.controller.pollingOverdueTime=00:01:00
## Configuration for RabbitMQ integration
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver

View File

@@ -25,13 +25,11 @@ import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.util.IpUtil; import org.eclipse.hawkbit.util.IpUtil;
import org.slf4j.Logger; 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.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal; import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
@@ -55,7 +53,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@RestController @RestController
@RequestMapping(ControllerConstants.ARTIFACTS_V1_REQUEST_MAPPING) @RequestMapping(ControllerConstants.ARTIFACTS_V1_REQUEST_MAPPING)
public class ArtifactStoreController implements EnvironmentAware { public class ArtifactStoreController {
private static final Logger LOG = LoggerFactory.getLogger(ArtifactStoreController.class); private static final Logger LOG = LoggerFactory.getLogger(ArtifactStoreController.class);
@Autowired @Autowired
@@ -67,14 +65,8 @@ public class ArtifactStoreController implements EnvironmentAware {
@Autowired @Autowired
private CacheWriteNotify cacheWriteNotify; private CacheWriteNotify cacheWriteNotify;
private static final String SP_SERVER_CONFIG_PREFIX = "hawkbit.server."; @Autowired
private RelaxedPropertyResolver environment; private HawkbitSecurityProperties securityProperties;
@Override
public void setEnvironment(final Environment environment) {
this.environment = new RelaxedPropertyResolver(environment, SP_SERVER_CONFIG_PREFIX);
}
/** /**
* Handles GET {@link Artifact} download request. This could be full or * Handles GET {@link Artifact} download request. This could be full or
@@ -138,8 +130,8 @@ public class ArtifactStoreController implements EnvironmentAware {
private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid, private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
final LocalArtifact artifact) { final LocalArtifact artifact) {
final Target target = controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest( final Target target = controllerManagement.updateLastTargetQuery(targetid,
request, environment.getProperty("security.rp.remote_ip_header", String.class, "X-Forwarded-For"))); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
final Action action = controllerManagement final Action action = controllerManagement
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), artifact.getSoftwareModule()); .getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), artifact.getSoftwareModule());

View File

@@ -41,15 +41,13 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.util.IpUtil; import org.eclipse.hawkbit.util.IpUtil;
import org.hibernate.validator.constraints.NotEmpty; import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger; 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.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -74,7 +72,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@RestController @RestController
@RequestMapping(ControllerConstants.BASE_V1_REQUEST_MAPPING) @RequestMapping(ControllerConstants.BASE_V1_REQUEST_MAPPING)
public class RootController implements EnvironmentAware { public class RootController {
private static final Logger LOG = LoggerFactory.getLogger(RootController.class); private static final Logger LOG = LoggerFactory.getLogger(RootController.class);
private static final String GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET = "given action ({}) is not assigned to given target ({})."; private static final String GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET = "given action ({}) is not assigned to given target ({}).";
@@ -99,16 +97,8 @@ public class RootController implements EnvironmentAware {
@Autowired @Autowired
private TenantAware tenantAware; private TenantAware tenantAware;
private String requestHeader; @Autowired
private HawkbitSecurityProperties securityProperties;
@Override
public void setEnvironment(final Environment environment) {
final RelaxedPropertyResolver relaxedPropertyResolver = new RelaxedPropertyResolver(environment,
SP_SERVER_CONFIG_PREFIX);
requestHeader = relaxedPropertyResolver.getProperty("security.rp.remote_ip_header", String.class,
"X-Forwarded-For");
}
/** /**
* Returns all artifacts of a given software module and target. * Returns all artifacts of a given software module and target.
@@ -155,12 +145,13 @@ public class RootController implements EnvironmentAware {
LOG.debug("getControllerBase({})", targetid); LOG.debug("getControllerBase({})", targetid);
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(targetid, final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(targetid,
IpUtil.getClientIpFromRequest(request, requestHeader)); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
if (target.getTargetInfo().getUpdateStatus() == TargetUpdateStatus.UNKNOWN) { if (target.getTargetInfo().getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
LOG.debug("target with {} extsisted but was in status UNKNOWN -> REGISTERED)", targetid); LOG.debug("target with {} extsisted but was in status UNKNOWN -> REGISTERED)", targetid);
controllerManagement.updateTargetStatus(target.getTargetInfo(), TargetUpdateStatus.REGISTERED, controllerManagement.updateTargetStatus(target.getTargetInfo(), TargetUpdateStatus.REGISTERED,
System.currentTimeMillis(), IpUtil.getClientIpFromRequest(request, requestHeader)); System.currentTimeMillis(),
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
} }
return new ResponseEntity<>( return new ResponseEntity<>(
@@ -195,7 +186,7 @@ public class RootController implements EnvironmentAware {
ResponseEntity<Void> result; ResponseEntity<Void> result;
final Target target = controllerManagement.updateLastTargetQuery(targetid, final Target target = controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, requestHeader)); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId); final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
if (checkModule(fileName, module)) { if (checkModule(fileName, module)) {
@@ -265,7 +256,8 @@ public class RootController implements EnvironmentAware {
public ResponseEntity<Void> downloadArtifactMd5(@PathVariable final String targetid, public ResponseEntity<Void> downloadArtifactMd5(@PathVariable final String targetid,
@PathVariable final Long softwareModuleId, @PathVariable final String fileName, @PathVariable final Long softwareModuleId, @PathVariable final String fileName,
final HttpServletResponse response, final HttpServletRequest request) { final HttpServletResponse response, final HttpServletRequest request) {
controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(request, requestHeader)); controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId); final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
@@ -311,7 +303,7 @@ public class RootController implements EnvironmentAware {
LOG.debug("getControllerBasedeploymentAction({},{})", targetid, resource); LOG.debug("getControllerBasedeploymentAction({},{})", targetid, resource);
final Target target = controllerManagement.updateLastTargetQuery(targetid, final Target target = controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, requestHeader)); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
final Action action = findActionWithExceptionIfNotFound(actionId); final Action action = findActionWithExceptionIfNotFound(actionId);
if (!action.getTarget().getId().equals(target.getId())) { if (!action.getTarget().getId().equals(target.getId())) {
@@ -362,7 +354,7 @@ public class RootController implements EnvironmentAware {
LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", targetid, actionId, feedback); LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", targetid, actionId, feedback);
final Target target = controllerManagement.updateLastTargetQuery(targetid, final Target target = controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, requestHeader)); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
if (!actionId.equals(feedback.getId())) { if (!actionId.equals(feedback.getId())) {
LOG.warn( LOG.warn(
@@ -469,7 +461,8 @@ public class RootController implements EnvironmentAware {
+ ControllerConstants.CONFIG_DATA_ACTION, method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) + ControllerConstants.CONFIG_DATA_ACTION, method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> putConfigData(@Valid @RequestBody final ConfigData configData, public ResponseEntity<Void> putConfigData(@Valid @RequestBody final ConfigData configData,
@PathVariable final String targetid, final HttpServletRequest request) { @PathVariable final String targetid, final HttpServletRequest request) {
controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(request, requestHeader)); controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
controllerManagement.updateControllerAttributes(targetid, configData.getData()); controllerManagement.updateControllerAttributes(targetid, configData.getData());
@@ -495,7 +488,7 @@ public class RootController implements EnvironmentAware {
LOG.debug("getControllerCancelAction({})", targetid); LOG.debug("getControllerCancelAction({})", targetid);
final Target target = controllerManagement.updateLastTargetQuery(targetid, final Target target = controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, requestHeader)); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
final Action action = findActionWithExceptionIfNotFound(actionId); final Action action = findActionWithExceptionIfNotFound(actionId);
if (!action.getTarget().getId().equals(target.getId())) { if (!action.getTarget().getId().equals(target.getId())) {
@@ -542,7 +535,7 @@ public class RootController implements EnvironmentAware {
LOG.debug("provideCancelActionFeedback for target [{}]: {}", targetid, feedback); LOG.debug("provideCancelActionFeedback for target [{}]: {}", targetid, feedback);
final Target target = controllerManagement.updateLastTargetQuery(targetid, final Target target = controllerManagement.updateLastTargetQuery(targetid,
IpUtil.getClientIpFromRequest(request, requestHeader)); IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
if (!actionId.equals(feedback.getId())) { if (!actionId.equals(feedback.getId())) {
LOG.warn( LOG.warn(

View File

@@ -24,7 +24,7 @@ hawkbit.server.database=H2
hawkbit.server.database.env=TEST hawkbit.server.database.env=TEST
spring.main.show_banner=false spring.main.show_banner=false
hawkbit.server.controller.security.authentication.header=true hawkbit.server.ddi.security.authentication.header=true
hawkbit.server.artifact.repo.upload.maxFileSize=5MB hawkbit.server.artifact.repo.upload.maxFileSize=5MB

View File

@@ -59,6 +59,11 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId> <artifactId>spring-boot</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>

View File

@@ -10,25 +10,34 @@ package org.eclipse.hawkbit.security;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* The common properties for DDI security. * The common properties for DDI security.
*/ */
@Component
@ConfigurationProperties("hawkbit.server.ddi.security") @ConfigurationProperties("hawkbit.server.ddi.security")
public class DdiSecurityProperties { public class DdiSecurityProperties {
private final Rp rp = new Rp();
private final Authentication authentication = new Authentication();
public Authentication getAuthentication() {
return authentication;
}
public Rp getRp() {
return rp;
}
/** /**
* Inner class for reverse proxy configuration. Defines the security * Reverse proxy configuration. Defines the security properties for
* properties for authenticating controllers behind a reverse proxy which * authenticating controllers behind a reverse proxy which terminates the
* terminates the SSL session at the reverse proxy but adding request header * SSL session at the reverse proxy but adding request header which contains
* which contains the CN of the certificate. * the CN of the certificate.
*/ */
@Component public static class Rp {
@ConfigurationProperties("hawkbit.server.ddi.security.rp")
public static class RpProperties {
/** /**
* HTTP header field for common name of a DDI target client certificate. * HTTP header field for common name of a DDI target client certificate.
@@ -94,54 +103,119 @@ public class DdiSecurityProperties {
} }
/** /**
* Inner class for anonymous enable configuration. * DDI Authentication options.
*/ */
@Component public static class Authentication {
@ConfigurationProperties("hawkbit.server.ddi.security.authentication.anonymous") private final Anonymous anonymous = new Anonymous();
public static class AnoymousAuthenticationProperties { private final Targettoken targettoken = new Targettoken();
private final Gatewaytoken gatewaytoken = new Gatewaytoken();
/** public Anonymous getAnonymous() {
* Set to true to enable anonymous DDI client authentication. return anonymous;
*/ }
private Boolean enabled = Boolean.FALSE;
/** public Gatewaytoken getGatewaytoken() {
* @param enabled return gatewaytoken;
* the enabled to set }
*/
public void setEnabled(final Boolean enabled) { public Targettoken getTargettoken() {
this.enabled = enabled; return targettoken;
} }
/** /**
* @return the enabled * Target token authentication. Tokens are defined per target.
*
*/ */
public Boolean getEnabled() { public static class Targettoken {
return enabled; /**
* Set to true to enable target token authentication.
*/
private boolean enabled = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
} }
} /**
* Gateway token authentication. Tokens are defined per tenant. Use with
* care!
*
*/
public static class Gatewaytoken {
@Autowired /**
private RpProperties rppProperties; * Gateway token based authentication enabled.
*/
private boolean enabled = false;
@Autowired /**
private AnoymousAuthenticationProperties authenticationsProperties; * Default gateway token name.
*/
private String name = "";
public String getRpCnHeader() { /**
return rppProperties.getCnHeader(); * Default gateway token itself.
} */
private String key = "";
public String getRpSslIssuerHashHeader() { public boolean isEnabled() {
return rppProperties.getSslIssuerHashHeader(); return enabled;
} }
public List<String> getRpTrustedIPs() { public void setEnabled(final boolean enabled) {
return rppProperties.getTrustedIPs(); this.enabled = enabled;
} }
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
}
/**
* Anonymous authentication.
*/
public static class Anonymous {
/**
* Set to true to enable anonymous DDI client authentication.
*/
private boolean enabled = false;
/**
* @param enabled
* the enabled to set
*/
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
/**
* @return the enabled
*/
public boolean isEnabled() {
return enabled;
}
}
public Boolean getAnonymousEnabled() {
return authenticationsProperties.getEnabled();
} }
} }

View File

@@ -1,16 +1,25 @@
/**
* 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; package org.eclipse.hawkbit.security;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Security related hawkbit configuration. * Security related hawkbit configuration.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.server.security") @ConfigurationProperties("hawkbit.server.security")
public class SecurityProperties { public class HawkbitSecurityProperties {
private final Clients clients = new Clients(); private final Clients clients = new Clients();
private final Dos dos = new Dos(); private final Dos dos = new Dos();
private final Xframe xframe = new Xframe(); private final Xframe xframe = new Xframe();
@@ -100,11 +109,6 @@ public class SecurityProperties {
*/ */
public static class Dos { public static class Dos {
/**
* White list of peer IP addresses for DOS filter (regular expression).
*/
private String whitelist = "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|169\\.254\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}";
/** /**
* Maximum number of status updates that the controller can report for * Maximum number of status updates that the controller can report for
* an action (0 to disable). * an action (0 to disable).
@@ -122,14 +126,6 @@ public class SecurityProperties {
return filter; return filter;
} }
public String getWhitelist() {
return whitelist;
}
public void setWhitelist(final String whitelist) {
this.whitelist = whitelist;
}
public int getMaxStatusEntriesPerAction() { public int getMaxStatusEntriesPerAction() {
return maxStatusEntriesPerAction; return maxStatusEntriesPerAction;
} }
@@ -148,6 +144,12 @@ public class SecurityProperties {
public static class Filter { public static class Filter {
/**
* White list of peer IP addresses for DOS filter (regular
* expression).
*/
private String whitelist = "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|169\\.254\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}";
/** /**
* # Maximum number of allowed REST read/GET requests per second per * # Maximum number of allowed REST read/GET requests per second per
* client. * client.
@@ -160,6 +162,14 @@ public class SecurityProperties {
*/ */
int maxWrite = 50; int maxWrite = 50;
public String getWhitelist() {
return whitelist;
}
public void setWhitelist(final String whitelist) {
this.whitelist = whitelist;
}
public int getMaxRead() { public int getMaxRead() {
return maxRead; return maxRead;
} }

View File

@@ -213,7 +213,6 @@
<groupId>org.vaadin.addons</groupId> <groupId>org.vaadin.addons</groupId>
<artifactId>tokenfield</artifactId> <artifactId>tokenfield</artifactId>
</dependency> </dependency>
<!-- To be mentioned in release notes -->
<dependency> <dependency>
<groupId>org.vaadin.alump.distributionbar</groupId> <groupId>org.vaadin.alump.distributionbar</groupId>
<artifactId>dbar-addon</artifactId> <artifactId>dbar-addon</artifactId>
@@ -222,7 +221,11 @@
<groupId>org.vaadin.addons</groupId> <groupId>org.vaadin.addons</groupId>
<artifactId>contextmenu</artifactId> <artifactId>contextmenu</artifactId>
</dependency> </dependency>
<!-- To be mentioned in release notes --> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>

View File

@@ -1,11 +1,21 @@
/**
* 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.ui; package org.eclipse.hawkbit.ui;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** /**
* Properties for Management UI customization. * Properties for Management UI customization.
* *
*/ */
@Component
@ConfigurationProperties("hawkbit.server.ui") @ConfigurationProperties("hawkbit.server.ui")
public class UiProperties { public class UiProperties {

View File

@@ -18,7 +18,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.hawkbit.ServerProperties; import org.eclipse.hawkbit.HawkbitServerProperties;
import org.eclipse.hawkbit.im.authentication.PermissionService; import org.eclipse.hawkbit.im.authentication.PermissionService;
import org.eclipse.hawkbit.im.authentication.UserPrincipal; import org.eclipse.hawkbit.im.authentication.UserPrincipal;
import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.UiProperties;
@@ -67,7 +67,7 @@ public final class DashboardMenu extends CustomComponent {
private transient UiProperties uiProperties; private transient UiProperties uiProperties;
@Autowired @Autowired
private transient ServerProperties serverProperties; private transient HawkbitServerProperties serverProperties;
private static final long serialVersionUID = 5394474618559481462L; private static final long serialVersionUID = 5394474618559481462L;

View File

@@ -559,7 +559,6 @@
<groupId>org.json</groupId> <groupId>org.json</groupId>
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>${json.version}</version> <version>${json.version}</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.flapdoodle.embed</groupId> <groupId>de.flapdoodle.embed</groupId>