Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PreAuthorize annotations reviewed and added/adapted where necessary #2166

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ Slice<Action> findActionsByTarget(@NotNull String rsqlParam, @NotEmpty String co
* @return assigned {@link DistributionSet}
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Optional<DistributionSet> getAssignedDistributionSet(@NotEmpty String controllerId);

/**
Expand All @@ -413,6 +414,7 @@ Slice<Action> findActionsByTarget(@NotNull String rsqlParam, @NotEmpty String co
* @return installed {@link DistributionSet}
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Optional<DistributionSet> getInstalledDistributionSet(@NotEmpty String controllerId);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidationCount;
import org.springframework.security.access.prepost.PreAuthorize;

/**
* A DistributionSetInvalidationManagement service provides operations to
Expand All @@ -24,6 +25,8 @@ public interface DistributionSetInvalidationManagement {
* cancels all auto assignments referring this {@link DistributionSet} and
* can not be undone. Optionally, all rollouts and actions referring this
* {@link DistributionSet} can be canceled.
* <p>
* {@link PreAuthorize} missing intentionally as it relies on the permission set defined in the management api methods that it calls internally.
*
* @param distributionSetInvalidation defines the {@link DistributionSet} and options what should be
* canceled
Expand All @@ -33,6 +36,8 @@ public interface DistributionSetInvalidationManagement {
/**
* Counts all entities for a list of {@link DistributionSet}s that will be
* canceled when invalidation is called for those {@link DistributionSet}s.
* <p>
* {@link PreAuthorize} missing intentionally as it relies on the permission set defined in the management api methods that it calls internally.
*
* @param distributionSetInvalidation defines the {@link DistributionSet} and options what should be
* canceled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ public interface TargetManagement {
* @return number of found {@link Target}s.
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
long countByAssignedDistributionSet(long distributionSetId);

/**
Expand All @@ -81,8 +80,7 @@ public interface TargetManagement {
* @return number of found {@link Target}s.
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
long countByInstalledDistributionSet(long distributionSetId);

/**
Expand All @@ -93,8 +91,7 @@ public interface TargetManagement {
* @return <code>true</code> if a {@link Target} exists.
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
boolean existsByInstalledOrAssignedDistributionSet(long distributionSetId);

/**
Expand Down Expand Up @@ -225,7 +222,7 @@ public interface TargetManagement {
* @return a page of the found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
Slice<Target> findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable(@NotNull Pageable pageRequest,
long distributionSetId, @NotNull String rsqlParam);

Expand All @@ -239,7 +236,7 @@ Slice<Target> findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable(@NotNull
* @return the count of found {@link Target}s
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
long countByRsqlAndNonDSAndCompatibleAndUpdatable(long distributionSetId, @NotNull String rsqlParam);

/**
Expand All @@ -254,17 +251,17 @@ Slice<Target> findByTargetFilterQueryAndNonDSAndCompatibleAndUpdatable(@NotNull
* withs
* @return a page of the found {@link Target}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
Slice<Target> findByTargetFilterQueryAndNotInRolloutGroupsAndCompatibleAndUpdatable(@NotNull Pageable pageRequest,
@NotEmpty Collection<Long> groups, @NotNull String targetFilterQuery,
@NotNull DistributionSetType distributionSetType);

@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
Slice<Target> findByNotInGEGroupAndNotInActiveActionGEWeightOrInRolloutAndTargetFilterQueryAndCompatibleAndUpdatable(
@NotNull Pageable pageRequest, final long rolloutId, final int weight, final long firstGroupId, @NotNull String targetFilterQuery,
@NotNull DistributionSetType distributionSetType);

@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
long countByActionsInRolloutGroup(final long rolloutGroupId);

/**
Expand All @@ -277,7 +274,7 @@ Slice<Target> findByNotInGEGroupAndNotInActiveActionGEWeightOrInRolloutAndTarget
* @param rolloutId rolloutId of the rollout to be retried.
* @return a page of the found {@link Target}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
Slice<Target> findByFailedRolloutAndNotInRolloutGroups(@NotNull Pageable pageRequest,
@NotEmpty Collection<Long> groups, @NotNull String rolloutId);

Expand All @@ -292,7 +289,7 @@ Slice<Target> findByFailedRolloutAndNotInRolloutGroups(@NotNull Pageable pageReq
* with
* @return count of the found {@link Target}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(@NotEmpty Collection<Long> groups,
@NotNull String rsqlParam, @NotNull DistributionSetType distributionSetType);

Expand All @@ -305,7 +302,7 @@ long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(@NotEmpty Collect
* @param rolloutId rolloutId of the rollout to be retried.
* @return count of the found {@link Target}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
long countByFailedRolloutAndNotInRolloutGroups(@NotEmpty Collection<Long> groups, @NotNull String rolloutId);

/**
Expand Down Expand Up @@ -526,9 +523,7 @@ Page<Target> findByInstalledDistributionSetAndRsql(@NotNull Pageable pageReq, lo
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
default List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId) {
return assignTag(controllerIds, targetTagId, null);
}
List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId);

/**
* Un-assign a {@link TargetTag} assignment to given {@link Target}s.
Expand All @@ -551,9 +546,7 @@ default List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
default List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId) {
return unassignTag(controllerIds, targetTagId, null);
}
List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId);

/**
* Un-assign a {@link TargetType} assignment to given {@link Target}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
package org.eclipse.hawkbit.repository;

import java.io.Serializable;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
import java.util.function.Function;

Expand All @@ -22,8 +18,6 @@
import org.eclipse.hawkbit.repository.model.PollStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.env.Environment;
import org.springframework.security.access.prepost.PreAuthorize;
Expand Down Expand Up @@ -126,25 +120,6 @@ <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(Strin
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ)
<T> T getGlobalConfigurationValue(String configurationKeyName, Class<T> propertyType);

// PreAuthorize for TENANT_CONFIGURATION_READ won't be applied but actually we want just read target
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_READ_TARGET)
default Function<Target, PollStatus> pollStatusResolver() {
final Duration pollTime = DurationHelper.formattedStringToDuration(
getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
final Duration overdueTime = DurationHelper.formattedStringToDuration(
getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
.getValue());
return target -> {
final Long lastTargetQuery = target.getLastTargetQuery();
if (lastTargetQuery == null) {
return null;
}
final LocalDateTime currentDate = LocalDateTime.now();
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
ZoneId.systemDefault());
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
};
}
Function<Target, PollStatus> pollStatusResolver();
}
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,19 @@ public TargetTypeAssignmentResult unassignType(final Collection<String> controll
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<Target> assignTag(final Collection<String> controllerIds, final long targetTagId,
final Consumer<Collection<String>> notFoundHandler) {
return assignTag0(controllerIds, targetTagId, notFoundHandler);
}

@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<Target> assignTag(final Collection<String> controllerIds, final long targetTagId) {
return assignTag0(controllerIds, targetTagId, null);
}

private List<Target> assignTag0(final Collection<String> controllerIds, final long targetTagId,
final Consumer<Collection<String>> notFoundHandler) {
return updateTag(controllerIds, targetTagId, notFoundHandler, (tag, target) -> {
if (target.getTags().contains(tag)) {
return target;
Expand All @@ -546,6 +559,19 @@ public List<Target> assignTag(final Collection<String> controllerIds, final long
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<Target> unassignTag(final Collection<String> controllerIds, final long targetTagId,
final Consumer<Collection<String>> notFoundHandler) {
return unassignTag0(controllerIds, targetTagId, notFoundHandler);
}

@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<Target> unassignTag(final Collection<String> controllerIds, final long targetTagId) {
return unassignTag0(controllerIds, targetTagId, null);
}

private List<Target> unassignTag0(final Collection<String> controllerIds, final long targetTagId,
final Consumer<Collection<String>> notFoundHandler) {
return updateTag(controllerIds, targetTagId, notFoundHandler, (tag, target) -> {
if (target.getTags().contains(tag)) {
target.removeTag(tag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED;

import java.io.Serializable;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
Expand All @@ -30,10 +35,13 @@
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
import org.eclipse.hawkbit.repository.jpa.repository.TenantConfigurationRepository;
import org.eclipse.hawkbit.repository.model.PollStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -146,6 +154,27 @@ public <T> T getGlobalConfigurationValue(final String configurationKeyName, fina
return CONVERSION_SERVICE.convert(key.getDefaultValue(), propertyType);
}

@Override
public Function<Target, PollStatus> pollStatusResolver() {
final Duration pollTime = DurationHelper.formattedStringToDuration(
getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
final Duration overdueTime = DurationHelper.formattedStringToDuration(
getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
.getValue());
return target -> {
final Long lastTargetQuery = target.getLastTargetQuery();
if (lastTargetQuery == null) {
return null;
}
final LocalDateTime currentDate = LocalDateTime.now();
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
ZoneId.systemDefault());
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
};
}

/**
* Validates the data type of the tenant configuration. If it is possible to
* cast to the given data type.
Expand Down
Loading