Code format - hawkbit-security-core (#1925)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-11-05 09:21:55 +02:00
committed by GitHub
parent 5bb6cc8cb3
commit 71aa00ca7c
21 changed files with 332 additions and 392 deletions

View File

@@ -9,64 +9,64 @@
SPDX-License-Identifier: 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" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.eclipse.hawkbit</groupId> <groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-parent</artifactId> <artifactId>hawkbit-parent</artifactId>
<version>${revision}</version> <version>${revision}</version>
</parent> </parent>
<artifactId>hawkbit-security-core</artifactId> <artifactId>hawkbit-security-core</artifactId>
<name>hawkBit :: Core Security</name> <name>hawkBit :: Core Security</name>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.eclipse.hawkbit</groupId> <groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-core</artifactId> <artifactId>hawkbit-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>jakarta.servlet</groupId> <groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId> <artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId> <artifactId>spring-data-commons</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId> <artifactId>spring-security-core</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId> <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId> <artifactId>spring-boot</artifactId>
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.qameta.allure</groupId> <groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId> <artifactId>allure-junit5</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -22,12 +22,12 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public final class PermissionUtils { public final class PermissionUtils {
/** /**
* Returns all authorities. * Returns all authorities.
* *
* @return a list of {@link GrantedAuthority} * @return a list of {@link GrantedAuthority}
*/ */
public static List<GrantedAuthority> createAllAuthorityList() { public static List<GrantedAuthority> createAllAuthorityList() {
return SpPermission.getAllAuthorities().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()); return SpPermission.getAllAuthorities().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
} }
} }

View File

@@ -146,6 +146,7 @@ public final class SpPermission {
/** /**
* Return all permission. * Return all permission.
*
* @return all permissions * @return all permissions
*/ */
public static List<String> getAllAuthorities() { public static List<String> getAllAuthorities() {
@@ -189,6 +190,7 @@ public final class SpPermission {
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public static final class SpringEvalExpressions { public static final class SpringEvalExpressions {
/* /*
* Spring security eval expressions. * Spring security eval expressions.
*/ */
@@ -197,37 +199,21 @@ public final class SpPermission {
public static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'"; public static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'";
public static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE; public static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE;
public static final String HAS_AUTH_AND = " and "; public static final String HAS_AUTH_AND = " and ";
/**
* The role which contains in the spring security context in case an
* controller is authenticated.
*/
public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER";
/**
* The role which contained in the spring security context in case that a
* controller is authenticated, but only as 'anonymous'.
*/
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
/** /**
* The role which contains the spring security context in case the * The role which contains the spring security context in case the
* system is executing code which is necessary to be privileged. * system is executing code which is necessary to be privileged.
*/ */
public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE"; public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE";
/** /**
* The spring security eval expression operator {@code or}. * The spring security eval expression operator {@code or}.
*/ */
public static final String HAS_AUTH_OR = " or "; public static final String HAS_AUTH_OR = " or ";
/** /**
* Spring security eval hasAnyRole expression to check if the spring * Spring security eval hasAnyRole expression to check if the spring
* context contains system code role * context contains system code role
* {@link SpringEvalExpressions#SYSTEM_ROLE}. * {@link SpringEvalExpressions#SYSTEM_ROLE}.
*/ */
public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#UPDATE_TARGET} or * context contains {@link SpPermission#UPDATE_TARGET} or
@@ -235,7 +221,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#SYSTEM_ADMIN} or * context contains {@link SpPermission#SYSTEM_ADMIN} or
@@ -243,7 +228,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_TARGET} or * context contains {@link SpPermission#READ_TARGET} or
@@ -251,7 +235,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR
+ IS_SYSTEM_CODE; + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_TARGET_SEC_TOKEN} or * context contains {@link SpPermission#READ_TARGET_SEC_TOKEN} or
@@ -259,7 +242,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_READ_TARGET_SEC_TOKEN = HAS_AUTH_PREFIX + READ_TARGET_SEC_TOKEN public static final String HAS_AUTH_READ_TARGET_SEC_TOKEN = HAS_AUTH_PREFIX + READ_TARGET_SEC_TOKEN
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#CREATE_TARGET} or * context contains {@link SpPermission#CREATE_TARGET} or
@@ -267,7 +249,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#DELETE_TARGET} or * context contains {@link SpPermission#DELETE_TARGET} or
@@ -275,7 +256,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_REPOSITORY} and * context contains {@link SpPermission#READ_REPOSITORY} and
@@ -284,7 +264,6 @@ public final class SpPermission {
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#CREATE_REPOSITORY} or * context contains {@link SpPermission#CREATE_REPOSITORY} or
@@ -292,7 +271,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#DELETE_REPOSITORY} or * context contains {@link SpPermission#DELETE_REPOSITORY} or
@@ -300,7 +278,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_REPOSITORY} or * context contains {@link SpPermission#READ_REPOSITORY} or
@@ -308,7 +285,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#UPDATE_REPOSITORY} or * context contains {@link SpPermission#UPDATE_REPOSITORY} or
@@ -316,7 +292,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_REPOSITORY} and * context contains {@link SpPermission#READ_REPOSITORY} and
@@ -325,7 +300,6 @@ public final class SpPermission {
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_REPOSITORY = BRACKET_OPEN + HAS_AUTH_PREFIX public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_REPOSITORY = BRACKET_OPEN + HAS_AUTH_PREFIX
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_REPOSITORY + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_REPOSITORY
+ HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_REPOSITORY} and * context contains {@link SpPermission#READ_REPOSITORY} and
@@ -334,7 +308,6 @@ public final class SpPermission {
public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or * context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or
@@ -342,15 +315,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/**
* Spring security eval hasAnyRole expression to check if the spring
* context contains the anonymous role or the controller specific role
* {@link SpringEvalExpressions#CONTROLLER_ROLE}.
*/
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
+ "')";
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#CREATE_REPOSITORY} and * context contains {@link SpPermission#CREATE_REPOSITORY} and
@@ -359,7 +323,6 @@ public final class SpPermission {
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
+ CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_ROLLOUT} or * context contains {@link SpPermission#READ_ROLLOUT} or
@@ -367,7 +330,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + READ_ROLLOUT + HAS_AUTH_SUFFIX public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + READ_ROLLOUT + HAS_AUTH_SUFFIX
+ HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_ROLLOUT} and * context contains {@link SpPermission#READ_ROLLOUT} and
@@ -376,7 +338,6 @@ public final class SpPermission {
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX
+ READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#CREATE_ROLLOUT} or * context contains {@link SpPermission#CREATE_ROLLOUT} or
@@ -384,7 +345,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + CREATE_ROLLOUT public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + CREATE_ROLLOUT
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#HANDLE_ROLLOUT} or * context contains {@link SpPermission#HANDLE_ROLLOUT} or
@@ -392,7 +352,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + HANDLE_ROLLOUT public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + HANDLE_ROLLOUT
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#APPROVE_ROLLOUT} or * context contains {@link SpPermission#APPROVE_ROLLOUT} or
@@ -400,7 +359,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE = HAS_AUTH_PREFIX + APPROVE_ROLLOUT public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE = HAS_AUTH_PREFIX + APPROVE_ROLLOUT
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#UPDATE_ROLLOUT} or * context contains {@link SpPermission#UPDATE_ROLLOUT} or
@@ -408,7 +366,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + UPDATE_ROLLOUT public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + UPDATE_ROLLOUT
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#DELETE_ROLLOUT} or * context contains {@link SpPermission#DELETE_ROLLOUT} or
@@ -416,7 +373,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + DELETE_ROLLOUT public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + DELETE_ROLLOUT
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#READ_TENANT_CONFIGURATION} or * context contains {@link SpPermission#READ_TENANT_CONFIGURATION} or
@@ -424,7 +380,6 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + READ_TENANT_CONFIGURATION public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + READ_TENANT_CONFIGURATION
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#TENANT_CONFIGURATION} or * context contains {@link SpPermission#TENANT_CONFIGURATION} or
@@ -432,7 +387,23 @@ public final class SpPermission {
*/ */
public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
/**
* The role which contains in the spring security context in case an
* controller is authenticated.
*/
public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER";
/**
* The role which contained in the spring security context in case that a
* controller is authenticated, but only as 'anonymous'.
*/
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
/**
* Spring security eval hasAnyRole expression to check if the spring
* context contains the anonymous role or the controller specific role
* {@link SpringEvalExpressions#CONTROLLER_ROLE}.
*/
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
+ "')";
/** /**
* Spring security eval hasAuthority expression to check if spring * Spring security eval hasAuthority expression to check if spring
* context contains {@link #IS_CONTROLLER} or * context contains {@link #IS_CONTROLLER} or

View File

@@ -20,53 +20,48 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public final class SpRole { public final class SpRole {
public static final String TARGET_ADMIN = "ROLE_TARGET_ADMIN";
public static final String REPOSITORY_ADMIN = "ROLE_REPOSITORY_ADMIN";
public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN";
public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN";
private static final String IMPLIES = " > "; private static final String IMPLIES = " > ";
private static final String LINE_BREAK = "\n"; private static final String LINE_BREAK = "\n";
public static final String TARGET_ADMIN = "ROLE_TARGET_ADMIN";
public static final String TARGET_ADMIN_HIERARCHY = public static final String TARGET_ADMIN_HIERARCHY =
TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET + LINE_BREAK +
TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_SEC_TOKEN + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_SEC_TOKEN + LINE_BREAK +
TARGET_ADMIN + IMPLIES + SpPermission.UPDATE_TARGET + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.UPDATE_TARGET + LINE_BREAK +
TARGET_ADMIN + IMPLIES + SpPermission.CREATE_TARGET + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.CREATE_TARGET + LINE_BREAK +
TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET + LINE_BREAK; TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET + LINE_BREAK;
public static final String REPOSITORY_ADMIN = "ROLE_REPOSITORY_ADMIN";
public static final String REPOSITORY_ADMIN_HIERARCHY = public static final String REPOSITORY_ADMIN_HIERARCHY =
REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_REPOSITORY + LINE_BREAK + REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_REPOSITORY + LINE_BREAK +
REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_REPOSITORY + LINE_BREAK + REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_REPOSITORY + LINE_BREAK +
REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_REPOSITORY + LINE_BREAK + REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_REPOSITORY + LINE_BREAK +
REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_REPOSITORY + LINE_BREAK + REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_REPOSITORY + LINE_BREAK +
REPOSITORY_ADMIN + IMPLIES + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + LINE_BREAK; REPOSITORY_ADMIN + IMPLIES + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + LINE_BREAK;
public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN";
public static final String ROLLOUT_ADMIN_HIERARCHY = public static final String ROLLOUT_ADMIN_HIERARCHY =
ROLLOUT_ADMIN + IMPLIES + SpPermission.READ_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.READ_ROLLOUT + LINE_BREAK +
ROLLOUT_ADMIN + IMPLIES + SpPermission.CREATE_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.CREATE_ROLLOUT + LINE_BREAK +
ROLLOUT_ADMIN + IMPLIES + SpPermission.UPDATE_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.UPDATE_ROLLOUT + LINE_BREAK +
ROLLOUT_ADMIN + IMPLIES + SpPermission.DELETE_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.DELETE_ROLLOUT + LINE_BREAK +
ROLLOUT_ADMIN + IMPLIES + SpPermission.HANDLE_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.HANDLE_ROLLOUT + LINE_BREAK +
ROLLOUT_ADMIN + IMPLIES + SpPermission.APPROVE_ROLLOUT + LINE_BREAK; ROLLOUT_ADMIN + IMPLIES + SpPermission.APPROVE_ROLLOUT + LINE_BREAK;
public static final String TENANT_CONFIGURATION_HIERARCHY = public static final String TENANT_CONFIGURATION_HIERARCHY =
SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_TENANT_CONFIGURATION + LINE_BREAK + SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_TENANT_CONFIGURATION + LINE_BREAK +
SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_GATEWAY_SEC_TOKEN + LINE_BREAK; SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_GATEWAY_SEC_TOKEN + LINE_BREAK;
public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN";
public static final String TENANT_ADMIN_HIERARCHY = public static final String TENANT_ADMIN_HIERARCHY =
TENANT_ADMIN + IMPLIES + TARGET_ADMIN + LINE_BREAK + TENANT_ADMIN + IMPLIES + TARGET_ADMIN + LINE_BREAK +
TENANT_ADMIN + IMPLIES + REPOSITORY_ADMIN + LINE_BREAK + TENANT_ADMIN + IMPLIES + REPOSITORY_ADMIN + LINE_BREAK +
TENANT_ADMIN + IMPLIES + ROLLOUT_ADMIN + LINE_BREAK + TENANT_ADMIN + IMPLIES + ROLLOUT_ADMIN + LINE_BREAK +
TENANT_ADMIN + IMPLIES + SpPermission.TENANT_CONFIGURATION + LINE_BREAK; TENANT_ADMIN + IMPLIES + SpPermission.TENANT_CONFIGURATION + LINE_BREAK;
public static final String SYSTEM_ADMIN_HIERARCHY = public static final String SYSTEM_ADMIN_HIERARCHY =
SpPermission.SYSTEM_ADMIN + IMPLIES + TENANT_ADMIN + LINE_BREAK; SpPermission.SYSTEM_ADMIN + IMPLIES + TENANT_ADMIN + LINE_BREAK;
public static String DEFAULT_ROLE_HIERARCHY = public static String DEFAULT_ROLE_HIERARCHY =
TARGET_ADMIN_HIERARCHY + TARGET_ADMIN_HIERARCHY +
REPOSITORY_ADMIN_HIERARCHY + REPOSITORY_ADMIN_HIERARCHY +
ROLLOUT_ADMIN_HIERARCHY + ROLLOUT_ADMIN_HIERARCHY +
TENANT_CONFIGURATION_HIERARCHY + TENANT_CONFIGURATION_HIERARCHY +
TENANT_ADMIN_HIERARCHY + TENANT_ADMIN_HIERARCHY +
SYSTEM_ADMIN_HIERARCHY; SYSTEM_ADMIN_HIERARCHY;
} }

View File

@@ -9,6 +9,14 @@
*/ */
package org.eclipse.hawkbit.im.authentication; package org.eclipse.hawkbit.im.authentication;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
@@ -21,14 +29,6 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
/** /**
* Authentication provider for configured via spring application properties users. * Authentication provider for configured via spring application properties users.
* The users could be tenant scoped or global. * The users could be tenant scoped or global.
@@ -128,7 +128,7 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider {
private static User clone(final User user) { private static User clone(final User user) {
if (user instanceof TenantAwareUser) { if (user instanceof TenantAwareUser) {
return new TenantAwareUser(user.getUsername(), user.getPassword(), user.getAuthorities(), return new TenantAwareUser(user.getUsername(), user.getPassword(), user.getAuthorities(),
((TenantAwareUser)user).getTenant()); ((TenantAwareUser) user).getTenant());
} else { } else {
return new User(user.getUsername(), user.getPassword(), user.getAuthorities()); return new User(user.getUsername(), user.getPassword(), user.getAuthorities());
} }

View File

@@ -31,12 +31,10 @@ public class TenantAwareAuthenticationDetails implements Serializable {
private final boolean controller; private final boolean controller;
/** /**
* @param tenant * @param tenant the current tenant
* the current tenant * @param controller boolean flag to indicate if this authenticated token is a
* @param controller * controller authentication. {@code true} in case of
* boolean flag to indicate if this authenticated token is a * authenticated controller otherwise {@code false}
* controller authentication. {@code true} in case of
* authenticated controller otherwise {@code false}
*/ */
public TenantAwareAuthenticationDetails(final String tenant, final boolean controller) { public TenantAwareAuthenticationDetails(final String tenant, final boolean controller) {
this.tenant = tenant; this.tenant = tenant;

View File

@@ -56,6 +56,11 @@ public class TenantAwareUser extends User {
this(username, "***", null, tenant); this(username, "***", null, tenant);
} }
@Override
public boolean isEnabled() {
return true;
}
@Override @Override
public boolean isAccountNonExpired() { public boolean isAccountNonExpired() {
return true; return true;
@@ -70,9 +75,4 @@ public class TenantAwareUser extends User {
public boolean isCredentialsNonExpired() { public boolean isCredentialsNonExpired() {
return true; return true;
} }
@Override
public boolean isEnabled() {
return true;
}
} }

View File

@@ -17,26 +17,21 @@ import org.springframework.security.core.GrantedAuthority;
/** /**
* The authentication token which transports the username, password and the * The authentication token which transports the username, password and the
* tenant information for authentication. * tenant information for authentication.
*
*/ */
public class TenantUserPasswordAuthenticationToken extends UsernamePasswordAuthenticationToken { public class TenantUserPasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {
private static final long serialVersionUID = 1L;
// Exception squid:S1948 - no need to be Serializable // Exception squid:S1948 - no need to be Serializable
@SuppressWarnings({ "squid:S1948" }) @SuppressWarnings({ "squid:S1948" })
final Object tenant; final Object tenant;
private static final long serialVersionUID = 1L;
/** /**
*
* Creating a new {@link TenantUserPasswordAuthenticationToken} as * Creating a new {@link TenantUserPasswordAuthenticationToken} as
* {@link #isAuthenticated()} will return {@code false}. * {@link #isAuthenticated()} will return {@code false}.
* *
* @param tenant * @param tenant the tenant to authenticate against
* the tenant to authenticate against * @param principal the principal to authenticate
* @param principal * @param credentials the credentials of the principal
* the principal to authenticate
* @param credentials
* the credentials of the principal
*/ */
public TenantUserPasswordAuthenticationToken(final Object tenant, final Object principal, public TenantUserPasswordAuthenticationToken(final Object tenant, final Object principal,
final Object credentials) { final Object credentials) {
@@ -48,14 +43,10 @@ public class TenantUserPasswordAuthenticationToken extends UsernamePasswordAuthe
* Creating a new {@link TenantUserPasswordAuthenticationToken} as * Creating a new {@link TenantUserPasswordAuthenticationToken} as
* {@link #isAuthenticated()} will return {@code true}. * {@link #isAuthenticated()} will return {@code true}.
* *
* @param tenant * @param tenant the tenant to authenticate against
* the tenant to authenticate against * @param principal the principal to authenticate
* @param principal * @param credentials the credentials of the principal
* the principal to authenticate * @param authorities the principal's authorities
* @param credentials
* the credentials of the principal
* @param authorities
* the principal's authorities
*/ */
public TenantUserPasswordAuthenticationToken(final Object tenant, final Object principal, final Object credentials, public TenantUserPasswordAuthenticationToken(final Object tenant, final Object principal, final Object credentials,
final List<GrantedAuthority> authorities) { final List<GrantedAuthority> authorities) {
@@ -70,14 +61,6 @@ public class TenantUserPasswordAuthenticationToken extends UsernamePasswordAuthe
return tenant; return tenant;
} }
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
return result;
}
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) { if (this == obj) {
@@ -100,4 +83,12 @@ public class TenantUserPasswordAuthenticationToken extends UsernamePasswordAuthe
return true; return true;
} }
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
return result;
}
} }

View File

@@ -15,7 +15,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
@@ -74,10 +73,10 @@ public class DdiSecurityProperties {
/** /**
* Target token authentication. Tokens are defined per target. * Target token authentication. Tokens are defined per target.
*
*/ */
@Data @Data
public static class Targettoken { public static class Targettoken {
/** /**
* Set to true to enable target token authentication. * Set to true to enable target token authentication.
*/ */

View File

@@ -104,6 +104,8 @@ public class HawkbitSecurityProperties {
@Data @Data
public static class Dos { public static class Dos {
private final Filter filter = new Filter();
private final Filter uiFilter = new Filter();
/** /**
* 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).
@@ -176,9 +178,6 @@ public class HawkbitSecurityProperties {
*/ */
private int maxDistributionSetTypesPerTargetType = 50; private int maxDistributionSetTypesPerTargetType = 50;
private final Filter filter = new Filter();
private final Filter uiFilter = new Filter();
/** /**
* Configuration for hawkBits DOS prevention filter. This is usually an * Configuration for hawkBits DOS prevention filter. This is usually an
* infrastructure topic (e.g. Web Application Firewall (WAF)) but might * infrastructure topic (e.g. Web Application Firewall (WAF)) but might

View File

@@ -26,7 +26,7 @@ public class InMemoryUserAuthoritiesResolver implements UserAuthoritiesResolver
/** /**
* Constructs the resolver based on the given authority lookup map. * Constructs the resolver based on the given authority lookup map.
* *
* @param usernamesToAuthorities The authority map to read from. Must not be <code>null</code>. * @param usernamesToAuthorities The authority map to read from. Must not be <code>null</code>.
*/ */
public InMemoryUserAuthoritiesResolver(final Map<String, List<String>> usernamesToAuthorities) { public InMemoryUserAuthoritiesResolver(final Map<String, List<String>> usernamesToAuthorities) {

View File

@@ -9,10 +9,15 @@
*/ */
package org.eclipse.hawkbit.security; package org.eclipse.hawkbit.security;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.Callable;
import jakarta.servlet.FilterChain; import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
@@ -25,10 +30,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.intercept.AuthorizationFilter; import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.Callable;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MdcHandler { public class MdcHandler {

View File

@@ -9,8 +9,6 @@
*/ */
package org.eclipse.hawkbit.security; package org.eclipse.hawkbit.security;
import org.springframework.security.core.context.SecurityContext;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@@ -19,6 +17,8 @@ import java.io.ObjectOutputStream;
import java.util.Base64; import java.util.Base64;
import java.util.Objects; import java.util.Objects;
import org.springframework.security.core.context.SecurityContext;
public interface SecurityContextSerializer { public interface SecurityContextSerializer {
/** /**
@@ -57,7 +57,8 @@ public interface SecurityContextSerializer {
*/ */
class Nop implements SecurityContextSerializer { class Nop implements SecurityContextSerializer {
private Nop() {} private Nop() {
}
@Override @Override
public String serialize(final SecurityContext securityContext) { public String serialize(final SecurityContext securityContext) {
@@ -75,13 +76,14 @@ public interface SecurityContextSerializer {
*/ */
class JavaSerialization implements SecurityContextSerializer { class JavaSerialization implements SecurityContextSerializer {
private JavaSerialization() {} private JavaSerialization() {
}
@Override @Override
public String serialize(final SecurityContext securityContext) { public String serialize(final SecurityContext securityContext) {
Objects.requireNonNull(securityContext); Objects.requireNonNull(securityContext);
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos)) { final ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(securityContext); oos.writeObject(securityContext);
oos.flush(); oos.flush();
return Base64.getEncoder().encodeToString(baos.toByteArray()); return Base64.getEncoder().encodeToString(baos.toByteArray());
@@ -94,7 +96,7 @@ public interface SecurityContextSerializer {
public SecurityContext deserialize(String securityContextString) { public SecurityContext deserialize(String securityContextString) {
Objects.requireNonNull(securityContextString); Objects.requireNonNull(securityContextString);
try (final ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(securityContextString)); try (final ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(securityContextString));
final ObjectInputStream ois = new ObjectInputStream(bais)) { final ObjectInputStream ois = new ObjectInputStream(bais)) {
return (SecurityContext) ois.readObject(); return (SecurityContext) ois.readObject();
} catch (final IOException | ClassNotFoundException e) { } catch (final IOException | ClassNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);

View File

@@ -54,9 +54,8 @@ public class SecurityContextTenantAware implements ContextAware {
* Creates the {@link SecurityContextTenantAware} based on the given * Creates the {@link SecurityContextTenantAware} based on the given
* {@link UserAuthoritiesResolver}. * {@link UserAuthoritiesResolver}.
* *
* @param authoritiesResolver * @param authoritiesResolver Resolver to retrieve the authorities for a given user. Must
* Resolver to retrieve the authorities for a given user. Must * not be <code>null</code>..
* not be <code>null</code>..
*/ */
public SecurityContextTenantAware(final UserAuthoritiesResolver authoritiesResolver) { public SecurityContextTenantAware(final UserAuthoritiesResolver authoritiesResolver) {
this.authoritiesResolver = authoritiesResolver; this.authoritiesResolver = authoritiesResolver;
@@ -66,11 +65,12 @@ public class SecurityContextTenantAware implements ContextAware {
/** /**
* Creates the {@link SecurityContextTenantAware} based on the given * Creates the {@link SecurityContextTenantAware} based on the given
* {@link UserAuthoritiesResolver}. * {@link UserAuthoritiesResolver}.
* *
* @param authoritiesResolver Resolver to retrieve the authorities for a given user. Must not be <code>null</code>. * @param authoritiesResolver Resolver to retrieve the authorities for a given user. Must not be <code>null</code>.
* @param securityContextSerializer Serializer that is used to serialize / deserialize {@link SecurityContext}s. * @param securityContextSerializer Serializer that is used to serialize / deserialize {@link SecurityContext}s.
*/ */
public SecurityContextTenantAware(final UserAuthoritiesResolver authoritiesResolver, @Nullable final SecurityContextSerializer securityContextSerializer) { public SecurityContextTenantAware(final UserAuthoritiesResolver authoritiesResolver,
@Nullable final SecurityContextSerializer securityContextSerializer) {
this.authoritiesResolver = authoritiesResolver; this.authoritiesResolver = authoritiesResolver;
this.securityContextSerializer = securityContextSerializer == null ? SecurityContextSerializer.NOP : securityContextSerializer; this.securityContextSerializer = securityContextSerializer == null ? SecurityContextSerializer.NOP : securityContextSerializer;
} }
@@ -104,11 +104,6 @@ public class SecurityContextTenantAware implements ContextAware {
return null; return null;
} }
@Override
public Optional<String> getCurrentContext() {
return Optional.ofNullable(SecurityContextHolder.getContext()).map(securityContextSerializer::serialize);
}
@Override @Override
public <T> T runAsTenant(final String tenant, final TenantRunner<T> tenantRunner) { public <T> T runAsTenant(final String tenant, final TenantRunner<T> tenantRunner) {
return runInContext(buildUserSecurityContext(tenant, SYSTEM_USER, SYSTEM_AUTHORITIES), tenantRunner::run); return runInContext(buildUserSecurityContext(tenant, SYSTEM_USER, SYSTEM_AUTHORITIES), tenantRunner::run);
@@ -125,6 +120,11 @@ public class SecurityContextTenantAware implements ContextAware {
return runInContext(buildUserSecurityContext(tenant, username, authorities), tenantRunner::run); return runInContext(buildUserSecurityContext(tenant, username, authorities), tenantRunner::run);
} }
@Override
public Optional<String> getCurrentContext() {
return Optional.ofNullable(SecurityContextHolder.getContext()).map(securityContextSerializer::serialize);
}
@Override @Override
public <T, R> R runInContext(final String serializedContext, final Function<T, R> function, final T t) { public <T, R> R runInContext(final String serializedContext, final Function<T, R> function, final T t) {
Objects.requireNonNull(serializedContext); Objects.requireNonNull(serializedContext);
@@ -153,7 +153,7 @@ public class SecurityContextTenantAware implements ContextAware {
final SecurityContext currentContext = SecurityContextHolder.getContext(); final SecurityContext currentContext = SecurityContextHolder.getContext();
SystemSecurityContext.setSystemContext(currentContext); SystemSecurityContext.setSystemContext(currentContext);
try { try {
return MdcHandler.getInstance().callWithAuthRE(tenantRunner::run); return MdcHandler.getInstance().callWithAuthRE(tenantRunner::run);
} finally { } finally {
SecurityContextHolder.setContext(currentContext); SecurityContextHolder.setContext(currentContext);
} }
@@ -188,6 +188,11 @@ public class SecurityContextTenantAware implements ContextAware {
tenantAwareAuthenticationDetails = new TenantAwareAuthenticationDetails(tenant, false); tenantAwareAuthenticationDetails = new TenantAwareAuthenticationDetails(tenant, false);
} }
@Override
public int hashCode() {
return delegate != null ? delegate.hashCode() : -1;
}
@Override @Override
public boolean equals(final Object another) { public boolean equals(final Object another) {
if (another instanceof Authentication anotherAuthentication) { if (another instanceof Authentication anotherAuthentication) {
@@ -204,11 +209,6 @@ public class SecurityContextTenantAware implements ContextAware {
return delegate != null ? delegate.toString() : null; return delegate != null ? delegate.toString() : null;
} }
@Override
public int hashCode() {
return delegate != null ? delegate.hashCode() : -1;
}
@Override @Override
public String getName() { public String getName() {
return delegate != null ? delegate.getName() : null; return delegate != null ? delegate.getName() : null;

View File

@@ -26,7 +26,7 @@ public class SecurityTokenGenerator {
/** /**
* Generates a random secure token of {@link #TOKEN_LENGTH} bytes length as * Generates a random secure token of {@link #TOKEN_LENGTH} bytes length as
* hexadecimal string. * hexadecimal string.
* *
* @return a new generated random alphanumeric string. * @return a new generated random alphanumeric string.
*/ */
public String generateToken() { public String generateToken() {

View File

@@ -29,6 +29,19 @@ public class SpringSecurityAuditorAware implements AuditorAware<String> {
// So this thread local variable provides option to override explicitly the auditor. // So this thread local variable provides option to override explicitly the auditor.
private static final ThreadLocal<String> AUDITOR_OVERRIDE = new ThreadLocal<>(); private static final ThreadLocal<String> AUDITOR_OVERRIDE = new ThreadLocal<>();
// Always shall be followed by {@link #clearAuditorOverride}
public static void setAuditorOverride(final String auditor) {
if (auditor == null) {
AUDITOR_OVERRIDE.remove();
} else {
AUDITOR_OVERRIDE.set(auditor);
}
}
public static void clearAuditorOverride() {
AUDITOR_OVERRIDE.remove();
}
@Override @Override
public Optional<String> getCurrentAuditor() { public Optional<String> getCurrentAuditor() {
if (AUDITOR_OVERRIDE.get() != null) { if (AUDITOR_OVERRIDE.get() != null) {
@@ -44,19 +57,6 @@ public class SpringSecurityAuditorAware implements AuditorAware<String> {
return Optional.ofNullable(getCurrentAuditor(authentication)); return Optional.ofNullable(getCurrentAuditor(authentication));
} }
// Always shall be followed by {@link #clearAuditorOverride}
public static void setAuditorOverride(final String auditor) {
if (auditor == null) {
AUDITOR_OVERRIDE.remove();
} else {
AUDITOR_OVERRIDE.set(auditor);
}
}
public static void clearAuditorOverride() {
AUDITOR_OVERRIDE.remove();
}
protected String getCurrentAuditor(final Authentication authentication) { protected String getCurrentAuditor(final Authentication authentication) {
if (authentication.getPrincipal() instanceof UserDetails) { if (authentication.getPrincipal() instanceof UserDetails) {
return ((UserDetails) authentication.getPrincipal()).getUsername(); return ((UserDetails) authentication.getPrincipal()).getUsername();

View File

@@ -19,8 +19,8 @@ import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AnonymousAuthenticationToken;
@@ -43,7 +43,7 @@ public class SystemSecurityContext {
/** /**
* Autowired constructor. * Autowired constructor.
* *
* @param tenantAware the tenant aware bean to retrieve the current tenant * @param tenantAware the tenant aware bean to retrieve the current tenant
*/ */
public SystemSecurityContext(final TenantAware tenantAware) { public SystemSecurityContext(final TenantAware tenantAware) {
@@ -68,13 +68,13 @@ public class SystemSecurityContext {
* context e.g. if the current security context does not contain the * context e.g. if the current security context does not contain the
* necessary permission it's necessary to execute code as system code to * necessary permission it's necessary to execute code as system code to
* execute necessary methods and functionality. * execute necessary methods and functionality.
* *
* The security context will be switched to the system code and back after * The security context will be switched to the system code and back after
* the callable is called. * the callable is called.
* *
* The system code is executed for a current tenant by using the * The system code is executed for a current tenant by using the
* {@link TenantAware#getCurrentTenant()}. * {@link TenantAware#getCurrentTenant()}.
* *
* @param callable the callable to call within the system security context * @param callable the callable to call within the system security context
* @return the return value of the {@link Callable#call()} method. * @return the return value of the {@link Callable#call()} method.
*/ */
@@ -91,13 +91,13 @@ public class SystemSecurityContext {
* context e.g. if the current security context does not contain the * context e.g. if the current security context does not contain the
* necessary permission it's necessary to execute code as system code to * necessary permission it's necessary to execute code as system code to
* execute necessary methods and functionality. * execute necessary methods and functionality.
* *
* The security context will be switched to the system code and back after * The security context will be switched to the system code and back after
* the callable is called. * the callable is called.
* *
* The system code is executed for a specific given tenant by using the * The system code is executed for a specific given tenant by using the
* {@link TenantAware}. * {@link TenantAware}.
* *
* @param callable the callable to call within the system security context * @param callable the callable to call within the system security context
* @param tenant the tenant to act as system code * @param tenant the tenant to act as system code
* @return the return value of the {@link Callable#call()} method. * @return the return value of the {@link Callable#call()} method.
@@ -122,10 +122,10 @@ public class SystemSecurityContext {
* Runs a given {@link Callable} within a system security context, which has * Runs a given {@link Callable} within a system security context, which has
* the provided {@link GrantedAuthority}s to successfully run the * the provided {@link GrantedAuthority}s to successfully run the
* {@link Callable}. * {@link Callable}.
* *
* The security context will be switched to the a new * The security context will be switched to the a new
* {@link SecurityContext} and back after the callable is called. * {@link SecurityContext} and back after the callable is called.
* *
* @param tenant under which the {@link Callable#call()} must be executed. * @param tenant under which the {@link Callable#call()} must be executed.
* @param callable to call within the security context * @param callable to call within the security context
* @return the return value of the {@link Callable#call()} method. * @return the return value of the {@link Callable#call()} method.

View File

@@ -39,18 +39,17 @@ public final class IpUtil {
.compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})(:[0-9]{1,5})?"); .compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})(:[0-9]{1,5})?");
private static final Pattern IPV6_ADDRESS_PATTERN = Pattern.compile("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}"); private static final Pattern IPV6_ADDRESS_PATTERN = Pattern.compile("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}");
// v6 address with [] amd (optionally) port // v6 address with [] amd (optionally) port
private static final Pattern IPV6_ADDRESS_WITH_PORT_PATTERN = Pattern.compile("\\[(?<address>([0-9a-f]{1,4}:){7}([0-9a-f]){1,4})](:[0-9]{1,5})?"); private static final Pattern IPV6_ADDRESS_WITH_PORT_PATTERN = Pattern.compile(
"\\[(?<address>([0-9a-f]{1,4}:){7}([0-9a-f]){1,4})](:[0-9]{1,5})?");
/** /**
* Retrieves the string based IP address from a given * Retrieves the string based IP address from a given
* {@link HttpServletRequest} by either the configured {@link HawkbitSecurityProperties.Clients#getRemoteIpHeader()} * {@link HttpServletRequest} by either the configured {@link HawkbitSecurityProperties.Clients#getRemoteIpHeader()}
* (by default X-Forwarded-For) or by the {@link HttpServletRequest#getRemoteAddr()} method. * (by default X-Forwarded-For) or by the {@link HttpServletRequest#getRemoteAddr()} method.
* *
* @param request * @param request the {@link HttpServletRequest} to determine the IP address
* the {@link HttpServletRequest} to determine the IP address * where this request has been sent from
* where this request has been sent from * @param securityProperties hawkBit security properties.
* @param securityProperties
* hawkBit security properties.
* @return the {@link URI} based IP address from the client which sent the * @return the {@link URI} based IP address from the client which sent the
* request * request
*/ */
@@ -65,12 +64,10 @@ public final class IpUtil {
* Retrieves the string based IP address from a given {@link HttpServletRequest} by either the * Retrieves the string based IP address from a given {@link HttpServletRequest} by either the
* forward header or by the {@link HttpServletRequest#getRemoteAddr()} method. * forward header or by the {@link HttpServletRequest#getRemoteAddr()} method.
* *
* @param request * @param request the {@link HttpServletRequest} to determine the IP address
* the {@link HttpServletRequest} to determine the IP address * where this request has been sent from
* where this request has been sent from * @param forwardHeader the header name containing the IP address e.g. forwarded by a
* @param forwardHeader * proxy {@code x-forwarded-for}
* the header name containing the IP address e.g. forwarded by a
* proxy {@code x-forwarded-for}
* @return the {@link URI} based IP address from the client which sent the * @return the {@link URI} based IP address from the client which sent the
* request * request
*/ */
@@ -78,6 +75,76 @@ public final class IpUtil {
return getClientIpFromRequest(request, forwardHeader, true); return getClientIpFromRequest(request, forwardHeader, true);
} }
/**
* Create a {@link URI} with scheme and host.
*
* @param scheme the scheme
* @param host the host
* @return the {@link URI}
* @throws IllegalArgumentException If the given string not parsable
*/
public static URI createUri(final String scheme, final String host) {
final boolean isIpV6 = host.indexOf(':') >= 0 && host.indexOf('.') == -1 && host.charAt(0) != '[';
if (isIpV6) {
return URI.create(scheme + SCHEME_SEPARATOR + "[" + host + "]");
}
return URI.create(scheme + SCHEME_SEPARATOR + host);
}
/**
* Create a {@link URI} with amqp scheme and host.
*
* @param host the host
* @param exchange the exchange will store in the path
* @return the {@link URI}
* @throws IllegalArgumentException If the given string not parse able
*/
public static URI createAmqpUri(final String host, final String exchange) {
return createUri(AMQP_SCHEME, host).resolve("/" + exchange);
}
/**
* Create a {@link URI} with http scheme and host.
*
* @param host the host
* @return the {@link URI}
* @throws IllegalArgumentException If the given string not parsable
*/
public static URI createHttpUri(final String host) {
return createUri(HTTP_SCHEME, host);
}
/**
* Check if scheme contains http and uri ist not <code>null</code>.
*
* @param uri the uri
* @return true = is http host false = not
*/
public static boolean isHttpUri(final URI uri) {
return uri != null && HTTP_SCHEME.equals(uri.getScheme());
}
/**
* Check if host scheme amqp and uri ist not <code>null</code>.
*
* @param uri the uri
* @return true = is http host false = not
*/
public static boolean isAmqpUri(final URI uri) {
return uri != null && AMQP_SCHEME.equals(uri.getScheme());
}
/**
* Check if the IP address of that {@link URI} is known, i.e. not an AQMP
* exchange in DMF case and not HIDDEN_IP in DDI case.
*
* @param uri the uri
* @return <code>true</code> if IP address is actually known by the server
*/
public static boolean isIpAddresKnown(final URI uri) {
return uri != null && !(AMQP_SCHEME.equals(uri.getScheme()) || HIDDEN_IP.equals(uri.getHost()));
}
private static URI getClientIpFromRequest(final HttpServletRequest request, final String forwardHeader, private static URI getClientIpFromRequest(final HttpServletRequest request, final String forwardHeader,
final boolean trackRemoteIp) { final boolean trackRemoteIp) {
String ip; String ip;
@@ -113,85 +180,4 @@ public final class IpUtil {
return null; return null;
} }
/**
* Create a {@link URI} with scheme and host.
*
* @param scheme
* the scheme
* @param host
* the host
* @return the {@link URI}
* @throws IllegalArgumentException
* If the given string not parsable
*/
public static URI createUri(final String scheme, final String host) {
final boolean isIpV6 = host.indexOf(':') >= 0 && host.indexOf('.') == -1 && host.charAt(0) != '[';
if (isIpV6) {
return URI.create(scheme + SCHEME_SEPARATOR + "[" + host + "]");
}
return URI.create(scheme + SCHEME_SEPARATOR + host);
}
/**
* Create a {@link URI} with amqp scheme and host.
*
* @param host
* the host
* @param exchange
* the exchange will store in the path
* @return the {@link URI}
* @throws IllegalArgumentException
* If the given string not parse able
*/
public static URI createAmqpUri(final String host, final String exchange) {
return createUri(AMQP_SCHEME, host).resolve("/" + exchange);
}
/**
* Create a {@link URI} with http scheme and host.
*
* @param host
* the host
* @return the {@link URI}
* @throws IllegalArgumentException
* If the given string not parsable
*/
public static URI createHttpUri(final String host) {
return createUri(HTTP_SCHEME, host);
}
/**
* Check if scheme contains http and uri ist not <code>null</code>.
*
* @param uri
* the uri
* @return true = is http host false = not
*/
public static boolean isHttpUri(final URI uri) {
return uri != null && HTTP_SCHEME.equals(uri.getScheme());
}
/**
* Check if host scheme amqp and uri ist not <code>null</code>.
*
* @param uri
* the uri
* @return true = is http host false = not
*/
public static boolean isAmqpUri(final URI uri) {
return uri != null && AMQP_SCHEME.equals(uri.getScheme());
}
/**
* Check if the IP address of that {@link URI} is known, i.e. not an AQMP
* exchange in DMF case and not HIDDEN_IP in DDI case.
*
* @param uri
* the uri
* @return <code>true</code> if IP address is actually known by the server
*/
public static boolean isIpAddresKnown(final URI uri) {
return uri != null && !(AMQP_SCHEME.equals(uri.getScheme()) || HIDDEN_IP.equals(uri.getHost()));
}
} }

View File

@@ -9,16 +9,16 @@
*/ */
package org.eclipse.hawkbit.util; package org.eclipse.hawkbit.util;
import java.nio.charset.StandardCharsets;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.springframework.web.util.UriUtils; import org.springframework.web.util.UriUtils;
import java.nio.charset.StandardCharsets;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UrlUtils { public class UrlUtils {
public static String decodeUriValue(String value) { public static String decodeUriValue(String value) {
return UriUtils.decode(value, StandardCharsets.UTF_8); return UriUtils.decode(value, StandardCharsets.UTF_8);
} }
} }

View File

@@ -16,13 +16,12 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.ReflectionUtils;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Story; import io.qameta.allure.Story;
import org.junit.jupiter.api.Test;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.ReflectionUtils;
/** /**
* Test {@link SpPermission}. * Test {@link SpPermission}.
@@ -31,17 +30,17 @@ import io.qameta.allure.Story;
@Story("Permission Test") @Story("Permission Test")
public final class SpPermissionTest { public final class SpPermissionTest {
@Test @Test
@Description("Verify the get permission function") @Description("Verify the get permission function")
public void testGetPermissions() { public void testGetPermissions() {
final int allPermission = 20; final int allPermission = 20;
final Collection<String> allAuthorities = SpPermission.getAllAuthorities(); final Collection<String> allAuthorities = SpPermission.getAllAuthorities();
final List<GrantedAuthority> allAuthoritiesList = PermissionUtils.createAllAuthorityList(); final List<GrantedAuthority> allAuthoritiesList = PermissionUtils.createAllAuthorityList();
assertThat(allAuthorities).hasSize(allPermission); assertThat(allAuthorities).hasSize(allPermission);
assertThat(allAuthoritiesList).hasSize(allPermission); assertThat(allAuthoritiesList).hasSize(allPermission);
assertThat(allAuthoritiesList.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList())) assertThat(allAuthoritiesList.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
.containsAll(allAuthorities); .containsAll(allAuthorities);
} }
@Test @Test
@Description("Try to double check if all permissions works as expected") @Description("Try to double check if all permissions works as expected")

View File

@@ -19,12 +19,11 @@ import java.net.URI;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties.Clients;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Story; import io.qameta.allure.Story;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties.Clients;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@@ -116,21 +115,6 @@ public class IpUtilTest {
checkHostInfoResolution("[0:0:0:0:0:0:0:1]:4233", "[0:0:0:0:0:0:0:1]", false); checkHostInfoResolution("[0:0:0:0:0:0:0:1]:4233", "[0:0:0:0:0:0:0:1]", false);
} }
private void checkHostInfoResolution(final String hostInfo, final String expectedHost, final boolean remoteAddress) {
reset(requestMock);
when(remoteAddress ? requestMock.getRemoteAddr() : requestMock.getHeader(KNOWN_REQUEST_HEADER)).thenReturn(hostInfo);
final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, KNOWN_REQUEST_HEADER);
// verify
assertThat(remoteAddr.getHost()).as("The remote address should be as the known client IP address")
.isEqualTo(expectedHost);
verify(requestMock, times(1)).getHeader(KNOWN_REQUEST_HEADER);
if (remoteAddress) {
verify(requestMock, times(1)).getRemoteAddr();
}
}
@Test @Test
@Description("Tests create http uri ipv4 and ipv6") @Description("Tests create http uri ipv4 and ipv6")
public void testCreateHttpUri() { public void testCreateHttpUri() {
@@ -147,13 +131,6 @@ public class IpUtilTest {
assertHttpUri("[" + ipv6 + "]", httpUri); assertHttpUri("[" + ipv6 + "]", httpUri);
} }
private void assertHttpUri(final String host, final URI httpUri) {
assertThat(IpUtil.isHttpUri(httpUri)).as("The given URI has an http scheme").isTrue();
assertThat(IpUtil.isAmqpUri(httpUri)).as("The given URI is not an AMQP scheme").isFalse();
assertThat(host).as("The URI hosts matches the given host").isEqualTo(httpUri.getHost());
assertThat(httpUri.getScheme()).as("The given URI scheme is http").isEqualTo("http");
}
@Test @Test
@Description("Tests create amqp uri ipv4 and ipv6") @Description("Tests create amqp uri ipv4 and ipv6")
public void testCreateAmqpUri() { public void testCreateAmqpUri() {
@@ -181,15 +158,6 @@ public class IpUtilTest {
assertAmqpUri(ipv6Braces, amqpUri); assertAmqpUri(ipv6Braces, amqpUri);
} }
private void assertAmqpUri(final String host, final URI amqpUri) {
assertThat(IpUtil.isAmqpUri(amqpUri)).as("The given URI is an AMQP scheme").isTrue();
assertThat(IpUtil.isHttpUri(amqpUri)).as("The given URI is not an HTTP scheme").isFalse();
assertThat(amqpUri.getHost()).as("The given host matches the URI host").isEqualTo(host);
assertThat(amqpUri.getScheme()).as("The given URI has an AMQP scheme").isEqualTo("amqp");
assertThat(amqpUri.getRawPath()).as("The given URI has an AMQP path").isEqualTo("/path");
}
@Test @Test
@Description("Tests create invalid uri") @Description("Tests create invalid uri")
public void testCreateInvalidUri() { public void testCreateInvalidUri() {
@@ -208,4 +176,35 @@ public class IpUtilTest {
// expected // expected
} }
} }
private void checkHostInfoResolution(final String hostInfo, final String expectedHost, final boolean remoteAddress) {
reset(requestMock);
when(remoteAddress ? requestMock.getRemoteAddr() : requestMock.getHeader(KNOWN_REQUEST_HEADER)).thenReturn(hostInfo);
final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, KNOWN_REQUEST_HEADER);
// verify
assertThat(remoteAddr.getHost()).as("The remote address should be as the known client IP address")
.isEqualTo(expectedHost);
verify(requestMock, times(1)).getHeader(KNOWN_REQUEST_HEADER);
if (remoteAddress) {
verify(requestMock, times(1)).getRemoteAddr();
}
}
private void assertHttpUri(final String host, final URI httpUri) {
assertThat(IpUtil.isHttpUri(httpUri)).as("The given URI has an http scheme").isTrue();
assertThat(IpUtil.isAmqpUri(httpUri)).as("The given URI is not an AMQP scheme").isFalse();
assertThat(host).as("The URI hosts matches the given host").isEqualTo(httpUri.getHost());
assertThat(httpUri.getScheme()).as("The given URI scheme is http").isEqualTo("http");
}
private void assertAmqpUri(final String host, final URI amqpUri) {
assertThat(IpUtil.isAmqpUri(amqpUri)).as("The given URI is an AMQP scheme").isTrue();
assertThat(IpUtil.isHttpUri(amqpUri)).as("The given URI is not an HTTP scheme").isFalse();
assertThat(amqpUri.getHost()).as("The given host matches the URI host").isEqualTo(host);
assertThat(amqpUri.getScheme()).as("The given URI has an AMQP scheme").isEqualTo("amqp");
assertThat(amqpUri.getRawPath()).as("The given URI has an AMQP path").isEqualTo("/path");
}
} }