Improve Permission Management (#2604)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-08-12 14:09:27 +03:00
committed by GitHub
parent 5b299e0a62
commit 441b78460d
40 changed files with 361 additions and 351 deletions

View File

@@ -10,7 +10,7 @@
package org.eclipse.hawkbit.ddi.rest.resource; package org.eclipse.hawkbit.ddi.rest.resource;
import static org.assertj.core.api.Assertions.assertThat; 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.im.authentication.SpPermission.TENANT_CONFIGURATION;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs;

View File

@@ -14,7 +14,7 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import lombok.EqualsAndHashCode; 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.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -77,7 +77,7 @@ public interface Authenticator {
private static class AuthenticatedController extends AbstractAuthenticationToken { private static class AuthenticatedController extends AbstractAuthenticationToken {
private static final Collection<GrantedAuthority> CONTROLLER_AUTHORITY = private static final Collection<GrantedAuthority> CONTROLLER_AUTHORITY =
List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE));
private final String controllerId; private final String controllerId;
AuthenticatedController(final String tenant, final String controllerId) { AuthenticatedController(final String tenant, final String controllerId) {

View File

@@ -13,7 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import org.eclipse.hawkbit.im.authentication.SpPermission; 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.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus; 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 * Tests whether request succeed if a role is granted for the user
*/ */
@Test @Test
@WithUser(authorities = { SpringEvalExpressions.CONTROLLER_ROLE }, autoCreateTenant = false) @WithUser(authorities = { SpRole.CONTROLLER_ROLE }, autoCreateTenant = false)
void successIfHasRole() throws Exception { void successIfHasRole() throws Exception {
mvc.perform(get("/DEFAULT/controller/v1/controllerId")) mvc.perform(get("/DEFAULT/controller/v1/controllerId"))
.andExpect(result -> assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); .andExpect(result -> assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value()));

View File

@@ -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.DmfAutoConfirmation;
import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing; import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing;
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode; 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.ConfirmationManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.RepositoryConstants; import org.eclipse.hawkbit.repository.RepositoryConstants;
@@ -192,7 +192,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
private static void setTenantSecurityContext(final String tenantId) { private static void setTenantSecurityContext(final String tenantId) {
final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken( final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken(
UUID.randomUUID().toString(), "AMQP-Controller", 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)); authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenantId, true));
setSecurityContext(authenticationToken); setSecurityContext(authenticationToken);
} }

View File

@@ -16,6 +16,7 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.artifact.model.DbArtifact; import org.eclipse.hawkbit.repository.artifact.model.DbArtifact;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.ArtifactDeleteFailedException; import org.eclipse.hawkbit.repository.exception.ArtifactDeleteFailedException;
@@ -34,11 +35,15 @@ import org.springframework.security.access.prepost.PreAuthorize;
/** /**
* Service for {@link Artifact} management operations. * 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 * @return the total amount of local artifacts stored in the artifact management
* management
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long count(); long count();
@@ -75,8 +80,7 @@ public interface ArtifactManagement {
* @param id to search for * @param id to search for
* @return found {@link Artifact} * @return found {@link Artifact}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER)
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> get(long id); Optional<Artifact> get(long id);
/** /**
@@ -87,8 +91,7 @@ public interface ArtifactManagement {
* @return found {@link Artifact} * @return found {@link Artifact}
* @throws EntityNotFoundException if software module with given ID does not exist * @throws EntityNotFoundException if software module with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER)
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> getByFilenameAndSoftwareModule(@NotNull String filename, long softwareModuleId); Optional<Artifact> getByFilenameAndSoftwareModule(@NotNull String filename, long softwareModuleId);
/** /**
@@ -97,8 +100,7 @@ public interface ArtifactManagement {
* @param sha1 the sha1 * @param sha1 the sha1
* @return the first local artifact * @return the first local artifact
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER)
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> findFirstBySHA1(@NotNull String sha1); Optional<Artifact> findFirstBySHA1(@NotNull String sha1);
/** /**
@@ -107,8 +109,7 @@ public interface ArtifactManagement {
* @param filename to search for * @param filename to search for
* @return found List of {@link Artifact}s. * @return found List of {@link Artifact}s.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER)
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> getByFilename(@NotNull String filename); Optional<Artifact> getByFilename(@NotNull String filename);
/** /**
@@ -140,9 +141,7 @@ public interface ArtifactManagement {
* @param isEncrypted flag to indicate if artifact is encrypted. * @param isEncrypted flag to indicate if artifact is encrypted.
* @return loaded {@link DbArtifact} * @return loaded {@link DbArtifact}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize("hasAuthority('" + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER)
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<DbArtifact> loadArtifactBinary(@NotEmpty String sha1Hash, long softwareModuleId, Optional<DbArtifact> loadArtifactBinary(@NotEmpty String sha1Hash, long softwareModuleId,
final boolean isEncrypted); final boolean isEncrypted);
} }

View File

@@ -15,6 +15,7 @@ import java.util.Optional;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.AutoConfirmationStatus; 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. * 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"; 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. * 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 * @param remark optional field to set a remark
* @return the persisted {@link AutoConfirmationStatus} * @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); 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 code optional value to specify a code for the created action status
* @param messages optional value to specify message 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<String> messages); Action confirmAction(long actionId, Integer code, Collection<String> messages);
/** /**
@@ -56,7 +64,7 @@ public interface ConfirmationManagement {
* @param code optional value to specify a code for the created action status * @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 * @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<String> messages); Action denyAction(long actionId, Integer code, Collection<String> messages);
/** /**
@@ -64,7 +72,7 @@ public interface ConfirmationManagement {
* *
* @param controllerId to disable auto confirmation for * @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); void deactivateAutoConfirmation(@NotEmpty String controllerId);
/** /**
@@ -73,8 +81,7 @@ public interface ConfirmationManagement {
* @param controllerId to check the state for * @param controllerId to check the state for
* @return instance of {@link AutoConfirmationStatus} wrapped in an {@link Optional}. Present if active and empty if disabled. * @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 + @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER)
SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Optional<AutoConfirmationStatus> getStatus(@NotEmpty String controllerId); Optional<AutoConfirmationStatus> getStatus(@NotEmpty String controllerId);
/** /**
@@ -83,6 +90,6 @@ public interface ConfirmationManagement {
* @param controllerId of the target to check * @param controllerId of the target to check
* @return a list of {@link Action} * @return a list of {@link Action}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<Action> findActiveActionsWaitingConfirmation(@NotEmpty String controllerId); List<Action> findActiveActionsWaitingConfirmation(@NotEmpty String controllerId);
} }

View File

@@ -267,7 +267,7 @@ public interface ControllerManagement {
* @return {@link Target} or {@code null} if it does not exist * @return {@link Target} or {@code null} if it does not exist
* @see Target#getControllerId() * @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<Target> getByControllerId(@NotEmpty String controllerId); Optional<Target> getByControllerId(@NotEmpty String controllerId);
/** /**
@@ -279,7 +279,7 @@ public interface ControllerManagement {
* @return {@link Target} or {@code null} if it does not exist * @return {@link Target} or {@code null} if it does not exist
* @see Target#getId() * @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<Target> get(long targetId); Optional<Target> get(long targetId);
/** /**

View File

@@ -19,6 +19,7 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; 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. * 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 * 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 * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same
* target and multi-assignment is disabled * target and multi-assignment is disabled
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET)
List<DistributionSetAssignmentResult> assignDistributionSets(@Valid @NotEmpty List<DeploymentRequest> deploymentRequests); List<DistributionSetAssignmentResult> assignDistributionSets(@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
/** /**
@@ -92,7 +101,7 @@ public interface DeploymentManagement {
* @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same
* target and multi-assignment is disabled * target and multi-assignment is disabled
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET)
List<DistributionSetAssignmentResult> assignDistributionSets( List<DistributionSetAssignmentResult> assignDistributionSets(
String initiatedBy, @Valid @NotEmpty List<DeploymentRequest> deploymentRequests, String actionMessage); String initiatedBy, @Valid @NotEmpty List<DeploymentRequest> deploymentRequests, String actionMessage);
@@ -118,10 +127,10 @@ public interface DeploymentManagement {
* @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same
* target and multi-assignment is disabled * target and multi-assignment is disabled
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET)
List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(String initiatedBy, Collection<Entry<String, Long>> assignments); List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(String initiatedBy, Collection<Entry<String, Long>> assignments);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET)
List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(Collection<Entry<String, Long>> assignments); List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(Collection<Entry<String, Long>> 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 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 * @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); Action cancelAction(long actionId);
/** /**
@@ -147,7 +156,7 @@ public interface DeploymentManagement {
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
* @throws EntityNotFoundException if target with given ID does not exist * @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); long countActionsByTarget(@NotNull String rsql, @NotEmpty String controllerId);
/** /**
@@ -156,7 +165,7 @@ public interface DeploymentManagement {
* *
* @return the total amount of stored actions * @return the total amount of stored actions
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countActionsAll(); long countActionsAll();
/** /**
@@ -166,7 +175,7 @@ public interface DeploymentManagement {
* @param rsql RSQL query. * @param rsql RSQL query.
* @return the total number of actions matching the given 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); long countActions(@NotNull String rsql);
/** /**
@@ -176,7 +185,7 @@ public interface DeploymentManagement {
* @return the count value of found actions associated to the target * @return the count value of found actions associated to the target
* @throws EntityNotFoundException if target with given ID does not exist * @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); long countActionsByTarget(@NotEmpty String controllerId);
/** /**
@@ -185,7 +194,7 @@ public interface DeploymentManagement {
* @param actionId to be id of the action * @param actionId to be id of the action
* @return the corresponding {@link Action} * @return the corresponding {@link Action}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Action> findAction(long actionId); Optional<Action> findAction(long actionId);
/** /**
@@ -196,7 +205,7 @@ public interface DeploymentManagement {
* @param pageable pagination parameter * @param pageable pagination parameter
* @return a paged list of {@link Action}s * @return a paged list of {@link Action}s
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<Action> findActionsAll(@NotNull Pageable pageable); Slice<Action> findActionsAll(@NotNull Pageable pageable);
/** /**
@@ -207,7 +216,7 @@ public interface DeploymentManagement {
* @param pageable the page request parameter for paging and sorting the result * @param pageable the page request parameter for paging and sorting the result
* @return a paged list of {@link Action}s. * @return a paged list of {@link Action}s.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<Action> findActions(@NotNull String rsql, @NotNull Pageable pageable); Slice<Action> findActions(@NotNull String rsql, @NotNull Pageable pageable);
/** /**
@@ -221,7 +230,7 @@ public interface DeploymentManagement {
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<Action> findActionsByTarget(@NotNull String rsql, @NotEmpty String controllerId, @NotNull Pageable pageable); Slice<Action> 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 * @param pageable the pageable request to limit, sort the actions
* @return a slice of actions found for a specific target * @return a slice of actions found for a specific target
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<Action> findActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable); Slice<Action> findActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable);
/** /**
@@ -242,7 +251,7 @@ public interface DeploymentManagement {
* @return the corresponding {@link Page} of {@link ActionStatus} * @return the corresponding {@link Page} of {@link ActionStatus}
* @throws EntityNotFoundException if action with given ID does not exist * @throws EntityNotFoundException if action with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<ActionStatus> findActionStatusByAction(long actionId, @NotNull Pageable pageable); Page<ActionStatus> findActionStatusByAction(long actionId, @NotNull Pageable pageable);
/** /**
@@ -252,7 +261,7 @@ public interface DeploymentManagement {
* @return count of {@link ActionStatus} entries * @return count of {@link ActionStatus} entries
* @throws EntityNotFoundException if action with given ID does not exist * @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); long countActionStatusByAction(long actionId);
/** /**
@@ -263,7 +272,7 @@ public interface DeploymentManagement {
* @param pageable the page request parameter for paging and sorting the result * @param pageable the page request parameter for paging and sorting the result
* @return a page of messages by a specific {@link ActionStatus} id * @return a page of messages by a specific {@link ActionStatus} id
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<String> findMessagesByActionStatusId(long actionStatusId, @NotNull Pageable pageable); Page<String> findMessagesByActionStatusId(long actionStatusId, @NotNull Pageable pageable);
/** /**
@@ -272,7 +281,7 @@ public interface DeploymentManagement {
* @param actionId to be id of the action * @param actionId to be id of the action
* @return the corresponding {@link Action} * @return the corresponding {@link Action}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Action> findActionWithDetails(long actionId); Optional<Action> findActionWithDetails(long actionId);
/** /**
@@ -283,7 +292,7 @@ public interface DeploymentManagement {
* @return a list of actions associated with the given target * @return a list of actions associated with the given target
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Action> findActiveActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable); Page<Action> findActiveActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable);
/** /**
@@ -294,7 +303,7 @@ public interface DeploymentManagement {
* @return a list of actions associated with the given target * @return a list of actions associated with the given target
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Action> findInActiveActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable); Page<Action> findInActiveActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable);
/** /**
@@ -304,7 +313,7 @@ public interface DeploymentManagement {
* @param maxActionCount max size of returned list * @param maxActionCount max size of returned list
* @return the action * @return the action
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<Action> findActiveActionsWithHighestWeight(@NotEmpty String controllerId, int maxActionCount); List<Action> findActiveActionsWithHighestWeight(@NotEmpty String controllerId, int maxActionCount);
/** /**
@@ -324,7 +333,7 @@ public interface DeploymentManagement {
* @throws CancelActionNotAllowedException in case the given action is not active * @throws CancelActionNotAllowedException in case the given action is not active
* @throws EntityNotFoundException if action with given ID does not exist * @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); Action forceQuitAction(long actionId);
/** /**
@@ -334,7 +343,7 @@ public interface DeploymentManagement {
* @return the updated or the found {@link Action} * @return the updated or the found {@link Action}
* @throws EntityNotFoundException if action with given ID does not exist * @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); Action forceTargetAction(long actionId);
/** /**
@@ -342,7 +351,7 @@ public interface DeploymentManagement {
* *
* @param targetIds ids of the {@link Target}s the actions belong to * @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<Long> targetIds); void cancelInactiveScheduledActionsForTargets(List<Long> targetIds);
/** /**
@@ -353,7 +362,7 @@ public interface DeploymentManagement {
* @param distributionSetId to assign * @param distributionSetId to assign
* @param rolloutGroupParentId the parent rollout group the actions should reference. null references the first group * @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); 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 * @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<Action> rolloutGroupActions); void startScheduledActions(final List<Action> rolloutGroupActions);
/** /**
@@ -371,7 +380,7 @@ public interface DeploymentManagement {
* @return assigned {@link DistributionSet} * @return assigned {@link DistributionSet}
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<DistributionSet> getAssignedDistributionSet(@NotEmpty String controllerId); Optional<DistributionSet> getAssignedDistributionSet(@NotEmpty String controllerId);
/** /**
@@ -381,7 +390,7 @@ public interface DeploymentManagement {
* @return installed {@link DistributionSet} * @return installed {@link DistributionSet}
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<DistributionSet> getInstalledDistributionSet(@NotEmpty String controllerId); Optional<DistributionSet> getInstalledDistributionSet(@NotEmpty String controllerId);
/** /**
@@ -402,7 +411,7 @@ public interface DeploymentManagement {
* @param targetId of target * @param targetId of target
* @return if actions in CANCELING state are present * @return if actions in CANCELING state are present
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
boolean hasPendingCancellations(@NotNull Long targetId); boolean hasPendingCancellations(@NotNull Long targetId);
/** /**
@@ -411,6 +420,6 @@ public interface DeploymentManagement {
* @param cancelationType defines if a force or soft cancel is executed * @param cancelationType defines if a force or soft cancel is executed
* @param set the distribution set for that the actions should be canceled * @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); void cancelActionsForDistributionSet(final CancelationType cancelationType, final DistributionSet set);
} }

View File

@@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
@@ -56,7 +57,7 @@ public interface DistributionSetManagement<T extends DistributionSet>
@Override @Override
default String permissionGroup() { default String permissionGroup() {
return "DISTRIBUTION_SET"; return SpPermission.DISTRIBUTION_SET;
} }
/** /**

View File

@@ -19,6 +19,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -37,6 +38,11 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface DistributionSetTagManagement<T extends DistributionSetTag> public interface DistributionSetTagManagement<T extends DistributionSetTag>
extends RepositoryManagement<T, DistributionSetTagManagement.Create, DistributionSetTagManagement.Update> { extends RepositoryManagement<T, DistributionSetTagManagement.Create, DistributionSetTagManagement.Update> {
@Override
default String permissionGroup() {
return SpPermission.DISTRIBUTION_SET;
}
@SuperBuilder @SuperBuilder
@Getter @Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)

View File

@@ -21,6 +21,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -38,6 +39,11 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface DistributionSetTypeManagement<T extends DistributionSetType> public interface DistributionSetTypeManagement<T extends DistributionSetType>
extends RepositoryManagement<T, DistributionSetTypeManagement.Create, DistributionSetTypeManagement.Update> { extends RepositoryManagement<T, DistributionSetTypeManagement.Create, DistributionSetTypeManagement.Update> {
@Override
default String permissionGroup() {
return SpPermission.DISTRIBUTION_SET;
}
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByKey(@NotEmpty String key); Optional<T> findByKey(@NotEmpty String key);

View File

@@ -49,6 +49,6 @@ public interface RolloutExecutor {
* change {@link RolloutStatus#DELETED} or hard delete from the persistence * change {@link RolloutStatus#DELETED} or hard delete from the persistence
* otherwise. * otherwise.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void execute(Rollout rollout); void execute(Rollout rollout);
} }

View File

@@ -13,6 +13,7 @@ import java.util.Optional;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
@@ -27,7 +28,14 @@ import org.springframework.security.access.prepost.PreAuthorize;
/** /**
* Repository management service for RolloutGroup. * 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. * 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 * @return a page of found {@link RolloutGroup}s
* @throws EntityNotFoundException of rollout with given ID does not exist * @throws EntityNotFoundException of rollout with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<RolloutGroup> findByRolloutWithDetailedStatus(long rolloutId, @NotNull Pageable pageable); Page<RolloutGroup> findByRolloutWithDetailedStatus(long rolloutId, @NotNull Pageable pageable);
/** /**
@@ -46,7 +54,7 @@ public interface RolloutGroupManagement {
* @param rolloutGroupId the ID of the rollout group to find * @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 * @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<RolloutGroup> get(long rolloutGroupId); Optional<RolloutGroup> get(long rolloutGroupId);
/** /**
@@ -60,7 +68,7 @@ public interface RolloutGroupManagement {
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<RolloutGroup> findByRolloutAndRsql(long rolloutId, @NotNull String rsql, @NotNull Pageable pageable); Page<RolloutGroup> findByRolloutAndRsql(long rolloutId, @NotNull String rsql, @NotNull Pageable pageable);
/** /**
@@ -74,7 +82,7 @@ public interface RolloutGroupManagement {
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<RolloutGroup> findByRolloutAndRsqlWithDetailedStatus(long rolloutId, @NotNull String rsql, @NotNull Pageable pageable); Page<RolloutGroup> 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 * @param pageable the page request to sort and limit the result
* @return a page of found {@link RolloutGroup}s * @return a page of found {@link RolloutGroup}s
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<RolloutGroup> findByRollout(long rolloutId, @NotNull Pageable pageable); Page<RolloutGroup> 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 * @param rolloutId the ID of the rollout to filter the {@link RolloutGroup}s
* @return a page of found {@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); long countByRollout(long rolloutId);
/** /**
@@ -104,7 +112,7 @@ public interface RolloutGroupManagement {
* @return Page<Target> list of targets of a rollout group * @return Page<Target> list of targets of a rollout group
* @throws EntityNotFoundException if group with ID does not exist * @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<Target> findTargetsOfRolloutGroup(long rolloutGroupId, @NotNull Pageable pageable); Page<Target> findTargetsOfRolloutGroup(long rolloutGroupId, @NotNull Pageable pageable);
/** /**
@@ -118,7 +126,7 @@ public interface RolloutGroupManagement {
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @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<Target> findTargetsOfRolloutGroupByRsql(long rolloutGroupId, @NotNull String rsql, @NotNull Pageable pageable); Page<Target> findTargetsOfRolloutGroupByRsql(long rolloutGroupId, @NotNull String rsql, @NotNull Pageable pageable);
/** /**
@@ -127,7 +135,7 @@ public interface RolloutGroupManagement {
* @param rolloutGroupId rollout group id * @param rolloutGroupId rollout group id
* @return rolloutGroup with details of targets count for different statuses * @return rolloutGroup with details of targets count for different statuses
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<RolloutGroup> getWithDetailedStatus(long rolloutGroupId); Optional<RolloutGroup> getWithDetailedStatus(long rolloutGroupId);
/** /**
@@ -137,6 +145,6 @@ public interface RolloutGroupManagement {
* @return the target rollout group count * @return the target rollout group count
* @throws EntityNotFoundException if rollout group with given ID does not exist * @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); long countTargetsOfRolloutsGroup(long rolloutGroupId);
} }

View File

@@ -28,6 +28,7 @@ import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; 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 * 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. * 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. * Counts all {@link Rollout}s in the repository that are not marked as deleted.
* *
* @return number of rollouts * @return number of rollouts
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long count(); long count();
/** /**
@@ -72,7 +81,7 @@ public interface RolloutManagement {
* @param setId the distribution set * @param setId the distribution set
* @return the count * @return the count
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countByDistributionSetIdAndRolloutIsStoppable(long setId); long countByDistributionSetIdAndRolloutIsStoppable(long setId);
/** /**
@@ -102,7 +111,7 @@ public interface RolloutManagement {
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is * @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
* exceeded. * exceeded.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) @PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Rollout create( Rollout create(
@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired, @NotNull @Valid Create create, int amountGroup, boolean confirmationRequired,
@NotNull RolloutGroupConditions conditions, DynamicRolloutGroupTemplate dynamicRolloutGroupTemplate); @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 * @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
* exceeded. * exceeded.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) @PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Rollout create(@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired, Rollout create(@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired,
@NotNull RolloutGroupConditions conditions); @NotNull RolloutGroupConditions conditions);
@@ -164,7 +173,7 @@ public interface RolloutManagement {
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is * @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
* exceeded. * exceeded.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) @PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Rollout create(@Valid @NotNull Create rollout, @NotNull @Valid List<GroupCreate> groups, RolloutGroupConditions conditions); Rollout create(@Valid @NotNull Create rollout, @NotNull @Valid List<GroupCreate> groups, RolloutGroupConditions conditions);
/** /**
@@ -174,7 +183,7 @@ public interface RolloutManagement {
* @param pageable the page request to sort and limit the result * @param pageable the page request to sort and limit the result
* @return a page of found rollouts * @return a page of found rollouts
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Rollout> findAll(boolean deleted, @NotNull Pageable pageable); Page<Rollout> 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 * @return a list of rollouts with details of targets count for different
* statuses * statuses
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Rollout> findAllWithDetailedStatus(boolean deleted, @NotNull Pageable pageable); Page<Rollout> findAllWithDetailedStatus(boolean deleted, @NotNull Pageable pageable);
/** /**
@@ -199,7 +208,7 @@ public interface RolloutManagement {
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Rollout> findByRsql(@NotNull String rsql, boolean deleted, @NotNull Pageable pageable); Page<Rollout> 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 * @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 * @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<Rollout> findByRsqlWithDetailedStatus(@NotEmpty String rsql, boolean deleted, @NotNull Pageable pageable); Page<Rollout> findByRsqlWithDetailedStatus(@NotEmpty String rsql, boolean deleted, @NotNull Pageable pageable);
/** /**
@@ -218,7 +227,7 @@ public interface RolloutManagement {
* *
* @return a list of active rollouts * @return a list of active rollouts
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<Long> findActiveRollouts(); List<Long> findActiveRollouts();
/** /**
@@ -228,7 +237,7 @@ public interface RolloutManagement {
* @return the founded rollout or {@code null} if rollout with given ID does * @return the founded rollout or {@code null} if rollout with given ID does
* not exists * not exists
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Rollout> get(long rolloutId); Optional<Rollout> get(long rolloutId);
/** /**
@@ -238,7 +247,7 @@ public interface RolloutManagement {
* @return the founded rollout or {@code null} if rollout with given name * @return the founded rollout or {@code null} if rollout with given name
* does not exists * does not exists
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Rollout> getByName(@NotEmpty String rolloutName); Optional<Rollout> getByName(@NotEmpty String rolloutName);
/** /**
@@ -247,7 +256,7 @@ public interface RolloutManagement {
* @param rolloutId rollout id * @param rolloutId rollout id
* @return rollout details of targets count for different statuses * @return rollout details of targets count for different statuses
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Rollout> getWithDetailedStatus(long rolloutId); Optional<Rollout> getWithDetailedStatus(long rolloutId);
/** /**
@@ -272,7 +281,7 @@ public interface RolloutManagement {
* @throws EntityNotFoundException if rollout or group with given ID does not exist * @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. * @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); void pauseRollout(long rolloutId);
/** /**
@@ -282,7 +291,7 @@ public interface RolloutManagement {
* @throws EntityNotFoundException if rollout with given ID does not exist * @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. * @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); 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 * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts
* waiting for approval can be acted upon. * 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); Rollout approveOrDeny(long rolloutId, Rollout.ApprovalDecision decision);
/** /**
@@ -314,7 +323,7 @@ public interface RolloutManagement {
* {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts * {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts
* waiting for approveOrDeny can be acted upon. * 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); 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 * @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#READY}. Only
* ready rollouts can be started. * ready rollouts can be started.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) @PreAuthorize(HAS_ROLLOUT_HANDLE)
Rollout start(long rolloutId); 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 * @throws EntityReadOnlyException if rollout is in soft deleted state, i.e. only kept as
* reference * reference
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
Rollout update(@NotNull @Valid Update update); Rollout update(@NotNull @Valid Update update);
/** /**
@@ -351,7 +360,7 @@ public interface RolloutManagement {
* *
* @param rolloutId the ID of the rollout to be deleted * @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); void delete(long rolloutId);
/** /**
@@ -362,7 +371,7 @@ public interface RolloutManagement {
* @param set the {@link DistributionSet} for that the rollouts should be * @param set the {@link DistributionSet} for that the rollouts should be
* canceled * canceled
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void cancelRolloutsForDistributionSet(DistributionSet set); void cancelRolloutsForDistributionSet(DistributionSet set);
/** /**
@@ -373,7 +382,7 @@ public interface RolloutManagement {
* @throws EntityNotFoundException if rollout or group with given ID does not exist * @throws EntityNotFoundException if rollout or group with given ID does not exist
* @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#RUNNING}. * @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); void triggerNextGroup(long rolloutId);
@SuperBuilder @SuperBuilder

View File

@@ -23,6 +23,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
@@ -46,7 +47,7 @@ public interface SoftwareModuleManagement<T extends SoftwareModule>
@Override @Override
default String permissionGroup() { default String permissionGroup() {
return "SOFTWARE_MODULE"; return SpPermission.SOFTWARE_MODULE;
} }
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)

View File

@@ -20,6 +20,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -32,6 +33,11 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface SoftwareModuleTypeManagement<T extends SoftwareModuleType> public interface SoftwareModuleTypeManagement<T extends SoftwareModuleType>
extends RepositoryManagement<T, SoftwareModuleTypeManagement.Create, SoftwareModuleTypeManagement.Update> { extends RepositoryManagement<T, SoftwareModuleTypeManagement.Create, SoftwareModuleTypeManagement.Update> {
@Override
default String permissionGroup() {
return SpPermission.SOFTWARE_MODULE;
}
/** /**
* @param key to search for * @param key to search for
* @return {@link SoftwareModuleType} in the repository with given {@link SoftwareModuleType#getKey()} * @return {@link SoftwareModuleType} in the repository with given {@link SoftwareModuleType#getKey()}

View File

@@ -13,6 +13,7 @@ import java.util.function.Consumer;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -29,7 +30,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
*/ */
public interface SystemManagement { public interface SystemManagement {
/** /**
* Deletes all data related to a given tenant. * Deletes all data related to a given tenant.
* *
@@ -76,18 +76,18 @@ public interface SystemManagement {
/** /**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or "
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or "
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR + "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or "
+ SpringEvalExpressions.IS_CONTROLLER) + SpringEvalExpressions.IS_CONTROLLER)
TenantMetaData getTenantMetadata(); TenantMetaData getTenantMetadata();
/** /**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()}) * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()})
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or "
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or "
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR + "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or "
+ SpringEvalExpressions.IS_CONTROLLER) + SpringEvalExpressions.IS_CONTROLLER)
TenantMetaData getTenantMetadataWithoutDetails(); TenantMetaData getTenantMetadataWithoutDetails();
@@ -113,7 +113,7 @@ public interface SystemManagement {
* @param defaultDsType to update * @param defaultDsType to update
* @return updated {@link TenantMetaData} entity * @return updated {@link TenantMetaData} entity
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) @PreAuthorize("hasAuthority('UPDATE_" + SpPermission.TENANT_CONFIGURATION + "')")
TenantMetaData updateTenantMetadata(long defaultDsType); TenantMetaData updateTenantMetadata(long defaultDsType);
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)

View File

@@ -22,6 +22,7 @@ import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -48,7 +49,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
@Override @Override
default String permissionGroup() { default String permissionGroup() {
return "TARGET"; return SpPermission.TARGET;
} }
/** /**
@@ -60,7 +61,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
boolean verifyTargetFilterQuerySyntax(@NotNull String query); boolean verifyTargetFilterQuerySyntax(@NotNull String query);
/** /**
@@ -72,7 +73,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
* @param autoAssignDistributionSetId the id of the distribution set * @param autoAssignDistributionSetId the id of the distribution set
* @return the count * @return the count
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countByAutoAssignDistributionSetId(long autoAssignDistributionSetId); long countByAutoAssignDistributionSetId(long autoAssignDistributionSetId);
/** /**
@@ -84,7 +85,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
* @return the page with the found {@link TargetFilterQuery}s * @return the page with the found {@link TargetFilterQuery}s
* @throws EntityNotFoundException if DS with given ID does not exist * @throws EntityNotFoundException if DS with given ID does not exist
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<TargetFilterQuery> findByAutoAssignDSAndRsql(long setId, String rsql, @NotNull Pageable pageable); Page<TargetFilterQuery> findByAutoAssignDSAndRsql(long setId, String rsql, @NotNull Pageable pageable);
/** /**
@@ -93,7 +94,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
* @param pageable pagination information * @param pageable pagination information
* @return the page with the found {@link TargetFilterQuery}s * @return the page with the found {@link TargetFilterQuery}s
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<TargetFilterQuery> findWithAutoAssignDS(@NotNull Pageable pageable); Slice<TargetFilterQuery> findWithAutoAssignDS(@NotNull Pageable pageable);
/** /**
@@ -112,7 +113,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
* @throws InvalidDistributionSetException if the provided auto-assign {@link DistributionSet} is * @throws InvalidDistributionSetException if the provided auto-assign {@link DistributionSet} is
* invalidated * invalidated
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
TargetFilterQuery updateAutoAssignDS(@NotNull @Valid AutoAssignDistributionSetUpdate autoAssignDistributionSetUpdate); TargetFilterQuery updateAutoAssignDS(@NotNull @Valid AutoAssignDistributionSetUpdate autoAssignDistributionSetUpdate);
/** /**
@@ -121,7 +122,7 @@ public interface TargetFilterQueryManagement<T extends TargetFilterQuery>
* @param setId the {@link DistributionSet} to be removed from auto * @param setId the {@link DistributionSet} to be removed from auto
* assignments. * assignments.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void cancelAutoAssignmentForDistributionSet(long setId); void cancelAutoAssignmentForDistributionSet(long setId);
@SuperBuilder @SuperBuilder

View File

@@ -9,16 +9,9 @@
*/ */
package org.eclipse.hawkbit.repository; package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_DELETE_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_OPEN; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_AND; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_UPDATE_REPOSITORY;
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 java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -64,19 +57,16 @@ import org.springframework.util.ObjectUtils;
public interface TargetManagement<T extends Target> public interface TargetManagement<T extends Target>
extends RepositoryManagement<T, TargetManagement.Create, TargetManagement.Update> { extends RepositoryManagement<T, TargetManagement.Create, TargetManagement.Update> {
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_BASE = "base";
String DETAILS_AUTO_CONFIRMATION_STATUS = "autoConfirmationStatus"; String DETAILS_AUTO_CONFIRMATION_STATUS = "autoConfirmationStatus";
String DETAILS_TAGS = "tags"; 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 @Override
default String permissionGroup() { default String permissionGroup() {
return "TARGET"; return SpPermission.TARGET;
} }
/** /**
@@ -86,7 +76,7 @@ public interface TargetManagement<T extends Target>
* @return controller attributes as key/value pairs * @return controller attributes as key/value pairs
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Map<String, String> getControllerAttributes(@NotEmpty String controllerId); Map<String, String> getControllerAttributes(@NotEmpty String controllerId);
/** /**
@@ -98,7 +88,7 @@ public interface TargetManagement<T extends Target>
* @param targetFilterQuery to execute * @param targetFilterQuery to execute
* @return true if it matches * @return true if it matches
*/ */
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET) @PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET)
boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable( boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable(
@NotNull String controllerId, long distributionSetId, @NotNull String targetFilterQuery); @NotNull String controllerId, long distributionSetId, @NotNull String targetFilterQuery);
@@ -108,7 +98,7 @@ public interface TargetManagement<T extends Target>
* @param controllerIDs to look for. * @param controllerIDs to look for.
* @return List of found{@link Target}s * @return List of found{@link Target}s
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
List<Target> getByControllerId(@NotEmpty Collection<String> controllerIDs); List<Target> getByControllerId(@NotEmpty Collection<String> controllerIDs);
/** /**
@@ -118,15 +108,15 @@ public interface TargetManagement<T extends Target>
* @param detailsKey the key of the details to include, e.g. {@link #DETAILS_AUTO_CONFIRMATION_STATUS} * @param detailsKey the key of the details to include, e.g. {@link #DETAILS_AUTO_CONFIRMATION_STATUS}
* @return {@link Target} * @return {@link Target}
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Target getWithDetails(@NotEmpty String controllerId, String detailsKey); Target getWithDetails(@NotEmpty String controllerId, String detailsKey);
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
default Target getWithDetails(@NotEmpty String controllerId) { default Target getWithDetails(@NotEmpty String controllerId) {
return getWithDetails(controllerId, DETAILS_BASE); return getWithDetails(controllerId, DETAILS_BASE);
} }
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
default Target getWithAutoConfigurationStatus(@NotEmpty String controllerId) { default Target getWithAutoConfigurationStatus(@NotEmpty String controllerId) {
return getWithDetails(controllerId, DETAILS_AUTO_CONFIRMATION_STATUS); return getWithDetails(controllerId, DETAILS_AUTO_CONFIRMATION_STATUS);
} }
@@ -141,7 +131,7 @@ public interface TargetManagement<T extends Target>
* @return a page of the found {@link Target}s * @return a page of the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist * @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<Target> findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable( Slice<Target> findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable(
long distributionSetId, @NotNull String rsql, @NotNull Pageable pageable); long distributionSetId, @NotNull String rsql, @NotNull Pageable pageable);
@@ -155,7 +145,7 @@ public interface TargetManagement<T extends Target>
* @param pageable the pageable to enhance the query for paging and sorting * @param pageable the pageable to enhance the query for paging and sorting
* @return a page of the found {@link Target}s * @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<Target> findByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable( Slice<Target> findByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(
@NotEmpty Collection<Long> groups, @NotNull String rsql, @NotNull DistributionSetType distributionSetType, @NotEmpty Collection<Long> groups, @NotNull String rsql, @NotNull DistributionSetType distributionSetType,
@NotNull Pageable pageable); @NotNull Pageable pageable);
@@ -169,11 +159,11 @@ public interface TargetManagement<T extends Target>
* @param pageable the pageable to enhance the query for paging and sorting * @param pageable the pageable to enhance the query for paging and sorting
* @return a page of the found {@link Target}s * @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<Target> findByFailedRolloutAndNotInRolloutGroups( Slice<Target> findByFailedRolloutAndNotInRolloutGroups(
@NotNull String rolloutId, @NotEmpty Collection<Long> groups, @NotNull Pageable pageable); @NotNull String rolloutId, @NotEmpty Collection<Long> groups, @NotNull Pageable pageable);
@PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT)
Slice<Target> findByRsqlAndNoOverridingActionsAndNotInRolloutAndCompatibleAndUpdatable( Slice<Target> findByRsqlAndNoOverridingActionsAndNotInRolloutAndCompatibleAndUpdatable(
final long rolloutId, @NotNull String rsql, @NotNull DistributionSetType distributionSetType, @NotNull Pageable pageable); final long rolloutId, @NotNull String rsql, @NotNull DistributionSetType distributionSetType, @NotNull Pageable pageable);
@@ -185,7 +175,7 @@ public interface TargetManagement<T extends Target>
* @return the found {@link Target}s * @return the found {@link Target}s
* @throws EntityNotFoundException if rollout group with given ID does not exist * @throws EntityNotFoundException if rollout group with given ID does not exist
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Slice<Target> findByInRolloutGroupWithoutAction(long group, @NotNull Pageable pageable); Slice<Target> findByInRolloutGroupWithoutAction(long group, @NotNull Pageable pageable);
/** /**
@@ -196,7 +186,7 @@ public interface TargetManagement<T extends Target>
* @return the found {@link Target}s * @return the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist * @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<Target> findByAssignedDistributionSet(long distributionSetId, @NotNull Pageable pageable); Page<Target> findByAssignedDistributionSet(long distributionSetId, @NotNull Pageable pageable);
/** /**
@@ -211,7 +201,7 @@ public interface TargetManagement<T extends Target>
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
* @throws EntityNotFoundException if distribution set with given ID does not exist * @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<Target> findByAssignedDistributionSetAndRsql(long distributionSetId, @NotNull String rsql, @NotNull Pageable pageable); Page<Target> findByAssignedDistributionSetAndRsql(long distributionSetId, @NotNull String rsql, @NotNull Pageable pageable);
/** /**
@@ -223,7 +213,7 @@ public interface TargetManagement<T extends Target>
* compatible with * compatible with
* @return the found number of{@link Target}s * @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); long countByRsqlAndCompatible(@NotEmpty String rsql, @NotNull Long distributionSetIdTypeId);
/** /**
@@ -234,7 +224,7 @@ public interface TargetManagement<T extends Target>
* @param dsTypeId ID of the {@link DistributionSetType} the targets need to be compatible with * @param dsTypeId ID of the {@link DistributionSetType} the targets need to be compatible with
* @return the found number of{@link Target}s * @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); long countByFailedInRollout(@NotEmpty String rolloutId, @NotNull Long dsTypeId);
/** /**
@@ -246,7 +236,7 @@ public interface TargetManagement<T extends Target>
* @return the count of found {@link Target}s * @return the count of found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist * @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); long countByRsqlAndNonDsAndCompatibleAndUpdatable(long distributionSetId, @NotNull String rsql);
/** /**
@@ -258,7 +248,7 @@ public interface TargetManagement<T extends Target>
* @param distributionSetType type of the {@link DistributionSet} the targets must be compatible with * @param distributionSetType type of the {@link DistributionSet} the targets must be compatible with
* @return count of the found {@link Target}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 countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable( long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(
@NotNull String rsql, @NotEmpty Collection<Long> groups, @NotNull DistributionSetType distributionSetType); @NotNull String rsql, @NotEmpty Collection<Long> groups, @NotNull DistributionSetType distributionSetType);
@@ -270,10 +260,10 @@ public interface TargetManagement<T extends Target>
* @param groups the list of {@link RolloutGroup}s * @param groups the list of {@link RolloutGroup}s
* @return count of the found {@link Target}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<Long> groups); long countByFailedRolloutAndNotInRolloutGroups(@NotNull String rolloutId, @NotEmpty Collection<Long> groups);
@PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) @PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT)
long countByActionsInRolloutGroup(final long rolloutGroupId); long countByActionsInRolloutGroup(final long rolloutGroupId);
/** /**
@@ -282,7 +272,7 @@ public interface TargetManagement<T extends Target>
* @param controllerId to look for. * @param controllerId to look for.
* @return {@link Target} * @return {@link Target}
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Optional<Target> getByControllerId(@NotEmpty String controllerId); Optional<Target> getByControllerId(@NotEmpty String controllerId);
/** /**
@@ -293,7 +283,7 @@ public interface TargetManagement<T extends Target>
* @return the found {@link Target}s * @return the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist * @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<Target> findByInstalledDistributionSet(long distributionSetId, @NotNull Pageable pageReq); Page<Target> findByInstalledDistributionSet(long distributionSetId, @NotNull Pageable pageReq);
/** /**
@@ -309,7 +299,7 @@ public interface TargetManagement<T extends Target>
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
* @throws EntityNotFoundException if distribution set with given ID does not exist * @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<Target> findByInstalledDistributionSetAndRsql(long distributionSetId, @NotNull String rsql, @NotNull Pageable pageReq); Page<Target> findByInstalledDistributionSetAndRsql(long distributionSetId, @NotNull String rsql, @NotNull Pageable pageReq);
/** /**
@@ -320,7 +310,7 @@ public interface TargetManagement<T extends Target>
* @return list of matching targets * @return list of matching targets
* @throws EntityNotFoundException if target tag with given ID does not exist * @throws EntityNotFoundException if target tag with given ID does not exist
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Page<Target> findByTag(long tagId, @NotNull Pageable pageable); Page<Target> findByTag(long tagId, @NotNull Pageable pageable);
/** /**
@@ -335,7 +325,7 @@ public interface TargetManagement<T extends Target>
* given {@code fieldNameProvider} * given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Page<Target> findByRsqlAndTag(@NotNull String rsql, long tagId, @NotNull Pageable pageable); Page<Target> findByRsqlAndTag(@NotNull String rsql, long tagId, @NotNull Pageable pageable);
@@ -345,7 +335,7 @@ public interface TargetManagement<T extends Target>
* @param controllerId the controller ID of the target to be deleted * @param controllerId the controller ID of the target to be deleted
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(HAS_AUTH_DELETE_TARGET) @PreAuthorize(HAS_DELETE_REPOSITORY)
void deleteByControllerId(@NotEmpty String controllerId); void deleteByControllerId(@NotEmpty String controllerId);
/** /**
@@ -356,7 +346,7 @@ public interface TargetManagement<T extends Target>
* @return the unassigned target * @return the unassigned target
* @throws EntityNotFoundException if TargetType with given target ID does not exist * @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); Target assignType(@NotEmpty String controllerId, @NotNull Long targetTypeId);
/** /**
@@ -365,7 +355,7 @@ public interface TargetManagement<T extends Target>
* @param controllerId to un-assign for * @param controllerId to un-assign for
* @return the unassigned target * @return the unassigned target
*/ */
@PreAuthorize(HAS_AUTH_UPDATE_TARGET) @PreAuthorize(HAS_UPDATE_REPOSITORY)
Target unassignType(@NotEmpty String controllerId); Target unassignType(@NotEmpty String controllerId);
/** /**
@@ -377,7 +367,7 @@ public interface TargetManagement<T extends Target>
* @return list of assigned targets * @return list of assigned targets
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist * @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<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final Consumer<Collection<String>> notFoundHandler); List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final Consumer<Collection<String>> notFoundHandler);
/** /**
@@ -388,7 +378,7 @@ public interface TargetManagement<T extends Target>
* @return list of assigned targets * @return list of assigned targets
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist * @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<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId); List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId);
/** /**
@@ -398,7 +388,7 @@ public interface TargetManagement<T extends Target>
* @return the found Tag set * @return the found Tag set
* @throws EntityNotFoundException if target with given ID does not exist * @throws EntityNotFoundException if target with given ID does not exist
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Set<TargetTag> getTags(@NotEmpty String controllerId); Set<TargetTag> getTags(@NotEmpty String controllerId);
/** /**
@@ -410,7 +400,7 @@ public interface TargetManagement<T extends Target>
* @return list of unassigned targets * @return list of unassigned targets
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist * @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<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final Consumer<Collection<String>> notFoundHandler); List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final Consumer<Collection<String>> notFoundHandler);
/** /**
@@ -421,7 +411,7 @@ public interface TargetManagement<T extends Target>
* @return list of unassigned targets * @return list of unassigned targets
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist * @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<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId); List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId);
/** /**
@@ -430,7 +420,7 @@ public interface TargetManagement<T extends Target>
* @param group target group parameter * @param group target group parameter
* @param rsql rsql filter for {@link Target} * @param rsql rsql filter for {@link Target}
*/ */
@PreAuthorize(HAS_AUTH_UPDATE_TARGET) @PreAuthorize(HAS_UPDATE_REPOSITORY)
void assignTargetGroupWithRsql(String group, @NotNull String rsql); void assignTargetGroupWithRsql(String group, @NotNull String rsql);
/** /**
@@ -439,7 +429,7 @@ public interface TargetManagement<T extends Target>
* @param group target group parameter * @param group target group parameter
* @param controllerIds list of targets * @param controllerIds list of targets
*/ */
@PreAuthorize(HAS_AUTH_UPDATE_TARGET) @PreAuthorize(HAS_UPDATE_REPOSITORY)
void assignTargetsWithGroup(String group, @NotEmpty List<String> controllerIds); void assignTargetsWithGroup(String group, @NotEmpty List<String> controllerIds);
/** /**
@@ -450,7 +440,7 @@ public interface TargetManagement<T extends Target>
* @param pageable - page parameter * @param pageable - page parameter
* @return all matching targets to provided group/subgroup * @return all matching targets to provided group/subgroup
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
Page<Target> findTargetsByGroup(@NotEmpty String group, boolean withSubgroups, @NotNull Pageable pageable); Page<Target> findTargetsByGroup(@NotEmpty String group, boolean withSubgroups, @NotNull Pageable pageable);
/** /**
@@ -458,7 +448,7 @@ public interface TargetManagement<T extends Target>
* *
* @return list of all distinct target groups * @return list of all distinct target groups
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET) @PreAuthorize(HAS_READ_REPOSITORY)
List<String> findGroups(); List<String> findGroups();
/** /**

View File

@@ -16,6 +16,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
@@ -28,7 +29,7 @@ public interface TargetTagManagement<T extends TargetTag>
@Override @Override
default String permissionGroup() { default String permissionGroup() {
return "TARGET"; return SpPermission.TARGET;
} }
@SuperBuilder @SuperBuilder

View File

@@ -9,12 +9,7 @@
*/ */
package org.eclipse.hawkbit.repository; package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY;
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 java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -30,6 +25,7 @@ import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission; 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.exception.TargetTypeKeyOrNameRequiredException;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
@@ -43,29 +39,25 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface TargetTypeManagement<T extends TargetType> public interface TargetTypeManagement<T extends TargetType>
extends RepositoryManagement<T, TargetTypeManagement.Create, TargetTypeManagement.Update> { extends RepositoryManagement<T, TargetTypeManagement.Create, TargetTypeManagement.Update> {
String HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE = BRACKET_OPEN + String HAS_UPDATE_TARGET_TYPE_AND_READ_DISTRIBUTION_SET = SpringEvalExpressions.HAS_UPDATE_REPOSITORY + " and hasAuthority('READ_" + SpPermission.DISTRIBUTION_SET + "')";
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;
@Override @Override
default String permissionGroup() { default String permissionGroup() {
return "TARGET_TYPE"; return SpPermission.TARGET_TYPE;
} }
/** /**
* @param key as {@link TargetType#getKey()} * @param key as {@link TargetType#getKey()}
* @return {@link TargetType} * @return {@link TargetType}
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) @PreAuthorize(HAS_READ_REPOSITORY)
Optional<TargetType> getByKey(@NotEmpty String key); Optional<TargetType> getByKey(@NotEmpty String key);
/** /**
* @param name as {@link TargetType#getName()} * @param name as {@link TargetType#getName()}
* @return {@link TargetType} * @return {@link TargetType}
*/ */
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) @PreAuthorize(HAS_READ_REPOSITORY)
Optional<TargetType> getByName(@NotEmpty String name); Optional<TargetType> getByName(@NotEmpty String name);
/** /**
@@ -73,7 +65,7 @@ public interface TargetTypeManagement<T extends TargetType>
* @param distributionSetTypeIds Distribution set ID * @param distributionSetTypeIds Distribution set ID
* @return Target type * @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<Long> distributionSetTypeIds); TargetType assignCompatibleDistributionSetTypes(long id, @NotEmpty Collection<Long> distributionSetTypeIds);
/** /**
@@ -81,7 +73,7 @@ public interface TargetTypeManagement<T extends TargetType>
* @param distributionSetTypeIds Distribution set ID * @param distributionSetTypeIds Distribution set ID
* @return Target type * @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); TargetType unassignDistributionSetType(long id, long distributionSetTypeIds);
@SuperBuilder @SuperBuilder

View File

@@ -13,6 +13,7 @@ import java.io.Serializable;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException; import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException;
import org.eclipse.hawkbit.repository.model.PollStatus; import org.eclipse.hawkbit.repository.model.PollStatus;
@@ -25,7 +26,12 @@ import org.springframework.security.access.prepost.PreAuthorize;
/** /**
* Management service for tenant configurations. * 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. * Adds or updates a specific configuration for a specific tenant.
@@ -37,7 +43,7 @@ public interface TenantConfigurationManagement {
* format defined by the Key * format defined by the Key
* @throws ConversionFailedException if the property cannot be converted to the given * @throws ConversionFailedException if the property cannot be converted to the given
*/ */
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) @PreAuthorize(value = SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
<T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(String configurationKeyName, T value); <T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(String configurationKeyName, T value);
/** /**
@@ -49,7 +55,7 @@ public interface TenantConfigurationManagement {
* match the expected type and format defined by the Key * match the expected type and format defined by the Key
* @throws ConversionFailedException if the property cannot be converted to the given * @throws ConversionFailedException if the property cannot be converted to the given
*/ */
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) @PreAuthorize(value = SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
<T extends Serializable> Map<String, TenantConfigurationValue<T>> addOrUpdateConfiguration(Map<String, T> configurations); <T extends Serializable> Map<String, TenantConfigurationValue<T>> addOrUpdateConfiguration(Map<String, T> configurations);
/** /**
@@ -58,7 +64,7 @@ public interface TenantConfigurationManagement {
* *
* @param configurationKey the configuration key to be deleted * @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); void deleteConfiguration(String configurationKey);
/** /**
@@ -76,7 +82,7 @@ public interface TenantConfigurationManagement {
* @throws ConversionFailedException if the property cannot be converted to the given * @throws ConversionFailedException if the property cannot be converted to the given
* {@code propertyType} * {@code propertyType}
*/ */
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) @PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY)
<T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(String configurationKeyName); <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(String configurationKeyName);
/** /**
@@ -97,7 +103,7 @@ public interface TenantConfigurationManagement {
* @throws ConversionFailedException if the property cannot be converted to the given * @throws ConversionFailedException if the property cannot be converted to the given
* {@code propertyType} * {@code propertyType}
*/ */
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) @PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY)
<T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(String configurationKeyName, <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(String configurationKeyName,
Class<T> propertyType); Class<T> propertyType);
@@ -116,9 +122,9 @@ public interface TenantConfigurationManagement {
* @throws ConversionFailedException if the property cannot be converted to the given * @throws ConversionFailedException if the property cannot be converted to the given
* {@code propertyType} * {@code propertyType}
*/ */
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) @PreAuthorize(value = SpringEvalExpressions.HAS_READ_REPOSITORY)
<T> T getGlobalConfigurationValue(String configurationKeyName, Class<T> propertyType); <T> T getGlobalConfigurationValue(String configurationKeyName, Class<T> propertyType);
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_READ_TARGET) @PreAuthorize(value = "hasAuthority('READ_" + SpPermission.TARGET + "')")
Function<Target, PollStatus> pollStatusResolver(); Function<Target, PollStatus> pollStatusResolver();
} }

View File

@@ -9,6 +9,7 @@
*/ */
package org.eclipse.hawkbit.repository; package org.eclipse.hawkbit.repository;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.eclipse.hawkbit.repository.report.model.TenantUsage;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -24,11 +25,8 @@ public interface TenantStatsManagement {
* *
* @return collected statistics * @return collected statistics
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR @PreAuthorize("hasAuthority('" + SpRole.TENANT_ADMIN + "')" + " or " +
+ SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + " or " +
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR SpringEvalExpressions.IS_SYSTEM_CODE)
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_SYSTEM_CODE)
TenantUsage getStatsOfTenant(); TenantUsage getStatsOfTenant();
} }

View File

@@ -62,11 +62,11 @@ public class RepositoryConfiguration {
@Override @Override
public boolean hasPermission(final Authentication authentication, final Object targetDomainObject, final Object permission) { public boolean hasPermission(final Authentication authentication, final Object targetDomainObject, final Object permission) {
if (targetDomainObject instanceof MethodSecurityExpressionOperations root) { if (targetDomainObject instanceof MethodSecurityExpressionOperations root &&
final String neededPermission = root.getThis() instanceof PermissionSupport permissionSupport) {
permission + "_" + (root.getThis() instanceof PermissionSupport permissionSupport final String neededPermission = permission + "_" + permissionSupport.permissionGroup();
? permissionSupport.permissionGroup()
: "REPOSITORY"); // TODO - should not fall back here - all using permissions should extend repository management interface // do permissions check
final boolean hasPermission = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities()).stream() final boolean hasPermission = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities()).stream()
.map(GrantedAuthority::getAuthority) .map(GrantedAuthority::getAuthority)
.anyMatch(authority -> authority.equals(neededPermission)); .anyMatch(authority -> authority.equals(neededPermission));
@@ -75,10 +75,12 @@ public class RepositoryConfiguration {
"User {} does not have permission {} for target {}", "User {} does not have permission {} for target {}",
authentication.getName(), neededPermission, targetDomainObject); authentication.getName(), neededPermission, targetDomainObject);
} }
return hasPermission; return hasPermission;
} } else {
return super.hasPermission(authentication, targetDomainObject, permission); return super.hasPermission(authentication, targetDomainObject, permission);
} }
}
}; };
} }

View File

@@ -374,11 +374,11 @@ public class JpaRepositoryConfiguration {
final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy, final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy,
final EntityManager entityManager, final PlatformTransactionManager txManager, final EntityManager entityManager, final PlatformTransactionManager txManager,
final AfterTransactionCommitExecutor afterCommit, final AfterTransactionCommitExecutor afterCommit,
final TenantAware tenantAware, final RepositoryProperties repositoryProperties) { final TenantAware tenantAware, final ContextAware contextAware, final RepositoryProperties repositoryProperties) {
return new JpaRolloutExecutor(actionRepository, rolloutGroupRepository, rolloutTargetGroupRepository, return new JpaRolloutExecutor(actionRepository, rolloutGroupRepository, rolloutTargetGroupRepository,
rolloutRepository, targetManagement, deploymentManagement, rolloutGroupManagement, rolloutManagement, rolloutRepository, targetManagement, deploymentManagement, rolloutGroupManagement, rolloutManagement,
quotaManagement, evaluationManager, rolloutApprovalStrategy, entityManager, txManager, afterCommit, quotaManagement, evaluationManager, rolloutApprovalStrategy, entityManager, txManager, afterCommit,
tenantAware, repositoryProperties); tenantAware, contextAware, repositoryProperties);
} }
/** /**

View File

@@ -22,6 +22,7 @@ import java.util.stream.StreamSupport;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.ContextAware;
import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.RepositoryProperties;
@@ -112,6 +113,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
private final PlatformTransactionManager txManager; private final PlatformTransactionManager txManager;
private final AfterTransactionCommitExecutor afterCommit; private final AfterTransactionCommitExecutor afterCommit;
private final TenantAware tenantAware; private final TenantAware tenantAware;
private final ContextAware contextAware;
private final RepositoryProperties repositoryProperties; private final RepositoryProperties repositoryProperties;
private final Map<Long, AtomicLong> lastDynamicGroupFill = new ConcurrentHashMap<>(); private final Map<Long, AtomicLong> lastDynamicGroupFill = new ConcurrentHashMap<>();
@@ -125,7 +127,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy, final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy,
final EntityManager entityManager, final PlatformTransactionManager txManager, final EntityManager entityManager, final PlatformTransactionManager txManager,
final AfterTransactionCommitExecutor afterCommit, final AfterTransactionCommitExecutor afterCommit,
final TenantAware tenantAware, final RepositoryProperties repositoryProperties) { final TenantAware tenantAware, final ContextAware contextAware, final RepositoryProperties repositoryProperties) {
this.actionRepository = actionRepository; this.actionRepository = actionRepository;
this.rolloutGroupRepository = rolloutGroupRepository; this.rolloutGroupRepository = rolloutGroupRepository;
this.rolloutTargetGroupRepository = rolloutTargetGroupRepository; this.rolloutTargetGroupRepository = rolloutTargetGroupRepository;
@@ -141,11 +143,23 @@ public class JpaRolloutExecutor implements RolloutExecutor {
this.txManager = txManager; this.txManager = txManager;
this.afterCommit = afterCommit; this.afterCommit = afterCommit;
this.tenantAware = tenantAware; this.tenantAware = tenantAware;
this.contextAware = contextAware;
this.repositoryProperties = repositoryProperties; this.repositoryProperties = repositoryProperties;
} }
@Override @Override
public void execute(final Rollout rollout) { 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()); log.debug("Processing rollout {}", rollout.getId());
switch (rollout.getStatus()) { switch (rollout.getStatus()) {

View File

@@ -112,22 +112,8 @@ public class JpaRolloutHandler implements RolloutHandler {
DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId, status -> { DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId, status -> {
rolloutManagement.get(rolloutId).ifPresentOrElse( rolloutManagement.get(rolloutId).ifPresentOrElse(
rollout -> rolloutExecutor::execute,
// auditor is retrieved and set on transaction commit if not overridden, the system user will be the auditor () -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.", rolloutId));
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));
return 0L; return 0L;
}); });

View File

@@ -13,7 +13,7 @@ import java.io.ByteArrayInputStream;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.im.authentication.SpPermission; 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.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.ArtifactUpload; import org.eclipse.hawkbit.repository.model.ArtifactUpload;
import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.repository.test.util.WithUser;
@@ -60,7 +60,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void getPermissionCheck() { void getPermissionCheck() {
assertPermissions(() -> artifactManagement.get(1L), List.of(SpPermission.READ_REPOSITORY)); 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), assertPermissions(() -> artifactManagement.getByFilenameAndSoftwareModule("filename", 1L),
List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY)); List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.getByFilenameAndSoftwareModule("filename", 1L), 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 @Test
void findFirstBySHA1PermissionCheck() { void findFirstBySHA1PermissionCheck() {
assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpPermission.READ_REPOSITORY)); 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 @Test
void getByFilenamePermissionCheck() { void getByFilenamePermissionCheck() {
assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpPermission.READ_REPOSITORY)); 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 @Test
void loadArtifactBinaryPermissionCheck() { 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(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));
} }
} }

View File

@@ -27,6 +27,7 @@ import java.util.concurrent.Callable;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
import org.apache.commons.io.IOUtils; 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.DbArtifact;
import org.eclipse.hawkbit.repository.artifact.model.DbArtifactHash; import org.eclipse.hawkbit.repository.artifact.model.DbArtifactHash;
import org.eclipse.hawkbit.im.authentication.SpPermission; 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. * Trys and fails to load an artifact without required permission. Checks if expected InsufficientPermissionException is thrown.
*/ */
@Test @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() { void loadArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() {
assertThatExceptionOfType(InsufficientPermissionException.class) assertThatExceptionOfType(InsufficientPermissionException.class)
.as("Should not have worked with missing permission.") .as("Should not have worked with missing permission.")

View File

@@ -12,7 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.management;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.im.authentication.SpPermission; 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.jpa.AbstractJpaIntegrationTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -46,7 +46,7 @@ class ConfirmationManagementSecurityTest extends AbstractJpaIntegrationTest {
void getStatusPermissionsCheck() { void getStatusPermissionsCheck() {
assertPermissions(() -> confirmationManagement.getStatus("controllerId"), List.of(SpPermission.READ_TARGET), assertPermissions(() -> confirmationManagement.getStatus("controllerId"), List.of(SpPermission.READ_TARGET),
List.of(SpPermission.CREATE_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));
} }
/** /**

View File

@@ -14,7 +14,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.im.authentication.SpRole; 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.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -37,7 +36,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
void addCancelActionStatusPermissionsCheck() { void addCancelActionStatusPermissionsCheck() {
assertPermissions(() -> controllerManagement.addCancelActionStatus( assertPermissions(() -> controllerManagement.addCancelActionStatus(
ActionStatusCreate.builder().actionId(0L).status(Action.Status.DOWNLOADED).build()), 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 @Test
void getSoftwareModulePermissionsCheck() { 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 @Test
void findTargetVisibleMetaDataBySoftwareModuleIdPermissionsCheck() { void findTargetVisibleMetaDataBySoftwareModuleIdPermissionsCheck() {
assertPermissions(() -> controllerManagement.findTargetVisibleMetaDataBySoftwareModuleId(List.of(1L)), 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() { void addInformationalActionStatusPermissionsCheck() {
assertPermissions(() -> controllerManagement.addInformationalActionStatus( assertPermissions(() -> controllerManagement.addInformationalActionStatus(
ActionStatusCreate.builder().actionId(0L).status(Action.Status.DOWNLOADED).build()), 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() { void addUpdateActionStatusPermissionsCheck() {
assertPermissions(() -> controllerManagement.addUpdateActionStatus( assertPermissions(() -> controllerManagement.addUpdateActionStatus(
ActionStatusCreate.builder().actionId(0L).status(Action.Status.DOWNLOADED).build()), 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 @Test
void findActiveActionWithHighestWeightPermissionsCheck() { void findActiveActionWithHighestWeightPermissionsCheck() {
assertPermissions(() -> controllerManagement.findActiveActionWithHighestWeight("controllerId"), assertPermissions(() -> controllerManagement.findActiveActionWithHighestWeight("controllerId"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -92,7 +91,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void findActiveActionsWithHighestWeightPermissionsCheck() { void findActiveActionsWithHighestWeightPermissionsCheck() {
assertPermissions(() -> controllerManagement.findActiveActionsWithHighestWeight("controllerId", 1), assertPermissions(() -> controllerManagement.findActiveActionsWithHighestWeight("controllerId", 1),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -100,7 +99,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void findActionWithDetailsPermissionsCheck() { 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 @Test
void findActionStatusByActionPermissionsCheck() { void findActionStatusByActionPermissionsCheck() {
assertPermissions(() -> controllerManagement.findActionStatusByAction(1L, Pageable.unpaged()), 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 @Test
void findOrRegisterTargetIfItDoesNotExistPermissionsCheck() { void findOrRegisterTargetIfItDoesNotExistPermissionsCheck() {
assertPermissions(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("controllerId", URI.create("someaddress")), 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() { void findOrRegisterTargetIfItDoesNotExistWithDetailsPermissionsCheck() {
assertPermissions( assertPermissions(
() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("controllerId", URI.create("someaddress"), "name", "type"), () -> 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 @Test
void getActionForDownloadByTargetAndSoftwareModulePermissionsCheck() { void getActionForDownloadByTargetAndSoftwareModulePermissionsCheck() {
assertPermissions(() -> controllerManagement.getActionForDownloadByTargetAndSoftwareModule("controllerId", 1L), assertPermissions(() -> controllerManagement.getActionForDownloadByTargetAndSoftwareModule("controllerId", 1L),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -145,7 +144,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void getPollingTimePermissionsCheck() { 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 // expected since action is not found
} }
return null; return null;
}, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); }, List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -171,7 +170,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void hasTargetArtifactAssignedPermissionsCheck() { void hasTargetArtifactAssignedPermissionsCheck() {
assertPermissions(() -> controllerManagement.hasTargetArtifactAssigned("controllerId", "sha1Hash"), assertPermissions(() -> controllerManagement.hasTargetArtifactAssigned("controllerId", "sha1Hash"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -180,7 +179,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void hasTargetArtifactAssignedByIdPermissionsCheck() { void hasTargetArtifactAssignedByIdPermissionsCheck() {
assertPermissions(() -> controllerManagement.hasTargetArtifactAssigned(1L, "sha1Hash"), assertPermissions(() -> controllerManagement.hasTargetArtifactAssigned(1L, "sha1Hash"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -189,7 +188,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void updateControllerAttributesPermissionsCheck() { void updateControllerAttributesPermissionsCheck() {
assertPermissions(() -> controllerManagement.updateControllerAttributes("controllerId", Map.of(), null), 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 @Test
void getByControllerIdPermissionsCheck() { void getByControllerIdPermissionsCheck() {
assertPermissions(() -> controllerManagement.getByControllerId("controllerId"), assertPermissions(() -> controllerManagement.getByControllerId("controllerId"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
assertPermissions(() -> controllerManagement.getByControllerId("controllerId"), assertPermissions(() -> controllerManagement.getByControllerId("controllerId"),
List.of(SpRole.SYSTEM_ROLE)); List.of(SpRole.SYSTEM_ROLE));
} }
@@ -208,7 +207,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void getPermissionsCheck() { 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)); assertPermissions(() -> controllerManagement.get(1L), List.of(SpRole.SYSTEM_ROLE));
} }
@@ -218,7 +217,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void getActionHistoryMessagesPermissionsCheck() { void getActionHistoryMessagesPermissionsCheck() {
assertPermissions(() -> controllerManagement.getActionHistoryMessages(1L, 1), 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 // expected since action is not found
} }
return null; return null;
}, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); }, List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -246,7 +245,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
assertPermissions(() -> { assertPermissions(() -> {
controllerManagement.updateActionExternalRef(1L, "externalRef"); controllerManagement.updateActionExternalRef(1L, "externalRef");
return null; return null;
}, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); }, List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -255,7 +254,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void getActionByExternalRefPermissionsCheck() { void getActionByExternalRefPermissionsCheck() {
assertPermissions(() -> controllerManagement.getActionByExternalRef("externalRef"), assertPermissions(() -> controllerManagement.getActionByExternalRef("externalRef"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -266,7 +265,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
assertPermissions(() -> { assertPermissions(() -> {
controllerManagement.deleteExistingTarget("controllerId"); controllerManagement.deleteExistingTarget("controllerId");
return null; 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(); final Target target = testdataFactory.createTarget();
assertPermissions( assertPermissions(
() -> controllerManagement.getInstalledActionByTarget(target), () -> controllerManagement.getInstalledActionByTarget(target),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -287,7 +286,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
void activateAutoConfirmationPermissionsCheck() { void activateAutoConfirmationPermissionsCheck() {
assertPermissions( assertPermissions(
() -> controllerManagement.activateAutoConfirmation("controllerId", "initiator", "remark"), () -> controllerManagement.activateAutoConfirmation("controllerId", "initiator", "remark"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -298,7 +297,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
assertPermissions(() -> { assertPermissions(() -> {
controllerManagement.deactivateAutoConfirmation("controllerId"); controllerManagement.deactivateAutoConfirmation("controllerId");
return null; return null;
}, List.of(SpringEvalExpressions.CONTROLLER_ROLE)); }, List.of(SpRole.CONTROLLER_ROLE));
} }
/** /**
@@ -307,7 +306,7 @@ class ControllerManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void updateOfflineAssignedVersionPermissionsCheck() { void updateOfflineAssignedVersionPermissionsCheck() {
assertPermissions(() -> controllerManagement.updateOfflineAssignedVersion("controllerId", "distributionName", "version"), assertPermissions(() -> controllerManagement.updateOfflineAssignedVersion("controllerId", "distributionName", "version"),
List.of(SpringEvalExpressions.CONTROLLER_ROLE)); List.of(SpRole.CONTROLLER_ROLE));
} }
} }

View File

@@ -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.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException; 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.SpRole.CONTROLLER_ROLE;
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.repository.jpa.configuration.Constants.TX_RT_MAX; 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.model.Action.ActionType.DOWNLOAD_ONLY;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;

View File

@@ -55,7 +55,8 @@ class DeploymentManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void offlineAssignedDistributionSetsPermissionsCheck() { 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));
} }
/** /**

View File

@@ -14,7 +14,6 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.junit.jupiter.api.Test; 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_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_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(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_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_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(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));
} }
/** /**

View File

@@ -12,7 +12,7 @@ package org.eclipse.hawkbit.repository.test.util;
import static org.assertj.core.api.Assertions.assertThat; 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.SpPermission.READ_TENANT_CONFIGURATION;
import static org.eclipse.hawkbit.im.authentication.SpRole.SYSTEM_ROLE; 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.File;
import java.io.IOException; import java.io.IOException;

View File

@@ -45,10 +45,10 @@ public class SecurityContextSwitch {
public static <T> T callAs(final WithUser withUser, final Callable<T> callable) throws Exception { public static <T> T callAs(final WithUser withUser, final Callable<T> callable) throws Exception {
final SecurityContext oldContext = SecurityContextHolder.getContext(); final SecurityContext oldContext = SecurityContextHolder.getContext();
setSecurityContext(withUser); setSecurityContext(withUser);
try {
if (withUser.autoCreateTenant()) { if (withUser.autoCreateTenant()) {
createTenant(withUser.tenantId()); createTenant(withUser.tenantId());
} }
try {
return callable.call(); return callable.call();
} finally { } finally {
SecurityContextHolder.setContext(oldContext); SecurityContextHolder.setContext(oldContext);

View File

@@ -36,25 +36,38 @@ import org.springframework.util.function.SingletonSupplier;
@Slf4j @Slf4j
public final class SpPermission { public final class SpPermission {
public static final String CREATE_TARGET = "CREATE_TARGET"; // Permission prefixes
public static final String READ_TARGET = "READ_TARGET"; public static final String CREATE_PREFIX = "CREATE_";
public static final String UPDATE_TARGET = "UPDATE_TARGET"; public static final String READ_PREFIX = "READ_";
public static final String DELETE_TARGET = "DELETE_TARGET"; 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 * Permission to read the target security token. The security token is security
* concerned and should be protected. So the combination * concerned and should be protected. So the combination
* {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to * {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to
* be able to read the security token of a target. * 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_PREFIX + TARGET_TYPE;
public static final String READ_TARGET_TYPE = "READ_TARGET_TYPE"; public static final String UPDATE_TARGET_TYPE = UPDATE_PREFIX + TARGET_TYPE;
public static final String UPDATE_TARGET_TYPE = "UPDATE_TARGET_TYPE"; public static final String DELETE_TARGET_TYPE = DELETE_PREFIX + TARGET_TYPE;
public static final String DELETE_TARGET_TYPE = "DELETE_TARGET_TYPE";
public static final String READ_DISTRIBUTION_SET = "READ_DISTRIBUTION_SET"; public static final String READ_DISTRIBUTION_SET = READ_PREFIX + DISTRIBUTION_SET;
public static final String UPDATE_DISTRIBUTION_SET = "UPDATE_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 READ_REPOSITORY = "READ_REPOSITORY";
public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY"; public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY";
@@ -66,7 +79,8 @@ public final class SpPermission {
/** /**
* Permission to read the tenant settings. * 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 * 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}, * 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. * 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"; 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 CREATE_ROLLOUT = CREATE_PREFIX + ROLLOUT;
public static final String READ_ROLLOUT = "READ_ROLLOUT"; public static final String READ_ROLLOUT = READ_PREFIX + ROLLOUT;
public static final String UPDATE_ROLLOUT = "UPDATE_ROLLOUT"; public static final String UPDATE_ROLLOUT = UPDATE_PREFIX + ROLLOUT;
public static final String DELETE_ROLLOUT = "DELETE_ROLLOUT"; public static final String DELETE_ROLLOUT = DELETE_PREFIX + ROLLOUT;
/** Permission to approve or deny a rollout prior to starting. */ /** 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. */ /** 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. */ /** 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"; public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN";
@@ -108,7 +118,10 @@ public final class SpPermission {
DELETE_REPOSITORY > DELETE_SOFTWARE_MODULE DELETE_REPOSITORY > DELETE_SOFTWARE_MODULE
"""; """;
public static final String TENANT_CONFIGURATION_HIERARCHY = """ public static final String TENANT_CONFIGURATION_HIERARCHY = """
TENANT_CONFIGURATION > CREATE_TENANT_CONFIGURATION
TENANT_CONFIGURATION > READ_TENANT_CONFIGURATION TENANT_CONFIGURATION > READ_TENANT_CONFIGURATION
TENANT_CONFIGURATION > UPDATE_TENANT_CONFIGURATION
TENANT_CONFIGURATION > DELETE_TENANT_CONFIGURATION
TENANT_CONFIGURATION > READ_GATEWAY_SECURITY_TOKEN TENANT_CONFIGURATION > READ_GATEWAY_SECURITY_TOKEN
"""; """;

View File

@@ -25,10 +25,12 @@ public final class SpRole {
public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN"; public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN";
public static final String TENANT_ADMIN = "ROLE_TENANT_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"; 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 IMPLIES = " > ";
private static final String LINE_BREAK = "\n"; private static final String LINE_BREAK = "\n";

View File

@@ -36,35 +36,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SpringEvalExpressions { public final class SpringEvalExpressions {
public static final String BRACKET_OPEN = "("; public static final String IS_SYSTEM_CODE = "hasAuthority('ROLE_SYSTEM_CODE')";
public static final String BRACKET_CLOSE = ")"; public static final String HAS_AUTH_SYSTEM_ADMIN = "hasAuthority('SYSTEM_ADMIN')";
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;
// evaluated to <permission>_<permissionGroup> (e.g. DISTRIBUTION_SET_CREATE) // evaluated to <permission>_<permissionGroup> (e.g. DISTRIBUTION_SET_CREATE)
public static final String HAS_CREATE_REPOSITORY = "hasPermission(#root, '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_UPDATE_REPOSITORY = "hasPermission(#root, 'UPDATE')";
public static final String HAS_DELETE_REPOSITORY = "hasPermission(#root, 'DELETE')"; 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 IS_CONTROLLER = "hasAnyRole('" + SpRole.CONTROLLER_ROLE_ANONYMOUS + "', '" + SpRole.CONTROLLER_ROLE + "')";
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;
} }

View File

@@ -24,7 +24,6 @@ import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.SpRole; 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.TenantAware;
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
@@ -107,7 +106,7 @@ public class SystemSecurityContext {
*/ */
public <T> T runAsControllerAsTenant(@NotEmpty final String tenant, @NotNull final Callable<T> callable) { public <T> T runAsControllerAsTenant(@NotEmpty final String tenant, @NotNull final Callable<T> callable) {
final SecurityContext oldContext = SecurityContextHolder.getContext(); final SecurityContext oldContext = SecurityContextHolder.getContext();
final List<SimpleGrantedAuthority> authorities = List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)); final List<SimpleGrantedAuthority> authorities = List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE_ANONYMOUS));
try { try {
return tenantAware.runAsTenant(tenant, () -> { return tenantAware.runAsTenant(tenant, () -> {
setCustomSecurityContext(tenant, oldContext.getAuthentication().getPrincipal(), authorities); setCustomSecurityContext(tenant, oldContext.getAuthentication().getPrincipal(), authorities);