Splitting monolith app to micro services (#1490)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2023-11-30 15:41:12 +02:00
committed by GitHub
parent b362698af8
commit a6fa75697f
68 changed files with 2222 additions and 225 deletions

View File

@@ -20,6 +20,7 @@ import javax.servlet.FilterConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.cache.DownloadIdCache;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants; import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
@@ -81,9 +82,13 @@ import org.springframework.security.web.authentication.AnonymousAuthenticationFi
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.BasicAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.security.web.session.SessionManagementFilter; import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource;
@@ -583,6 +588,51 @@ public class SecurityManagedConfiguration {
} }
} }
/**
* HttpFirewall which enables to define a list of allowed host names.
*
* @return the http firewall.
*/
@Bean
public HttpFirewall httpFirewall(final HawkbitSecurityProperties hawkbitSecurityProperties) {
final List<String> allowedHostNames = hawkbitSecurityProperties.getAllowedHostNames();
final IgnorePathsStrictHttpFirewall firewall = new IgnorePathsStrictHttpFirewall(
hawkbitSecurityProperties.getHttpFirewallIgnoredPaths());
if (!CollectionUtils.isEmpty(allowedHostNames)) {
firewall.setAllowedHostnames(hostName -> {
LOG.debug("Firewall check host: {}, allowed: {}", hostName, allowedHostNames.contains(hostName));
return allowedHostNames.contains(hostName);
});
}
return firewall;
}
private static class IgnorePathsStrictHttpFirewall extends StrictHttpFirewall {
private final Collection<String> pathsToIgnore;
public IgnorePathsStrictHttpFirewall(final Collection<String> pathsToIgnore) {
super();
this.pathsToIgnore = pathsToIgnore;
}
@Override
public FirewalledRequest getFirewalledRequest(final HttpServletRequest request) {
if (pathsToIgnore != null && pathsToIgnore.contains(request.getRequestURI())) {
return new FirewalledRequest(request) {
@Override
public void reset() {
// nothing to do
}
};
}
return super.getFirewalledRequest(request);
}
}
private static AuthenticationManager setAuthenticationManager(final HttpSecurity http, final DdiSecurityProperties ddiSecurityConfiguration) throws Exception { private static AuthenticationManager setAuthenticationManager(final HttpSecurity http, final DdiSecurityProperties ddiSecurityConfiguration) throws Exception {
// configure authentication manager // configure authentication manager
final AuthenticationManager authenticationManager = final AuthenticationManager authenticationManager =

1
hawkbit-runtime/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
**/artifactrepo/

View File

@@ -27,7 +27,7 @@ Start the hawkBit Update Server and Device Simulator together with an MySQL and
```bash ```bash
$ docker swarm init $ docker swarm init
$ docker stack deploy -c docker-compose-stack.yml hawkbit $ docker stack deploy -c docker-compose-deps-mysql.yml hawkbit
``` ```
# Access # Access

View File

@@ -0,0 +1,44 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
version: '3.7'
services:
# ---------------------
# MySQL service
# ---------------------
mysql:
image: "mysql:8.0"
environment:
MYSQL_DATABASE: "hawkbit"
# MYSQL_USER: "root" is created by default in the container for mysql 8.0+
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
restart: always
ports:
- "3306:3306"
labels:
NAME: "mysql"
# ---------------------
# RabbitMQ service
# ---------------------
rabbitmq:
image: "rabbitmq:3-management-alpine"
hostname: "rabbitmq"
environment:
RABBITMQ_DEFAULT_VHOST: "/"
RABBITMQ_DEFAULT_USER: "guest"
RABBITMQ_DEFAULT_PASS: "guest"
ports:
- "15672:15672"
- "5672:5672"
deploy:
restart_policy:
condition: on-failure

View File

@@ -0,0 +1,44 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
version: '3.7'
services:
# ---------------------
# Postgres service
# ---------------------
postgres:
image: "postgres:16.1"
ports:
- "5432:5432"
deploy:
restart_policy:
condition: on-failure
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "admin"
POSTGRES_DB: "hawkbit"
# ---------------------
# RabbitMQ service
# ---------------------
rabbitmq:
image: "rabbitmq:3-management-alpine"
hostname: "rabbitmq"
environment:
RABBITMQ_DEFAULT_VHOST: "/"
RABBITMQ_DEFAULT_USER: "guest"
RABBITMQ_DEFAULT_PASS: "guest"
ports:
- "15672:15672"
- "5672:5672"
deploy:
restart_policy:
condition: on-failure

View File

@@ -0,0 +1,82 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
version: '3.7'
include:
- docker-compose-deps-mysql.yml
services:
# ---------------------
# HawkBit DDI
# ---------------------
hawkbit-ddi:
image: "hawkbit/hawkbit-ddi-server:latest-mysql"
environment:
- 'SPRING_DATASOURCE_URL=jdbc:mariadb://mysql:3306/hawkbit'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
- 'SPRING_DATASOURCE_USERNAME=root'
restart: always
ports:
- "8081:8081"
labels:
NAME: "hawkbit-ddi"
# ---------------------
# HawkBit DMF
# ---------------------
hawkbit-dmf:
image: "hawkbit/hawkbit-dmf-server:latest-mysql"
environment:
- 'SPRING_DATASOURCE_URL=jdbc:mariadb://mysql:3306/hawkbit'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
- 'SPRING_DATASOURCE_USERNAME=root'
restart: always
labels:
NAME: "hawkbit-dmf"
# ---------------------
# HawkBit MGMT
# ---------------------
hawkbit-mgmt:
image: "hawkbit/hawkbit-mgmt-server:latest-mysql"
environment:
- 'SPRING_DATASOURCE_URL=jdbc:mariadb://mysql:3306/hawkbit'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
- 'SPRING_DATASOURCE_USERNAME=root'
restart: always
ports:
- "8080:8080"
labels:
NAME: "hawkbit-mgmt"
# ---------------------
# HawkBit MGMT
# ---------------------
hawkbit-vv8ui:
image: "hawkbit/hawkbit-vv8-ui:latest-mysql"
environment:
- 'SPRING_DATASOURCE_URL=jdbc:mariadb://mysql:3306/hawkbit'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
- 'SPRING_DATASOURCE_USERNAME=root'
restart: always
ports:
- "8082:8082"
labels:
NAME: "hawkbit-vv8-ui"

View File

@@ -1,86 +0,0 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
version: '3.7'
services:
# ---------------------
# MySQL service
# ---------------------
mysql:
image: "mysql:8.0"
networks:
- hawknet
ports:
- "3306:3306"
deploy:
restart_policy:
condition: on-failure
environment:
MYSQL_DATABASE: "hawkbit"
# MYSQL_USER: "root" is created by default in the container for mysql 8.0+
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
# ---------------------
# RabbitMQ service
# ---------------------
rabbitmq:
image: "rabbitmq:3-management"
networks:
- hawknet
ports:
- "15672:15672"
- "5672:5672"
deploy:
restart_policy:
condition: on-failure
# ---------------------
# hawkBit service
# ---------------------
hawkbit:
image: "hawkbit/hawkbit-update-server:latest-mysql"
networks:
- hawknet
ports:
- "8080:8080"
deploy:
restart_policy:
condition: on-failure
environment:
- 'SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/hawkbit'
- 'SPRING_DATASOURCE_USERNAME=root'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
# ---------------------
# hawkBit simulator
# ---------------------
simulator:
image: "hawkbit/hawkbit-device-simulator:latest"
networks:
- hawknet
ports:
- "8083:8083"
deploy:
restart_policy:
condition: on-failure
environment:
- 'HAWKBIT_DEVICE_SIMULATOR_AUTOSTARTS_[0]_TENANT=DEFAULT'
- 'SPRING_RABBITMQ_VIRTUALHOST=/'
- 'SPRING_RABBITMQ_HOST=rabbitmq'
- 'SPRING_RABBITMQ_PORT=5672'
- 'SPRING_RABBITMQ_USERNAME=guest'
- 'SPRING_RABBITMQ_PASSWORD=guest'
networks:
hawknet:
driver: overlay

View File

@@ -0,0 +1,45 @@
#!/bin/bash
#
# Copyright (c) 2023 Bosch.IO GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
set -xe
VERSION=0.4.0-SNAPSHOT
FLAVOUR="standard"
MVN_REPO=~/.m2/repository
while getopts v:f:r: option
do
case "${option}"
in
v)VERSION=${OPTARG};;
f)FLAVOUR=${OPTARG};;
r)MVN_REPO=${OPTARG};;
esac
done
echo "hawkBit version : ${VERSION}"
echo "docker image flavour : ${FLAVOUR}"
echo "maven repository : ${MVN_REPO}"
if [ ${FLAVOUR} == "mysql" ]
then
DOCKER_FILE="Dockerfile_dev-mysql"
TAG_SUFFIX="-mysql"
else
DOCKER_FILE="Dockerfile_dev"
TAG_SUFFIX=""
fi
echo "docker file : ${DOCKER_FILE}"
docker build -t hawkbit/hawkbit-ddi-server:${VERSION}${TAG_SUFFIX} -t hawkbit/hawkbit-ddi-server:latest${TAG_SUFFIX} --build-arg HAWKBIT_APP=hawkbit-ddi-server --build-arg HAWKBIT_VERSION=${VERSION} -f ${DOCKER_FILE} "${MVN_REPO}"
docker build -t hawkbit/hawkbit-dmf-server:${VERSION}${TAG_SUFFIX} -t hawkbit/hawkbit-dmf-server:latest${TAG_SUFFIX} --build-arg HAWKBIT_APP=hawkbit-dmf-server --build-arg HAWKBIT_VERSION=${VERSION} -f ${DOCKER_FILE} "${MVN_REPO}"
docker build -t hawkbit/hawkbit-mgmt-server:${VERSION}${TAG_SUFFIX} -t hawkbit/hawkbit-mgmt-server:latest${TAG_SUFFIX} --build-arg HAWKBIT_APP=hawkbit-mgmt-server --build-arg HAWKBIT_VERSION=${VERSION} -f ${DOCKER_FILE} "${MVN_REPO}"
docker build -t hawkbit/hawkbit-vv8-ui:${VERSION}${TAG_SUFFIX} -t hawkbit/hawkbit-vv8-ui:latest${TAG_SUFFIX} --build-arg HAWKBIT_APP=hawkbit-vv8-ui --build-arg HAWKBIT_VERSION=${VERSION} -f ${DOCKER_FILE} "${MVN_REPO}"

View File

@@ -0,0 +1,50 @@
# hawkBit DDI Server
The hawkBit DDI Server is a standalone spring-boot application with an embedded servlet container. It should be started with at least hawkbit-mgmt-server.
## On your own workstation
### Run
```bash
java -jar hawkbit-runtime/hawkbit-ddi-server/target/hawkbit-ddi-server-*-SNAPSHOT.jar
```
_(Note: you have to add the JDBC driver also to your class path if you intend to use another database than H2.)_
Or:
```bash
run org.eclipse.hawkbit.app.ddi.DDIStart
```
### Usage
The Management API can be accessed via http://localhost:8081/rest/v1
The root url http://localhost:8081 will redirect directly to the Swagger Management UI
### Clustering (Experimental!!!)
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
## Optional Protostuff for Sprign cloud bus
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
Add/Uncomment to/in your `application.properties` :
```properties
spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff
```
Add to your `pom.xml` :
```xml
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
</dependency>
```

View File

@@ -0,0 +1,39 @@
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-runtime-parent</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hawkbit-ddi-server</artifactId>
<name>hawkBit :: Runtime :: DDI Server</name>
<properties>
<spring.app.class>org.eclipse.hawkbit.app.ddi.DDIStart</spring.app.class>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-boot-starter-ddi-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.ddi;
import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
/**
* A {@link SpringBootApplication} annotated class with a main method to start.
* The minimal configuration for the stand alone hawkBit DDI server.
*/
@SpringBootApplication
@EnableHawkbitManagedSecurityConfiguration
public class DDIStart {
/**
* Main method to start the spring-boot application.
*
* @param args
* the VM arguments.
*/
public static void main(final String[] args) {
SpringApplication.run(DDIStart.class, args);
}
@Controller
public static class RedirectController {
@GetMapping("/")
public RedirectView redirectToSwagger(
RedirectAttributes attributes) {
attributes.addFlashAttribute("flashAttribute", "redirectWithRedirectView");
attributes.addAttribute("attribute", "redirectWithRedirectView");
return new RedirectView("swagger-ui/index.html");
}
}
}

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2019 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a DB2 DB usage.
# Keep in mind that you need the DB2 driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=DB2
spring.datasource.url=jdbc:db2://localhost:50000/hawkbit
spring.datasource.username=db2inst1
spring.datasource.password=db2inst1-pwd
spring.datasource.driverClassName=com.ibm.db2.jcc.DB2Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a Microsoft SQL Server DB usage.
# Keep in mind that you need the SQL server driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=SQL_SERVER
spring.datasource.url=jdbc:sqlserver://localhost:1433;database=hawkbit
spring.datasource.username=SA
spring.datasource.password=
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a MySQL DB usage.
# Keep in mind that you need the MariaDB driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mariadb://localhost:3306/hawkbit
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=org.mariadb.jdbc.Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2020 Enapter Co.,Ltd
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a PostgreSQL usage.
# Keep in mind that you need the PostgreSQL driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/hawkbit
spring.datasource.username=postgres
spring.datasource.password=admin
spring.datasource.driverClassName=org.postgresql.Driver

View File

@@ -0,0 +1,76 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
spring.application.name=ddi-server
server.port=8081
# User Security
spring.security.user.name=admin
spring.security.user.password={noop}admin
spring.main.allow-bean-definition-overriding=true
# Http Encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
# DDI authentication configuration
hawkbit.server.ddi.security.authentication.anonymous.enabled=false
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
# Optional events
hawkbit.server.repository.publish-target-poll-event=false
## Configuration for DMF/RabbitMQ integration
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
# Enable CORS and specify the allowed origins:
#hawkbit.server.security.cors.enabled=true
#hawkbit.server.security.cors.allowedOrigins=http://localhost
# Swagger Configuration
#springdoc.swagger-ui.path=/update-server-documentation
#springdoc.api-docs.path=/update-server-api-docs
springdoc.show-oauth2-endpoints=true
springdoc.api-docs.version=openapi_3_0
springdoc.show-login-endpoint=true
springdoc.packages-to-scan=org.eclipse.hawkbit.ddi
springdoc.swagger-ui.oauth2RedirectUrl=/login/oauth2/code/suite
springdoc.paths-to-exclude=/system/**
# Flyway disabled - US only
spring.flyway.enabled=false
## SQL Database Configuration - END
## No Schedulers - START
hawkbit.autoassign.scheduler.enabled=false
hawkbit.rollout.scheduler.enabled=false
## No Schedulers - END
# Disable discovery client of spring-cloud-commons
spring.cloud.discovery.enabled=false
# Enable communication between services
spring.cloud.bus.enabled=true
spring.cloud.bus.ack.enabled=false
spring.cloud.bus.refresh.enabled=false
spring.cloud.bus.env.enabled=false
endpoints.spring.cloud.bus.refresh.enabled=false
endpoints.spring.cloud.bus.env.enabled=false
spring.cloud.stream.bindings.springCloudBusInput.group=ddi-server
# To use protostuff (for instance fot improved performance) you shall uncomment
# the following two lines and add io.protostuff:protostuff-core and io.protostuff:protostuff-runtime to dependencies
#spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
#spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff

View File

@@ -0,0 +1,14 @@
______ _ _ _ _ ____ _ _ _____ _____ _____
| ____| | (_) | | | | | _ \(_) | | __ \| __ \_ _|
| |__ ___| |_ _ __ ___ ___ | |__ __ ___ _| | _| |_) |_| |_ | | | | | | || |
| __| / __| | | '_ \/ __|/ _ \ | '_ \ / _` \ \ /\ / / |/ / _ <| | __| | | | | | | || |
| |___| (__| | | |_) \__ \ __/ | | | | (_| |\ V V /| <| |_) | | |_ | |__| | |__| || |_
|______\___|_|_| .__/|___/\___| |_| |_|\__,_| \_/\_/ |_|\_\____/|_|\__| |_____/|_____/_____|
| |
|_|
Eclipse hawkBit DDI Server ${application.formatted-version}
using Spring Boot ${spring-boot.formatted-version}
Go to https://www.eclipse.org/hawkbit for more information.

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.eclipse.hawkbit.eventbus.DeadEventListener" level="WARN" />
<Logger name="org.springframework.boot.actuate.audit.listener.AuditListener" level="WARN" />
<Logger name="org.hibernate.validator.internal.util.Version" level="WARN" />
<!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" />
<Root level="INFO">
<appender-ref ref="CONSOLE" />
</Root>
</configuration>

View File

@@ -0,0 +1,38 @@
/**
* Copyright (c) 2020 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.ddi;
import org.eclipse.hawkbit.repository.test.util.SharedSqlTestDatabaseExtension;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest(properties = { "hawkbit.dmf.rabbitmq.enabled=false" })
@ExtendWith(SharedSqlTestDatabaseExtension.class)
public abstract class AbstractSecurityTest {
@Autowired
private WebApplicationContext context;
protected MockMvc mvc;
@BeforeEach
public void setup() {
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
.apply(SecurityMockMvcConfigurers.springSecurity()).dispatchOptions(true);
mvc = builder.build();
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2019 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.ddi;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import io.qameta.allure.Description;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.RequestRejectedException;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
"hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" })
@Feature("Integration Test - Security")
@Story("Allowed Host Names")
public class AllowedHostNamesTest extends AbstractSecurityTest {
@Test
@Description("Tests whether a RequestRejectedException is thrown when not allowed host is used")
public void allowedHostNameWithNotAllowedHost() {
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(
() -> mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com")));
}
@Test
@Description("Tests whether request is redirected when allowed host is used")
public void allowedHostNameWithAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "localhost")).andExpect(status().is3xxRedirection());
}
@Test
@Description("Tests whether request without allowed host name and with ignored path end up with a client error")
public void notAllowedHostnameWithIgnoredPath() throws Exception {
mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com"))
.andExpect(status().is4xxClientError());
}
}

View File

@@ -0,0 +1,46 @@
# hawkBit DMF Server
The hawkBit DMF Server is a standalone spring-boot application with an embedded servlet container. It should be started with at least hawkbit-mgmt-server.
## On your own workstation
### Run
```bash
java -jar hawkbit-runtime/hawkbit-dmf-server/target/hawkbit-dmf-server-*-SNAPSHOT.jar
```
_(Note: you have to add the JDBC driver also to your class path if you intend to use another database than H2.)_
Or:
```bash
run org.eclipse.hawkbit.app.dmf.DMFStart
```
### Clustering (Experimental!!!)
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
## Optional Protostuff for Sprign cloud bus
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
Add/Uncomment to/in your `application.properties` :
```properties
spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff
```
Add to your `pom.xml` :
```xml
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
</dependency>
```

View File

@@ -0,0 +1,39 @@
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-runtime-parent</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hawkbit-dmf-server</artifactId>
<name>hawkBit :: Runtime :: DMF Server</name>
<properties>
<spring.app.class>org.eclipse.hawkbit.app.ddi.DMFStart</spring.app.class>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-boot-starter-dmf-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.dmf;
import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* A {@link SpringBootApplication} annotated class with a main method to start.
* The minimal configuration for the stand alone hawkBit DMF server.
*/
@SpringBootApplication
@EnableHawkbitManagedSecurityConfiguration
public class DMFStart {
/**
* Main method to start the spring-boot application.
*
* @param args the VM arguments.
*/
public static void main(final String[] args) {
SpringApplication.run(DMFStart.class, args);
}
}

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2019 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a DB2 DB usage.
# Keep in mind that you need the DB2 driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=DB2
spring.datasource.url=jdbc:db2://localhost:50000/hawkbit
spring.datasource.username=db2inst1
spring.datasource.password=db2inst1-pwd
spring.datasource.driverClassName=com.ibm.db2.jcc.DB2Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a Microsoft SQL Server DB usage.
# Keep in mind that you need the SQL server driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=SQL_SERVER
spring.datasource.url=jdbc:sqlserver://localhost:1433;database=hawkbit
spring.datasource.username=SA
spring.datasource.password=
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a MySQL DB usage.
# Keep in mind that you need the MariaDB driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mariadb://localhost:3306/hawkbit
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=org.mariadb.jdbc.Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2020 Enapter Co.,Ltd
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a PostgreSQL usage.
# Keep in mind that you need the PostgreSQL driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/hawkbit
spring.datasource.username=postgres
spring.datasource.password=admin
spring.datasource.driverClassName=org.postgresql.Driver

View File

@@ -0,0 +1,51 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
spring.application.name=dmf-server
spring.main.allow-bean-definition-overriding=true
# Optional events
hawkbit.server.repository.publish-target-poll-event=false
## Configuration for DMF/RabbitMQ integration
hawkbit.dmf.rabbitmq.enabled=true
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.main.web-application-type=none
hawkbit.server.security.dos.filter.enabled=false
# Flyway disabled - US only
spring.flyway.enabled=false
## SQL Database Configuration - END
## No Schedulers - START
hawkbit.autoassign.scheduler.enabled=false
hawkbit.rollout.scheduler.enabled=false
## No Schedulers - END
# Disable discovery client of spring-cloud-commons
spring.cloud.discovery.enabled=false
# Enable communication between services
spring.cloud.bus.enabled=true
spring.cloud.bus.ack.enabled=false
spring.cloud.bus.refresh.enabled=false
spring.cloud.bus.env.enabled=false
endpoints.spring.cloud.bus.refresh.enabled=false
endpoints.spring.cloud.bus.env.enabled=false
spring.cloud.stream.bindings.springCloudBusInput.group=dmf-server
# To use protostuff (for instance fot improved performance) you shall uncomment
# the following two lines and add io.protostuff:protostuff-core and io.protostuff:protostuff-runtime to dependencies
#spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
#spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff

View File

@@ -0,0 +1,14 @@
______ _ _ _ _ ____ _ _ _____ __ __ ______
| ____| | (_) | | | | | _ \(_) | | __ \| \/ | ____|
| |__ ___| |_ _ __ ___ ___ | |__ __ ___ _| | _| |_) |_| |_ | | | | \ / | |__
| __| / __| | | '_ \/ __|/ _ \ | '_ \ / _` \ \ /\ / / |/ / _ <| | __| | | | | |\/| | __|
| |___| (__| | | |_) \__ \ __/ | | | | (_| |\ V V /| <| |_) | | |_ | |__| | | | | |
|______\___|_|_| .__/|___/\___| |_| |_|\__,_| \_/\_/ |_|\_\____/|_|\__| |_____/|_| |_|_|
| |
|_|
Eclipse hawkBit DMF Server ${application.formatted-version}
using Spring Boot ${spring-boot.formatted-version}
Go to https://www.eclipse.org/hawkbit for more information.

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.eclipse.hawkbit.eventbus.DeadEventListener" level="WARN" />
<Logger name="org.springframework.boot.actuate.audit.listener.AuditListener" level="WARN" />
<Logger name="org.hibernate.validator.internal.util.Version" level="WARN" />
<!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" />
<Root level="INFO">
<appender-ref ref="CONSOLE" />
</Root>
</configuration>

View File

@@ -0,0 +1,50 @@
# hawkBit Management Server
The hawkBit Management Server is a standalone spring-boot application with an embedded servlet container. It should be started with at least one (or both) of the device interface servers - hawkbit-ddi-server or/and hawkbit-dmf-server.
## On your own workstation
### Run
```bash
java -jar hawkbit-runtime/hawkbit-mgmt-server/target/hawkbit-mgmt-server-*-SNAPSHOT.jar
```
_(Note: you have to add the JDBC driver also to your class path if you intend to use another database than H2.)_
Or:
```bash
run org.eclipse.hawkbit.app.mgmt.MgmtServerStart
```
### Usage
The Management API can be accessed via http://localhost:8080/rest/v1
The root url http://localhost:8080 will redirect directly to the Swagger Management UI
### Clustering (Experimental!!!)
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
## Optional Protostuff for Sprign cloud bus
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
Add/Uncomment to/in your `application.properties` :
```properties
spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff
```
Add to your `pom.xml` :
```xml
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
</dependency>
```

View File

@@ -0,0 +1,39 @@
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-runtime-parent</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hawkbit-mgmt-server</artifactId>
<name>hawkBit :: Runtime :: Management Server</name>
<properties>
<spring.app.class>org.eclipse.hawkbit.app.mgmt.UpdateServerStart</spring.app.class>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-boot-starter-mgmt-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,70 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.mgmt;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Error page controller that ensures that ocet stream does not return text in
* case of an error.
*/
@Controller
// Exception squid:S3752 - errors need handling for all methods
@SuppressWarnings("squid:S3752")
public class ErrorController extends BasicErrorController {
private static final String PATH = "path";
/**
* A new {@link ErrorController}.
*
* @param errorAttributes
* the error attributes
* @param serverProperties
* configuration properties
*/
public ErrorController(final ErrorAttributes errorAttributes, final ServerProperties serverProperties) {
super(errorAttributes, serverProperties.getError());
}
@RequestMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<Void> errorStream(final HttpServletRequest request, final HttpServletResponse response) {
final HttpStatus status = getStatus(request);
return new ResponseEntity<>(status);
}
@Override
@RequestMapping
public ResponseEntity<Map<String, Object>> error(final HttpServletRequest request) {
final HttpStatus status = getStatus(request);
final Map<String, Object> body = getErrorAttributesWithoutPath(request);
return new ResponseEntity<>(body, status);
}
private Map<String, Object> getErrorAttributesWithoutPath(final HttpServletRequest request) {
final Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
if (body != null && body.containsKey(PATH)) {
body.remove(PATH);
}
return body;
}
}

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.mgmt;
import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
/**
* A {@link SpringBootApplication} annotated class with a main method to start.
* The minimal configuration for the stand alone hawkBit server.
*
*/
@SpringBootApplication
@EnableHawkbitManagedSecurityConfiguration
public class MgmtServerStart {
/**
* Main method to start the spring-boot application.
*
* @param args the VM arguments.
*/
public static void main(final String[] args) {
SpringApplication.run(MgmtServerStart.class, args);
}
@Controller
public static class RedirectController {
@GetMapping("/")
public RedirectView redirectToSwagger(
RedirectAttributes attributes) {
attributes.addFlashAttribute("flashAttribute", "redirectWithRedirectView");
attributes.addAttribute("attribute", "redirectWithRedirectView");
return new RedirectView("swagger-ui/index.html");
}
}
}

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2019 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a DB2 DB usage.
# Keep in mind that you need the DB2 driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=DB2
spring.datasource.url=jdbc:db2://localhost:50000/hawkbit
spring.datasource.username=db2inst1
spring.datasource.password=db2inst1-pwd
spring.datasource.driverClassName=com.ibm.db2.jcc.DB2Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a Microsoft SQL Server DB usage.
# Keep in mind that you need the SQL server driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=SQL_SERVER
spring.datasource.url=jdbc:sqlserver://localhost:1433;database=hawkbit
spring.datasource.username=SA
spring.datasource.password=
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a MySQL DB usage.
# Keep in mind that you need the MariaDB driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mariadb://localhost:3306/hawkbit
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=org.mariadb.jdbc.Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2020 Enapter Co.,Ltd
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a PostgreSQL usage.
# Keep in mind that you need the PostgreSQL driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/hawkbit
spring.datasource.username=postgres
spring.datasource.password=admin
spring.datasource.driverClassName=org.postgresql.Driver

View File

@@ -0,0 +1,72 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
spring.application.name=mgmt-server
spring.port=8080
# User Security
spring.security.user.name=admin
spring.security.user.password={noop}admin
spring.main.allow-bean-definition-overriding=true
# Http Encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
# Optional events
hawkbit.server.repository.publish-target-poll-event=false
## Configuration for DMF/RabbitMQ integration
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
# Define own users instead of default "admin" user:
#hawkbit.server.im.users[0].username=hawkbit
#hawkbit.server.im.users[0].password={noop}isAwesome!
#hawkbit.server.im.users[0].firstname=Eclipse
#hawkbit.server.im.users[0].lastname=HawkBit
#hawkbit.server.im.users[0].permissions=ALL
# Enable CORS and specify the allowed origins:
#hawkbit.server.security.cors.enabled=true
#hawkbit.server.security.cors.allowedOrigins=http://localhost
hawkbit.server.swagger.mgmt.api.group.enabled=true
hawkbit.server.swagger.ddi.api.group.enabled=false
# Swagger Configuration
#springdoc.swagger-ui.path=/update-server-documentation
#springdoc.api-docs.path=/update-server-api-docs
springdoc.show-oauth2-endpoints=true
springdoc.api-docs.version=openapi_3_0
springdoc.show-login-endpoint=true
springdoc.packages-to-scan=org.eclipse.hawkbit.mgmt
springdoc.swagger-ui.oauth2RedirectUrl=/login/oauth2/code/suite
springdoc.paths-to-exclude=/system/**
# Disable discovery client of spring-cloud-commons
spring.cloud.discovery.enabled=false
# Enable communication between services
spring.cloud.bus.enabled=true
spring.cloud.bus.ack.enabled=false
spring.cloud.bus.refresh.enabled=false
spring.cloud.bus.env.enabled=false
endpoints.spring.cloud.bus.refresh.enabled=false
endpoints.spring.cloud.bus.env.enabled=false
spring.cloud.stream.bindings.springCloudBusInput.group=mgmt-server
# To use protostuff (for instance fot improved performance) you shall uncomment
# the following two lines and add io.protostuff:protostuff-core and io.protostuff:protostuff-runtime to dependencies
#spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
#spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff

View File

@@ -0,0 +1,14 @@
______ _ _ _ _ ____ _ _ __ __ _
| ____| | (_) | | | | | _ \(_) | | \/ | | |
| |__ ___| |_ _ __ ___ ___ | |__ __ ___ _| | _| |_) |_| |_ | \ / | __ _ _ __ ___ | |_
| __| / __| | | '_ \/ __|/ _ \ | '_ \ / _` \ \ /\ / / |/ / _ <| | __| | |\/| |/ _` | '_ ` _ \| __|
| |___| (__| | | |_) \__ \ __/ | | | | (_| |\ V V /| <| |_) | | |_ | | | | (_| | | | | | | |_
|______\___|_|_| .__/|___/\___| |_| |_|\__,_| \_/\_/ |_|\_\____/|_|\__| |_| |_|\__, |_| |_| |_|\__|
| | __/ |
|_| |___/
Eclipse hawkBit Management Server ${application.formatted-version}
using Spring Boot ${spring-boot.formatted-version}
Go to https://www.eclipse.org/hawkbit for more information.

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.eclipse.hawkbit.eventbus.DeadEventListener" level="WARN" />
<Logger name="org.springframework.boot.actuate.audit.listener.AuditListener" level="WARN" />
<Logger name="org.hibernate.validator.internal.util.Version" level="WARN" />
<!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" />
<Root level="INFO">
<appender-ref ref="CONSOLE" />
</Root>
</configuration>

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2020 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.mgmt;
import org.eclipse.hawkbit.repository.test.util.SharedSqlTestDatabaseExtension;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest(properties = { "hawkbit.dmf.rabbitmq.enabled=false" })
@ExtendWith(SharedSqlTestDatabaseExtension.class)
public abstract class AbstractSecurityTest {
@Autowired
private WebApplicationContext context;
protected MockMvc mvc;
@BeforeEach
public void setup() {
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
.apply(SecurityMockMvcConfigurers.springSecurity()).dispatchOptions(true);
mvc = builder.build();
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2019 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.mgmt;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import io.qameta.allure.Description;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.RequestRejectedException;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
"hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" })
@Feature("Integration Test - Security")
@Story("Allowed Host Names")
public class AllowedHostNamesTest extends AbstractSecurityTest {
@Test
@Description("Tests whether a RequestRejectedException is thrown when not allowed host is used")
public void allowedHostNameWithNotAllowedHost() {
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(
() -> mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com")));
}
@Test
@Description("Tests whether request is redirected when allowed host is used")
public void allowedHostNameWithAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "localhost")).andExpect(status().is3xxRedirection());
}
@Test
@Description("Tests whether request without allowed host name and with ignored path end up with a client error")
public void notAllowedHostnameWithIgnoredPath() throws Exception {
mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com"))
.andExpect(status().is4xxClientError());
}
}

View File

@@ -0,0 +1,76 @@
/**
* Copyright (c) 2019 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.mgmt;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.web.servlet.ResultActions;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
@SpringBootTest(properties = {
"hawkbit.dmf.rabbitmq.enabled=false",
"hawkbit.server.security.cors.enabled=true",
"hawkbit.server.security.cors.allowedOrigins="
+ CorsTest.ALLOWED_ORIGIN_FIRST + ","
+ CorsTest.ALLOWED_ORIGIN_SECOND,
"hawkbit.server.security.cors.exposedHeaders="
+ HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN})
@Feature("Integration Test - Security")
@Story("CORS")
public class CorsTest extends AbstractSecurityTest {
final static String ALLOWED_ORIGIN_FIRST = "http://test.first.origin";
final static String ALLOWED_ORIGIN_SECOND = "http://test.second.origin";
private final static String INVALID_ORIGIN = "http://test.invalid.origin";
private final static String INVALID_CORS_REQUEST = "Invalid CORS request";
@WithUserDetails("admin")
@Test
@Description("Ensures that Cors is working.")
public void validateCorsRequest() throws Exception {
performOptionsRequestToRestWithOrigin(ALLOWED_ORIGIN_FIRST).andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, ALLOWED_ORIGIN_FIRST));
performOptionsRequestToRestWithOrigin(ALLOWED_ORIGIN_SECOND).andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, ALLOWED_ORIGIN_SECOND));
final String invalidOriginResponseBody = performOptionsRequestToRestWithOrigin(INVALID_ORIGIN)
.andExpect(status().isForbidden())
.andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).andReturn().getResponse()
.getContentAsString();
assertThat(invalidOriginResponseBody).isEqualTo(INVALID_CORS_REQUEST);
final String invalidCorsUrlResponseBody = performOptionsRequestToUrlWithOrigin(
MgmtRestConstants.BASE_SYSTEM_MAPPING, ALLOWED_ORIGIN_FIRST).andExpect(status().isForbidden())
.andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).andReturn()
.getResponse().getContentAsString();
assertThat(invalidCorsUrlResponseBody).isEqualTo(INVALID_CORS_REQUEST);
}
private ResultActions performOptionsRequestToRestWithOrigin(final String origin) throws Exception {
return performOptionsRequestToUrlWithOrigin(MgmtRestConstants.BASE_V1_REQUEST_MAPPING, origin);
}
private ResultActions performOptionsRequestToUrlWithOrigin(final String url, final String origin) throws Exception {
return mvc.perform(options(url).header("Access-Control-Request-Method", "GET").header("Origin", origin));
}
}

View File

@@ -1 +0,0 @@
/artifactrepo/

View File

@@ -1,6 +1,6 @@
# hawkBit Update Server # hawkBit Update Server
The hawkBit Update Server is a standalone spring-boot application with an embedded servlet container . The hawkBit Update Server (Monolith) is a standalone spring-boot application with an embedded servlet container .
## On your own workstation ## On your own workstation
@@ -15,7 +15,7 @@ _(Note: you have to add the JDBC driver also to your class path if you intend to
Or: Or:
```bash ```bash
run org.eclipse.hawkbit.app.Start run org.eclipse.hawkbit.doc.Start
``` ```
### Usage ### Usage

View File

@@ -18,47 +18,11 @@
<version>${revision}</version> <version>${revision}</version>
</parent> </parent>
<artifactId>hawkbit-update-server</artifactId> <artifactId>hawkbit-update-server</artifactId>
<name>hawkBit :: Runtime :: Update Server</name> <name>hawkBit :: Runtime :: Update Server (Monolith)</name>
<profiles> <properties>
<profile> <spring.app.class>org.eclipse.hawkbit.doc.Start</spring.app.class>
<id>docker</id> </properties>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<outputDirectory>${baseDir}</outputDirectory>
<mainClass>org.eclipse.hawkbit.app.Start</mainClass>
<layout>JAR</layout>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -66,46 +30,5 @@
<artifactId>hawkbit-boot-starter</artifactId> <artifactId>hawkbit-boot-starter</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -15,5 +15,5 @@
spring.jpa.database=POSTGRESQL spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/hawkbit spring.datasource.url=jdbc:postgresql://localhost:5432/hawkbit
spring.datasource.username=postgres spring.datasource.username=postgres
spring.datasource.password= spring.datasource.password=admin
spring.datasource.driverClassName=org.postgresql.Driver spring.datasource.driverClassName=org.postgresql.Driver

View File

@@ -18,7 +18,6 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;

View File

@@ -0,0 +1,49 @@
# hawkBit Vaadin 8 UI (Deprecated)
The hawkBit Vaadin v8 UI is a standalone spring-boot application with an embedded servlet container. It should be started with at least hawkbit-mgmt-server.
## On your own workstation
### Run
```bash
java -jar hawkbit-runtime/hawkbit-vv8-ui/target/hawkbit-vv8-ui-*-SNAPSHOT.jar
```
_(Note: you have to add the JDBC driver also to your class path if you intend to use another database than H2.)_
Or:
```bash
run org.eclipse.hawkbit.app.vv8ui.Vv8UIStart
```
### Usage
The Management UI can be accessed via http://localhost:8082/UI
### Clustering (Experimental!!!)
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
## Optional Protostuff for Sprign cloud bus
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
Add/Uncomment to/in your `application.properties` :
```properties
spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff
```
Add to your `pom.xml` :
```xml
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
</dependency>
```

View File

@@ -0,0 +1,39 @@
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-runtime-parent</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hawkbit-vv8-ui</artifactId>
<name>hawkBit :: Runtime :: Vaadin v8 UI</name>
<properties>
<spring.app.class>org.eclipse.hawkbit.app.vv8ui.Vaadin8UIStart</spring.app.class>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-boot-starter-mgmt-ui</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,70 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.vv8ui;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Error page controller that ensures that ocet stream does not return text in
* case of an error.
*/
@Controller
// Exception squid:S3752 - errors need handling for all methods
@SuppressWarnings("squid:S3752")
public class ErrorController extends BasicErrorController {
private static final String PATH = "path";
/**
* A new {@link ErrorController}.
*
* @param errorAttributes
* the error attributes
* @param serverProperties
* configuration properties
*/
public ErrorController(final ErrorAttributes errorAttributes, final ServerProperties serverProperties) {
super(errorAttributes, serverProperties.getError());
}
@RequestMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<Void> errorStream(final HttpServletRequest request, final HttpServletResponse response) {
final HttpStatus status = getStatus(request);
return new ResponseEntity<>(status);
}
@Override
@RequestMapping
public ResponseEntity<Map<String, Object>> error(final HttpServletRequest request) {
final HttpStatus status = getStatus(request);
final Map<String, Object> body = getErrorAttributesWithoutPath(request);
return new ResponseEntity<>(body, status);
}
private Map<String, Object> getErrorAttributesWithoutPath(final HttpServletRequest request) {
final Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
if (body != null && body.containsKey(PATH)) {
body.remove(PATH);
}
return body;
}
}

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.vv8ui;
import org.eclipse.hawkbit.im.authentication.MultitenancyIndicator;
import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.login.AbstractHawkbitLoginUI;
import org.eclipse.hawkbit.ui.themes.HawkbitTheme;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.vaadin.spring.security.VaadinSecurity;
import com.vaadin.spring.annotation.SpringUI;
/**
* Example hawkBit login UI implementation.
*
* A {@link SpringUI} annotated class must be present in the classpath for the
* login path. The easiest way to get an hawkBit login UI running is to extend
* the {@link AbstractHawkbitLoginUI} and to annotated it with {@link SpringUI}
* as in this example to the defined {@link HawkbitTheme#LOGIN_UI_PATH}.
*/
@SpringUI(path = HawkbitTheme.LOGIN_UI_PATH)
// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from
// Vaadin.
@SuppressWarnings({ "squid:MaximumInheritanceDepth" })
public class MyLoginUI extends AbstractHawkbitLoginUI {
private static final long serialVersionUID = 1L;
@Autowired
MyLoginUI(final ApplicationContext context, final VaadinSecurity vaadinSecurity, final VaadinMessageSource i18n,
final UiProperties uiProperties, final MultitenancyIndicator multiTenancyIndicator) {
super(context, vaadinSecurity, i18n, uiProperties, multiTenancyIndicator);
}
}

View File

@@ -0,0 +1,59 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.vv8ui;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.components.NotificationUnreadButton;
import org.eclipse.hawkbit.ui.error.ErrorView;
import org.eclipse.hawkbit.ui.menu.DashboardMenu;
import org.eclipse.hawkbit.ui.push.EventPushStrategy;
import org.eclipse.hawkbit.ui.push.UIEventProvider;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.annotations.Push;
import com.vaadin.server.ErrorHandler;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.spring.navigator.SpringViewProvider;
/**
* Example hawkBit UI implementation.
*
* A {@link SpringUI} annotated class must be present in the classpath. The
* easiest way to get an hawkBit UI running is to extend the
* {@link AbstractHawkbitUI} and to annotated it with {@link SpringUI} as in
* this example. WEBSOCKET_XHR transport is used instead of WEBSOCKET in order
* to preserve Spring Security Context, that does not work using websocket
* communication with Vaadin Shared Security.
*
*/
@SpringUI
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET_XHR)
// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from
// Vaadin.
@SuppressWarnings({ "squid:MaximumInheritanceDepth" })
public class MyUI extends AbstractHawkbitUI {
private static final long serialVersionUID = 1L;
@Autowired
MyUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus, final UIEventProvider eventProvider,
final SpringViewProvider viewProvider, final ApplicationContext context, final DashboardMenu dashboardMenu,
final ErrorView errorview, final NotificationUnreadButton notificationUnreadButton,
final UiProperties uiProperties, final VaadinMessageSource i18n, final ErrorHandler uiErrorHandler) {
super(pushStrategy, eventBus, eventProvider, viewProvider, context, dashboardMenu, errorview,
notificationUnreadButton, uiProperties, i18n, uiErrorHandler);
}
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.vv8ui;
import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* A {@link SpringBootApplication} annotated class with a main method to start.
* The minimal configuration for the stand alone hawkBit server.
*
*/
@SpringBootApplication
@EnableHawkbitManagedSecurityConfiguration
public class Vaadin8UIStart {
/**
* Main method to start the spring-boot application.
*
* @param args
* the VM arguments.
*/
public static void main(final String[] args) {
SpringApplication.run(Vaadin8UIStart.class, args);
}
}

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2019 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a DB2 DB usage.
# Keep in mind that you need the DB2 driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=DB2
spring.datasource.url=jdbc:db2://localhost:50000/hawkbit
spring.datasource.username=db2inst1
spring.datasource.password=db2inst1-pwd
spring.datasource.driverClassName=com.ibm.db2.jcc.DB2Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a Microsoft SQL Server DB usage.
# Keep in mind that you need the SQL server driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=SQL_SERVER
spring.datasource.url=jdbc:sqlserver://localhost:1433;database=hawkbit
spring.datasource.username=SA
spring.datasource.password=
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a MySQL DB usage.
# Keep in mind that you need the MariaDB driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mariadb://localhost:3306/hawkbit
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=org.mariadb.jdbc.Driver

View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2020 Enapter Co.,Ltd
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# This profile adds basic configurations for a PostgreSQL usage.
# Keep in mind that you need the PostgreSQL driver in your classpath on compile.
# see https://www.eclipse.org/hawkbit/guides/runhawkbit/
spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/hawkbit
spring.datasource.username=postgres
spring.datasource.password=admin
spring.datasource.driverClassName=org.postgresql.Driver

View File

@@ -0,0 +1,77 @@
#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others
#
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
spring.application.name=vv8-ui-server
server.port=8082
# User Security
spring.security.user.name=admin
spring.security.user.password={noop}admin
spring.main.allow-bean-definition-overriding=true
# Http Encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
# DDI authentication configuration
hawkbit.server.ddi.security.authentication.anonymous.enabled=false
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
# Optional events
hawkbit.server.repository.publish-target-poll-event=false
## Configuration for DMF/RabbitMQ integration
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
# Define own users instead of default "admin" user:
#hawkbit.server.im.users[0].username=hawkbit
#hawkbit.server.im.users[0].password={noop}isAwesome!
#hawkbit.server.im.users[0].firstname=Eclipse
#hawkbit.server.im.users[0].lastname=HawkBit
#hawkbit.server.im.users[0].permissions=ALL
# Enable CORS and specify the allowed origins:
#hawkbit.server.security.cors.enabled=true
#hawkbit.server.security.cors.allowedOrigins=http://localhost
## Disable swagger
hawkbit.server.swagger.mgmt.api.group.enabled=false
hawkbit.server.swagger.ddi.api.group.enabled=false
# Flyway disabled - US only
spring.flyway.enabled=false
## SQL Database Configuration - END
## No Schedulers - START
hawkbit.autoassign.scheduler.enabled=false
hawkbit.rollout.scheduler.enabled=false
## No Schedulers - END
# Disable discovery client of spring-cloud-commons
spring.cloud.discovery.enabled=false
# Enable communication between services
spring.cloud.bus.enabled=true
spring.cloud.bus.ack.enabled=false
spring.cloud.bus.refresh.enabled=false
spring.cloud.bus.env.enabled=false
endpoints.spring.cloud.bus.refresh.enabled=false
endpoints.spring.cloud.bus.env.enabled=false
spring.cloud.stream.bindings.springCloudBusInput.group=vv8-ui-server
# To use protostuff (for instance fot improved performance) you shall uncomment
# the following two lines and add io.protostuff:protostuff-core and io.protostuff:protostuff-runtime to dependencies
#spring.cloud.stream.bindings.springCloudBusInput.content-type=application/binary+protostuff
#spring.cloud.stream.bindings.springCloudBusOutput.content-type=application/binary+protostuff

View File

@@ -0,0 +1,18 @@
______ _ _ _ _ ____ _ _
| ____| | (_) | | | | | _ \(_) |
| |__ ___| |_ _ __ ___ ___ | |__ __ ___ _| | _| |_) |_| |_
| __| / __| | | '_ \/ __|/ _ \ | '_ \ / _` \ \ /\ / / |/ / _ <| | __|
| |___| (__| | | |_) \__ \ __/ | | | | (_| |\ V V /| <| |_) | | |_
|______\___|_|_| .__/|___/\___| |_| |_|\__,_| \_/\_/ |_|\_\____/|_|\__|
__ __ | | _ _ ___ _ _ _____
\ \ / / |_| | (_) / _ \ | | | |_ _|
\ \ / /_ _ __ _ __| |_ _ __ __ _| (_) | | | | | | |
\ \/ / _` |/ _` |/ _` | | '_ \ \ \ / /> _ < | | | | | |
\ / (_| | (_| | (_| | | | | | \ V /| (_) | | |__| |_| |_
\/ \__,_|\__,_|\__,_|_|_| |_| \_/ \___/ \____/|_____|
Eclipse hawkBit Vaadin v8 UI ${application.formatted-version}
using Spring Boot ${spring-boot.formatted-version}
Go to https://www.eclipse.org/hawkbit for more information.

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
-->
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.eclipse.hawkbit.eventbus.DeadEventListener" level="WARN" />
<Logger name="org.springframework.boot.actuate.audit.listener.AuditListener" level="WARN" />
<Logger name="org.hibernate.validator.internal.util.Version" level="WARN" />
<!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" />
<!-- Suppressing "More than one Servlet Mapping defined. WebSocket may not work"
error due to the way VaadinServletConfiguration configures the endpoints mapping ("/UI" and "/UI/*").
At the end only the first "/UI" is taken for websocket communication. -->
<logger name="org.atmosphere.util.IOUtils" level="OFF" />
<Root level="INFO">
<appender-ref ref="CONSOLE" />
</Root>
</configuration>

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2020 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.vv8ui;
import org.eclipse.hawkbit.repository.test.util.SharedSqlTestDatabaseExtension;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest(properties = { "hawkbit.dmf.rabbitmq.enabled=false" })
@ExtendWith(SharedSqlTestDatabaseExtension.class)
public abstract class AbstractSecurityTest {
@Autowired
private WebApplicationContext context;
protected MockMvc mvc;
@BeforeEach
public void setup() {
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
.apply(SecurityMockMvcConfigurers.springSecurity()).dispatchOptions(true);
mvc = builder.build();
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2019 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.app.vv8ui;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import io.qameta.allure.Description;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.RequestRejectedException;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
"hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" })
@Feature("Integration Test - Security")
@Story("Allowed Host Names")
public class AllowedHostNamesTest extends AbstractSecurityTest {
@Test
@Description("Tests whether a RequestRejectedException is thrown when not allowed host is used")
public void allowedHostNameWithNotAllowedHost() {
assertThatExceptionOfType(RequestRejectedException.class).isThrownBy(
() -> mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com")));
}
@Test
@Description("Tests whether request is redirected when allowed host is used")
public void allowedHostNameWithAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "localhost")).andExpect(status().is3xxRedirection());
}
@Test
@Description("Tests whether request without allowed host name and with ignored path end up with a client error")
public void notAllowedHostnameWithIgnoredPath() throws Exception {
mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com"))
.andExpect(status().is4xxClientError());
}
}

View File

@@ -19,10 +19,100 @@
</parent> </parent>
<artifactId>hawkbit-runtime-parent</artifactId> <artifactId>hawkbit-runtime-parent</artifactId>
<name>hawkBit :: Runtime</name> <name>hawkBit :: Runtime :: Parent</name>
<packaging>pom</packaging> <packaging>pom</packaging>
<!-- Common runtime dependences -->
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<outputDirectory>${baseDir}</outputDirectory>
<mainClass>${spring.app.class}</mainClass>
<layout>JAR</layout>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>docker</id>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<modules> <modules>
<module>hawkbit-ddi-server</module>
<module>hawkbit-dmf-server</module>
<module>hawkbit-mgmt-server</module>
<module>hawkbit-vv8-ui</module>
<module>hawkbit-update-server</module> <module>hawkbit-update-server</module>
</modules> </modules>
</project> </project>

View File

@@ -195,5 +195,4 @@
</build> </build>
</profile> </profile>
</profiles> </profiles>
</project> </project>

View File

@@ -46,11 +46,7 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.security.web.session.HttpSessionEventPublisher; import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.vaadin.spring.http.HttpService; import org.vaadin.spring.http.HttpService;
import org.vaadin.spring.security.annotation.EnableVaadinSharedSecurity; import org.vaadin.spring.security.annotation.EnableVaadinSharedSecurity;
@@ -59,10 +55,7 @@ import org.vaadin.spring.security.shared.VaadinAuthenticationSuccessHandler;
import org.vaadin.spring.security.shared.VaadinUrlAuthenticationSuccessHandler; import org.vaadin.spring.security.shared.VaadinUrlAuthenticationSuccessHandler;
import org.vaadin.spring.security.web.VaadinRedirectStrategy; import org.vaadin.spring.security.web.VaadinRedirectStrategy;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/** /**
* {@link WebSecurityConfigurer} for external (management) access. * {@link WebSecurityConfigurer} for external (management) access.
@@ -204,49 +197,6 @@ public class UISecurityConfigurationAdapter {
return httpSec.build(); return httpSec.build();
} }
/**
* HttpFirewall which enables to define a list of allowed host names.
*
* @return the http firewall.
*/
@Bean
public HttpFirewall httpFirewall() {
final List<String> allowedHostNames = hawkbitSecurityProperties.getAllowedHostNames();
final IgnorePathsStrictHttpFirewall firewall = new IgnorePathsStrictHttpFirewall(
hawkbitSecurityProperties.getHttpFirewallIgnoredPaths());
if (!CollectionUtils.isEmpty(allowedHostNames)) {
firewall.setAllowedHostnames(hostName -> {
LOG.debug("Firewall check host: {}, allowed: {}", hostName, allowedHostNames.contains(hostName));
return allowedHostNames.contains(hostName);
});
}
return firewall;
}
private static class IgnorePathsStrictHttpFirewall extends StrictHttpFirewall {
private final Collection<String> pathsToIgnore;
public IgnorePathsStrictHttpFirewall(final Collection<String> pathsToIgnore) {
super();
this.pathsToIgnore = pathsToIgnore;
}
@Override
public FirewalledRequest getFirewalledRequest(final HttpServletRequest request) {
if (pathsToIgnore != null && pathsToIgnore.contains(request.getRequestURI())) {
return new FirewalledRequest(request) {
@Override
public void reset() {
// nothing to do
}
};
}
return super.getFirewalledRequest(request);
}
}
@Bean @Bean
public WebSecurityCustomizer webSecurityCustomizer() { public WebSecurityCustomizer webSecurityCustomizer() {
// No security for static content // No security for static content