From 441b78460d67604e5e2cdaeb1f78afd2074b28c0 Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Tue, 12 Aug 2025 14:09:27 +0300 Subject: [PATCH] Improve Permission Management (#2604) Signed-off-by: Avgustin Marinov --- .../rest/resource/DdiRootControllerTest.java | 2 +- .../security/controller/Authenticator.java | 4 +- .../app/ddi/PreAuthorizeEnabledTest.java | 4 +- .../amqp/AmqpMessageHandlerService.java | 4 +- .../repository/ArtifactManagement.java | 29 +++--- .../repository/ConfirmationManagement.java | 23 +++-- .../repository/ControllerManagement.java | 4 +- .../repository/DeploymentManagement.java | 71 ++++++++------ .../repository/DistributionSetManagement.java | 3 +- .../DistributionSetTagManagement.java | 6 ++ .../DistributionSetTypeManagement.java | 6 ++ .../hawkbit/repository/RolloutExecutor.java | 2 +- .../repository/RolloutGroupManagement.java | 30 +++--- .../hawkbit/repository/RolloutManagement.java | 55 ++++++----- .../repository/SoftwareModuleManagement.java | 3 +- .../SoftwareModuleTypeManagement.java | 6 ++ .../hawkbit/repository/SystemManagement.java | 16 ++-- .../TargetFilterQueryManagement.java | 15 +-- .../hawkbit/repository/TargetManagement.java | 96 +++++++++---------- .../repository/TargetTagManagement.java | 3 +- .../repository/TargetTypeManagement.java | 24 ++--- .../TenantConfigurationManagement.java | 24 +++-- .../repository/TenantStatsManagement.java | 12 +-- .../repository/RepositoryConfiguration.java | 14 +-- .../jpa/JpaRepositoryConfiguration.java | 4 +- .../repository/jpa/JpaRolloutExecutor.java | 16 +++- .../repository/jpa/JpaRolloutHandler.java | 18 +--- .../ArtifactManagementSecurityTest.java | 12 +-- .../management/ArtifactManagementTest.java | 4 +- .../ConfirmationManagementSecurityTest.java | 4 +- .../ControllerManagementSecurityTest.java | 57 ++++++----- .../management/ControllerManagementTest.java | 4 +- .../DeploymentManagementSecurityTest.java | 3 +- .../SystemManagementSecurityTest.java | 5 +- .../test/util/AbstractIntegrationTest.java | 2 +- .../test/util/SecurityContextSwitch.java | 6 +- .../im/authentication/SpPermission.java | 57 ++++++----- .../hawkbit/im/authentication/SpRole.java | 8 +- .../authentication/SpringEvalExpressions.java | 53 +--------- .../security/SystemSecurityContext.java | 3 +- 40 files changed, 361 insertions(+), 351 deletions(-) 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 586f45c23..32b00ebde 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 @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ddi.rest.resource; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS; +import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS; import static org.eclipse.hawkbit.im.authentication.SpPermission.TENANT_CONFIGURATION; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs; diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java index 45ab60434..c6f1fe66d 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java @@ -14,7 +14,7 @@ import java.util.List; import java.util.Objects; import lombok.EqualsAndHashCode; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; @@ -77,7 +77,7 @@ public interface Authenticator { private static class AuthenticatedController extends AbstractAuthenticationToken { private static final Collection CONTROLLER_AUTHORITY = - List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE)); private final String controllerId; AuthenticatedController(final String tenant, final String controllerId) { diff --git a/hawkbit-ddi/hawkbit-ddi-server/src/test/java/org/eclipse/hawkbit/app/ddi/PreAuthorizeEnabledTest.java b/hawkbit-ddi/hawkbit-ddi-server/src/test/java/org/eclipse/hawkbit/app/ddi/PreAuthorizeEnabledTest.java index 71eb93926..865ea9d8a 100644 --- a/hawkbit-ddi/hawkbit-ddi-server/src/test/java/org/eclipse/hawkbit/app/ddi/PreAuthorizeEnabledTest.java +++ b/hawkbit-ddi/hawkbit-ddi-server/src/test/java/org/eclipse/hawkbit/app/ddi/PreAuthorizeEnabledTest.java @@ -13,7 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.repository.test.util.WithUser; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; @@ -40,7 +40,7 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { * Tests whether request succeed if a role is granted for the user */ @Test - @WithUser(authorities = { SpringEvalExpressions.CONTROLLER_ROLE }, autoCreateTenant = false) + @WithUser(authorities = { SpRole.CONTROLLER_ROLE }, autoCreateTenant = false) void successIfHasRole() throws Exception { mvc.perform(get("/DEFAULT/controller/v1/controllerId")) .andExpect(result -> assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); 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 bef84ca7f..af103a22b 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 @@ -36,7 +36,7 @@ import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate; import org.eclipse.hawkbit.dmf.json.model.DmfAutoConfirmation; import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing; import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.repository.ConfirmationManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.RepositoryConstants; @@ -192,7 +192,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { private static void setTenantSecurityContext(final String tenantId) { final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken( UUID.randomUUID().toString(), "AMQP-Controller", - Collections.singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS))); + List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE_ANONYMOUS))); authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenantId, true)); setSecurityContext(authenticationToken); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java index 5c9f57249..d06bbb24c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java @@ -16,6 +16,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.artifact.model.DbArtifact; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.ArtifactDeleteFailedException; @@ -34,11 +35,15 @@ import org.springframework.security.access.prepost.PreAuthorize; /** * Service for {@link Artifact} management operations. */ -public interface ArtifactManagement { +public interface ArtifactManagement extends PermissionSupport { + + @Override + default String permissionGroup() { + return SpPermission.SOFTWARE_MODULE; + } /** - * @return the total amount of local artifacts stored in the artifact - * management + * @return the total amount of local artifacts stored in the artifact management */ @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long count(); @@ -75,8 +80,7 @@ public interface ArtifactManagement { * @param id to search for * @return found {@link Artifact} */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER) Optional get(long id); /** @@ -87,8 +91,7 @@ public interface ArtifactManagement { * @return found {@link Artifact} * @throws EntityNotFoundException if software module with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER) Optional getByFilenameAndSoftwareModule(@NotNull String filename, long softwareModuleId); /** @@ -97,8 +100,7 @@ public interface ArtifactManagement { * @param sha1 the sha1 * @return the first local artifact */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER) Optional findFirstBySHA1(@NotNull String sha1); /** @@ -107,8 +109,7 @@ public interface ArtifactManagement { * @param filename to search for * @return found List of {@link Artifact}s. */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER) Optional getByFilename(@NotNull String filename); /** @@ -140,9 +141,7 @@ public interface ArtifactManagement { * @param isEncrypted flag to indicate if artifact is encrypted. * @return loaded {@link DbArtifact} */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) + @PreAuthorize("hasAuthority('" + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) Optional loadArtifactBinary(@NotEmpty String sha1Hash, long softwareModuleId, final boolean isEncrypted); - -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ConfirmationManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ConfirmationManagement.java index 5f75e8016..7e195a559 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ConfirmationManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ConfirmationManagement.java @@ -15,6 +15,7 @@ import java.util.Optional; import jakarta.validation.constraints.NotEmpty; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.AutoConfirmationStatus; @@ -24,10 +25,17 @@ import org.springframework.security.access.prepost.PreAuthorize; /** * Service layer for all confirmation related operations. */ -public interface ConfirmationManagement { +public interface ConfirmationManagement extends PermissionSupport { + + String HAS_UPDATE_TARGET_OR_IS_CONTROLLER = SpringEvalExpressions.HAS_UPDATE_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER; String CONFIRMATION_CODE_MSG_PREFIX = "Confirmation status code: %d"; + @Override + default String permissionGroup() { + return SpPermission.TARGET; + } + /** * Activate auto confirmation for a given controller ID. In case auto confirmation is active already, this method will fail with an exception. * @@ -36,7 +44,7 @@ public interface ConfirmationManagement { * @param remark optional field to set a remark * @return the persisted {@link AutoConfirmationStatus} */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER) AutoConfirmationStatus activateAutoConfirmation(@NotEmpty String controllerId, final String initiator, final String remark); /** @@ -46,7 +54,7 @@ public interface ConfirmationManagement { * @param code optional value to specify a code for the created action status * @param messages optional value to specify message for the created action status */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER) Action confirmAction(long actionId, Integer code, Collection messages); /** @@ -56,7 +64,7 @@ public interface ConfirmationManagement { * @param code optional value to specify a code for the created action status * @param messages optional value to specify message for the created action status */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER) Action denyAction(long actionId, Integer code, Collection messages); /** @@ -64,7 +72,7 @@ public interface ConfirmationManagement { * * @param controllerId to disable auto confirmation for */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER) void deactivateAutoConfirmation(@NotEmpty String controllerId); /** @@ -73,8 +81,7 @@ public interface ConfirmationManagement { * @param controllerId to check the state for * @return instance of {@link AutoConfirmationStatus} wrapped in an {@link Optional}. Present if active and empty if disabled. */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR + - SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER) Optional getStatus(@NotEmpty String controllerId); /** @@ -83,6 +90,6 @@ public interface ConfirmationManagement { * @param controllerId of the target to check * @return a list of {@link Action} */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) List findActiveActionsWaitingConfirmation(@NotEmpty String controllerId); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index 6abc2beb6..a3770e42d 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -267,7 +267,7 @@ public interface ControllerManagement { * @return {@link Target} or {@code null} if it does not exist * @see Target#getControllerId() */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + " or " + SpringEvalExpressions.IS_SYSTEM_CODE) Optional getByControllerId(@NotEmpty String controllerId); /** @@ -279,7 +279,7 @@ public interface ControllerManagement { * @return {@link Target} or {@code null} if it does not exist * @see Target#getId() */ - @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + " or " + SpringEvalExpressions.IS_SYSTEM_CODE) Optional get(long targetId); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index ff34697b1..42c60fa8b 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -19,6 +19,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; @@ -48,7 +49,15 @@ import org.springframework.security.access.prepost.PreAuthorize; /** * A DeploymentManagement service provides operations for the deployment of {@link DistributionSet}s to {@link Target}s. */ -public interface DeploymentManagement { +public interface DeploymentManagement extends PermissionSupport { + + String HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET = + SpringEvalExpressions.HAS_UPDATE_REPOSITORY + " and hasAuthority('READ_" + SpPermission.DISTRIBUTION_SET + "')"; + + @Override + default String permissionGroup() { + return SpPermission.TARGET; + } /** * build a {@link DeploymentRequest} for a target distribution set assignment @@ -74,7 +83,7 @@ public interface DeploymentManagement { * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same * target and multi-assignment is disabled */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET) List assignDistributionSets(@Valid @NotEmpty List deploymentRequests); /** @@ -92,7 +101,7 @@ public interface DeploymentManagement { * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same * target and multi-assignment is disabled */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET) List assignDistributionSets( String initiatedBy, @Valid @NotEmpty List deploymentRequests, String actionMessage); @@ -118,10 +127,10 @@ public interface DeploymentManagement { * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same * target and multi-assignment is disabled */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET) List offlineAssignedDistributionSets(String initiatedBy, Collection> assignments); - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) + @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET) List offlineAssignedDistributionSets(Collection> assignments); /** @@ -133,7 +142,7 @@ public interface DeploymentManagement { * @throws CancelActionNotAllowedException in case the given action is not active or is already a cancel action * @throws EntityNotFoundException if action with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) Action cancelAction(long actionId); /** @@ -147,7 +156,7 @@ public interface DeploymentManagement { * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countActionsByTarget(@NotNull String rsql, @NotEmpty String controllerId); /** @@ -156,7 +165,7 @@ public interface DeploymentManagement { * * @return the total amount of stored actions */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countActionsAll(); /** @@ -166,7 +175,7 @@ public interface DeploymentManagement { * @param rsql RSQL query. * @return the total number of actions matching the given RSQL query. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countActions(@NotNull String rsql); /** @@ -176,7 +185,7 @@ public interface DeploymentManagement { * @return the count value of found actions associated to the target * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countActionsByTarget(@NotEmpty String controllerId); /** @@ -185,7 +194,7 @@ public interface DeploymentManagement { * @param actionId to be id of the action * @return the corresponding {@link Action} */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional findAction(long actionId); /** @@ -196,7 +205,7 @@ public interface DeploymentManagement { * @param pageable pagination parameter * @return a paged list of {@link Action}s */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Slice findActionsAll(@NotNull Pageable pageable); /** @@ -207,7 +216,7 @@ public interface DeploymentManagement { * @param pageable the page request parameter for paging and sorting the result * @return a paged list of {@link Action}s. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Slice findActions(@NotNull String rsql, @NotNull Pageable pageable); /** @@ -221,7 +230,7 @@ public interface DeploymentManagement { * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Slice findActionsByTarget(@NotNull String rsql, @NotEmpty String controllerId, @NotNull Pageable pageable); /** @@ -231,7 +240,7 @@ public interface DeploymentManagement { * @param pageable the pageable request to limit, sort the actions * @return a slice of actions found for a specific target */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Slice findActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable); /** @@ -242,7 +251,7 @@ public interface DeploymentManagement { * @return the corresponding {@link Page} of {@link ActionStatus} * @throws EntityNotFoundException if action with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findActionStatusByAction(long actionId, @NotNull Pageable pageable); /** @@ -252,7 +261,7 @@ public interface DeploymentManagement { * @return count of {@link ActionStatus} entries * @throws EntityNotFoundException if action with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countActionStatusByAction(long actionId); /** @@ -263,7 +272,7 @@ public interface DeploymentManagement { * @param pageable the page request parameter for paging and sorting the result * @return a page of messages by a specific {@link ActionStatus} id */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findMessagesByActionStatusId(long actionStatusId, @NotNull Pageable pageable); /** @@ -272,7 +281,7 @@ public interface DeploymentManagement { * @param actionId to be id of the action * @return the corresponding {@link Action} */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional findActionWithDetails(long actionId); /** @@ -283,7 +292,7 @@ public interface DeploymentManagement { * @return a list of actions associated with the given target * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findActiveActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable); /** @@ -294,7 +303,7 @@ public interface DeploymentManagement { * @return a list of actions associated with the given target * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findInActiveActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable); /** @@ -304,7 +313,7 @@ public interface DeploymentManagement { * @param maxActionCount max size of returned list * @return the action */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) List findActiveActionsWithHighestWeight(@NotEmpty String controllerId, int maxActionCount); /** @@ -324,7 +333,7 @@ public interface DeploymentManagement { * @throws CancelActionNotAllowedException in case the given action is not active * @throws EntityNotFoundException if action with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) Action forceQuitAction(long actionId); /** @@ -334,7 +343,7 @@ public interface DeploymentManagement { * @return the updated or the found {@link Action} * @throws EntityNotFoundException if action with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) Action forceTargetAction(long actionId); /** @@ -342,7 +351,7 @@ public interface DeploymentManagement { * * @param targetIds ids of the {@link Target}s the actions belong to */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) void cancelInactiveScheduledActionsForTargets(List targetIds); /** @@ -353,7 +362,7 @@ public interface DeploymentManagement { * @param distributionSetId to assign * @param rolloutGroupParentId the parent rollout group the actions should reference. null references the first group */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) void startScheduledActionsByRolloutGroupParent(long rolloutId, long distributionSetId, Long rolloutGroupParentId); /** @@ -361,7 +370,7 @@ public interface DeploymentManagement { * * @param rolloutGroupActions rollouts group actions part of a same group */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) void startScheduledActions(final List rolloutGroupActions); /** @@ -371,7 +380,7 @@ public interface DeploymentManagement { * @return assigned {@link DistributionSet} * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional getAssignedDistributionSet(@NotEmpty String controllerId); /** @@ -381,7 +390,7 @@ public interface DeploymentManagement { * @return installed {@link DistributionSet} * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional getInstalledDistributionSet(@NotEmpty String controllerId); /** @@ -402,7 +411,7 @@ public interface DeploymentManagement { * @param targetId of target * @return if actions in CANCELING state are present */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) boolean hasPendingCancellations(@NotNull Long targetId); /** @@ -411,6 +420,6 @@ public interface DeploymentManagement { * @param cancelationType defines if a force or soft cancel is executed * @param set the distribution set for that the actions should be canceled */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) void cancelActionsForDistributionSet(final CancelationType cancelationType, final DistributionSet set); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index 8d162c1ae..838a00dbc 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; @@ -56,7 +57,7 @@ public interface DistributionSetManagement @Override default String permissionGroup() { - return "DISTRIBUTION_SET"; + return SpPermission.DISTRIBUTION_SET; } /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java index 65c4c072d..f4c9fafd1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java @@ -19,6 +19,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -37,6 +38,11 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface DistributionSetTagManagement extends RepositoryManagement { + @Override + default String permissionGroup() { + return SpPermission.DISTRIBUTION_SET; + } + @SuperBuilder @Getter @EqualsAndHashCode(callSuper = true) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java index a41708b36..b53488a4a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java @@ -21,6 +21,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; @@ -38,6 +39,11 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface DistributionSetTypeManagement extends RepositoryManagement { + @Override + default String permissionGroup() { + return SpPermission.DISTRIBUTION_SET; + } + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional findByKey(@NotEmpty String key); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutExecutor.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutExecutor.java index ca7989c63..eaf33d877 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutExecutor.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutExecutor.java @@ -49,6 +49,6 @@ public interface RolloutExecutor { * change {@link RolloutStatus#DELETED} or hard delete from the persistence * otherwise. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) + @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) void execute(Rollout rollout); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java index 736f9ca8c..4073a250c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java @@ -13,6 +13,7 @@ import java.util.Optional; import jakarta.validation.constraints.NotNull; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; @@ -27,7 +28,14 @@ import org.springframework.security.access.prepost.PreAuthorize; /** * Repository management service for RolloutGroup. */ -public interface RolloutGroupManagement { +public interface RolloutGroupManagement extends PermissionSupport { + + String HAS_READ_ROLLOUT_AND_READ_TARGET = SpringEvalExpressions.HAS_READ_REPOSITORY + " and hasAuthority('READ_" + SpPermission.TARGET + "')"; + + @Override + default String permissionGroup() { + return SpPermission.ROLLOUT; + } /** * Retrieves a page of {@link RolloutGroup}s filtered by a given {@link Rollout} with the detailed status. @@ -37,7 +45,7 @@ public interface RolloutGroupManagement { * @return a page of found {@link RolloutGroup}s * @throws EntityNotFoundException of rollout with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByRolloutWithDetailedStatus(long rolloutId, @NotNull Pageable pageable); /** @@ -46,7 +54,7 @@ public interface RolloutGroupManagement { * @param rolloutGroupId the ID of the rollout group to find * @return the found {@link RolloutGroup} by its ID or {@code null} if it does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional get(long rolloutGroupId); /** @@ -60,7 +68,7 @@ public interface RolloutGroupManagement { * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByRolloutAndRsql(long rolloutId, @NotNull String rsql, @NotNull Pageable pageable); /** @@ -74,7 +82,7 @@ public interface RolloutGroupManagement { * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByRolloutAndRsqlWithDetailedStatus(long rolloutId, @NotNull String rsql, @NotNull Pageable pageable); /** @@ -84,7 +92,7 @@ public interface RolloutGroupManagement { * @param pageable the page request to sort and limit the result * @return a page of found {@link RolloutGroup}s */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByRollout(long rolloutId, @NotNull Pageable pageable); /** @@ -93,7 +101,7 @@ public interface RolloutGroupManagement { * @param rolloutId the ID of the rollout to filter the {@link RolloutGroup}s * @return a page of found {@link RolloutGroup}s */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countByRollout(long rolloutId); /** @@ -104,7 +112,7 @@ public interface RolloutGroupManagement { * @return Page list of targets of a rollout group * @throws EntityNotFoundException if group with ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_ROLLOUT_AND_READ_TARGET) Page findTargetsOfRolloutGroup(long rolloutGroupId, @NotNull Pageable pageable); /** @@ -118,7 +126,7 @@ public interface RolloutGroupManagement { * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_ROLLOUT_AND_READ_TARGET) Page findTargetsOfRolloutGroupByRsql(long rolloutGroupId, @NotNull String rsql, @NotNull Pageable pageable); /** @@ -127,7 +135,7 @@ public interface RolloutGroupManagement { * @param rolloutGroupId rollout group id * @return rolloutGroup with details of targets count for different statuses */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional getWithDetailedStatus(long rolloutGroupId); /** @@ -137,6 +145,6 @@ public interface RolloutGroupManagement { * @return the target rollout group count * @throws EntityNotFoundException if rollout group with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countTargetsOfRolloutsGroup(long rolloutGroupId); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index 57681fc16..354fa44fa 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -28,6 +28,7 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; @@ -53,14 +54,22 @@ import org.springframework.security.access.prepost.PreAuthorize; * RolloutManagement to control rollouts e.g. like creating, starting, resuming and pausing rollouts. This service secures all the * functionality based on the {@link PreAuthorize} annotation on methods. */ -public interface RolloutManagement { +public interface RolloutManagement extends PermissionSupport { + + String HAS_ROLLOUT_APPROVE = "hasPermission(#root, 'APPROVE')"; + String HAS_ROLLOUT_HANDLE = "hasPermission(#root, 'HANDLE')"; + + @Override + default String permissionGroup() { + return SpPermission.ROLLOUT; + } /** * Counts all {@link Rollout}s in the repository that are not marked as deleted. * * @return number of rollouts */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long count(); /** @@ -72,7 +81,7 @@ public interface RolloutManagement { * @param setId the distribution set * @return the count */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countByDistributionSetIdAndRolloutIsStoppable(long setId); /** @@ -102,7 +111,7 @@ public interface RolloutManagement { * @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is * exceeded. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) + @PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY) Rollout create( @NotNull @Valid Create create, int amountGroup, boolean confirmationRequired, @NotNull RolloutGroupConditions conditions, DynamicRolloutGroupTemplate dynamicRolloutGroupTemplate); @@ -133,7 +142,7 @@ public interface RolloutManagement { * @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is * exceeded. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) + @PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY) Rollout create(@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired, @NotNull RolloutGroupConditions conditions); @@ -164,7 +173,7 @@ public interface RolloutManagement { * @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is * exceeded. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) + @PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY) Rollout create(@Valid @NotNull Create rollout, @NotNull @Valid List groups, RolloutGroupConditions conditions); /** @@ -174,7 +183,7 @@ public interface RolloutManagement { * @param pageable the page request to sort and limit the result * @return a page of found rollouts */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findAll(boolean deleted, @NotNull Pageable pageable); /** @@ -185,7 +194,7 @@ public interface RolloutManagement { * @return a list of rollouts with details of targets count for different * statuses */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findAllWithDetailedStatus(boolean deleted, @NotNull Pageable pageable); /** @@ -199,7 +208,7 @@ public interface RolloutManagement { * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByRsql(@NotNull String rsql, boolean deleted, @NotNull Pageable pageable); /** @@ -210,7 +219,7 @@ public interface RolloutManagement { * @param pageable the page request to sort and limit the result * @return the founded rollout or {@code null} if rollout with given ID does not exists */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByRsqlWithDetailedStatus(@NotEmpty String rsql, boolean deleted, @NotNull Pageable pageable); /** @@ -218,7 +227,7 @@ public interface RolloutManagement { * * @return a list of active rollouts */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) List findActiveRollouts(); /** @@ -228,7 +237,7 @@ public interface RolloutManagement { * @return the founded rollout or {@code null} if rollout with given ID does * not exists */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional get(long rolloutId); /** @@ -238,7 +247,7 @@ public interface RolloutManagement { * @return the founded rollout or {@code null} if rollout with given name * does not exists */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional getByName(@NotEmpty String rolloutName); /** @@ -247,7 +256,7 @@ public interface RolloutManagement { * @param rolloutId rollout id * @return rollout details of targets count for different statuses */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Optional getWithDetailedStatus(long rolloutId); /** @@ -272,7 +281,7 @@ public interface RolloutManagement { * @throws EntityNotFoundException if rollout or group with given ID does not exist * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#RUNNING}. Only running rollouts can be paused. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) + @PreAuthorize(HAS_ROLLOUT_HANDLE) void pauseRollout(long rolloutId); /** @@ -282,7 +291,7 @@ public interface RolloutManagement { * @throws EntityNotFoundException if rollout with given ID does not exist * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#PAUSED}. Only paused rollouts can be resumed. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) + @PreAuthorize(HAS_ROLLOUT_HANDLE) void resumeRollout(long rolloutId); /** @@ -296,7 +305,7 @@ public interface RolloutManagement { * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts * waiting for approval can be acted upon. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE) + @PreAuthorize(HAS_ROLLOUT_APPROVE) Rollout approveOrDeny(long rolloutId, Rollout.ApprovalDecision decision); /** @@ -314,7 +323,7 @@ public interface RolloutManagement { * {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts * waiting for approveOrDeny can be acted upon. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE) + @PreAuthorize(HAS_ROLLOUT_APPROVE) Rollout approveOrDeny(long rolloutId, Rollout.ApprovalDecision decision, String remark); /** @@ -330,7 +339,7 @@ public interface RolloutManagement { * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) + @PreAuthorize(HAS_ROLLOUT_HANDLE) Rollout start(long rolloutId); /** @@ -342,7 +351,7 @@ public interface RolloutManagement { * @throws EntityReadOnlyException if rollout is in soft deleted state, i.e. only kept as * reference */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) Rollout update(@NotNull @Valid Update update); /** @@ -351,7 +360,7 @@ public interface RolloutManagement { * * @param rolloutId the ID of the rollout to be deleted */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE) + @PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY) void delete(long rolloutId); /** @@ -362,7 +371,7 @@ public interface RolloutManagement { * @param set the {@link DistributionSet} for that the rollouts should be * canceled */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) void cancelRolloutsForDistributionSet(DistributionSet set); /** @@ -373,7 +382,7 @@ public interface RolloutManagement { * @throws EntityNotFoundException if rollout or group with given ID does not exist * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#RUNNING}. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) void triggerNextGroup(long rolloutId); @SuperBuilder diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java index 1f31c94e5..e6e64dd30 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java @@ -23,6 +23,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; @@ -46,7 +47,7 @@ public interface SoftwareModuleManagement @Override default String permissionGroup() { - return "SOFTWARE_MODULE"; + return SpPermission.SOFTWARE_MODULE; } @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java index b20fe5c3f..fd82a9f6d 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java @@ -20,6 +20,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; @@ -32,6 +33,11 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface SoftwareModuleTypeManagement extends RepositoryManagement { + @Override + default String permissionGroup() { + return SpPermission.SOFTWARE_MODULE; + } + /** * @param key to search for * @return {@link SoftwareModuleType} in the repository with given {@link SoftwareModuleType#getKey()} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 9dc4c0bd6..673382cb3 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -13,6 +13,7 @@ import java.util.function.Consumer; import jakarta.validation.constraints.NotNull; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; @@ -29,7 +30,6 @@ import org.springframework.security.access.prepost.PreAuthorize; */ public interface SystemManagement { - /** * Deletes all data related to a given tenant. * @@ -76,18 +76,18 @@ public interface SystemManagement { /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR + @PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or " + + "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or " + + "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) TenantMetaData getTenantMetadata(); /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()}) */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR + @PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or " + + "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or " + + "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) TenantMetaData getTenantMetadataWithoutDetails(); @@ -113,7 +113,7 @@ public interface SystemManagement { * @param defaultDsType to update * @return updated {@link TenantMetaData} entity */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize("hasAuthority('UPDATE_" + SpPermission.TENANT_CONFIGURATION + "')") TenantMetaData updateTenantMetadata(long defaultDsType); @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java index d4f4fe2ef..4553f35b2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java @@ -22,6 +22,7 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; @@ -48,7 +49,7 @@ public interface TargetFilterQueryManagement @Override default String permissionGroup() { - return "TARGET"; + return SpPermission.TARGET; } /** @@ -60,7 +61,7 @@ public interface TargetFilterQueryManagement * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) boolean verifyTargetFilterQuerySyntax(@NotNull String query); /** @@ -72,7 +73,7 @@ public interface TargetFilterQueryManagement * @param autoAssignDistributionSetId the id of the distribution set * @return the count */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) long countByAutoAssignDistributionSetId(long autoAssignDistributionSetId); /** @@ -84,7 +85,7 @@ public interface TargetFilterQueryManagement * @return the page with the found {@link TargetFilterQuery}s * @throws EntityNotFoundException if DS with given ID does not exist */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Page findByAutoAssignDSAndRsql(long setId, String rsql, @NotNull Pageable pageable); /** @@ -93,7 +94,7 @@ public interface TargetFilterQueryManagement * @param pageable pagination information * @return the page with the found {@link TargetFilterQuery}s */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) Slice findWithAutoAssignDS(@NotNull Pageable pageable); /** @@ -112,7 +113,7 @@ public interface TargetFilterQueryManagement * @throws InvalidDistributionSetException if the provided auto-assign {@link DistributionSet} is * invalidated */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) TargetFilterQuery updateAutoAssignDS(@NotNull @Valid AutoAssignDistributionSetUpdate autoAssignDistributionSetUpdate); /** @@ -121,7 +122,7 @@ public interface TargetFilterQueryManagement * @param setId the {@link DistributionSet} to be removed from auto * assignments. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY) void cancelAutoAssignmentForDistributionSet(long setId); @SuperBuilder diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index 3442bd4d6..b1e073133 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -9,16 +9,9 @@ */ package org.eclipse.hawkbit.repository; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_OPEN; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_AND; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_DELETE_TARGET; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_PREFIX; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_TARGET; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_SUFFIX; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET; +import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_DELETE_REPOSITORY; +import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY; +import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_UPDATE_REPOSITORY; import java.util.Collection; import java.util.List; @@ -64,19 +57,16 @@ import org.springframework.util.ObjectUtils; public interface TargetManagement extends RepositoryManagement { + String HAS_READ_TARGET_AND_READ_ROLLOUT = HAS_READ_REPOSITORY + " and hasAuthority('READ_" + SpPermission.ROLLOUT + "')"; + String HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET = HAS_READ_REPOSITORY + " and hasAuthority('READ_" + SpPermission.DISTRIBUTION_SET + "')"; + String DETAILS_BASE = "base"; String DETAILS_AUTO_CONFIRMATION_STATUS = "autoConfirmationStatus"; String DETAILS_TAGS = "tags"; - String HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET = BRACKET_OPEN + - HAS_AUTH_PREFIX + SpPermission.READ_DISTRIBUTION_SET + HAS_AUTH_SUFFIX + - HAS_AUTH_AND + - HAS_AUTH_PREFIX + SpPermission.READ_TARGET + HAS_AUTH_SUFFIX + - BRACKET_CLOSE; - @Override default String permissionGroup() { - return "TARGET"; + return SpPermission.TARGET; } /** @@ -86,7 +76,7 @@ public interface TargetManagement * @return controller attributes as key/value pairs * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Map getControllerAttributes(@NotEmpty String controllerId); /** @@ -98,7 +88,7 @@ public interface TargetManagement * @param targetFilterQuery to execute * @return true if it matches */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable( @NotNull String controllerId, long distributionSetId, @NotNull String targetFilterQuery); @@ -108,7 +98,7 @@ public interface TargetManagement * @param controllerIDs to look for. * @return List of found{@link Target}s */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) List getByControllerId(@NotEmpty Collection controllerIDs); /** @@ -118,15 +108,15 @@ public interface TargetManagement * @param detailsKey the key of the details to include, e.g. {@link #DETAILS_AUTO_CONFIRMATION_STATUS} * @return {@link Target} */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Target getWithDetails(@NotEmpty String controllerId, String detailsKey); - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) default Target getWithDetails(@NotEmpty String controllerId) { return getWithDetails(controllerId, DETAILS_BASE); } - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) default Target getWithAutoConfigurationStatus(@NotEmpty String controllerId) { return getWithDetails(controllerId, DETAILS_AUTO_CONFIRMATION_STATUS); } @@ -141,7 +131,7 @@ public interface TargetManagement * @return a page of the found {@link Target}s * @throws EntityNotFoundException if distribution set with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) Slice findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable( long distributionSetId, @NotNull String rsql, @NotNull Pageable pageable); @@ -155,7 +145,7 @@ public interface TargetManagement * @param pageable the pageable to enhance the query for paging and sorting * @return a page of the found {@link Target}s */ - @PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT) Slice findByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable( @NotEmpty Collection groups, @NotNull String rsql, @NotNull DistributionSetType distributionSetType, @NotNull Pageable pageable); @@ -169,11 +159,11 @@ public interface TargetManagement * @param pageable the pageable to enhance the query for paging and sorting * @return a page of the found {@link Target}s */ - @PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT) Slice findByFailedRolloutAndNotInRolloutGroups( @NotNull String rolloutId, @NotEmpty Collection groups, @NotNull Pageable pageable); - @PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT) Slice findByRsqlAndNoOverridingActionsAndNotInRolloutAndCompatibleAndUpdatable( final long rolloutId, @NotNull String rsql, @NotNull DistributionSetType distributionSetType, @NotNull Pageable pageable); @@ -185,7 +175,7 @@ public interface TargetManagement * @return the found {@link Target}s * @throws EntityNotFoundException if rollout group with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Slice findByInRolloutGroupWithoutAction(long group, @NotNull Pageable pageable); /** @@ -196,7 +186,7 @@ public interface TargetManagement * @return the found {@link Target}s * @throws EntityNotFoundException if distribution set with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) Page findByAssignedDistributionSet(long distributionSetId, @NotNull Pageable pageable); /** @@ -211,7 +201,7 @@ public interface TargetManagement * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws EntityNotFoundException if distribution set with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) Page findByAssignedDistributionSetAndRsql(long distributionSetId, @NotNull String rsql, @NotNull Pageable pageable); /** @@ -223,7 +213,7 @@ public interface TargetManagement * compatible with * @return the found number of{@link Target}s */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) long countByRsqlAndCompatible(@NotEmpty String rsql, @NotNull Long distributionSetIdTypeId); /** @@ -234,7 +224,7 @@ public interface TargetManagement * @param dsTypeId ID of the {@link DistributionSetType} the targets need to be compatible with * @return the found number of{@link Target}s */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) long countByFailedInRollout(@NotEmpty String rolloutId, @NotNull Long dsTypeId); /** @@ -246,7 +236,7 @@ public interface TargetManagement * @return the count of found {@link Target}s * @throws EntityNotFoundException if distribution set with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) long countByRsqlAndNonDsAndCompatibleAndUpdatable(long distributionSetId, @NotNull String rsql); /** @@ -258,7 +248,7 @@ public interface TargetManagement * @param distributionSetType type of the {@link DistributionSet} the targets must be compatible with * @return count of the found {@link Target}s */ - @PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT) long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable( @NotNull String rsql, @NotEmpty Collection groups, @NotNull DistributionSetType distributionSetType); @@ -270,10 +260,10 @@ public interface TargetManagement * @param groups the list of {@link RolloutGroup}s * @return count of the found {@link Target}s */ - @PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT) long countByFailedRolloutAndNotInRolloutGroups(@NotNull String rolloutId, @NotEmpty Collection groups); - @PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) + @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT) long countByActionsInRolloutGroup(final long rolloutGroupId); /** @@ -282,7 +272,7 @@ public interface TargetManagement * @param controllerId to look for. * @return {@link Target} */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Optional getByControllerId(@NotEmpty String controllerId); /** @@ -293,7 +283,7 @@ public interface TargetManagement * @return the found {@link Target}s * @throws EntityNotFoundException if distribution set with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) Page findByInstalledDistributionSet(long distributionSetId, @NotNull Pageable pageReq); /** @@ -309,7 +299,7 @@ public interface TargetManagement * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws EntityNotFoundException if distribution set with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) + @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET) Page findByInstalledDistributionSetAndRsql(long distributionSetId, @NotNull String rsql, @NotNull Pageable pageReq); /** @@ -320,7 +310,7 @@ public interface TargetManagement * @return list of matching targets * @throws EntityNotFoundException if target tag with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Page findByTag(long tagId, @NotNull Pageable pageable); /** @@ -335,7 +325,7 @@ public interface TargetManagement * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Page findByRsqlAndTag(@NotNull String rsql, long tagId, @NotNull Pageable pageable); @@ -345,7 +335,7 @@ public interface TargetManagement * @param controllerId the controller ID of the target to be deleted * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(HAS_AUTH_DELETE_TARGET) + @PreAuthorize(HAS_DELETE_REPOSITORY) void deleteByControllerId(@NotEmpty String controllerId); /** @@ -356,7 +346,7 @@ public interface TargetManagement * @return the unassigned target * @throws EntityNotFoundException if TargetType with given target ID does not exist */ - @PreAuthorize(HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) Target assignType(@NotEmpty String controllerId, @NotNull Long targetTypeId); /** @@ -365,7 +355,7 @@ public interface TargetManagement * @param controllerId to un-assign for * @return the unassigned target */ - @PreAuthorize(HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) Target unassignType(@NotEmpty String controllerId); /** @@ -377,7 +367,7 @@ public interface TargetManagement * @return list of assigned targets * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist */ - @PreAuthorize(HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) List assignTag(@NotEmpty Collection controllerIds, long targetTagId, final Consumer> notFoundHandler); /** @@ -388,7 +378,7 @@ public interface TargetManagement * @return list of assigned targets * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist */ - @PreAuthorize(HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) List assignTag(@NotEmpty Collection controllerIds, long targetTagId); /** @@ -398,7 +388,7 @@ public interface TargetManagement * @return the found Tag set * @throws EntityNotFoundException if target with given ID does not exist */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Set getTags(@NotEmpty String controllerId); /** @@ -410,7 +400,7 @@ public interface TargetManagement * @return list of unassigned targets * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist */ - @PreAuthorize(HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) List unassignTag(@NotEmpty Collection controllerIds, long targetTagId, final Consumer> notFoundHandler); /** @@ -421,7 +411,7 @@ public interface TargetManagement * @return list of unassigned targets * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist */ - @PreAuthorize(HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) List unassignTag(@NotEmpty Collection controllerIds, long targetTagId); /** @@ -430,7 +420,7 @@ public interface TargetManagement * @param group target group parameter * @param rsql rsql filter for {@link Target} */ - @PreAuthorize(HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) void assignTargetGroupWithRsql(String group, @NotNull String rsql); /** @@ -439,7 +429,7 @@ public interface TargetManagement * @param group target group parameter * @param controllerIds list of targets */ - @PreAuthorize(HAS_AUTH_UPDATE_TARGET) + @PreAuthorize(HAS_UPDATE_REPOSITORY) void assignTargetsWithGroup(String group, @NotEmpty List controllerIds); /** @@ -450,7 +440,7 @@ public interface TargetManagement * @param pageable - page parameter * @return all matching targets to provided group/subgroup */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) Page findTargetsByGroup(@NotEmpty String group, boolean withSubgroups, @NotNull Pageable pageable); /** @@ -458,7 +448,7 @@ public interface TargetManagement * * @return list of all distinct target groups */ - @PreAuthorize(HAS_AUTH_READ_TARGET) + @PreAuthorize(HAS_READ_REPOSITORY) List findGroups(); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTagManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTagManagement.java index e6eb83bf1..32aa3f3be 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTagManagement.java @@ -16,6 +16,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.TargetTag; @@ -28,7 +29,7 @@ public interface TargetTagManagement @Override default String permissionGroup() { - return "TARGET"; + return SpPermission.TARGET; } @SuperBuilder diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTypeManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTypeManagement.java index 34b5df12c..ee7f6baeb 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetTypeManagement.java @@ -9,12 +9,7 @@ */ package org.eclipse.hawkbit.repository; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_OPEN; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_AND; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_PREFIX; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_TARGET_TYPE; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_SUFFIX; +import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY; import java.util.Collection; import java.util.Collections; @@ -30,6 +25,7 @@ import lombok.Getter; import lombok.ToString; import lombok.experimental.SuperBuilder; import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.TargetTypeKeyOrNameRequiredException; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.NamedEntity; @@ -43,29 +39,25 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface TargetTypeManagement extends RepositoryManagement { - String HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE = BRACKET_OPEN + - HAS_AUTH_PREFIX + SpPermission.READ_DISTRIBUTION_SET + HAS_AUTH_SUFFIX + - HAS_AUTH_AND + - HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET_TYPE + HAS_AUTH_SUFFIX + - BRACKET_CLOSE; + String HAS_UPDATE_TARGET_TYPE_AND_READ_DISTRIBUTION_SET = SpringEvalExpressions.HAS_UPDATE_REPOSITORY + " and hasAuthority('READ_" + SpPermission.DISTRIBUTION_SET + "')"; @Override default String permissionGroup() { - return "TARGET_TYPE"; + return SpPermission.TARGET_TYPE; } /** * @param key as {@link TargetType#getKey()} * @return {@link TargetType} */ - @PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) + @PreAuthorize(HAS_READ_REPOSITORY) Optional getByKey(@NotEmpty String key); /** * @param name as {@link TargetType#getName()} * @return {@link TargetType} */ - @PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) + @PreAuthorize(HAS_READ_REPOSITORY) Optional getByName(@NotEmpty String name); /** @@ -73,7 +65,7 @@ public interface TargetTypeManagement * @param distributionSetTypeIds Distribution set ID * @return Target type */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE) + @PreAuthorize(HAS_UPDATE_TARGET_TYPE_AND_READ_DISTRIBUTION_SET) TargetType assignCompatibleDistributionSetTypes(long id, @NotEmpty Collection distributionSetTypeIds); /** @@ -81,7 +73,7 @@ public interface TargetTypeManagement * @param distributionSetTypeIds Distribution set ID * @return Target type */ - @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE) + @PreAuthorize(HAS_UPDATE_TARGET_TYPE_AND_READ_DISTRIBUTION_SET) TargetType unassignDistributionSetType(long id, long distributionSetTypeIds); @SuperBuilder diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index a221da546..b874f4cf2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -13,6 +13,7 @@ import java.io.Serializable; import java.util.Map; import java.util.function.Function; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException; import org.eclipse.hawkbit.repository.model.PollStatus; @@ -25,7 +26,12 @@ import org.springframework.security.access.prepost.PreAuthorize; /** * Management service for tenant configurations. */ -public interface TenantConfigurationManagement { +public interface TenantConfigurationManagement extends PermissionSupport { + + @Override + default String permissionGroup() { + return SpPermission.TENANT_CONFIGURATION; + } /** * Adds or updates a specific configuration for a specific tenant. @@ -37,7 +43,7 @@ public interface TenantConfigurationManagement { * format defined by the Key * @throws ConversionFailedException if the property cannot be converted to the given */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_UPDATE_REPOSITORY) TenantConfigurationValue addOrUpdateConfiguration(String configurationKeyName, T value); /** @@ -49,7 +55,7 @@ public interface TenantConfigurationManagement { * match the expected type and format defined by the Key * @throws ConversionFailedException if the property cannot be converted to the given */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_UPDATE_REPOSITORY) Map> addOrUpdateConfiguration(Map configurations); /** @@ -58,7 +64,7 @@ public interface TenantConfigurationManagement { * * @param configurationKey the configuration key to be deleted */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_DELETE_REPOSITORY) void deleteConfiguration(String configurationKey); /** @@ -76,7 +82,7 @@ public interface TenantConfigurationManagement { * @throws ConversionFailedException if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) + @PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY) TenantConfigurationValue getConfigurationValue(String configurationKeyName); /** @@ -97,7 +103,7 @@ public interface TenantConfigurationManagement { * @throws ConversionFailedException if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) + @PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY) TenantConfigurationValue getConfigurationValue(String configurationKeyName, Class propertyType); @@ -116,9 +122,9 @@ public interface TenantConfigurationManagement { * @throws ConversionFailedException if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) + @PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY) T getGlobalConfigurationValue(String configurationKeyName, Class propertyType); - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_READ_TARGET) + @PreAuthorize(value = "hasAuthority('READ_" + SpPermission.TARGET + "')") Function pollStatusResolver(); -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java index f213ca117..af83e363c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java @@ -9,6 +9,7 @@ */ package org.eclipse.hawkbit.repository; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.springframework.security.access.prepost.PreAuthorize; @@ -24,11 +25,8 @@ public interface TenantStatsManagement { * * @return collected statistics */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize("hasAuthority('" + SpRole.TENANT_ADMIN + "')" + " or " + + SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + " or " + + SpringEvalExpressions.IS_SYSTEM_CODE) TenantUsage getStatsOfTenant(); - -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java index e08d4a81e..02c886423 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java @@ -62,11 +62,11 @@ public class RepositoryConfiguration { @Override public boolean hasPermission(final Authentication authentication, final Object targetDomainObject, final Object permission) { - if (targetDomainObject instanceof MethodSecurityExpressionOperations root) { - final String neededPermission = - permission + "_" + (root.getThis() instanceof PermissionSupport permissionSupport - ? permissionSupport.permissionGroup() - : "REPOSITORY"); // TODO - should not fall back here - all using permissions should extend repository management interface + if (targetDomainObject instanceof MethodSecurityExpressionOperations root && + root.getThis() instanceof PermissionSupport permissionSupport) { + final String neededPermission = permission + "_" + permissionSupport.permissionGroup(); + + // do permissions check final boolean hasPermission = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities()).stream() .map(GrantedAuthority::getAuthority) .anyMatch(authority -> authority.equals(neededPermission)); @@ -75,9 +75,11 @@ public class RepositoryConfiguration { "User {} does not have permission {} for target {}", authentication.getName(), neededPermission, targetDomainObject); } + return hasPermission; + } else { + return super.hasPermission(authentication, targetDomainObject, permission); } - return super.hasPermission(authentication, targetDomainObject, permission); } }; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java index 02e1dad0c..a5760f49d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRepositoryConfiguration.java @@ -374,11 +374,11 @@ public class JpaRepositoryConfiguration { final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy, final EntityManager entityManager, final PlatformTransactionManager txManager, final AfterTransactionCommitExecutor afterCommit, - final TenantAware tenantAware, final RepositoryProperties repositoryProperties) { + final TenantAware tenantAware, final ContextAware contextAware, final RepositoryProperties repositoryProperties) { return new JpaRolloutExecutor(actionRepository, rolloutGroupRepository, rolloutTargetGroupRepository, rolloutRepository, targetManagement, deploymentManagement, rolloutGroupManagement, rolloutManagement, quotaManagement, evaluationManager, rolloutApprovalStrategy, entityManager, txManager, afterCommit, - tenantAware, repositoryProperties); + tenantAware, contextAware, repositoryProperties); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java index 9cfd51c1f..c02689a06 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java @@ -22,6 +22,7 @@ import java.util.stream.StreamSupport; import jakarta.persistence.EntityManager; import lombok.extern.slf4j.Slf4j; +import org.eclipse.hawkbit.ContextAware; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.RepositoryProperties; @@ -112,6 +113,7 @@ public class JpaRolloutExecutor implements RolloutExecutor { private final PlatformTransactionManager txManager; private final AfterTransactionCommitExecutor afterCommit; private final TenantAware tenantAware; + private final ContextAware contextAware; private final RepositoryProperties repositoryProperties; private final Map lastDynamicGroupFill = new ConcurrentHashMap<>(); @@ -125,7 +127,7 @@ public class JpaRolloutExecutor implements RolloutExecutor { final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy, final EntityManager entityManager, final PlatformTransactionManager txManager, final AfterTransactionCommitExecutor afterCommit, - final TenantAware tenantAware, final RepositoryProperties repositoryProperties) { + final TenantAware tenantAware, final ContextAware contextAware, final RepositoryProperties repositoryProperties) { this.actionRepository = actionRepository; this.rolloutGroupRepository = rolloutGroupRepository; this.rolloutTargetGroupRepository = rolloutTargetGroupRepository; @@ -141,11 +143,23 @@ public class JpaRolloutExecutor implements RolloutExecutor { this.txManager = txManager; this.afterCommit = afterCommit; this.tenantAware = tenantAware; + this.contextAware = contextAware; this.repositoryProperties = repositoryProperties; } @Override public void execute(final Rollout rollout) { + rollout.getAccessControlContext().ifPresentOrElse( + context -> // has stored context - executes it with it + contextAware.runInContext(context, () -> execute0(rollout)), + () -> // has no stored context - executes it in the tenant & user scope + contextAware.runAsTenantAsUser(contextAware.getCurrentTenant(), rollout.getCreatedBy(), () -> { + execute0(rollout); + return null; + })); + } + + private void execute0(final Rollout rollout) { log.debug("Processing rollout {}", rollout.getId()); switch (rollout.getStatus()) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutHandler.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutHandler.java index 70723ec6d..1bf35f3fe 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutHandler.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutHandler.java @@ -112,22 +112,8 @@ public class JpaRolloutHandler implements RolloutHandler { DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId, status -> { rolloutManagement.get(rolloutId).ifPresentOrElse( - rollout -> - // auditor is retrieved and set on transaction commit if not overridden, the system user will be the auditor - rollout.getAccessControlContext().ifPresentOrElse( - context -> // has stored context - executes it with it - contextAware.runInContext( - context, - () -> rolloutExecutor.execute(rollout)), - () -> // has no stored context - executes it in the tenant & user scope - contextAware.runAsTenantAsUser( - contextAware.getCurrentTenant(), - rollout.getCreatedBy(), () -> { - rolloutExecutor.execute(rollout); - return null; - })), - () -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.", - rolloutId)); + rolloutExecutor::execute, + () -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.", rolloutId)); return 0L; }); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementSecurityTest.java index 5d5af16da..cd1fe3d74 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementSecurityTest.java @@ -13,7 +13,7 @@ import java.io.ByteArrayInputStream; import java.util.List; import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.ArtifactUpload; import org.eclipse.hawkbit.repository.test.util.WithUser; @@ -60,7 +60,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void getPermissionCheck() { assertPermissions(() -> artifactManagement.get(1L), List.of(SpPermission.READ_REPOSITORY)); - assertPermissions(() -> artifactManagement.get(1L), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + assertPermissions(() -> artifactManagement.get(1L), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } /** @@ -71,7 +71,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest { assertPermissions(() -> artifactManagement.getByFilenameAndSoftwareModule("filename", 1L), List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY)); assertPermissions(() -> artifactManagement.getByFilenameAndSoftwareModule("filename", 1L), - List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } /** @@ -80,7 +80,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void findFirstBySHA1PermissionCheck() { assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpPermission.READ_REPOSITORY)); - assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } /** @@ -89,7 +89,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void getByFilenamePermissionCheck() { assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpPermission.READ_REPOSITORY)); - assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } /** @@ -114,7 +114,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void loadArtifactBinaryPermissionCheck() { assertPermissions(() -> artifactManagement.loadArtifactBinary("sha1", 1L, false), List.of(SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT), List.of(SpPermission.CREATE_REPOSITORY)); - assertPermissions(() -> artifactManagement.loadArtifactBinary("sha1", 1L, false), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + assertPermissions(() -> artifactManagement.loadArtifactBinary("sha1", 1L, false), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } } \ No newline at end of file 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 bd798a783..48a0c20f4 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 @@ -27,6 +27,7 @@ import java.util.concurrent.Callable; import jakarta.validation.ConstraintViolationException; import org.apache.commons.io.IOUtils; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.repository.artifact.model.DbArtifact; import org.eclipse.hawkbit.repository.artifact.model.DbArtifactHash; import org.eclipse.hawkbit.im.authentication.SpPermission; @@ -425,7 +426,8 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest { * Trys and fails to load an artifact without required permission. Checks if expected InsufficientPermissionException is thrown. */ @Test - @WithUser(allSpPermissions = true, removeFromAllPermission = { SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT }) + @WithUser(allSpPermissions = true, removeFromAllPermission = { + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT, SpRole.CONTROLLER_ROLE, SpRole.CONTROLLER_ROLE_ANONYMOUS }) void loadArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() { assertThatExceptionOfType(InsufficientPermissionException.class) .as("Should not have worked with missing permission.") diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementSecurityTest.java index 21aa966a0..ae311ed8f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementSecurityTest.java @@ -12,7 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.management; import java.util.List; import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; +import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.junit.jupiter.api.Test; @@ -46,7 +46,7 @@ class ConfirmationManagementSecurityTest extends AbstractJpaIntegrationTest { void getStatusPermissionsCheck() { assertPermissions(() -> confirmationManagement.getStatus("controllerId"), List.of(SpPermission.READ_TARGET), List.of(SpPermission.CREATE_TARGET)); - assertPermissions(() -> confirmationManagement.getStatus("controllerId"), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_TARGET)); + assertPermissions(() -> confirmationManagement.getStatus("controllerId"), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_TARGET)); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementSecurityTest.java index 0777abf48..41574b85c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementSecurityTest.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.Map; import org.eclipse.hawkbit.im.authentication.SpRole; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; @@ -37,7 +36,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { void addCancelActionStatusPermissionsCheck() { assertPermissions(() -> controllerManagement.addCancelActionStatus( ActionStatusCreate.builder().actionId(0L).status(Action.Status.DOWNLOADED).build()), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -45,7 +44,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { */ @Test void getSoftwareModulePermissionsCheck() { - assertPermissions(() -> controllerManagement.getSoftwareModule(1L), List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + assertPermissions(() -> controllerManagement.getSoftwareModule(1L), List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -54,7 +53,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void findTargetVisibleMetaDataBySoftwareModuleIdPermissionsCheck() { assertPermissions(() -> controllerManagement.findTargetVisibleMetaDataBySoftwareModuleId(List.of(1L)), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -64,7 +63,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { void addInformationalActionStatusPermissionsCheck() { assertPermissions(() -> controllerManagement.addInformationalActionStatus( ActionStatusCreate.builder().actionId(0L).status(Action.Status.DOWNLOADED).build()), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -74,7 +73,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { void addUpdateActionStatusPermissionsCheck() { assertPermissions(() -> controllerManagement.addUpdateActionStatus( ActionStatusCreate.builder().actionId(0L).status(Action.Status.DOWNLOADED).build()), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -83,7 +82,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void findActiveActionWithHighestWeightPermissionsCheck() { assertPermissions(() -> controllerManagement.findActiveActionWithHighestWeight("controllerId"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -92,7 +91,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void findActiveActionsWithHighestWeightPermissionsCheck() { assertPermissions(() -> controllerManagement.findActiveActionsWithHighestWeight("controllerId", 1), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -100,7 +99,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { */ @Test void findActionWithDetailsPermissionsCheck() { - assertPermissions(() -> controllerManagement.findActionWithDetails(1L), List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + assertPermissions(() -> controllerManagement.findActionWithDetails(1L), List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -109,7 +108,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void findActionStatusByActionPermissionsCheck() { assertPermissions(() -> controllerManagement.findActionStatusByAction(1L, Pageable.unpaged()), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -118,7 +117,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void findOrRegisterTargetIfItDoesNotExistPermissionsCheck() { assertPermissions(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("controllerId", URI.create("someaddress")), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -128,7 +127,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { void findOrRegisterTargetIfItDoesNotExistWithDetailsPermissionsCheck() { assertPermissions( () -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("controllerId", URI.create("someaddress"), "name", "type"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -137,7 +136,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void getActionForDownloadByTargetAndSoftwareModulePermissionsCheck() { assertPermissions(() -> controllerManagement.getActionForDownloadByTargetAndSoftwareModule("controllerId", 1L), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -145,7 +144,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { */ @Test void getPollingTimePermissionsCheck() { - assertPermissions(() -> controllerManagement.getPollingTime(null), List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + assertPermissions(() -> controllerManagement.getPollingTime(null), List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -162,7 +161,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { // expected since action is not found } return null; - }, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + }, List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -171,7 +170,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void hasTargetArtifactAssignedPermissionsCheck() { assertPermissions(() -> controllerManagement.hasTargetArtifactAssigned("controllerId", "sha1Hash"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -180,7 +179,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void hasTargetArtifactAssignedByIdPermissionsCheck() { assertPermissions(() -> controllerManagement.hasTargetArtifactAssigned(1L, "sha1Hash"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -189,7 +188,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void updateControllerAttributesPermissionsCheck() { assertPermissions(() -> controllerManagement.updateControllerAttributes("controllerId", Map.of(), null), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -198,7 +197,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void getByControllerIdPermissionsCheck() { assertPermissions(() -> controllerManagement.getByControllerId("controllerId"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); assertPermissions(() -> controllerManagement.getByControllerId("controllerId"), List.of(SpRole.SYSTEM_ROLE)); } @@ -208,7 +207,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { */ @Test void getPermissionsCheck() { - assertPermissions(() -> controllerManagement.get(1L), List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + assertPermissions(() -> controllerManagement.get(1L), List.of(SpRole.CONTROLLER_ROLE)); assertPermissions(() -> controllerManagement.get(1L), List.of(SpRole.SYSTEM_ROLE)); } @@ -218,7 +217,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void getActionHistoryMessagesPermissionsCheck() { assertPermissions(() -> controllerManagement.getActionHistoryMessages(1L, 1), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -235,7 +234,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { // expected since action is not found } return null; - }, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + }, List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -246,7 +245,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { assertPermissions(() -> { controllerManagement.updateActionExternalRef(1L, "externalRef"); return null; - }, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + }, List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -255,7 +254,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void getActionByExternalRefPermissionsCheck() { assertPermissions(() -> controllerManagement.getActionByExternalRef("externalRef"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -266,7 +265,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { assertPermissions(() -> { controllerManagement.deleteExistingTarget("controllerId"); return null; - }, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + }, List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -277,7 +276,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { final Target target = testdataFactory.createTarget(); assertPermissions( () -> controllerManagement.getInstalledActionByTarget(target), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -287,7 +286,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { void activateAutoConfirmationPermissionsCheck() { assertPermissions( () -> controllerManagement.activateAutoConfirmation("controllerId", "initiator", "remark"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -298,7 +297,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { assertPermissions(() -> { controllerManagement.deactivateAutoConfirmation("controllerId"); return null; - }, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + }, List.of(SpRole.CONTROLLER_ROLE)); } /** @@ -307,7 +306,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest { @Test void updateOfflineAssignedVersionPermissionsCheck() { assertPermissions(() -> controllerManagement.updateOfflineAssignedVersion("controllerId", "distributionName", "version"), - List.of(SpringEvalExpressions.CONTROLLER_ROLE)); + List.of(SpRole.CONTROLLER_ROLE)); } } \ No newline at end of file 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 e8a255399..825c6835d 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 @@ -12,8 +12,8 @@ package org.eclipse.hawkbit.repository.jpa.management; 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.im.authentication.SpringEvalExpressions.CONTROLLER_ROLE; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS; +import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE; +import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS; import static org.eclipse.hawkbit.repository.jpa.configuration.Constants.TX_RT_MAX; import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java index 4385d8713..3c91d36a4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java @@ -55,7 +55,8 @@ class DeploymentManagementSecurityTest extends AbstractJpaIntegrationTest { */ @Test void offlineAssignedDistributionSetsPermissionsCheck() { - assertPermissions(() -> deploymentManagement.offlineAssignedDistributionSets(List.of()), List.of(SpPermission.READ_REPOSITORY)); + assertPermissions(() -> deploymentManagement.offlineAssignedDistributionSets(List.of()), + List.of(SpPermission.READ_REPOSITORY, SpPermission.UPDATE_TARGET)); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SystemManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SystemManagementSecurityTest.java index 0f0649e44..16c6bc701 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SystemManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SystemManagementSecurityTest.java @@ -14,7 +14,6 @@ import java.util.List; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpRole; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.junit.jupiter.api.Test; @@ -79,7 +78,7 @@ class SystemManagementSecurityTest extends AbstractJpaIntegrationTest { assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY)); assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpPermission.READ_TARGET), List.of(SpPermission.CREATE_REPOSITORY)); assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpPermission.READ_TENANT_CONFIGURATION), List.of(SpPermission.CREATE_REPOSITORY)); - assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } /** @@ -90,7 +89,7 @@ class SystemManagementSecurityTest extends AbstractJpaIntegrationTest { assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY)); assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpPermission.READ_TARGET), List.of(SpPermission.CREATE_REPOSITORY)); assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpPermission.READ_TENANT_CONFIGURATION), List.of(SpPermission.CREATE_REPOSITORY)); - assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); + assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY)); } /** diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index a98da7922..2d97d8444 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -12,7 +12,7 @@ package org.eclipse.hawkbit.repository.test.util; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TENANT_CONFIGURATION; import static org.eclipse.hawkbit.im.authentication.SpRole.SYSTEM_ROLE; -import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.CONTROLLER_ROLE; +import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE; import java.io.File; import java.io.IOException; diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java index c72848bc4..f98ef8620 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java @@ -45,10 +45,10 @@ public class SecurityContextSwitch { public static T callAs(final WithUser withUser, final Callable callable) throws Exception { final SecurityContext oldContext = SecurityContextHolder.getContext(); setSecurityContext(withUser); - if (withUser.autoCreateTenant()) { - createTenant(withUser.tenantId()); - } try { + if (withUser.autoCreateTenant()) { + createTenant(withUser.tenantId()); + } return callable.call(); } finally { SecurityContextHolder.setContext(oldContext); diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index bde8facc5..8eab32a04 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -36,25 +36,38 @@ import org.springframework.util.function.SingletonSupplier; @Slf4j public final class SpPermission { - public static final String CREATE_TARGET = "CREATE_TARGET"; - public static final String READ_TARGET = "READ_TARGET"; - public static final String UPDATE_TARGET = "UPDATE_TARGET"; - public static final String DELETE_TARGET = "DELETE_TARGET"; + // Permission prefixes + public static final String CREATE_PREFIX = "CREATE_"; + public static final String READ_PREFIX = "READ_"; + public static final String UPDATE_PREFIX = "UPDATE_"; + public static final String DELETE_PREFIX = "DELETE_"; + + // Permission groups + public static final String TARGET = "TARGET"; + public static final String TARGET_TYPE = "TARGET_TYPE"; + public static final String SOFTWARE_MODULE = "SOFTWARE_MODULE"; + public static final String DISTRIBUTION_SET = "DISTRIBUTION_SET"; + public static final String ROLLOUT = "ROLLOUT"; + public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION"; + + public static final String CREATE_TARGET = CREATE_PREFIX + TARGET; + public static final String READ_TARGET = READ_PREFIX + TARGET; + public static final String UPDATE_TARGET = UPDATE_PREFIX + TARGET; + public static final String DELETE_TARGET = DELETE_PREFIX + TARGET; /** * Permission to read the target security token. The security token is security * concerned and should be protected. So the combination * {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to * be able to read the security token of a target. */ - public static final String READ_TARGET_SEC_TOKEN = "READ_TARGET_SECURITY_TOKEN"; + public static final String READ_TARGET_SEC_TOKEN = READ_TARGET + "_SECURITY_TOKEN"; - public static final String CREATE_TARGET_TYPE = "CREATE_TARGET_TYPE"; - public static final String READ_TARGET_TYPE = "READ_TARGET_TYPE"; - public static final String UPDATE_TARGET_TYPE = "UPDATE_TARGET_TYPE"; - public static final String DELETE_TARGET_TYPE = "DELETE_TARGET_TYPE"; + public static final String READ_TARGET_TYPE = READ_PREFIX + TARGET_TYPE; + public static final String UPDATE_TARGET_TYPE = UPDATE_PREFIX + TARGET_TYPE; + public static final String DELETE_TARGET_TYPE = DELETE_PREFIX + TARGET_TYPE; - public static final String READ_DISTRIBUTION_SET = "READ_DISTRIBUTION_SET"; - public static final String UPDATE_DISTRIBUTION_SET = "UPDATE_DISTRIBUTION_SET"; + public static final String READ_DISTRIBUTION_SET = READ_PREFIX + DISTRIBUTION_SET; + public static final String UPDATE_DISTRIBUTION_SET = UPDATE_PREFIX + DISTRIBUTION_SET; public static final String READ_REPOSITORY = "READ_REPOSITORY"; public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY"; @@ -66,7 +79,8 @@ public final class SpPermission { /** * Permission to read the tenant settings. */ - public static final String READ_TENANT_CONFIGURATION = "READ_TENANT_CONFIGURATION"; + public static final String READ_TENANT_CONFIGURATION = READ_PREFIX + TENANT_CONFIGURATION; + /** * Permission to read the gateway security token. The gateway security token is security * concerned and should be protected. So in addition to {@linkplain #READ_TENANT_CONFIGURATION}, @@ -74,19 +88,15 @@ public final class SpPermission { * implies both permissions - so it is sufficient to read the gateway security token. */ public static final String READ_GATEWAY_SEC_TOKEN = "READ_GATEWAY_SECURITY_TOKEN"; - /** - * Permission to administrate the tenant settings. - */ - public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION"; - public static final String CREATE_ROLLOUT = "CREATE_ROLLOUT"; - public static final String READ_ROLLOUT = "READ_ROLLOUT"; - public static final String UPDATE_ROLLOUT = "UPDATE_ROLLOUT"; - public static final String DELETE_ROLLOUT = "DELETE_ROLLOUT"; + public static final String CREATE_ROLLOUT = CREATE_PREFIX + ROLLOUT; + public static final String READ_ROLLOUT = READ_PREFIX + ROLLOUT; + public static final String UPDATE_ROLLOUT = UPDATE_PREFIX + ROLLOUT; + public static final String DELETE_ROLLOUT = DELETE_PREFIX + ROLLOUT; /** Permission to approve or deny a rollout prior to starting. */ - public static final String APPROVE_ROLLOUT = "APPROVE_ROLLOUT"; + public static final String APPROVE_ROLLOUT = "APPROVE_" + ROLLOUT; /** Permission to start/stop/resume a rollout. */ - public static final String HANDLE_ROLLOUT = "HANDLE_ROLLOUT"; + public static final String HANDLE_ROLLOUT = "HANDLE_" + ROLLOUT; /** Permission to administrate the system on a global, i.e. tenant independent scale. That includes the deletion of tenants. */ public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN"; @@ -108,7 +118,10 @@ public final class SpPermission { DELETE_REPOSITORY > DELETE_SOFTWARE_MODULE """; public static final String TENANT_CONFIGURATION_HIERARCHY = """ + TENANT_CONFIGURATION > CREATE_TENANT_CONFIGURATION TENANT_CONFIGURATION > READ_TENANT_CONFIGURATION + TENANT_CONFIGURATION > UPDATE_TENANT_CONFIGURATION + TENANT_CONFIGURATION > DELETE_TENANT_CONFIGURATION TENANT_CONFIGURATION > READ_GATEWAY_SECURITY_TOKEN """; diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java index 415e85416..376d531bb 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java @@ -25,10 +25,12 @@ public final class SpRole { public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN"; public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN"; - /** - * The role which contains the spring security context in case the system is executing code which is necessary to be privileged. - */ + /** The role which contains the spring security context in case the system is executing code which is necessary to be privileged. */ 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-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpringEvalExpressions.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpringEvalExpressions.java index 1eb0db066..c45d7a2e4 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpringEvalExpressions.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpringEvalExpressions.java @@ -36,35 +36,8 @@ import org.springframework.security.access.prepost.PreAuthorize; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class SpringEvalExpressions { - public static final String BRACKET_OPEN = "("; - public static final String BRACKET_CLOSE = ")"; - 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_AND = " and "; - public static final String HAS_AUTH_OR = " or "; - - /** - * The role which contains in the spring security context in case ancontroller 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"; - - public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SpRole.SYSTEM_ROLE + HAS_AUTH_SUFFIX; - - public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SpPermission.SYSTEM_ADMIN + HAS_AUTH_SUFFIX; - - public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + SpPermission.CREATE_TARGET + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + SpPermission.READ_TARGET + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + SpPermission.DELETE_TARGET + HAS_AUTH_SUFFIX; - - public static final String HAS_AUTH_CREATE_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.CREATE_TARGET_TYPE + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_UPDATE_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET_TYPE + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_READ_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.READ_TARGET_TYPE + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_DELETE_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.DELETE_TARGET_TYPE + HAS_AUTH_SUFFIX; + public static final String IS_SYSTEM_CODE = "hasAuthority('ROLE_SYSTEM_CODE')"; + public static final String HAS_AUTH_SYSTEM_ADMIN = "hasAuthority('SYSTEM_ADMIN')"; // evaluated to _ (e.g. DISTRIBUTION_SET_CREATE) public static final String HAS_CREATE_REPOSITORY = "hasPermission(#root, 'CREATE')"; @@ -72,25 +45,5 @@ public final class SpringEvalExpressions { public static final String HAS_UPDATE_REPOSITORY = "hasPermission(#root, 'UPDATE')"; public static final String HAS_DELETE_REPOSITORY = "hasPermission(#root, 'DELETE')"; - public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX - + SpPermission.READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET + HAS_AUTH_SUFFIX - + BRACKET_CLOSE; - - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + SpPermission.CREATE_ROLLOUT + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + SpPermission.READ_ROLLOUT + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + SpPermission.UPDATE_ROLLOUT + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + SpPermission.DELETE_ROLLOUT + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE = HAS_AUTH_PREFIX + SpPermission.APPROVE_ROLLOUT + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + SpPermission.HANDLE_ROLLOUT + HAS_AUTH_SUFFIX; - - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX - + SpPermission.READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + SpPermission.READ_TARGET + HAS_AUTH_SUFFIX - + BRACKET_CLOSE; - - public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + SpPermission.READ_TENANT_CONFIGURATION + HAS_AUTH_SUFFIX; - public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + SpPermission.TENANT_CONFIGURATION + HAS_AUTH_SUFFIX; - - public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE + "')"; - public static final String IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = IS_CONTROLLER + HAS_AUTH_OR + HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET; + public static final String IS_CONTROLLER = "hasAnyRole('" + SpRole.CONTROLLER_ROLE_ANONYMOUS + "', '" + SpRole.CONTROLLER_ROLE + "')"; } \ No newline at end of file diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index 167161f22..cb736d04e 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -24,7 +24,6 @@ import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.im.authentication.SpRole; -import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; @@ -107,7 +106,7 @@ public class SystemSecurityContext { */ public T runAsControllerAsTenant(@NotEmpty final String tenant, @NotNull final Callable callable) { final SecurityContext oldContext = SecurityContextHolder.getContext(); - final List authorities = List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)); + final List authorities = List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE_ANONYMOUS)); try { return tenantAware.runAsTenant(tenant, () -> { setCustomSecurityContext(tenant, oldContext.getAuthentication().getPrincipal(), authorities);