Improve WithUser testing (#2943)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2026-02-27 12:59:13 +02:00
committed by GitHub
parent f2318078bd
commit 5d043b2766
19 changed files with 161 additions and 203 deletions

View File

@@ -7,7 +7,6 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.test.matcher;
import static org.assertj.core.api.Assertions.assertThat;

View File

@@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TENANT_CONFIGURATION;
import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE;
import static org.eclipse.hawkbit.auth.SpRole.SYSTEM_ROLE;
import static org.eclipse.hawkbit.auth.SpRole.TENANT_ADMIN;
import java.io.File;
import java.io.IOException;
@@ -37,6 +38,7 @@ import org.awaitility.Awaitility;
import org.awaitility.core.ConditionFactory;
import org.eclipse.hawkbit.artifact.ArtifactStorage;
import org.eclipse.hawkbit.artifact.exception.ArtifactStoreException;
import org.eclipse.hawkbit.auth.SpRole;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ConfirmationManagement;
import org.eclipse.hawkbit.repository.ControllerManagement;
@@ -103,7 +105,7 @@ import org.springframework.test.context.TestPropertySource;
@Slf4j
@ActiveProfiles({ "test" })
@ExtendWith({ TestLoggerExtension.class, SharedSqlTestDatabaseExtension.class })
@WithUser(principal = "bumlux", allSpPermissions = true, authorities = { CONTROLLER_ROLE, SYSTEM_ROLE })
@WithUser(principal = "bumlux", authorities = { TENANT_ADMIN, CONTROLLER_ROLE, SYSTEM_ROLE })
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ContextConfiguration(classes = { TestConfiguration.class })
// destroy the context after each test class because otherwise we get problem when context is

View File

@@ -9,19 +9,20 @@
*/
package org.eclipse.hawkbit.repository.test.util;
import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE;
import static org.eclipse.hawkbit.auth.SpRole.SYSTEM_ROLE;
import static org.eclipse.hawkbit.auth.SpRole.TENANT_ADMIN;
import java.io.Serial;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.auth.SpRole;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.tenancy.TenantAwareUser;
@@ -38,8 +39,8 @@ public class SecurityContextSwitch {
private static final SecurityContextSwitch INSTANCE = new SecurityContextSwitch();
public static final String DEFAULT_TENANT = "DEFAULT";
private static final WithUser PRIVILEGED_USER = createWithUser(
"bumlux", DEFAULT_TENANT, false, true, false, "ROLE_CONTROLLER", "ROLE_SYSTEM_CODE");
private static final WithUser PRIVILEGED_USER = new WithUserImpl(
DEFAULT_TENANT, "bumlux", new String[] {TENANT_ADMIN, CONTROLLER_ROLE, SYSTEM_ROLE}, false, false);
private static SystemManagement systemManagement;
@@ -92,21 +93,21 @@ public class SecurityContextSwitch {
}
public static WithUser withController(final String principal, final String... authorities) {
return withUserAndTenant(principal, DEFAULT_TENANT, true, false, true, authorities);
return withUserAndTenant(DEFAULT_TENANT, principal, authorities, true, true);
}
public static WithUser withUser(final String principal, final String... authorities) {
return withUserAndTenant(principal, DEFAULT_TENANT, true, false, false, authorities);
return withUserAndTenant(DEFAULT_TENANT, principal, authorities, false, true);
}
public static WithUser withUserAndTenantAllSpPermissions(final String principal, final String tenant) {
return withUserAndTenant(principal, tenant, true, true, false);
return withUserAndTenant(tenant, principal, new String[] { SpRole.TENANT_ADMIN }, false, true);
}
public static WithUser withUserAndTenant(final String principal, final String tenant,
final boolean autoCreateTenant, final boolean allSpPermission, final boolean controller,
final String... authorities) {
return createWithUser(principal, tenant, autoCreateTenant, allSpPermission, controller, authorities);
public static WithUser withUserAndTenant(
final String tenant, final String principal, final String[] authorities,
final boolean controller, final boolean autoCreateTenant) {
return new WithUserImpl(tenant, principal, authorities, controller, autoCreateTenant);
}
private static void setSecurityContext(final WithUser annotation) {
@@ -123,12 +124,6 @@ public class SecurityContextSwitch {
}
}
private static WithUser createWithUser(
final String principal, final String tenant, final boolean autoCreateTenant,
final boolean allSpPermission, final boolean controller, final String... authorities) {
return new WithUserImpl(principal, tenant, autoCreateTenant, allSpPermission, controller, authorities);
}
// should be used only for test purposes and taking in account 'annotation' non-transient field in a Serializable
@SuppressWarnings("java:S1948") // java:S1948 - see comments into the method
static class WithUserSecurityContext implements SecurityContext {
@@ -151,15 +146,9 @@ public class SecurityContextSwitch {
@Override
public Authentication getAuthentication() {
final String[] authorities;
if (annotation.allSpPermissions()) {
authorities = getAllAuthorities(annotation.authorities(), annotation.removeFromAllPermission());
} else {
authorities = annotation.authorities();
}
final TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken(
new TenantAwareUser(annotation.principal(), "***", null, annotation.tenantId()),
annotation.credentials(), authorities);
annotation.credentials(), annotation.authorities());
testingAuthenticationToken.setDetails(
new TenantAwareAuthenticationDetails(annotation.tenantId(), annotation.controller()));
return testingAuthenticationToken;
@@ -183,17 +172,6 @@ public class SecurityContextSwitch {
return false;
}
}
private String[] getAllAuthorities(final String[] additionalAuthorities, final String[] notInclude) {
final List<String> permissions = new ArrayList<>(SpPermission.getAllAuthorities()); // list is unmodifiable
if (notInclude != null) {
permissions.removeAll(Arrays.asList(notInclude));
}
if (additionalAuthorities != null) {
permissions.addAll(Arrays.asList(additionalAuthorities));
}
return permissions.toArray(new String[0]);
}
}
private static class WithUserImpl implements WithUser, Serializable {
@@ -201,22 +179,20 @@ public class SecurityContextSwitch {
@Serial
private static final long serialVersionUID = 1L;
private final String principal;
private final String tenant;
private final boolean autoCreateTenant;
private final boolean allSpPermission;
private final boolean controller;
private final String principal;
private final String[] authorities;
private final boolean controller;
private final boolean autoCreateTenant;
private WithUserImpl(
final String principal, final String tenant, final boolean autoCreateTenant,
final boolean allSpPermission, final boolean controller, final String... authorities) {
this.principal = principal;
final String tenant, final String principal, final String[] authorities,
final boolean controller, final boolean autoCreateTenant) {
this.tenant = tenant;
this.autoCreateTenant = autoCreateTenant;
this.allSpPermission = allSpPermission;
this.controller = controller;
this.principal = principal;
this.authorities = authorities;
this.controller = controller;
this.autoCreateTenant = autoCreateTenant;
}
@Override
@@ -224,6 +200,11 @@ public class SecurityContextSwitch {
return WithUser.class;
}
@Override
public String tenantId() {
return tenant;
}
@Override
public String principal() {
return principal;
@@ -234,34 +215,19 @@ public class SecurityContextSwitch {
return null;
}
@Override
public String tenantId() {
return tenant;
}
@Override
public boolean autoCreateTenant() {
return autoCreateTenant;
}
@Override
public String[] authorities() {
return authorities;
}
@Override
public boolean allSpPermissions() {
return allSpPermission;
}
@Override
public String[] removeFromAllPermission() {
return new String[0];
}
@Override
public boolean controller() {
return controller;
}
@Override
public boolean autoCreateTenant() {
return autoCreateTenant;
}
}
}

View File

@@ -28,6 +28,13 @@ import org.springframework.security.test.context.support.WithSecurityContextFact
@Inherited
public @interface WithUser {
/**
* Gets the test tenant id.
*
* @return test tenant id
*/
String tenantId() default "DEFAULT";
/**
* Gets the test principal.
*
@@ -42,20 +49,6 @@ public @interface WithUser {
*/
String credentials() default "TestCredentials";
/**
* Gets the test tenant id.
*
* @return test tenant id
*/
String tenantId() default "DEFAULT";
/**
* Should tenant auto created.
*
* @return <code>true</code> = auto create <code>false</code> not create
*/
boolean autoCreateTenant() default true;
/**
* Gets the test authorities.
*
@@ -64,18 +57,11 @@ public @interface WithUser {
String[] authorities() default {};
/**
* Gets the test all permissions.
* Should tenant auto created.
*
* @return permissions
* @return <code>true</code> = auto create <code>false</code> not create
*/
boolean allSpPermissions() default false;
/**
* Gets the test removeFromAllPermission.
*
* @return removeFromAllPermission
*/
String[] removeFromAllPermission() default {};
boolean autoCreateTenant() default true;
boolean controller() default false;