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;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS;
import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS;
import static org.eclipse.hawkbit.im.authentication.SpPermission.TENANT_CONFIGURATION;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs;

View File

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

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

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

View File

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

View File

@@ -15,6 +15,7 @@ import java.util.Optional;
import jakarta.validation.constraints.NotEmpty;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.AutoConfirmationStatus;
@@ -24,10 +25,17 @@ import org.springframework.security.access.prepost.PreAuthorize;
/**
* Service layer for all confirmation related operations.
*/
public interface ConfirmationManagement {
public interface ConfirmationManagement extends PermissionSupport {
String HAS_UPDATE_TARGET_OR_IS_CONTROLLER = SpringEvalExpressions.HAS_UPDATE_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER;
String CONFIRMATION_CODE_MSG_PREFIX = "Confirmation status code: %d";
@Override
default String permissionGroup() {
return SpPermission.TARGET;
}
/**
* Activate auto confirmation for a given controller ID. In case auto confirmation is active already, this method will fail with an exception.
*
@@ -36,7 +44,7 @@ public interface ConfirmationManagement {
* @param remark optional field to set a remark
* @return the persisted {@link AutoConfirmationStatus}
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER)
AutoConfirmationStatus activateAutoConfirmation(@NotEmpty String controllerId, final String initiator, final String remark);
/**
@@ -46,7 +54,7 @@ public interface ConfirmationManagement {
* @param code optional value to specify a code for the created action status
* @param messages optional value to specify message for the created action status
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER)
Action confirmAction(long actionId, Integer code, Collection<String> messages);
/**
@@ -56,7 +64,7 @@ public interface ConfirmationManagement {
* @param code optional value to specify a code for the created action status
* @param messages optional value to specify message for the created action status
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER)
Action denyAction(long actionId, Integer code, Collection<String> messages);
/**
@@ -64,7 +72,7 @@ public interface ConfirmationManagement {
*
* @param controllerId to disable auto confirmation for
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_TARGET_OR_IS_CONTROLLER)
void deactivateAutoConfirmation(@NotEmpty String controllerId);
/**
@@ -73,8 +81,7 @@ public interface ConfirmationManagement {
* @param controllerId to check the state for
* @return instance of {@link AutoConfirmationStatus} wrapped in an {@link Optional}. Present if active and empty if disabled.
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR +
SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + " or " + SpringEvalExpressions.IS_CONTROLLER)
Optional<AutoConfirmationStatus> getStatus(@NotEmpty String controllerId);
/**
@@ -83,6 +90,6 @@ public interface ConfirmationManagement {
* @param controllerId of the target to check
* @return a list of {@link Action}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<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
* @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);
/**
@@ -279,7 +279,7 @@ public interface ControllerManagement {
* @return {@link Target} or {@code null} if it does not exist
* @see Target#getId()
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE)
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + " or " + SpringEvalExpressions.IS_SYSTEM_CODE)
Optional<Target> get(long targetId);
/**

View File

@@ -19,6 +19,7 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
@@ -48,7 +49,15 @@ import org.springframework.security.access.prepost.PreAuthorize;
/**
* A DeploymentManagement service provides operations for the deployment of {@link DistributionSet}s to {@link Target}s.
*/
public interface DeploymentManagement {
public interface DeploymentManagement extends PermissionSupport {
String HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET =
SpringEvalExpressions.HAS_UPDATE_REPOSITORY + " and hasAuthority('READ_" + SpPermission.DISTRIBUTION_SET + "')";
@Override
default String permissionGroup() {
return SpPermission.TARGET;
}
/**
* build a {@link DeploymentRequest} for a target distribution set assignment
@@ -74,7 +83,7 @@ public interface DeploymentManagement {
* @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same
* target and multi-assignment is disabled
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET)
List<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
* 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(
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
* 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);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
@PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET)
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 EntityNotFoundException if action with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
Action cancelAction(long actionId);
/**
@@ -147,7 +156,7 @@ public interface DeploymentManagement {
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countActionsByTarget(@NotNull String rsql, @NotEmpty String controllerId);
/**
@@ -156,7 +165,7 @@ public interface DeploymentManagement {
*
* @return the total amount of stored actions
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countActionsAll();
/**
@@ -166,7 +175,7 @@ public interface DeploymentManagement {
* @param rsql RSQL query.
* @return the total number of actions matching the given RSQL query.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countActions(@NotNull String rsql);
/**
@@ -176,7 +185,7 @@ public interface DeploymentManagement {
* @return the count value of found actions associated to the target
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countActionsByTarget(@NotEmpty String controllerId);
/**
@@ -185,7 +194,7 @@ public interface DeploymentManagement {
* @param actionId to be id of the action
* @return the corresponding {@link Action}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Action> findAction(long actionId);
/**
@@ -196,7 +205,7 @@ public interface DeploymentManagement {
* @param pageable pagination parameter
* @return a paged list of {@link Action}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<Action> findActionsAll(@NotNull Pageable pageable);
/**
@@ -207,7 +216,7 @@ public interface DeploymentManagement {
* @param pageable the page request parameter for paging and sorting the result
* @return a paged list of {@link Action}s.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<Action> findActions(@NotNull String rsql, @NotNull Pageable pageable);
/**
@@ -221,7 +230,7 @@ public interface DeploymentManagement {
* given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<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
* @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);
/**
@@ -242,7 +251,7 @@ public interface DeploymentManagement {
* @return the corresponding {@link Page} of {@link ActionStatus}
* @throws EntityNotFoundException if action with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<ActionStatus> findActionStatusByAction(long actionId, @NotNull Pageable pageable);
/**
@@ -252,7 +261,7 @@ public interface DeploymentManagement {
* @return count of {@link ActionStatus} entries
* @throws EntityNotFoundException if action with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countActionStatusByAction(long actionId);
/**
@@ -263,7 +272,7 @@ public interface DeploymentManagement {
* @param pageable the page request parameter for paging and sorting the result
* @return a page of messages by a specific {@link ActionStatus} id
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<String> findMessagesByActionStatusId(long actionStatusId, @NotNull Pageable pageable);
/**
@@ -272,7 +281,7 @@ public interface DeploymentManagement {
* @param actionId to be id of the action
* @return the corresponding {@link Action}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Action> findActionWithDetails(long actionId);
/**
@@ -283,7 +292,7 @@ public interface DeploymentManagement {
* @return a list of actions associated with the given target
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<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
* @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);
/**
@@ -304,7 +313,7 @@ public interface DeploymentManagement {
* @param maxActionCount max size of returned list
* @return the action
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<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 EntityNotFoundException if action with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
Action forceQuitAction(long actionId);
/**
@@ -334,7 +343,7 @@ public interface DeploymentManagement {
* @return the updated or the found {@link Action}
* @throws EntityNotFoundException if action with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
Action forceTargetAction(long actionId);
/**
@@ -342,7 +351,7 @@ public interface DeploymentManagement {
*
* @param targetIds ids of the {@link Target}s the actions belong to
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void cancelInactiveScheduledActionsForTargets(List<Long> targetIds);
/**
@@ -353,7 +362,7 @@ public interface DeploymentManagement {
* @param distributionSetId to assign
* @param rolloutGroupParentId the parent rollout group the actions should reference. null references the first group
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
void startScheduledActionsByRolloutGroupParent(long rolloutId, long distributionSetId, Long rolloutGroupParentId);
/**
@@ -361,7 +370,7 @@ public interface DeploymentManagement {
*
* @param rolloutGroupActions rollouts group actions part of a same group
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
void startScheduledActions(final List<Action> rolloutGroupActions);
/**
@@ -371,7 +380,7 @@ public interface DeploymentManagement {
* @return assigned {@link DistributionSet}
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<DistributionSet> getAssignedDistributionSet(@NotEmpty String controllerId);
/**
@@ -381,7 +390,7 @@ public interface DeploymentManagement {
* @return installed {@link DistributionSet}
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<DistributionSet> getInstalledDistributionSet(@NotEmpty String controllerId);
/**
@@ -402,7 +411,7 @@ public interface DeploymentManagement {
* @param targetId of target
* @return if actions in CANCELING state are present
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
boolean hasPendingCancellations(@NotNull Long targetId);
/**
@@ -411,6 +420,6 @@ public interface DeploymentManagement {
* @param cancelationType defines if a force or soft cancel is executed
* @param set the distribution set for that the actions should be canceled
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void cancelActionsForDistributionSet(final CancelationType cancelationType, final DistributionSet set);
}

View File

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

View File

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

View File

@@ -21,6 +21,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -38,6 +39,11 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface DistributionSetTypeManagement<T extends DistributionSetType>
extends RepositoryManagement<T, DistributionSetTypeManagement.Create, DistributionSetTypeManagement.Update> {
@Override
default String permissionGroup() {
return SpPermission.DISTRIBUTION_SET;
}
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
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
* otherwise.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE)
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void execute(Rollout rollout);
}

View File

@@ -13,6 +13,7 @@ import java.util.Optional;
import jakarta.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
@@ -27,7 +28,14 @@ import org.springframework.security.access.prepost.PreAuthorize;
/**
* Repository management service for RolloutGroup.
*/
public interface RolloutGroupManagement {
public interface RolloutGroupManagement extends PermissionSupport {
String HAS_READ_ROLLOUT_AND_READ_TARGET = SpringEvalExpressions.HAS_READ_REPOSITORY + " and hasAuthority('READ_" + SpPermission.TARGET + "')";
@Override
default String permissionGroup() {
return SpPermission.ROLLOUT;
}
/**
* Retrieves a page of {@link RolloutGroup}s filtered by a given {@link Rollout} with the detailed status.
@@ -37,7 +45,7 @@ public interface RolloutGroupManagement {
* @return a page of found {@link RolloutGroup}s
* @throws EntityNotFoundException of rollout with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<RolloutGroup> findByRolloutWithDetailedStatus(long rolloutId, @NotNull Pageable pageable);
/**
@@ -46,7 +54,7 @@ public interface RolloutGroupManagement {
* @param rolloutGroupId the ID of the rollout group to find
* @return the found {@link RolloutGroup} by its ID or {@code null} if it does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<RolloutGroup> get(long rolloutGroupId);
/**
@@ -60,7 +68,7 @@ public interface RolloutGroupManagement {
* given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<RolloutGroup> findByRolloutAndRsql(long rolloutId, @NotNull String rsql, @NotNull Pageable pageable);
/**
@@ -74,7 +82,7 @@ public interface RolloutGroupManagement {
* given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<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
* @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);
/**
@@ -93,7 +101,7 @@ public interface RolloutGroupManagement {
* @param rolloutId the ID of the rollout to filter the {@link RolloutGroup}s
* @return a page of found {@link RolloutGroup}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countByRollout(long rolloutId);
/**
@@ -104,7 +112,7 @@ public interface RolloutGroupManagement {
* @return Page<Target> list of targets of a rollout group
* @throws EntityNotFoundException if group with ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
@PreAuthorize(HAS_READ_ROLLOUT_AND_READ_TARGET)
Page<Target> findTargetsOfRolloutGroup(long rolloutGroupId, @NotNull Pageable pageable);
/**
@@ -118,7 +126,7 @@ public interface RolloutGroupManagement {
* given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
@PreAuthorize(HAS_READ_ROLLOUT_AND_READ_TARGET)
Page<Target> findTargetsOfRolloutGroupByRsql(long rolloutGroupId, @NotNull String rsql, @NotNull Pageable pageable);
/**
@@ -127,7 +135,7 @@ public interface RolloutGroupManagement {
* @param rolloutGroupId rollout group id
* @return rolloutGroup with details of targets count for different statuses
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<RolloutGroup> getWithDetailedStatus(long rolloutGroupId);
/**
@@ -137,6 +145,6 @@ public interface RolloutGroupManagement {
* @return the target rollout group count
* @throws EntityNotFoundException if rollout group with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countTargetsOfRolloutsGroup(long rolloutGroupId);
}

View File

@@ -28,6 +28,7 @@ import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -53,14 +54,22 @@ import org.springframework.security.access.prepost.PreAuthorize;
* RolloutManagement to control rollouts e.g. like creating, starting, resuming and pausing rollouts. This service secures all the
* functionality based on the {@link PreAuthorize} annotation on methods.
*/
public interface RolloutManagement {
public interface RolloutManagement extends PermissionSupport {
String HAS_ROLLOUT_APPROVE = "hasPermission(#root, 'APPROVE')";
String HAS_ROLLOUT_HANDLE = "hasPermission(#root, 'HANDLE')";
@Override
default String permissionGroup() {
return SpPermission.ROLLOUT;
}
/**
* Counts all {@link Rollout}s in the repository that are not marked as deleted.
*
* @return number of rollouts
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long count();
/**
@@ -72,7 +81,7 @@ public interface RolloutManagement {
* @param setId the distribution set
* @return the count
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countByDistributionSetIdAndRolloutIsStoppable(long setId);
/**
@@ -102,7 +111,7 @@ public interface RolloutManagement {
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
* exceeded.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE)
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Rollout create(
@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired,
@NotNull RolloutGroupConditions conditions, DynamicRolloutGroupTemplate dynamicRolloutGroupTemplate);
@@ -133,7 +142,7 @@ public interface RolloutManagement {
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
* exceeded.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE)
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Rollout create(@NotNull @Valid Create create, int amountGroup, boolean confirmationRequired,
@NotNull RolloutGroupConditions conditions);
@@ -164,7 +173,7 @@ public interface RolloutManagement {
* @throws AssignmentQuotaExceededException if the maximum number of allowed targets per rollout group is
* exceeded.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE)
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Rollout create(@Valid @NotNull Create rollout, @NotNull @Valid List<GroupCreate> groups, RolloutGroupConditions conditions);
/**
@@ -174,7 +183,7 @@ public interface RolloutManagement {
* @param pageable the page request to sort and limit the result
* @return a page of found rollouts
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<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
* statuses
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Rollout> findAllWithDetailedStatus(boolean deleted, @NotNull Pageable pageable);
/**
@@ -199,7 +208,7 @@ public interface RolloutManagement {
* given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<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
* @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);
/**
@@ -218,7 +227,7 @@ public interface RolloutManagement {
*
* @return a list of active rollouts
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<Long> findActiveRollouts();
/**
@@ -228,7 +237,7 @@ public interface RolloutManagement {
* @return the founded rollout or {@code null} if rollout with given ID does
* not exists
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Rollout> get(long rolloutId);
/**
@@ -238,7 +247,7 @@ public interface RolloutManagement {
* @return the founded rollout or {@code null} if rollout with given name
* does not exists
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Rollout> getByName(@NotEmpty String rolloutName);
/**
@@ -247,7 +256,7 @@ public interface RolloutManagement {
* @param rolloutId rollout id
* @return rollout details of targets count for different statuses
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<Rollout> getWithDetailedStatus(long rolloutId);
/**
@@ -272,7 +281,7 @@ public interface RolloutManagement {
* @throws EntityNotFoundException if rollout or group with given ID does not exist
* @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#RUNNING}. Only running rollouts can be paused.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE)
@PreAuthorize(HAS_ROLLOUT_HANDLE)
void pauseRollout(long rolloutId);
/**
@@ -282,7 +291,7 @@ public interface RolloutManagement {
* @throws EntityNotFoundException if rollout with given ID does not exist
* @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#PAUSED}. Only paused rollouts can be resumed.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE)
@PreAuthorize(HAS_ROLLOUT_HANDLE)
void resumeRollout(long rolloutId);
/**
@@ -296,7 +305,7 @@ public interface RolloutManagement {
* @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts
* waiting for approval can be acted upon.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE)
@PreAuthorize(HAS_ROLLOUT_APPROVE)
Rollout approveOrDeny(long rolloutId, Rollout.ApprovalDecision decision);
/**
@@ -314,7 +323,7 @@ public interface RolloutManagement {
* {@link RolloutStatus#WAITING_FOR_APPROVAL}. Only rollouts
* waiting for approveOrDeny can be acted upon.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE)
@PreAuthorize(HAS_ROLLOUT_APPROVE)
Rollout approveOrDeny(long rolloutId, Rollout.ApprovalDecision decision, String remark);
/**
@@ -330,7 +339,7 @@ public interface RolloutManagement {
* @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#READY}. Only
* ready rollouts can be started.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE)
@PreAuthorize(HAS_ROLLOUT_HANDLE)
Rollout start(long rolloutId);
/**
@@ -342,7 +351,7 @@ public interface RolloutManagement {
* @throws EntityReadOnlyException if rollout is in soft deleted state, i.e. only kept as
* reference
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
Rollout update(@NotNull @Valid Update update);
/**
@@ -351,7 +360,7 @@ public interface RolloutManagement {
*
* @param rolloutId the ID of the rollout to be deleted
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE)
@PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY)
void delete(long rolloutId);
/**
@@ -362,7 +371,7 @@ public interface RolloutManagement {
* @param set the {@link DistributionSet} for that the rollouts should be
* canceled
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void cancelRolloutsForDistributionSet(DistributionSet set);
/**
@@ -373,7 +382,7 @@ public interface RolloutManagement {
* @throws EntityNotFoundException if rollout or group with given ID does not exist
* @throws RolloutIllegalStateException if given rollout is not in {@link RolloutStatus#RUNNING}.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void triggerNextGroup(long rolloutId);
@SuperBuilder

View File

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

View File

@@ -20,6 +20,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -32,6 +33,11 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface SoftwareModuleTypeManagement<T extends SoftwareModuleType>
extends RepositoryManagement<T, SoftwareModuleTypeManagement.Create, SoftwareModuleTypeManagement.Update> {
@Override
default String permissionGroup() {
return SpPermission.SOFTWARE_MODULE;
}
/**
* @param key to search for
* @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 org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -29,7 +30,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
*/
public interface SystemManagement {
/**
* Deletes all data related to a given tenant.
*
@@ -76,18 +76,18 @@ public interface SystemManagement {
/**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()}
*/
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or "
+ "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or "
+ "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or "
+ SpringEvalExpressions.IS_CONTROLLER)
TenantMetaData getTenantMetadata();
/**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()})
*/
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or "
+ "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or "
+ "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or "
+ SpringEvalExpressions.IS_CONTROLLER)
TenantMetaData getTenantMetadataWithoutDetails();
@@ -113,7 +113,7 @@ public interface SystemManagement {
* @param defaultDsType to update
* @return updated {@link TenantMetaData} entity
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
@PreAuthorize("hasAuthority('UPDATE_" + SpPermission.TENANT_CONFIGURATION + "')")
TenantMetaData updateTenantMetadata(long defaultDsType);
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)

View File

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

View File

@@ -9,16 +9,9 @@
*/
package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_OPEN;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_AND;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_DELETE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_SUFFIX;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_DELETE_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_UPDATE_REPOSITORY;
import java.util.Collection;
import java.util.List;
@@ -64,19 +57,16 @@ import org.springframework.util.ObjectUtils;
public interface TargetManagement<T extends Target>
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_AUTO_CONFIRMATION_STATUS = "autoConfirmationStatus";
String DETAILS_TAGS = "tags";
String HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET = BRACKET_OPEN +
HAS_AUTH_PREFIX + SpPermission.READ_DISTRIBUTION_SET + HAS_AUTH_SUFFIX +
HAS_AUTH_AND +
HAS_AUTH_PREFIX + SpPermission.READ_TARGET + HAS_AUTH_SUFFIX +
BRACKET_CLOSE;
@Override
default String permissionGroup() {
return "TARGET";
return SpPermission.TARGET;
}
/**
@@ -86,7 +76,7 @@ public interface TargetManagement<T extends Target>
* @return controller attributes as key/value pairs
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
Map<String, String> getControllerAttributes(@NotEmpty String controllerId);
/**
@@ -98,7 +88,7 @@ public interface TargetManagement<T extends Target>
* @param targetFilterQuery to execute
* @return true if it matches
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET)
@PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET)
boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable(
@NotNull String controllerId, long distributionSetId, @NotNull String targetFilterQuery);
@@ -108,7 +98,7 @@ public interface TargetManagement<T extends Target>
* @param controllerIDs to look for.
* @return List of found{@link Target}s
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
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}
* @return {@link Target}
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
Target getWithDetails(@NotEmpty String controllerId, String detailsKey);
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
default Target getWithDetails(@NotEmpty String controllerId) {
return getWithDetails(controllerId, DETAILS_BASE);
}
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
default Target getWithAutoConfigurationStatus(@NotEmpty String controllerId) {
return getWithDetails(controllerId, DETAILS_AUTO_CONFIRMATION_STATUS);
}
@@ -141,7 +131,7 @@ public interface TargetManagement<T extends Target>
* @return a page of the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET)
@PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET)
Slice<Target> findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable(
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
* @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(
@NotEmpty Collection<Long> groups, @NotNull String rsql, @NotNull DistributionSetType distributionSetType,
@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
* @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(
@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(
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
* @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);
/**
@@ -196,7 +186,7 @@ public interface TargetManagement<T extends Target>
* @return the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET)
@PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET)
Page<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 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);
/**
@@ -223,7 +213,7 @@ public interface TargetManagement<T extends Target>
* compatible with
* @return the found number of{@link Target}s
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
long countByRsqlAndCompatible(@NotEmpty String rsql, @NotNull Long distributionSetIdTypeId);
/**
@@ -234,7 +224,7 @@ public interface TargetManagement<T extends Target>
* @param dsTypeId ID of the {@link DistributionSetType} the targets need to be compatible with
* @return the found number of{@link Target}s
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
long countByFailedInRollout(@NotEmpty String rolloutId, @NotNull Long dsTypeId);
/**
@@ -246,7 +236,7 @@ public interface TargetManagement<T extends Target>
* @return the count of found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET)
@PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET)
long countByRsqlAndNonDsAndCompatibleAndUpdatable(long distributionSetId, @NotNull String rsql);
/**
@@ -258,7 +248,7 @@ public interface TargetManagement<T extends Target>
* @param distributionSetType type of the {@link DistributionSet} the targets must be compatible with
* @return count of the found {@link Target}s
*/
@PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
@PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT)
long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(
@NotNull String rsql, @NotEmpty Collection<Long> groups, @NotNull DistributionSetType distributionSetType);
@@ -270,10 +260,10 @@ public interface TargetManagement<T extends Target>
* @param groups the list of {@link RolloutGroup}s
* @return count of the found {@link Target}s
*/
@PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
@PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT)
long countByFailedRolloutAndNotInRolloutGroups(@NotNull String rolloutId, @NotEmpty Collection<Long> groups);
@PreAuthorize(HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
@PreAuthorize(HAS_READ_TARGET_AND_READ_ROLLOUT)
long countByActionsInRolloutGroup(final long rolloutGroupId);
/**
@@ -282,7 +272,7 @@ public interface TargetManagement<T extends Target>
* @param controllerId to look for.
* @return {@link Target}
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
Optional<Target> getByControllerId(@NotEmpty String controllerId);
/**
@@ -293,7 +283,7 @@ public interface TargetManagement<T extends Target>
* @return the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_READ_TARGET)
@PreAuthorize(HAS_READ_TARGET_AND_READ_DISTRIBUTION_SET)
Page<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 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);
/**
@@ -320,7 +310,7 @@ public interface TargetManagement<T extends Target>
* @return list of matching targets
* @throws EntityNotFoundException if target tag with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
Page<Target> findByTag(long tagId, @NotNull Pageable pageable);
/**
@@ -335,7 +325,7 @@ public interface TargetManagement<T extends Target>
* given {@code fieldNameProvider}
* @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);
@@ -345,7 +335,7 @@ public interface TargetManagement<T extends Target>
* @param controllerId the controller ID of the target to be deleted
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_DELETE_TARGET)
@PreAuthorize(HAS_DELETE_REPOSITORY)
void deleteByControllerId(@NotEmpty String controllerId);
/**
@@ -356,7 +346,7 @@ public interface TargetManagement<T extends Target>
* @return the unassigned target
* @throws EntityNotFoundException if TargetType with given target ID does not exist
*/
@PreAuthorize(HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
Target assignType(@NotEmpty String controllerId, @NotNull Long targetTypeId);
/**
@@ -365,7 +355,7 @@ public interface TargetManagement<T extends Target>
* @param controllerId to un-assign for
* @return the unassigned target
*/
@PreAuthorize(HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
Target unassignType(@NotEmpty String controllerId);
/**
@@ -377,7 +367,7 @@ public interface TargetManagement<T extends Target>
* @return list of assigned targets
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
*/
@PreAuthorize(HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
List<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
* @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);
/**
@@ -398,7 +388,7 @@ public interface TargetManagement<T extends Target>
* @return the found Tag set
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
Set<TargetTag> getTags(@NotEmpty String controllerId);
/**
@@ -410,7 +400,7 @@ public interface TargetManagement<T extends Target>
* @return list of unassigned targets
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
*/
@PreAuthorize(HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
List<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
* @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);
/**
@@ -430,7 +420,7 @@ public interface TargetManagement<T extends Target>
* @param group target group parameter
* @param rsql rsql filter for {@link Target}
*/
@PreAuthorize(HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void assignTargetGroupWithRsql(String group, @NotNull String rsql);
/**
@@ -439,7 +429,7 @@ public interface TargetManagement<T extends Target>
* @param group target group parameter
* @param controllerIds list of targets
*/
@PreAuthorize(HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void assignTargetsWithGroup(String group, @NotEmpty List<String> controllerIds);
/**
@@ -450,7 +440,7 @@ public interface TargetManagement<T extends Target>
* @param pageable - page parameter
* @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);
/**
@@ -458,7 +448,7 @@ public interface TargetManagement<T extends Target>
*
* @return list of all distinct target groups
*/
@PreAuthorize(HAS_AUTH_READ_TARGET)
@PreAuthorize(HAS_READ_REPOSITORY)
List<String> findGroups();
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -22,6 +22,7 @@ import java.util.stream.StreamSupport;
import jakarta.persistence.EntityManager;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.ContextAware;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.RepositoryProperties;
@@ -112,6 +113,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
private final PlatformTransactionManager txManager;
private final AfterTransactionCommitExecutor afterCommit;
private final TenantAware tenantAware;
private final ContextAware contextAware;
private final RepositoryProperties repositoryProperties;
private final Map<Long, AtomicLong> lastDynamicGroupFill = new ConcurrentHashMap<>();
@@ -125,7 +127,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy,
final EntityManager entityManager, final PlatformTransactionManager txManager,
final AfterTransactionCommitExecutor afterCommit,
final TenantAware tenantAware, final RepositoryProperties repositoryProperties) {
final TenantAware tenantAware, final ContextAware contextAware, final RepositoryProperties repositoryProperties) {
this.actionRepository = actionRepository;
this.rolloutGroupRepository = rolloutGroupRepository;
this.rolloutTargetGroupRepository = rolloutTargetGroupRepository;
@@ -141,11 +143,23 @@ public class JpaRolloutExecutor implements RolloutExecutor {
this.txManager = txManager;
this.afterCommit = afterCommit;
this.tenantAware = tenantAware;
this.contextAware = contextAware;
this.repositoryProperties = repositoryProperties;
}
@Override
public void execute(final Rollout rollout) {
rollout.getAccessControlContext().ifPresentOrElse(
context -> // has stored context - executes it with it
contextAware.runInContext(context, () -> execute0(rollout)),
() -> // has no stored context - executes it in the tenant & user scope
contextAware.runAsTenantAsUser(contextAware.getCurrentTenant(), rollout.getCreatedBy(), () -> {
execute0(rollout);
return null;
}));
}
private void execute0(final Rollout rollout) {
log.debug("Processing rollout {}", rollout.getId());
switch (rollout.getStatus()) {

View File

@@ -112,22 +112,8 @@ public class JpaRolloutHandler implements RolloutHandler {
DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId, status -> {
rolloutManagement.get(rolloutId).ifPresentOrElse(
rollout ->
// auditor is retrieved and set on transaction commit if not overridden, the system user will be the auditor
rollout.getAccessControlContext().ifPresentOrElse(
context -> // has stored context - executes it with it
contextAware.runInContext(
context,
() -> rolloutExecutor.execute(rollout)),
() -> // has no stored context - executes it in the tenant & user scope
contextAware.runAsTenantAsUser(
contextAware.getCurrentTenant(),
rollout.getCreatedBy(), () -> {
rolloutExecutor.execute(rollout);
return null;
})),
() -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.",
rolloutId));
rolloutExecutor::execute,
() -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.", rolloutId));
return 0L;
});

View File

@@ -13,7 +13,7 @@ import java.io.ByteArrayInputStream;
import java.util.List;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
import org.eclipse.hawkbit.repository.test.util.WithUser;
@@ -60,7 +60,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test
void getPermissionCheck() {
assertPermissions(() -> artifactManagement.get(1L), List.of(SpPermission.READ_REPOSITORY));
assertPermissions(() -> artifactManagement.get(1L), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.get(1L), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
/**
@@ -71,7 +71,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest {
assertPermissions(() -> artifactManagement.getByFilenameAndSoftwareModule("filename", 1L),
List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.getByFilenameAndSoftwareModule("filename", 1L),
List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
/**
@@ -80,7 +80,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test
void findFirstBySHA1PermissionCheck() {
assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpPermission.READ_REPOSITORY));
assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.findFirstBySHA1("sha1"), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
/**
@@ -89,7 +89,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test
void getByFilenamePermissionCheck() {
assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpPermission.READ_REPOSITORY));
assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.getByFilename("filename"), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
/**
@@ -114,7 +114,7 @@ class ArtifactManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test
void loadArtifactBinaryPermissionCheck() {
assertPermissions(() -> artifactManagement.loadArtifactBinary("sha1", 1L, false), List.of(SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.loadArtifactBinary("sha1", 1L, false), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> artifactManagement.loadArtifactBinary("sha1", 1L, false), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
}

View File

@@ -27,6 +27,7 @@ import java.util.concurrent.Callable;
import jakarta.validation.ConstraintViolationException;
import org.apache.commons.io.IOUtils;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.repository.artifact.model.DbArtifact;
import org.eclipse.hawkbit.repository.artifact.model.DbArtifactHash;
import org.eclipse.hawkbit.im.authentication.SpPermission;
@@ -425,7 +426,8 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
* Trys and fails to load an artifact without required permission. Checks if expected InsufficientPermissionException is thrown.
*/
@Test
@WithUser(allSpPermissions = true, removeFromAllPermission = { SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT })
@WithUser(allSpPermissions = true, removeFromAllPermission = {
SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT, SpRole.CONTROLLER_ROLE, SpRole.CONTROLLER_ROLE_ANONYMOUS })
void loadArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() {
assertThatExceptionOfType(InsufficientPermissionException.class)
.as("Should not have worked with missing permission.")

View File

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

View File

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

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

View File

@@ -55,7 +55,8 @@ class DeploymentManagementSecurityTest extends AbstractJpaIntegrationTest {
*/
@Test
void offlineAssignedDistributionSetsPermissionsCheck() {
assertPermissions(() -> deploymentManagement.offlineAssignedDistributionSets(List.of()), List.of(SpPermission.READ_REPOSITORY));
assertPermissions(() -> deploymentManagement.offlineAssignedDistributionSets(List.of()),
List.of(SpPermission.READ_REPOSITORY, SpPermission.UPDATE_TARGET));
}
/**

View File

@@ -14,7 +14,6 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.junit.jupiter.api.Test;
@@ -79,7 +78,7 @@ class SystemManagementSecurityTest extends AbstractJpaIntegrationTest {
assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpPermission.READ_TARGET), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpPermission.READ_TENANT_CONFIGURATION), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadata(), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
/**
@@ -90,7 +89,7 @@ class SystemManagementSecurityTest extends AbstractJpaIntegrationTest {
assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpPermission.READ_REPOSITORY), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpPermission.READ_TARGET), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpPermission.READ_TENANT_CONFIGURATION), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpringEvalExpressions.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
assertPermissions(() -> systemManagement.getTenantMetadataWithoutDetails(), List.of(SpRole.CONTROLLER_ROLE), List.of(SpPermission.CREATE_REPOSITORY));
}
/**

View File

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

View File

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

View File

@@ -36,25 +36,38 @@ import org.springframework.util.function.SingletonSupplier;
@Slf4j
public final class SpPermission {
public static final String CREATE_TARGET = "CREATE_TARGET";
public static final String READ_TARGET = "READ_TARGET";
public static final String UPDATE_TARGET = "UPDATE_TARGET";
public static final String DELETE_TARGET = "DELETE_TARGET";
// Permission prefixes
public static final String CREATE_PREFIX = "CREATE_";
public static final String READ_PREFIX = "READ_";
public static final String UPDATE_PREFIX = "UPDATE_";
public static final String DELETE_PREFIX = "DELETE_";
// Permission groups
public static final String TARGET = "TARGET";
public static final String TARGET_TYPE = "TARGET_TYPE";
public static final String SOFTWARE_MODULE = "SOFTWARE_MODULE";
public static final String DISTRIBUTION_SET = "DISTRIBUTION_SET";
public static final String ROLLOUT = "ROLLOUT";
public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION";
public static final String CREATE_TARGET = CREATE_PREFIX + TARGET;
public static final String READ_TARGET = READ_PREFIX + TARGET;
public static final String UPDATE_TARGET = UPDATE_PREFIX + TARGET;
public static final String DELETE_TARGET = DELETE_PREFIX + TARGET;
/**
* Permission to read the target security token. The security token is security
* concerned and should be protected. So the combination
* {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to
* be able to read the security token of a target.
*/
public static final String READ_TARGET_SEC_TOKEN = "READ_TARGET_SECURITY_TOKEN";
public static final String READ_TARGET_SEC_TOKEN = READ_TARGET + "_SECURITY_TOKEN";
public static final String CREATE_TARGET_TYPE = "CREATE_TARGET_TYPE";
public static final String READ_TARGET_TYPE = "READ_TARGET_TYPE";
public static final String UPDATE_TARGET_TYPE = "UPDATE_TARGET_TYPE";
public static final String DELETE_TARGET_TYPE = "DELETE_TARGET_TYPE";
public static final String READ_TARGET_TYPE = READ_PREFIX + TARGET_TYPE;
public static final String UPDATE_TARGET_TYPE = UPDATE_PREFIX + TARGET_TYPE;
public static final String DELETE_TARGET_TYPE = DELETE_PREFIX + TARGET_TYPE;
public static final String READ_DISTRIBUTION_SET = "READ_DISTRIBUTION_SET";
public static final String UPDATE_DISTRIBUTION_SET = "UPDATE_DISTRIBUTION_SET";
public static final String READ_DISTRIBUTION_SET = READ_PREFIX + DISTRIBUTION_SET;
public static final String UPDATE_DISTRIBUTION_SET = UPDATE_PREFIX + DISTRIBUTION_SET;
public static final String READ_REPOSITORY = "READ_REPOSITORY";
public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY";
@@ -66,7 +79,8 @@ public final class SpPermission {
/**
* Permission to read the tenant settings.
*/
public static final String READ_TENANT_CONFIGURATION = "READ_TENANT_CONFIGURATION";
public static final String READ_TENANT_CONFIGURATION = READ_PREFIX + TENANT_CONFIGURATION;
/**
* Permission to read the gateway security token. The gateway security token is security
* concerned and should be protected. So in addition to {@linkplain #READ_TENANT_CONFIGURATION},
@@ -74,19 +88,15 @@ public final class SpPermission {
* implies both permissions - so it is sufficient to read the gateway security token.
*/
public static final String READ_GATEWAY_SEC_TOKEN = "READ_GATEWAY_SECURITY_TOKEN";
/**
* Permission to administrate the tenant settings.
*/
public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION";
public static final String CREATE_ROLLOUT = "CREATE_ROLLOUT";
public static final String READ_ROLLOUT = "READ_ROLLOUT";
public static final String UPDATE_ROLLOUT = "UPDATE_ROLLOUT";
public static final String DELETE_ROLLOUT = "DELETE_ROLLOUT";
public static final String CREATE_ROLLOUT = CREATE_PREFIX + ROLLOUT;
public static final String READ_ROLLOUT = READ_PREFIX + ROLLOUT;
public static final String UPDATE_ROLLOUT = UPDATE_PREFIX + ROLLOUT;
public static final String DELETE_ROLLOUT = DELETE_PREFIX + ROLLOUT;
/** Permission to approve or deny a rollout prior to starting. */
public static final String APPROVE_ROLLOUT = "APPROVE_ROLLOUT";
public static final String APPROVE_ROLLOUT = "APPROVE_" + ROLLOUT;
/** Permission to start/stop/resume a rollout. */
public static final String HANDLE_ROLLOUT = "HANDLE_ROLLOUT";
public static final String HANDLE_ROLLOUT = "HANDLE_" + ROLLOUT;
/** Permission to administrate the system on a global, i.e. tenant independent scale. That includes the deletion of tenants. */
public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN";
@@ -108,7 +118,10 @@ public final class SpPermission {
DELETE_REPOSITORY > DELETE_SOFTWARE_MODULE
""";
public static final String TENANT_CONFIGURATION_HIERARCHY = """
TENANT_CONFIGURATION > CREATE_TENANT_CONFIGURATION
TENANT_CONFIGURATION > READ_TENANT_CONFIGURATION
TENANT_CONFIGURATION > UPDATE_TENANT_CONFIGURATION
TENANT_CONFIGURATION > DELETE_TENANT_CONFIGURATION
TENANT_CONFIGURATION > READ_GATEWAY_SECURITY_TOKEN
""";

View File

@@ -25,10 +25,12 @@ public final class SpRole {
public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN";
public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN";
/**
* The role which contains the spring security context in case the system is executing code which is necessary to be privileged.
*/
/** The role which contains the spring security context in case the system is executing code which is necessary to be privileged. */
public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE";
/** The role which contains in the spring security context in case a controller is authenticated */
public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER";
/** The role which contained in the spring security context in case that a controller is authenticated, but only as 'anonymous'. */
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
private static final String IMPLIES = " > ";
private static final String LINE_BREAK = "\n";

View File

@@ -36,35 +36,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SpringEvalExpressions {
public static final String BRACKET_OPEN = "(";
public static final String BRACKET_CLOSE = ")";
public static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'";
public static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE;
public static final String HAS_AUTH_AND = " and ";
public static final String HAS_AUTH_OR = " or ";
/**
* The role which contains in the spring security context in case ancontroller is authenticated.
*/
public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER";
/**
* The role which contained in the spring security context in case that a controller is authenticated, but only as 'anonymous'.
*/
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SpRole.SYSTEM_ROLE + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SpPermission.SYSTEM_ADMIN + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + SpPermission.CREATE_TARGET + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + SpPermission.READ_TARGET + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + SpPermission.DELETE_TARGET + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_CREATE_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.CREATE_TARGET_TYPE + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_UPDATE_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET_TYPE + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_READ_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.READ_TARGET_TYPE + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_DELETE_TARGET_TYPE = HAS_AUTH_PREFIX + SpPermission.DELETE_TARGET_TYPE + HAS_AUTH_SUFFIX;
public static final String IS_SYSTEM_CODE = "hasAuthority('ROLE_SYSTEM_CODE')";
public static final String HAS_AUTH_SYSTEM_ADMIN = "hasAuthority('SYSTEM_ADMIN')";
// evaluated to <permission>_<permissionGroup> (e.g. DISTRIBUTION_SET_CREATE)
public static final String HAS_CREATE_REPOSITORY = "hasPermission(#root, 'CREATE')";
@@ -72,25 +45,5 @@ public final class SpringEvalExpressions {
public static final String HAS_UPDATE_REPOSITORY = "hasPermission(#root, 'UPDATE')";
public static final String HAS_DELETE_REPOSITORY = "hasPermission(#root, 'DELETE')";
public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
+ SpPermission.READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET + HAS_AUTH_SUFFIX
+ BRACKET_CLOSE;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + SpPermission.CREATE_ROLLOUT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + SpPermission.READ_ROLLOUT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + SpPermission.UPDATE_ROLLOUT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + SpPermission.DELETE_ROLLOUT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE = HAS_AUTH_PREFIX + SpPermission.APPROVE_ROLLOUT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + SpPermission.HANDLE_ROLLOUT + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX
+ SpPermission.READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + SpPermission.READ_TARGET + HAS_AUTH_SUFFIX
+ BRACKET_CLOSE;
public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + SpPermission.READ_TENANT_CONFIGURATION + HAS_AUTH_SUFFIX;
public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + SpPermission.TENANT_CONFIGURATION + HAS_AUTH_SUFFIX;
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE + "')";
public static final String IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = IS_CONTROLLER + HAS_AUTH_OR + HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET;
public static final String IS_CONTROLLER = "hasAnyRole('" + SpRole.CONTROLLER_ROLE_ANONYMOUS + "', '" + SpRole.CONTROLLER_ROLE + "')";
}

View File

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