Improve WithUser testing (#2943)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -385,24 +385,34 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
* Loads an artifact binary based on given ID.
|
||||
*/
|
||||
@Test
|
||||
void loadStreamOfArtifact() throws IOException {
|
||||
void downloadStreamOfArtifact() throws IOException {
|
||||
final int artifactSize = 5 * 1024;
|
||||
final byte[] randomBytes = randomBytes(artifactSize);
|
||||
try (final InputStream input = new ByteArrayInputStream(randomBytes)) {
|
||||
final SoftwareModule smOs = testdataFactory.createSoftwareModuleOs();
|
||||
final Artifact artifact = createArtifactForSoftwareModule("file1", smOs.getId(), artifactSize, input);
|
||||
assertEqualFileContents(
|
||||
artifactManagement.getArtifactStream(artifact.getSha1Hash(), smOs.getId(), smOs.isEncrypted()), randomBytes);
|
||||
SecurityContextSwitch.runAs(
|
||||
SecurityContextSwitch.withUser("test_user", SpPermission.READ_SOFTWARE_MODULE_ARTIFACT),
|
||||
() -> assertEqualFileContents(
|
||||
artifactManagement.getArtifactStream(artifact.getSha1Hash(), smOs.getId(), smOs.isEncrypted()), randomBytes));
|
||||
SecurityContextSwitch.runAs(
|
||||
SecurityContextSwitch.withUser("test_user", SpRole.CONTROLLER_ROLE),
|
||||
() -> assertEqualFileContents(
|
||||
artifactManagement.getArtifactStream(artifact.getSha1Hash(), smOs.getId(), smOs.isEncrypted()), randomBytes));
|
||||
SecurityContextSwitch.runAs(
|
||||
SecurityContextSwitch.withUser("test_user", SpRole.CONTROLLER_ROLE_ANONYMOUS),
|
||||
() -> assertEqualFileContents(
|
||||
artifactManagement.getArtifactStream(artifact.getSha1Hash(), smOs.getId(), smOs.isEncrypted()), randomBytes));
|
||||
SecurityContextSwitch.runAs(
|
||||
SecurityContextSwitch.withUser("test_user", SpPermission.READ_PREFIX + SpPermission.SOFTWARE_MODULE),
|
||||
() -> assertThatExceptionOfType(InsufficientPermissionException.class)
|
||||
.as("Should not have worked with missing permission.")
|
||||
.isThrownBy(() -> artifactManagement.getArtifactStream("123", 1, false)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trys and fails to load an artifact without required permission. Checks if expected InsufficientPermissionException is thrown.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true, removeFromAllPermission = {
|
||||
SpPermission.READ_SOFTWARE_MODULE_ARTIFACT,
|
||||
SpRole.CONTROLLER_ROLE, SpRole.CONTROLLER_ROLE_ANONYMOUS })
|
||||
@WithUser(authorities = {})
|
||||
void getArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() {
|
||||
assertThatExceptionOfType(InsufficientPermissionException.class)
|
||||
.as("Should not have worked with missing permission.")
|
||||
@@ -543,11 +553,13 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(runAsTenant(tenant, () -> artifactRepository.findAll())).hasSize(count);
|
||||
}
|
||||
|
||||
private void assertEqualFileContents(final ArtifactStream artifact, final byte[] randomBytes) throws IOException {
|
||||
private void assertEqualFileContents(final ArtifactStream artifact, final byte[] randomBytes) {
|
||||
try (final InputStream inputStream = artifact) {
|
||||
assertTrue(
|
||||
IOUtils.contentEquals(new ByteArrayInputStream(randomBytes), inputStream),
|
||||
"The stored binary matches the given binary");
|
||||
} catch (final IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.management;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withUserAndTenant;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -55,7 +56,8 @@ class SystemManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
for (int i = 0; i < tenants; i++) {
|
||||
final String tenantname = "TENANT" + i;
|
||||
SecurityContextSwitch.getAs(SecurityContextSwitch.withUserAndTenant("bumlux", tenantname, true, true, false, SpRole.SYSTEM_ROLE),
|
||||
SecurityContextSwitch.getAs(
|
||||
withUserAndTenant(tenantname, "bumlux", new String[] { SpRole.SYSTEM_ROLE }, true, true),
|
||||
() -> {
|
||||
systemManagement.getTenantMetadataWithoutDetails();
|
||||
if (artifactSize > 0) {
|
||||
|
||||
@@ -482,7 +482,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
|
||||
* Checks that target type for a target can be created, updated and unassigned.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@WithUser(authorities = SpRole.TENANT_ADMIN)
|
||||
void createAndUpdateTargetTypeInTarget() {
|
||||
// create a target type
|
||||
final List<? extends TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2);
|
||||
@@ -519,7 +519,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
|
||||
* Checks that target type to a target can be assigned.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@WithUser(authorities = SpRole.TENANT_ADMIN)
|
||||
void assignTargetTypeInTarget() {
|
||||
// create a target
|
||||
final Target target = testdataFactory.createTarget("target1", "testtarget");
|
||||
@@ -547,7 +547,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
|
||||
* Tests the assignment of types to multiple targets.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@WithUser(authorities = SpRole.TENANT_ADMIN)
|
||||
@ExpectEvents({
|
||||
@Expect(type = TargetCreatedEvent.class, count = 20),
|
||||
@Expect(type = TargetTypeCreatedEvent.class, count = 2),
|
||||
@@ -577,7 +577,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
|
||||
* Checks that target type can be unassigned from target.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@WithUser(authorities = SpRole.TENANT_ADMIN)
|
||||
void unAssignTargetTypeFromTarget() {
|
||||
// create a target type
|
||||
final TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
|
||||
@@ -827,7 +827,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@WithUser(authorities = SpRole.TENANT_ADMIN)
|
||||
void failToAssignInvalidTargetTypeToTarget() {
|
||||
// create a target
|
||||
final Target target = testdataFactory.createTarget("target1", "testtarget");
|
||||
|
||||
@@ -71,7 +71,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
* Ensures that targets created by a tenant are not visible by another tenant.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(tenantId = "mytenant", allSpPermissions = true)
|
||||
@WithUser(tenantId = "mytenant", authorities = SpRole.TENANT_ADMIN)
|
||||
void queryTargetFromDifferentTenantIsNotVisible() throws Exception {
|
||||
// create target for another tenant
|
||||
final String anotherTenant = "anotherTenant";
|
||||
@@ -93,7 +93,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
* Ensures that tenant with proper permissions can read and delete other tenants.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(tenantId = "mytenant", allSpPermissions = true)
|
||||
@WithUser(tenantId = "mytenant", authorities = SpRole.TENANT_ADMIN)
|
||||
void deleteAnotherTenantNotPossibleWithTenantPermissions() throws Exception {
|
||||
// create target for another tenant
|
||||
final String anotherTenant = "anotherTenant";
|
||||
@@ -122,7 +122,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
* Ensures that tenant metadata is retrieved for the current tenant.
|
||||
*/
|
||||
@Test
|
||||
@WithUser(tenantId = "mytenant", autoCreateTenant = false, allSpPermissions = true)
|
||||
@WithUser(tenantId = "mytenant", autoCreateTenant = false, authorities = SpRole.TENANT_ADMIN)
|
||||
void getTenantMetdata() throws Exception {
|
||||
// logged in tenant mytenant - check if tenant default data is autogenerated
|
||||
assertThat(distributionSetTypeManagement.findAll(PAGE)).isEmpty();
|
||||
@@ -142,7 +142,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
* Ensures that targets created from a different tenant cannot be deleted from other tenants
|
||||
*/
|
||||
@Test
|
||||
@WithUser(tenantId = "mytenant", allSpPermissions = true)
|
||||
@WithUser(tenantId = "mytenant", authorities = SpRole.TENANT_ADMIN)
|
||||
void deleteTargetFromOtherTenantIsNotPossible() throws Exception {
|
||||
// create target for another tenant
|
||||
final String anotherTenant = "anotherTenant";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user