Merge branch 'master' into Rollout_Management_issues_refactor
This commit is contained in:
@@ -166,20 +166,12 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
final LocalArtifact localArtifact = findLocalArtifactByFileResource(fileResource);
|
||||
|
||||
if (localArtifact == null) {
|
||||
LOG.info("target {} requested file resource {} which does not exists to download",
|
||||
secruityToken.getControllerId(), fileResource);
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
|
||||
// check action for this download purposes, the method will throw an
|
||||
// EntityNotFoundException in case the controller is not allowed to
|
||||
// download this file because it's not assigned to an action and not
|
||||
// assigned to this controller. Otherwise no controllerId is set =
|
||||
// anonymous download
|
||||
if (secruityToken.getControllerId() != null) {
|
||||
final Action action = controllerManagement.getActionForDownloadByTargetAndSoftwareModule(
|
||||
secruityToken.getControllerId(), localArtifact.getSoftwareModule());
|
||||
LOG.info("Found action for download authentication request action: {}, resource: {}", action,
|
||||
secruityToken.getFileResource());
|
||||
}
|
||||
checkIfArtifactIsAssignedToTarget(secruityToken, localArtifact);
|
||||
|
||||
final Artifact artifact = convertDbArtifact(artifactManagement.loadLocalArtifactBinary(localArtifact));
|
||||
if (artifact == null) {
|
||||
@@ -213,6 +205,35 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
return getMessageConverter().toMessage(authentificationResponse, messageProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* check action for this download purposes, the method will throw an
|
||||
* EntityNotFoundException in case the controller is not allowed to download
|
||||
* this file because it's not assigned to an action and not assigned to this
|
||||
* controller. Otherwise no controllerId is set = anonymous download
|
||||
*
|
||||
* @param secruityToken
|
||||
* the security token which holds the target ID to check on
|
||||
* @param localArtifact
|
||||
* the local artifact to verify if the given target is allowed to
|
||||
* download this artifact
|
||||
*/
|
||||
private void checkIfArtifactIsAssignedToTarget(final TenantSecurityToken secruityToken,
|
||||
final LocalArtifact localArtifact) {
|
||||
final String controllerId = secruityToken.getControllerId();
|
||||
if (controllerId == null) {
|
||||
LOG.info("anonymous download no authentication check for artifact {}", localArtifact);
|
||||
return;
|
||||
}
|
||||
LOG.debug("no anonymous download request, doing authentication check for target {} and artifact {}",
|
||||
controllerId, localArtifact);
|
||||
if (!controllerManagement.hasTargetArtifactAssigned(controllerId, localArtifact)) {
|
||||
LOG.info("target {} tried to download artifact {} which is not assigned to the target", controllerId,
|
||||
localArtifact);
|
||||
throw new EntityNotFoundException();
|
||||
}
|
||||
LOG.info("download security check for target {} and artifact {} granted", controllerId, localArtifact);
|
||||
}
|
||||
|
||||
private LocalArtifact findLocalArtifactByFileResource(final FileResource fileResource) {
|
||||
if (fileResource.getSha1() != null) {
|
||||
return artifactManagement.findFirstLocalArtifactsBySHA1(fileResource.getSha1());
|
||||
|
||||
@@ -313,11 +313,10 @@ public class AmqpMessageHandlerServiceTest {
|
||||
|
||||
// mock
|
||||
final LocalArtifact localArtifactMock = mock(LocalArtifact.class);
|
||||
final Action actionMock = mock(Action.class);
|
||||
final DbArtifact dbArtifactMock = mock(DbArtifact.class);
|
||||
when(artifactManagementMock.findFirstLocalArtifactsBySHA1(anyString())).thenReturn(localArtifactMock);
|
||||
when(controllerManagementMock.getActionForDownloadByTargetAndSoftwareModule(anyObject(), anyObject()))
|
||||
.thenReturn(actionMock);
|
||||
when(controllerManagementMock.hasTargetArtifactAssigned(securityToken.getControllerId(), localArtifactMock))
|
||||
.thenReturn(true);
|
||||
when(artifactManagementMock.loadLocalArtifactBinary(localArtifactMock)).thenReturn(dbArtifactMock);
|
||||
when(dbArtifactMock.getArtifactId()).thenReturn("artifactId");
|
||||
when(dbArtifactMock.getSize()).thenReturn(1L);
|
||||
|
||||
@@ -28,12 +28,14 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus_;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Target_;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
|
||||
import org.eclipse.hawkbit.repository.specifications.ActionSpecifications;
|
||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
@@ -166,6 +168,31 @@ public class ControllerManagement {
|
||||
return action.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given target has currently or has even been assigned to the
|
||||
* given artifact through the action history list. This can e.g. indicate if
|
||||
* a target is allowed to download a given artifact because it has currently
|
||||
* assigned or had ever been assigned to the target and so it's visible to a
|
||||
* specific target e.g. for downloading.
|
||||
*
|
||||
* @param targetId
|
||||
* the ID of the target to check
|
||||
* @param localArtifact
|
||||
* the artifact to verify if the given target had even been
|
||||
* assigned to
|
||||
* @return {@code true} if the given target has currently or had ever a
|
||||
* relation to the given artifact through the action history,
|
||||
* otherwise {@code false}
|
||||
*/
|
||||
public boolean hasTargetArtifactAssigned(@NotNull final String targetId,
|
||||
@NotNull final LocalArtifact localArtifact) {
|
||||
final Target target = targetRepository.findByControllerId(targetId);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
return actionRepository.count(ActionSpecifications.hasTargetAssignedArtifact(target, localArtifact)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the time of the last time the controller has been connected to
|
||||
* the server.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.specifications;
|
||||
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.ListJoin;
|
||||
import javax.persistence.criteria.SetJoin;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action_;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet_;
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact_;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule_;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
/**
|
||||
* Utility class for {@link Action}s {@link Specification}s. The class provides
|
||||
* Spring Data JPQL Specifications.
|
||||
*
|
||||
*/
|
||||
public class ActionSpecifications {
|
||||
|
||||
private ActionSpecifications() {
|
||||
// utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification which joins all necessary tables to retrieve the dependency
|
||||
* between a target and a local file assignment through the assigen action
|
||||
* of the target. All actions are included, not only active actions.
|
||||
*
|
||||
* @param target
|
||||
* the target to verfiy if the given artifact is currently
|
||||
* assigned or had been assigned
|
||||
* @param localArtifact
|
||||
* the local artifact to check wherever the target had ever been
|
||||
* assigned
|
||||
* @return a specification to use with spring JPA
|
||||
*/
|
||||
public static Specification<Action> hasTargetAssignedArtifact(final Target target,
|
||||
final LocalArtifact localArtifact) {
|
||||
return (actionRoot, query, criteriaBuilder) -> {
|
||||
final Join<Action, DistributionSet> dsJoin = actionRoot.join(Action_.distributionSet);
|
||||
final SetJoin<DistributionSet, SoftwareModule> modulesJoin = dsJoin.join(DistributionSet_.modules);
|
||||
final ListJoin<SoftwareModule, LocalArtifact> artifactsJoin = modulesJoin.join(SoftwareModule_.artifacts);
|
||||
return criteriaBuilder.and(criteriaBuilder.equal(artifactsJoin.get(LocalArtifact_.id), localArtifact.getId()),
|
||||
criteriaBuilder.equal(actionRoot.get(Action_.target), target));
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -157,16 +157,9 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected Item addEntity(final SoftwareModule baseEntity) {
|
||||
final Item item = super.addEntity(baseEntity);
|
||||
|
||||
final String swNameVersion = HawkbitCommonUtil.concatStrings(":", baseEntity.getName(),
|
||||
baseEntity.getVersion());
|
||||
item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue(swNameVersion);
|
||||
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_VENDOR).setValue(baseEntity.getVendor());
|
||||
if (!artifactUploadState.getSelectedSoftwareModules().isEmpty()) {
|
||||
artifactUploadState.getSelectedSoftwareModules().stream().forEach(this::unselect);
|
||||
}
|
||||
@@ -175,6 +168,17 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void updateEntity(final SoftwareModule baseEntity, final Item item) {
|
||||
final String swNameVersion = HawkbitCommonUtil.concatStrings(":", baseEntity.getName(),
|
||||
baseEntity.getVersion());
|
||||
item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue(swNameVersion);
|
||||
item.getItemProperty("swId").setValue(baseEntity.getId());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_VENDOR).setValue(baseEntity.getVendor());
|
||||
super.updateEntity(baseEntity, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableColumn> getTableVisibleColumns() {
|
||||
final List<TableColumn> columnList = super.getTableVisibleColumns();
|
||||
|
||||
@@ -459,12 +459,8 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Item addEntity(final DistributionSet baseEntity) {
|
||||
final Item item = super.addEntity(baseEntity);
|
||||
item.getItemProperty(SPUILabelDefinitions.DIST_ID).setValue(baseEntity.getId());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_IS_DISTRIBUTION_COMPLETE).setValue(baseEntity.isComplete());
|
||||
|
||||
if (manageDistUIState.getSelectedDistributions().isPresent()) {
|
||||
manageDistUIState.getSelectedDistributions().get().stream().forEach(this::unselect);
|
||||
}
|
||||
@@ -472,6 +468,14 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void updateEntity(final DistributionSet baseEntity, final Item item) {
|
||||
item.getItemProperty(SPUILabelDefinitions.DIST_ID).setValue(baseEntity.getId());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_IS_DISTRIBUTION_COMPLETE).setValue(baseEntity.isComplete());
|
||||
super.updateEntity(baseEntity, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDataAvailable(final boolean available) {
|
||||
manageDistUIState.setNoDataAvailableDist(!available);
|
||||
|
||||
@@ -324,17 +324,9 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Item addEntity(final SoftwareModule baseEntity) {
|
||||
final Item item = super.addEntity(baseEntity);
|
||||
|
||||
final String swNameVersion = HawkbitCommonUtil.concatStrings(":", baseEntity.getName(),
|
||||
baseEntity.getVersion());
|
||||
item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue(swNameVersion);
|
||||
item.getItemProperty("swId").setValue(baseEntity.getId());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_VENDOR).setValue(baseEntity.getVendor());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_COLOR).setValue(baseEntity.getType().getColour());
|
||||
|
||||
if (!manageDistUIState.getSelectedSoftwareModules().isEmpty()) {
|
||||
manageDistUIState.getSelectedSoftwareModules().stream().forEach(this::unselect);
|
||||
}
|
||||
@@ -342,6 +334,18 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void updateEntity(final SoftwareModule baseEntity, final Item item) {
|
||||
final String swNameVersion = HawkbitCommonUtil.concatStrings(":", baseEntity.getName(),
|
||||
baseEntity.getVersion());
|
||||
item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue(swNameVersion);
|
||||
item.getItemProperty("swId").setValue(baseEntity.getId());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_VENDOR).setValue(baseEntity.getVendor());
|
||||
item.getItemProperty(SPUILabelDefinitions.VAR_COLOR).setValue(baseEntity.getType().getColour());
|
||||
super.updateEntity(baseEntity, item);
|
||||
}
|
||||
|
||||
private void showArtifactDetailsWindow(final Long itemId, final String nameVersionStr) {
|
||||
final Window atrifactDtlsWindow = new Window();
|
||||
atrifactDtlsWindow.setCaption(HawkbitCommonUtil.getArtifactoryDetailsLabelId(nameVersionStr));
|
||||
|
||||
Reference in New Issue
Block a user