From 7a642f564e12e1f308261e6919f89ef1d6a477c4 Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Thu, 5 Mar 2026 10:01:43 +0200 Subject: [PATCH] Remove the ROLE_CONTROLLER_ANONYMOUS (#2948) Signed-off-by: Avgustin Marinov --- .../java/org/eclipse/hawkbit/auth/SpRole.java | 2 - .../hawkbit/auth/SpringEvalExpressions.java | 5 +- .../rest/resource/DdiRootControllerTest.java | 50 ++++++++----------- .../amqp/AmqpMessageHandlerService.java | 2 +- .../jpa/model/AbstractJpaBaseEntity.java | 5 -- .../AbstractJpaTenantAwareBaseEntity.java | 4 -- .../management/ArtifactManagementTest.java | 4 -- .../management/ControllerManagementTest.java | 9 ++-- 8 files changed, 28 insertions(+), 53 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java index a7d8d5693..d281b60d3 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java @@ -29,8 +29,6 @@ public final class SpRole { public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE"; /** The role which contains in the spring security context in case a 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"; private static final String IMPLIES = " > "; private static final String LINE_BREAK = "\n"; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpringEvalExpressions.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpringEvalExpressions.java index b2c6578d6..5799d9285 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpringEvalExpressions.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpringEvalExpressions.java @@ -36,7 +36,8 @@ import org.springframework.security.access.prepost.PreAuthorize; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SpringEvalExpressions { - public static final String IS_SYSTEM_CODE = "hasAuthority('ROLE_SYSTEM_CODE')"; + public static final String IS_SYSTEM_CODE = "hasAuthority('" + SpRole.SYSTEM_ROLE + "')"; + public static final String IS_CONTROLLER = "hasAuthority('" + SpRole.CONTROLLER_ROLE + "')"; public static final String PERMISSION_GROUP_PLACEHOLDER = "${permissionGroup}"; // evaluated to _ (e.g. CREATE_DISTRIBUTION_SET) @@ -44,6 +45,4 @@ public final class SpringEvalExpressions { public static final String HAS_READ_REPOSITORY = "hasPermission(#root, 'READ_${permissionGroup}')"; public static final String HAS_UPDATE_REPOSITORY = "hasPermission(#root, 'UPDATE_${permissionGroup}')"; public static final String HAS_DELETE_REPOSITORY = "hasPermission(#root, 'DELETE_${permissionGroup}')"; - - public static final String IS_CONTROLLER = "hasAnyRole('" + SpRole.CONTROLLER_ROLE_ANONYMOUS + "', '" + SpRole.CONTROLLER_ROLE + "')"; } \ No newline at end of file diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java index 56ec4cdb9..41a9d3009 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.ddi.rest.resource; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.hawkbit.auth.SpPermission.TENANT_CONFIGURATION; -import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE_ANONYMOUS; +import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withController; @@ -34,7 +34,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.concurrent.Callable; import org.eclipse.hawkbit.auth.SpPermission; @@ -131,13 +130,12 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { final Target findTargetByControllerID = targetManagement.getByControllerId(knownTargetControllerId); assertThat(findTargetByControllerID.getCreatedBy()).isEqualTo(knownCreatedBy); // make a poll, audit information should not be changed, run as controller principal! - callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS), - () -> { - mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownTargetControllerId)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - return null; - }); + callAs(withController("controller", CONTROLLER_ROLE), () -> { + mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownTargetControllerId)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + return null; + }); // verify that audit information has not changed final Target targetVerify = targetManagement.getByControllerId(knownTargetControllerId); assertThat(targetVerify.getCreatedBy()).isEqualTo(findTargetByControllerID.getCreatedBy()); @@ -203,16 +201,14 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { @Expect(type = TenantConfigurationCreatedEvent.class, count = 1), @Expect(type = TenantConfigurationDeletedEvent.class, count = 1) }) void pollWithModifiedGlobalPollingTime() throws Exception { - withPollingTime("00:02:00", () -> callAs( - withUser("controller", CONTROLLER_ROLE_ANONYMOUS), - () -> { - mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)) - .andExpect(jsonPath("$.config.polling.sleep", equalTo("00:02:00"))); - return null; - })); + withPollingTime("00:02:00", () -> callAs(withUser("controller", CONTROLLER_ROLE), () -> { + mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)) + .andExpect(jsonPath("$.config.polling.sleep", equalTo("00:02:00"))); + return null; + })); } /** @@ -234,8 +230,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { }); withPollingTime("00:02:00, controllerid == 4711 -> 00:01:00, group == 'Europe' -> 00:05:05", () -> callAs( - withUser("controller", CONTROLLER_ROLE_ANONYMOUS), - () -> { + withUser("controller", CONTROLLER_ROLE), () -> { mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), 4711)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) @@ -381,13 +376,12 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { final String knownControllerId1 = "0815"; final long create = System.currentTimeMillis(); // make a poll, audit information should be set on plug and play - callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS), - () -> { - mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownControllerId1)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - return null; - }); + callAs(withController("controller", CONTROLLER_ROLE), () -> { + mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownControllerId1)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + return null; + }); // verify assertThat(targetManagement.getByControllerId(knownControllerId1)).satisfies(target -> { assertThat(target.getAddress()).isEqualTo(IpUtil.createHttpUri("127.0.0.1").toString()); diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index a83af238b..246f74dc2 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -172,7 +172,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { private static void setTenantSecurityContext(final String tenant) { final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken( UUID.randomUUID().toString(), "AMQP-Controller", - List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE_ANONYMOUS))); + List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE))); authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenant, true)); setSecurityContext(authenticationToken); } diff --git a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 9172f7c01..2b1d155d5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -9,8 +9,6 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import java.io.Serial; - import jakarta.persistence.Access; import jakarta.persistence.AccessType; import jakarta.persistence.Column; @@ -50,9 +48,6 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { protected static final int USERNAME_FIELD_LENGTH = 64; - @Serial - private static final long serialVersionUID = 1L; - @Setter // should be used just for test purposes @Getter @Id diff --git a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java index be9805785..76305e1a0 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java @@ -9,7 +9,6 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import java.io.Serial; import java.util.Objects; import jakarta.persistence.Column; @@ -41,9 +40,6 @@ import org.eclipse.persistence.annotations.TenantDiscriminatorColumn; @Multitenant(MultitenantType.SINGLE_TABLE) public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEntity implements TenantAwareBaseEntity { - @Serial - private static final long serialVersionUID = 1L; - @Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40) @Size(min = 1, max = 40) @NotNull diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java index 55e92b8ac..77a2cb27d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java @@ -398,10 +398,6 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest { 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) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java index a20efc93a..aea67feba 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java @@ -13,7 +13,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE; -import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE_ANONYMOUS; import static org.eclipse.hawkbit.context.AccessContext.asSystem; import static org.eclipse.hawkbit.repository.jpa.configuration.Constants.TX_RT_MAX; import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY; @@ -108,7 +107,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final int allowedAttributes = quotaManagement.getMaxAttributeEntriesPerTarget(); testdataFactory.createTarget(controllerId); - final WithUser withController = SecurityContextSwitch.withController("controller", CONTROLLER_ROLE_ANONYMOUS); + final WithUser withController = SecurityContextSwitch.withController("controller", CONTROLLER_ROLE); assertThatExceptionOfType(AssignmentQuotaExceededException.class) .isThrownBy(() -> runAs(withController, () -> writeAttributes(controllerId, allowedAttributes + 1, "key", "value"))) .withMessageContaining("" + allowedAttributes); @@ -184,7 +183,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final Long actionId = createTargetAndAssignDs(); SecurityContextSwitch - .getAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> { + .getAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE), () -> { // Fails as one entry is already in there from the assignment assertThatExceptionOfType(AssignmentQuotaExceededException.class) .isThrownBy(() -> writeStatus(actionId, allowStatusEntries)) @@ -1161,9 +1160,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final String controllerId = "test123"; final Target target = testdataFactory.createTarget(controllerId); - SecurityContextSwitch.getAs(SecurityContextSwitch.withController( - "controller", - CONTROLLER_ROLE_ANONYMOUS, SpPermission.READ_TARGET), () -> { + SecurityContextSwitch.getAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE, SpPermission.READ_TARGET), () -> { addAttributeAndVerify(controllerId); addSecondAttributeAndVerify(controllerId); updateAttributeAndVerify(controllerId);