From 722c5ad2c2f80e928785a3c7629efeb508a0d51a Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Fri, 19 Jan 2018 11:23:41 +0100 Subject: [PATCH] RedirectController into auto config as default and null pointer fix. (#621) * Vaadin patch and redirect controller to auto config. Signed-off-by: kaizimmerm * Fix potential null pointer. Signed-off-by: kaizimmerm * revert Vaadin update. Signed-off-by: kaizimmerm * Conditional on missing bean. Signed-off-by: kaizimmerm * Fix on permission checks. Signed-off-by: kaizimmerm * Fix permission checks. Signed-off-by: kaizimmerm * Fix nested cascade on delete. Signed-off-by: kaizimmerm --- .../mgmt/ui/MgmtUiAutoConfiguration.java | 14 ++- .../mgmt/ui}/RedirectController.java | 6 +- .../jpa/model/AbstractJpaBaseEntity.java | 5 +- .../repository/jpa/model/JpaRolloutGroup.java | 5 +- .../H2/V1_12_3__cascade_delete___H2.sql | 1 + .../MYSQL/V1_12_3__cascade_delete___MYSQL.sql | 1 + .../artifacts/UploadArtifactViewMenuItem.java | 2 +- .../table/AbstractNamedVersionTable.java | 5 +- .../ui/common/table/AbstractTable.java | 7 +- .../DistributionsViewMenuItem.java | 3 +- .../dstable/DistributionSetTable.java | 14 +-- .../FilterManagementView.java | 2 +- .../FilterManagementViewMenuItem.java | 2 +- .../filtermanagement/TargetFilterTable.java | 45 ++++++--- .../hawkbit/ui/management/DeploymentView.java | 97 ++++++++++++------- .../ui/management/DeploymentViewMenuItem.java | 3 +- .../management/dstable/DistributionTable.java | 9 +- .../dstag/DistributionTagButtons.java | 4 +- .../event/DistributionTagDropEvent.java | 4 +- .../footer/DeleteActionsLayout.java | 7 +- .../management/targettable/TargetTable.java | 20 ++-- .../targettag/TargetTagFilterButtons.java | 13 ++- .../src/main/resources/messages.properties | 2 +- 23 files changed, 173 insertions(+), 98 deletions(-) rename {hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app => hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui}/RedirectController.java (81%) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_3__cascade_delete___H2.sql create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/MYSQL/V1_12_3__cascade_delete___MYSQL.sql diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/MgmtUiAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/MgmtUiAutoConfiguration.java index 06b141bd4..a14657b32 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/MgmtUiAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/MgmtUiAutoConfiguration.java @@ -31,7 +31,7 @@ import org.vaadin.spring.security.annotation.EnableVaadinSecurity; import com.vaadin.spring.annotation.UIScope; /** - * The hawkbit-ui autoconfiguration. + * The Management UI auto configuration. */ @Configuration @EnableVaadinSecurity @@ -41,13 +41,19 @@ import com.vaadin.spring.annotation.UIScope; @Import(MgmtUiConfiguration.class) public class MgmtUiAutoConfiguration { + @Bean + @ConditionalOnMissingBean + RedirectController uiRedirectController() { + return new RedirectController(); + } + /** * A message source bean to add distributed message sources. * * @return the message bean. */ @Bean(name = "messageSource") - public DistributedResourceBundleMessageSource messageSource() { + DistributedResourceBundleMessageSource messageSource() { return new DistributedResourceBundleMessageSource(); } @@ -58,7 +64,7 @@ public class MgmtUiAutoConfiguration { */ @Bean @ConditionalOnMissingBean - public UIEventProvider eventProvider() { + UIEventProvider eventProvider() { return new HawkbitEventProvider(); } @@ -81,7 +87,7 @@ public class MgmtUiAutoConfiguration { @Bean @ConditionalOnMissingBean @UIScope - public EventPushStrategy eventPushStrategy(final ConfigurableApplicationContext applicationContext, + EventPushStrategy eventPushStrategy(final ConfigurableApplicationContext applicationContext, final ScheduledExecutorService executorService, final UIEventBus eventBus, final UIEventProvider eventProvider, final UiProperties uiProperties) { final DelayedEventBusPushStrategy delayedEventBusPushStrategy = new DelayedEventBusPushStrategy(executorService, diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/RedirectController.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/RedirectController.java similarity index 81% rename from hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/RedirectController.java rename to hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/RedirectController.java index e4cb0d820..3871dad01 100644 --- a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/RedirectController.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/ui/RedirectController.java @@ -6,15 +6,15 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.app; +package org.eclipse.hawkbit.autoconfigure.mgmt.ui; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** - * Redirects for convenience of the example apps users. hawkBit's management UI - * is by default not listening on / but on /UI. + * Redirects for convenience. hawkBit's management UI is by default not + * listening on / but on /UI. * */ @Controller diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index b4a1360a5..7431041b2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -121,8 +121,9 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { } private boolean isController() { - return SecurityContextHolder.getContext().getAuthentication() - .getDetails() instanceof TenantAwareAuthenticationDetails + return SecurityContextHolder.getContext().getAuthentication() != null + && SecurityContextHolder.getContext().getAuthentication() + .getDetails() instanceof TenantAwareAuthenticationDetails && ((TenantAwareAuthenticationDetails) SecurityContextHolder.getContext().getAuthentication() .getDetails()).isController(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 4b03bdd8f..290b56f0f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -72,8 +72,9 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) private List rolloutTargetGroup; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "parent_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rolloutgroup")) + // No foreign key to avoid to many nested cascades on delete which some DBs cannot handle + @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }) + @JoinColumn(name = "parent_id") private JpaRolloutGroup parent; @Column(name = "success_condition", nullable = false) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_3__cascade_delete___H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_3__cascade_delete___H2.sql new file mode 100644 index 000000000..9c92242e5 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_3__cascade_delete___H2.sql @@ -0,0 +1 @@ +alter table sp_rolloutgroup drop constraint fk_rolloutgroup_rolloutgroup; \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/MYSQL/V1_12_3__cascade_delete___MYSQL.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/MYSQL/V1_12_3__cascade_delete___MYSQL.sql new file mode 100644 index 000000000..56986b6b9 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/MYSQL/V1_12_3__cascade_delete___MYSQL.sql @@ -0,0 +1 @@ +alter table sp_rolloutgroup drop FOREIGN KEY fk_rolloutgroup_rolloutgroup; \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java index d0e5ec323..dae2cedc6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java @@ -61,6 +61,6 @@ public class UploadArtifactViewMenuItem extends AbstractDashboardMenuItemNotific @Override public List getPermissions() { - return Arrays.asList(SpPermission.CREATE_REPOSITORY, SpPermission.READ_REPOSITORY); + return Arrays.asList(SpPermission.READ_REPOSITORY); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java index 1daf4bc49..e567a9001 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.ui.common.table; +import java.util.Collections; import java.util.List; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; @@ -66,8 +67,8 @@ public abstract class AbstractNamedVersionTable } @Override - protected boolean hasDropPermission() { - return true; + protected List hasMissingPermissionsForDrop() { + return Collections.emptyList(); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java index 2bb182753..3bbc9030d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java @@ -431,8 +431,9 @@ public abstract class AbstractTable extends Table impleme final Transferable transferable = dragEvent.getTransferable(); final Component compsource = transferable.getSourceComponent(); - if (!hasDropPermission()) { - notification.displayValidationError(i18n.getMessage("message.permission.insufficient")); + final List missingPermissions = hasMissingPermissionsForDrop(); + if (!missingPermissions.isEmpty()) { + notification.displayValidationError(i18n.getMessage("message.permission.insufficient", missingPermissions)); return false; } @@ -487,7 +488,7 @@ public abstract class AbstractTable extends Table impleme publishSelectedEntityEvent(entity); } - protected abstract boolean hasDropPermission(); + protected abstract List hasMissingPermissionsForDrop(); protected abstract boolean validateDragAndDropWrapper(final DragAndDropWrapper wrapperSource); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsViewMenuItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsViewMenuItem.java index 84cb58eab..2e912003e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsViewMenuItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsViewMenuItem.java @@ -59,8 +59,7 @@ public class DistributionsViewMenuItem extends AbstractDashboardMenuItemNotifica @Override public List getPermissions() { - return Arrays.asList(SpPermission.CREATE_REPOSITORY, SpPermission.READ_REPOSITORY, - SpPermission.UPDATE_REPOSITORY); + return Arrays.asList(SpPermission.READ_REPOSITORY); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index bdea43c08..8b56586e6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.distributions.dstable; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -17,6 +19,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.TargetManagement; @@ -238,8 +241,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable softwareModulesIdList, final Object distId) { - final Optional distributionSet = distributionSetManagement - .get((Long) distId); + final Optional distributionSet = distributionSetManagement.get((Long) distId); if (!distributionSet.isPresent()) { notification.displayWarning(i18n.getMessage("distributionset.not.exists")); @@ -261,8 +263,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable softwareModule = softwareModuleManagement - .get(softwareModuleId); + final Optional softwareModule = softwareModuleManagement.get(softwareModuleId); if (softwareModule.isPresent() && validSoftwareModule((Long) distId, softwareModule.get())) { final SoftwareModuleIdName softwareModuleIdName = new SoftwareModuleIdName(softwareModuleId, @@ -384,8 +385,9 @@ public class DistributionSetTable extends AbstractNamedVersionTable hasMissingPermissionsForDrop() { + return permissionChecker.hasUpdateRepositoryPermission() ? Collections.emptyList() + : Arrays.asList(SpPermission.UPDATE_REPOSITORY); } private void addTableStyleGenerator() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java index 73c6ab9ae..ce9876b10 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java @@ -73,7 +73,7 @@ public class FilterManagementView extends VerticalLayout implements View { final TargetManagement targetManagement) { this.targetFilterHeader = new TargetFilterHeader(eventBus, filterManagementUIState, permissionChecker); this.targetFilterTable = new TargetFilterTable(i18n, notification, eventBus, filterManagementUIState, - targetFilterQueryManagement, manageDistUIState, targetManagement); + targetFilterQueryManagement, manageDistUIState, targetManagement, permissionChecker); this.createNewFilterHeader = new CreateOrUpdateFilterHeader(i18n, eventBus, filterManagementUIState, targetFilterQueryManagement, permissionChecker, notification, uiProperties, entityFactory, queryTextField); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementViewMenuItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementViewMenuItem.java index 1bd17980f..b6f1635e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementViewMenuItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementViewMenuItem.java @@ -59,7 +59,7 @@ public class FilterManagementViewMenuItem extends AbstractDashboardMenuItemNotif @Override public List getPermissions() { - return Arrays.asList(SpPermission.CREATE_TARGET, SpPermission.READ_TARGET); + return Arrays.asList(SpPermission.READ_TARGET); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java index de8c813e2..e3507ee8f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java @@ -13,8 +13,10 @@ import java.util.Date; import java.util.List; import java.util.Map; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.components.ProxyDistribution; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -67,19 +69,23 @@ public class TargetFilterTable extends Table { private final DistributionSetSelectWindow dsSelectWindow; + private final SpPermissionChecker permChecker; + private Container container; private static final int PROPERTY_DEPT = 3; - public TargetFilterTable(final VaadinMessageSource i18n, final UINotification notification, final UIEventBus eventBus, - final FilterManagementUIState filterManagementUIState, + public TargetFilterTable(final VaadinMessageSource i18n, final UINotification notification, + final UIEventBus eventBus, final FilterManagementUIState filterManagementUIState, final TargetFilterQueryManagement targetFilterQueryManagement, final ManageDistUIState manageDistUIState, - final TargetManagement targetManagement) { + final TargetManagement targetManagement, final SpPermissionChecker permChecker) { this.i18n = i18n; this.notification = notification; this.eventBus = eventBus; this.filterManagementUIState = filterManagementUIState; this.targetFilterQueryManagement = targetFilterQueryManagement; + this.permChecker = permChecker; + this.dsSelectWindow = new DistributionSetSelectWindow(i18n, eventBus, targetManagement, targetFilterQueryManagement, manageDistUIState); @@ -141,10 +147,14 @@ public class TargetFilterTable extends Table { private List getVisbleColumns() { final List columnList = new ArrayList<>(7); columnList.add(new TableColumn(SPUILabelDefinitions.NAME, i18n.getMessage("header.name"), 0.2F)); - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_USER, i18n.getMessage("header.createdBy"), 0.1F)); - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_DATE, i18n.getMessage("header.createdDate"), 0.2F)); - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_BY, i18n.getMessage("header.modifiedBy"), 0.1F)); - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_DATE, i18n.getMessage("header.modifiedDate"), 0.2F)); + columnList + .add(new TableColumn(SPUILabelDefinitions.VAR_CREATED_USER, i18n.getMessage("header.createdBy"), 0.1F)); + columnList.add( + new TableColumn(SPUILabelDefinitions.VAR_CREATED_DATE, i18n.getMessage("header.createdDate"), 0.2F)); + columnList + .add(new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_BY, i18n.getMessage("header.modifiedBy"), 0.1F)); + columnList.add( + new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_DATE, i18n.getMessage("header.modifiedDate"), 0.2F)); columnList.add(new TableColumn(SPUILabelDefinitions.AUTO_ASSIGN_DISTRIBUTION_SET, i18n.getMessage("header.auto.assignment.ds"), 0.1F)); columnList.add(new TableColumn(SPUIDefinitions.CUSTOM_FILTER_DELETE, i18n.getMessage("header.delete"), 0.1F)); @@ -175,12 +185,12 @@ public class TargetFilterTable extends Table { private void onDelete(final ClickEvent event) { /* Display the confirmation */ - final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.getMessage("caption.filter.delete.confirmbox"), - i18n.getMessage("message.delete.filter.confirm"), i18n.getMessage("button.ok"), i18n.getMessage("button.cancel"), ok -> { + final ConfirmationDialog confirmDialog = new ConfirmationDialog( + i18n.getMessage("caption.filter.delete.confirmbox"), i18n.getMessage("message.delete.filter.confirm"), + i18n.getMessage("button.ok"), i18n.getMessage("button.cancel"), ok -> { if (ok) { final Long rowId = (Long) ((Button) event.getComponent()).getData(); - final String deletedFilterName = targetFilterQueryManagement.get(rowId) - .get().getName(); + final String deletedFilterName = targetFilterQueryManagement.get(rowId).get().getName(); targetFilterQueryManagement.delete(rowId); /* @@ -229,10 +239,12 @@ public class TargetFilterTable extends Table { Button updateIcon; if (distSet == null) { updateIcon = SPUIComponentProvider.getButton(buttonId, i18n.getMessage("button.no.auto.assignment"), - i18n.getMessage("button.auto.assignment.desc"), null, false, null, SPUIButtonStyleSmallNoBorder.class); + i18n.getMessage("button.auto.assignment.desc"), null, false, null, + SPUIButtonStyleSmallNoBorder.class); } else { updateIcon = SPUIComponentProvider.getButton(buttonId, distSet.getNameVersion(), - i18n.getMessage("button.auto.assignment.desc"), null, false, null, SPUIButtonStyleSmallNoBorder.class); + i18n.getMessage("button.auto.assignment.desc"), null, false, null, + SPUIButtonStyleSmallNoBorder.class); } updateIcon.addClickListener(this::onClickOfDistributionSetButton); @@ -246,7 +258,12 @@ public class TargetFilterTable extends Table { final Item item = (Item) ((Button) event.getComponent()).getData(); final Long tfqId = (Long) item.getItemProperty(SPUILabelDefinitions.VAR_ID).getValue(); - dsSelectWindow.showForTargetFilter(tfqId); + if (permChecker.hasReadRepositoryPermission()) { + dsSelectWindow.showForTargetFilter(tfqId); + } else { + notification.displayValidationError( + i18n.getMessage("message.permission.insufficient", SpPermission.READ_REPOSITORY)); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java index 2c2cde881..042a10219 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java @@ -136,38 +136,56 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW this.i18n = i18n; this.uiNotification = uiNotification; this.managementUIState = managementUIState; - this.actionHistoryLayout = new ActionHistoryLayout(i18n, deploymentManagement, eventBus, uiNotification, - managementUIState); - this.actionStatusLayout = new ActionStatusLayout(i18n, eventBus, managementUIState); - this.actionStatusMsgLayout = new ActionStatusMsgLayout(i18n, eventBus, managementUIState); - final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout = new CreateUpdateTargetTagLayoutWindow( - i18n, targetTagManagement, entityFactory, eventBus, permChecker, uiNotification); - this.targetTagFilterLayout = new TargetTagFilterLayout(i18n, createUpdateTargetTagLayout, managementUIState, - managementViewClientCriterion, permChecker, eventBus, uiNotification, entityFactory, - targetFilterQueryManagement); - final TargetTable targetTable = new TargetTable(eventBus, i18n, uiNotification, targetManagement, - managementUIState, permChecker, managementViewClientCriterion, distributionSetManagement, - targetTagManagement); - - this.targetTableLayout = new TargetTableLayout(eventbus, targetTable, targetManagement, entityFactory, i18n, - eventBus, uiNotification, managementUIState, managementViewClientCriterion, deploymentManagement, - uiproperties, permChecker, uiNotification, targetTagManagement, distributionSetManagement, uiExecutor); - - this.distributionTagLayout = new DistributionTagLayout(eventbus, managementUIState, i18n, permChecker, eventBus, - distributionSetTagManagement, entityFactory, uiNotification, distFilterParameters, - distributionSetManagement, managementViewClientCriterion); - this.distributionTableLayout = new DistributionTableLayout(i18n, eventBus, permChecker, managementUIState, - distributionSetManagement, distributionSetTypeManagement, managementViewClientCriterion, entityFactory, - uiNotification, distributionSetTagManagement, targetTagManagement, systemManagement, targetManagement, - deploymentManagement); - this.deleteAndActionsLayout = new DeleteActionsLayout(i18n, permChecker, eventBus, uiNotification, - targetTagManagement, distributionSetTagManagement, managementViewClientCriterion, managementUIState, - targetManagement, targetTable, deploymentManagement, distributionSetManagement); this.deploymentViewMenuItem = deploymentViewMenuItem; - actionHistoryLayout.registerDetails(((ActionStatusGrid) actionStatusLayout.getGrid()).getDetailsSupport()); - actionStatusLayout.registerDetails(((ActionStatusMsgGrid) actionStatusMsgLayout.getGrid()).getDetailsSupport()); + if (permChecker.hasTargetReadPermission()) { + this.actionHistoryLayout = new ActionHistoryLayout(i18n, deploymentManagement, eventBus, uiNotification, + managementUIState); + this.actionStatusLayout = new ActionStatusLayout(i18n, eventBus, managementUIState); + this.actionStatusMsgLayout = new ActionStatusMsgLayout(i18n, eventBus, managementUIState); + final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout = new CreateUpdateTargetTagLayoutWindow( + i18n, targetTagManagement, entityFactory, eventBus, permChecker, uiNotification); + this.targetTagFilterLayout = new TargetTagFilterLayout(i18n, createUpdateTargetTagLayout, managementUIState, + managementViewClientCriterion, permChecker, eventBus, uiNotification, entityFactory, + targetFilterQueryManagement); + final TargetTable targetTable = new TargetTable(eventBus, i18n, uiNotification, targetManagement, + managementUIState, permChecker, managementViewClientCriterion, distributionSetManagement, + targetTagManagement); + + this.targetTableLayout = new TargetTableLayout(eventbus, targetTable, targetManagement, entityFactory, i18n, + eventBus, uiNotification, managementUIState, managementViewClientCriterion, deploymentManagement, + uiproperties, permChecker, uiNotification, targetTagManagement, distributionSetManagement, + uiExecutor); + this.deleteAndActionsLayout = new DeleteActionsLayout(i18n, permChecker, eventBus, uiNotification, + targetTagManagement, distributionSetTagManagement, managementViewClientCriterion, managementUIState, + targetManagement, targetTable, deploymentManagement, distributionSetManagement); + + actionHistoryLayout.registerDetails(((ActionStatusGrid) actionStatusLayout.getGrid()).getDetailsSupport()); + actionStatusLayout + .registerDetails(((ActionStatusMsgGrid) actionStatusMsgLayout.getGrid()).getDetailsSupport()); + } else { + this.actionHistoryLayout = null; + this.actionStatusLayout = null; + this.actionStatusMsgLayout = null; + this.targetTagFilterLayout = null; + this.targetTableLayout = null; + this.deleteAndActionsLayout = null; + } + + if (permChecker.hasReadRepositoryPermission()) { + this.distributionTagLayout = new DistributionTagLayout(eventbus, managementUIState, i18n, permChecker, + eventBus, distributionSetTagManagement, entityFactory, uiNotification, distFilterParameters, + distributionSetManagement, managementViewClientCriterion); + this.distributionTableLayout = new DistributionTableLayout(i18n, eventBus, permChecker, managementUIState, + distributionSetManagement, distributionSetTypeManagement, managementViewClientCriterion, + entityFactory, uiNotification, distributionSetTagManagement, targetTagManagement, systemManagement, + targetManagement, deploymentManagement); + } else { + this.distributionTagLayout = null; + this.distributionTableLayout = null; + } + } @PostConstruct @@ -182,7 +200,9 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW @Override public void enter(final ViewChangeEvent event) { - distributionTableLayout.getDistributionTable().selectEntity(managementUIState.getLastSelectedDsIdName()); + if (permChecker.hasReadRepositoryPermission()) { + distributionTableLayout.getDistributionTable().selectEntity(managementUIState.getLastSelectedDsIdName()); + } } @Override @@ -382,17 +402,22 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW private void showOrHideFilterButtons(final int browserWidth) { if (browserWidth < SPUIDefinitions.REQ_MIN_BROWSER_WIDTH) { - targetTagFilterLayout.setVisible(false); - targetTableLayout.setShowFilterButtonVisible(true); - distributionTagLayout.setVisible(false); - distributionTableLayout.setShowFilterButtonVisible(true); + if (permChecker.hasTargetReadPermission()) { + targetTagFilterLayout.setVisible(false); + targetTableLayout.setShowFilterButtonVisible(true); + } + + if (permChecker.hasReadRepositoryPermission()) { + distributionTagLayout.setVisible(false); + distributionTableLayout.setShowFilterButtonVisible(true); + } } else { - if (!managementUIState.isTargetTagFilterClosed()) { + if (permChecker.hasTargetReadPermission() && !managementUIState.isTargetTagFilterClosed()) { targetTagFilterLayout.setVisible(true); targetTableLayout.setShowFilterButtonVisible(false); } - if (!managementUIState.isDistTagFilterClosed()) { + if (permChecker.hasReadRepositoryPermission() && !managementUIState.isDistTagFilterClosed()) { distributionTagLayout.setVisible(true); distributionTableLayout.setShowFilterButtonVisible(false); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentViewMenuItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentViewMenuItem.java index b7412026e..7a2831c99 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentViewMenuItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentViewMenuItem.java @@ -57,8 +57,7 @@ public class DeploymentViewMenuItem extends AbstractDashboardMenuItemNotificatio @Override public List getPermissions() { - return Arrays.asList(SpPermission.CREATE_REPOSITORY, SpPermission.READ_REPOSITORY, SpPermission.CREATE_TARGET, - SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET, SpPermission.UPDATE_REPOSITORY); + return Arrays.asList(SpPermission.READ_REPOSITORY, SpPermission.READ_TARGET); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 90e204f4e..bb9599999 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -9,7 +9,9 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -18,6 +20,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.TargetManagement; @@ -124,6 +127,7 @@ public class DistributionTable extends AbstractNamedVersionTable hasMissingPermissionsForDrop() { + return permissionChecker.hasUpdateTargetPermission() ? Collections.emptyList() + : Arrays.asList(SpPermission.UPDATE_TARGET); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java index 51784245c..b34d434c3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java @@ -61,7 +61,9 @@ public class DistributionTagButtons extends AbstractFilterButtons implements Ref this.managementUIState = managementUIState; this.entityFactory = entityFactory; - addNewTag(entityFactory.tag().create().name(NO_TAG).build()); + if (permChecker.hasReadRepositoryPermission()) { + addNewTag(entityFactory.tag().create().name(NO_TAG).build()); + } } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java index 3c1ca3b8e..1c474cdde 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.management.event; import java.util.List; import java.util.Set; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.ui.SpPermissionChecker; @@ -111,7 +112,8 @@ public class DistributionTagDropEvent implements DropHandler { private boolean checkForDSUpdatePermission() { if (!permChecker.hasUpdateRepositoryPermission()) { - notification.displayValidationError(i18n.getMessage("message.permission.insufficient")); + notification.displayValidationError( + i18n.getMessage("message.permission.insufficient", SpPermission.UPDATE_REPOSITORY)); return false; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java index f1a69e65d..2c0b6723a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java @@ -15,6 +15,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement; @@ -379,7 +380,8 @@ public class DeleteActionsLayout extends AbstractDeleteActionsLayout { private Boolean canTargetBeDeleted() { if (!permChecker.hasDeleteTargetPermission()) { - notification.displayValidationError(i18n.getMessage("message.permission.insufficient")); + notification.displayValidationError( + i18n.getMessage("message.permission.insufficient", SpPermission.DELETE_TARGET)); return false; } return true; @@ -387,7 +389,8 @@ public class DeleteActionsLayout extends AbstractDeleteActionsLayout { private Boolean canDSBeDeleted() { if (!permChecker.hasDeleteRepositoryPermission()) { - notification.displayValidationError(i18n.getMessage("message.permission.insufficient")); + notification.displayValidationError( + i18n.getMessage("message.permission.insufficient", SpPermission.DELETE_REPOSITORY)); return false; } return true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index a7b48df39..3cad09fba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -9,7 +9,9 @@ package org.eclipse.hawkbit.ui.management.targettable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -19,6 +21,7 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.TargetManagement; @@ -479,8 +482,8 @@ public class TargetTable extends AbstractTable { final String tagName = ((DragAndDropWrapper) (event.getTransferable().getSourceComponent())).getData() .toString(); if (tagName.equals(SPUIDefinitions.TARGET_TAG_BUTTON)) { - notification.displayValidationError(i18n.getMessage("message.tag.cannot.be.assigned", - new Object[] { i18n.getMessage("label.no.tag.assigned") })); + notification.displayValidationError( + i18n.getMessage("message.tag.cannot.be.assigned", i18n.getMessage("label.no.tag.assigned"))); return false; } return true; @@ -528,7 +531,7 @@ public class TargetTable extends AbstractTable { final Optional tag = tagManagement.getByName(targTagName); if (!tag.isPresent()) { - notification.displayWarning(i18n.getMessage("targettag.not.exists", new Object[] { targTagName })); + notification.displayWarning(i18n.getMessage("targettag.not.exists", targTagName)); return new TargetTagAssignmentResult(0, 0, 0, Lists.newArrayListWithCapacity(0), Lists.newArrayListWithCapacity(0), null); } @@ -563,8 +566,9 @@ public class TargetTable extends AbstractTable { } @Override - protected boolean hasDropPermission() { - return permChecker.hasUpdateTargetPermission(); + protected List hasMissingPermissionsForDrop() { + return permChecker.hasUpdateTargetPermission() ? Collections.emptyList() + : Arrays.asList(SpPermission.UPDATE_TARGET); } private void dsToTargetAssignment(final DragAndDropEvent event) { @@ -575,13 +579,13 @@ public class TargetTable extends AbstractTable { final Object targetItemId = dropData.getItemIdOver(); LOG.debug("Adding a log to check if targetItemId is null : {} ", targetItemId); if (targetItemId == null) { - getNotification().displayWarning(i18n.getMessage("target.not.exists", new Object[] { "" })); + getNotification().displayWarning(i18n.getMessage("target.not.exists", "")); return; } final Long targetId = (Long) targetItemId; final Optional target = targetManagement.get(targetId); if (!target.isPresent()) { - getNotification().displayWarning(i18n.getMessage("target.not.exists", new Object[] { "" })); + getNotification().displayWarning(i18n.getMessage("target.not.exists", "")); return; } final TargetIdName createTargetIdName = new TargetIdName(target.get()); @@ -635,7 +639,7 @@ public class TargetTable extends AbstractTable { private String getPendingActionMessage(final String message, final String distName, final String controllerId) { if (message == null) { - return i18n.getMessage("message.dist.pending.action", new Object[] { controllerId, distName }); + return i18n.getMessage("message.dist.pending.action", controllerId, distName); } return i18n.getMessage("message.target.assigned.pending"); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java index f500c67c9..83a0eaafa 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.management.targettag; import java.util.List; import java.util.Set; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; @@ -163,7 +164,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref final AbstractTable source = (AbstractTable) tabletransferable.getSourceComponent(); - if (!validateIfSourceisTargetTable(source) && !checkForTargetUpdatePermission()) { + if (!validateIfSourceisTargetTable(source) && !hasTargetUpdatePermission()) { return false; } @@ -182,10 +183,10 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref * * @return boolean */ - private boolean checkForTargetUpdatePermission() { + private boolean hasTargetUpdatePermission() { if (!permChecker.hasUpdateTargetPermission()) { - - notification.displayValidationError(i18n.getMessage("message.permission.insufficient")); + notification.displayValidationError( + i18n.getMessage("message.permission.insufficient", SpPermission.UPDATE_TARGET)); return false; } @@ -201,6 +202,10 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref final String targTagName = HawkbitCommonUtil.removePrefix(targetDetails.getTarget().getId(), SPUIDefinitions.TARGET_TAG_ID_PREFIXS); + if (!hasTargetUpdatePermission()) { + return; + } + final TargetTagAssignmentResult result = targetTable.toggleTagAssignment(targetList, targTagName); publishAssignTargetTagEvent(result); diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index c4f691e08..f1835c857 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -312,7 +312,7 @@ message.no.actionupdateds.available = No other updates available for this action message.mandatory.check = Mandatory details are missing message.target.duplicate.check = Target [ {0} ] must be unique, entered value already exists. message.target.whitespace.check = Please enter a valid controller ID with no whitespaces -message.permission.insufficient = Insufficient permissions to perform this action. +message.permission.insufficient = Missing permissions to perform this action: {0} message.error.temp = The operation cannot be fulfilled due to {0}. Please contact administrator message.dist.alreadyassigned = {0} : {1} is already assigned/installed, cannot be updated message.dist.tag.alreadyassigned = {0} : {1} is already assigned/installed, cannot assign/un-assign to tag