Quota must be checked with conditions over incoming status, not curre… (#1847)
* Quota must be checked with conditions over incoming status, not current persisted in db * Fix Download_Only case where DOWNLOADED is threated as 'final'. Fix ci build tests. * Review findings
This commit is contained in:
@@ -33,6 +33,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.ERROR;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.FINISHED;
|
||||
|
||||
/**
|
||||
@@ -111,13 +112,12 @@ public class JpaActionManagement {
|
||||
*/
|
||||
private boolean isUpdatingActionStatusAllowed(final JpaAction action, final JpaActionStatus actionStatus) {
|
||||
|
||||
final boolean isIntermediateFeedback = (FINISHED != actionStatus.getStatus())
|
||||
&& (Action.Status.ERROR != actionStatus.getStatus());
|
||||
final boolean intermediateStatus = isIntermediateStatus(actionStatus);
|
||||
|
||||
final boolean isAllowedByRepositoryConfiguration = !repositoryProperties.isRejectActionStatusForClosedAction()
|
||||
&& isIntermediateFeedback;
|
||||
final boolean isAllowedByRepositoryConfiguration = intermediateStatus && !repositoryProperties.isRejectActionStatusForClosedAction();
|
||||
|
||||
final boolean isAllowedForDownloadOnlyActions = isDownloadOnly(action) && !isIntermediateFeedback;
|
||||
//in case of download_only action Status#DOWNLOADED is treated as 'final' already, so we accept one final status from device in case it sends
|
||||
final boolean isAllowedForDownloadOnlyActions = isDownloadOnly(action) && action.getStatus() == Action.Status.DOWNLOADED && !intermediateStatus;
|
||||
|
||||
return action.isActive() || isAllowedByRepositoryConfiguration || isAllowedForDownloadOnlyActions;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public class JpaActionManagement {
|
||||
*/
|
||||
private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final JpaAction action) {
|
||||
// information status entry - check for a potential DOS attack
|
||||
assertActionStatusQuota(action);
|
||||
assertActionStatusQuota(actionStatus, action);
|
||||
assertActionStatusMessageQuota(actionStatus);
|
||||
actionStatus.setAction(action);
|
||||
|
||||
@@ -157,9 +157,8 @@ public class JpaActionManagement {
|
||||
// can be overwritten to intercept the persistence of the action status
|
||||
}
|
||||
|
||||
protected void assertActionStatusQuota(final JpaAction action) {
|
||||
final boolean intermediateStatus = FINISHED != action.getStatus() && Action.Status.ERROR != action.getStatus();
|
||||
if (intermediateStatus) {// check for quota only for intermediate statuses
|
||||
protected void assertActionStatusQuota(final JpaActionStatus newActionStatus, final JpaAction action) {
|
||||
if (isIntermediateStatus(newActionStatus)) {// check for quota only for intermediate statuses
|
||||
QuotaHelper.assertAssignmentQuota(action.getId(), 1, quotaManagement.getMaxStatusEntriesPerAction(),
|
||||
ActionStatus.class, Action.class, actionStatusRepository::countByActionId);
|
||||
}
|
||||
@@ -169,4 +168,8 @@ public class JpaActionManagement {
|
||||
QuotaHelper.assertAssignmentQuota(actionStatus.getId(), actionStatus.getMessages().size(),
|
||||
quotaManagement.getMaxMessagesPerActionStatus(), "Message", ActionStatus.class.getSimpleName(), null);
|
||||
}
|
||||
|
||||
private static boolean isIntermediateStatus(final JpaActionStatus actionStatus) {
|
||||
return FINISHED != actionStatus.getStatus() && ERROR != actionStatus.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,37 +9,12 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.management;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.DOWNLOADED;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.FINISHED;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.eclipse.hawkbit.repository.ConfirmationManagement;
|
||||
@@ -115,6 +90,30 @@ import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.DOWNLOADED;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.FINISHED;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
|
||||
/**
|
||||
* JPA based {@link ControllerManagement} implementation.
|
||||
*/
|
||||
@@ -613,7 +612,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
|
||||
break;
|
||||
default:
|
||||
// information status entry - check for a potential DOS attack
|
||||
assertActionStatusQuota(action);
|
||||
assertActionStatusQuota(actionStatus, action);
|
||||
assertActionStatusMessageQuota(actionStatus);
|
||||
break;
|
||||
}
|
||||
@@ -891,7 +890,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
|
||||
final JpaActionStatus statusMessage = create.build();
|
||||
statusMessage.setAction(action);
|
||||
|
||||
assertActionStatusQuota(action);
|
||||
assertActionStatusQuota(statusMessage, action);
|
||||
assertActionStatusMessageQuota(statusMessage);
|
||||
|
||||
return actionStatusRepository.save(statusMessage);
|
||||
|
||||
Reference in New Issue
Block a user