Skip to content

Commit

Permalink
PreAuthorize annotations reviewed and added/adapted where necessary. (#…
Browse files Browse the repository at this point in the history
…2166)

Default methods implementation from ManagementAPI Interfaces moved to classes.

Co-authored-by: vasilchev <vasil.ilchev@bosch.com>
  • Loading branch information
vasilchev and vasilchev authored Jan 6, 2025
1 parent 241a2ae commit 7e7fb0c
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 46 deletions.
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

0 comments on commit 7e7fb0c

Please sign in to comment.