From 1a6ab123e39dbb840ab9f6e6c5d08d209589cb9d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 7 Feb 2018 12:39:20 +0100 Subject: [PATCH] Introduce new permission structure for rollout management. (#624) * Introduce new permission structure for rollout management. Signed-off-by: kaizimmerm * JavaDocs Signed-off-by: kaizimmerm * Add target read check for filters. Signed-off-by: kaizimmerm --- .../resource/MgmtRolloutResourceTest.java | 2 +- .../hawkbit/repository/RolloutManagement.java | 16 ++--- .../im/authentication/SpPermission.java | 67 +++++++++++++++---- .../im/authentication/PermissionTest.java | 2 +- .../hawkbit/ui/SpPermissionChecker.java | 64 ++++++++++-------- .../components/AbstractNotificationView.java | 10 +-- .../ui/rollout/RolloutViewMenuItem.java | 2 +- .../ui/rollout/rollout/RolloutListGrid.java | 11 ++- 8 files changed, 116 insertions(+), 58 deletions(-) diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java index e241cd208..d00940884 100644 --- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java +++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java @@ -78,7 +78,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes @Test @Description("Testing that creating rollout with insufficient permission returns forbidden") - @WithUser(allSpPermissions = true, removeFromAllPermission = "ROLLOUT_MANAGEMENT") + @WithUser(allSpPermissions = true, removeFromAllPermission = "CREATE_ROLLOUT") public void createRolloutWithInsufficientPermissionReturnsForbidden() throws Exception { final DistributionSet dsA = testdataFactory.createDistributionSet(""); mvc.perform(post("/rest/v1/rollouts") diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index c06082d27..7b450c31f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -71,7 +71,7 @@ public interface RolloutManagement { * otherwise. * */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) void handleRollouts(); /** @@ -123,7 +123,7 @@ public interface RolloutManagement { * @throws ConstraintViolationException * if rollout or group parameters are invalid. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) Rollout create(@NotNull RolloutCreate create, int amountGroup, @NotNull RolloutGroupConditions conditions); /** @@ -157,7 +157,7 @@ public interface RolloutManagement { * @throws ConstraintViolationException * if rollout or group parameters are invalid */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE) Rollout create(@NotNull RolloutCreate rollout, @NotNull List groups, RolloutGroupConditions conditions); @@ -312,7 +312,7 @@ public interface RolloutManagement { * Only running rollouts can be paused. * */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) void pauseRollout(@NotNull Long rolloutId); /** @@ -329,7 +329,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#PAUSED}. Only * paused rollouts can be resumed. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) void resumeRollout(@NotNull Long rolloutId); /** @@ -350,7 +350,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE) Rollout start(@NotNull Long rolloutId); /** @@ -368,7 +368,7 @@ public interface RolloutManagement { * reference * */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) Rollout update(@NotNull RolloutUpdate update); /** @@ -379,7 +379,7 @@ public interface RolloutManagement { * @param rolloutId * the ID of the rollout to be deleted */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE) void delete(@NotNull Long rolloutId); } diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index efdb33f5b..0015925b4 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -142,9 +142,29 @@ public final class SpPermission { public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION"; /** - * Permission to administrate a rollout management. + * Permission to read a rollout. */ - public static final String ROLLOUT_MANAGEMENT = "ROLLOUT_MANAGEMENT"; + public static final String READ_ROLLOUT = "READ_ROLLOUT"; + + /** + * Permission to create a rollout. + */ + public static final String CREATE_ROLLOUT = "CREATE_ROLLOUT"; + + /** + * Permission to update a rollout. + */ + public static final String UPDATE_ROLLOUT = "UPDATE_ROLLOUT"; + + /** + * Permission to delete a rollout. + */ + public static final String DELETE_ROLLOUT = "DELETE_ROLLOUT"; + + /** + * Permission to start/stop/resume a rollout. + */ + public static final String HANDLE_ROLLOUT = "HANDLE_ROLLOUT"; private SpPermission() { // Constants only @@ -389,29 +409,52 @@ public final class SpPermission { /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} or + * context contains {@link SpPermission#READ_ROLLOUT} or * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + READ_ROLLOUT + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and + * context contains {@link SpPermission#READ_ROLLOUT} and * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX - + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and - * {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}. + * context contains {@link SpPermission#CREATE_ROLLOUT} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = BRACKET_OPEN + HAS_AUTH_PREFIX - + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET - + HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + CREATE_ROLLOUT + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#HANDLE_ROLLOUT} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + HANDLE_ROLLOUT + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#UPDATE_ROLLOUT} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + UPDATE_ROLLOUT + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#DELETE_ROLLOUT} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + DELETE_ROLLOUT + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java index a639a2128..d777452fb 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java @@ -31,7 +31,7 @@ public final class PermissionTest { @Test @Description("Verify the get permission function") public void testGetPermissions() { - final int allPermission = 15; + final int allPermission = 19; final int permissionWithoutSystem = allPermission - 3; final Collection allAuthorities = SpPermission.getAllAuthorities(); final List allAuthoritiesList = PermissionUtils.createAllAuthorityList(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java index b4533447e..dc05dfd6c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java @@ -14,11 +14,11 @@ import org.eclipse.hawkbit.im.authentication.PermissionService; import org.eclipse.hawkbit.im.authentication.SpPermission; /** - * Bean which contains all SP permissions. + * Bean which contains all permissions. * */ public class SpPermissionChecker implements Serializable { - private static final long serialVersionUID = 2757865286212875704L; + private static final long serialVersionUID = 1L; protected transient PermissionService permissionService; @@ -27,7 +27,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP monitor View Permission. + * Gets the monitor View Permission. * * @return SYSTEM_MONITOR boolean value */ @@ -36,7 +36,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP diagnosis retrieval Permission. + * Gets the diagnosis retrieval Permission. * * @return SYSTEM_DIAG boolean value */ @@ -45,7 +45,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP read Target & Dist Permission. + * Gets the read Target & Dist Permission. * * @return TARGET_REPOSITORY_READ boolean value */ @@ -54,7 +54,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP read Target Permission. + * Gets the read Target Permission. * * @return READ_TARGET boolean value */ @@ -63,7 +63,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP create Target Permission. + * Gets the create Target Permission. * * @return READ_TARGET boolean value */ @@ -72,7 +72,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP update Target Permission. + * Gets the update Target Permission. * * @return READ_TARGET boolean value */ @@ -81,7 +81,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP delete Target Permission. + * Gets the delete Target Permission. * * @return READ_TARGET boolean value */ @@ -90,7 +90,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP READ Repository Permission. + * Gets the READ Repository Permission. * * @return READ_REPOSITORY boolean value */ @@ -99,7 +99,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP create Repository Permission. + * Gets the create Repository Permission. * * @return CREATE_REPOSITORY boolean value */ @@ -108,7 +108,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP update Repository Permission. + * Gets the update Repository Permission. * * @return UPDATE_REPOSITORY boolean value */ @@ -117,7 +117,7 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP delete Repository Permission. + * Has the delete Repository Permission. * * @return DELETE_REPOSITORY boolean value */ @@ -126,41 +126,47 @@ public class SpPermissionChecker implements Serializable { } /** - * Gets the SP rollout create permission. + * Has the rollout update permission. * * @return permission for rollout update */ public boolean hasRolloutUpdatePermission() { - return hasUpdateTargetPermission() && hasReadRepositoryPermission() - && permissionService.hasPermission(SpPermission.ROLLOUT_MANAGEMENT); + return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.UPDATE_ROLLOUT); } /** - * Gets the SP rollout create permission. - * - * @return permission for rollout create + * @return true if rollout create permission */ public boolean hasRolloutCreatePermission() { - return hasUpdateTargetPermission() && hasReadRepositoryPermission() - && permissionService.hasPermission(SpPermission.ROLLOUT_MANAGEMENT); + return hasTargetReadPermission() && hasReadRepositoryPermission() + && permissionService.hasPermission(SpPermission.CREATE_ROLLOUT); } /** - * - * Gets the SP rollout read permission. - * - * @return Gets the SP rollout read permission. + * @return true if rollout read permission */ public boolean hasRolloutReadPermission() { - return permissionService.hasPermission(SpPermission.ROLLOUT_MANAGEMENT); + return permissionService.hasPermission(SpPermission.READ_ROLLOUT); + } + + /** + * @return true if rollout delete permission + */ + public boolean hasRolloutDeletePermission() { + return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.DELETE_ROLLOUT); + } + + /** + * @return true if rollout handle permission. + */ + public boolean hasRolloutHandlePermission() { + return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.HANDLE_ROLLOUT); } /** - * Gets the SP rollout targets read permission. - * * @return permission to read rollout targets */ public boolean hasRolloutTargetsReadPermission() { - return hasTargetReadPermission() && permissionService.hasPermission(SpPermission.ROLLOUT_MANAGEMENT); + return hasTargetReadPermission() && permissionService.hasPermission(SpPermission.READ_ROLLOUT); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/AbstractNotificationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/AbstractNotificationView.java index 7f5e350fc..b8a352516 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/AbstractNotificationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/AbstractNotificationView.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.components; import static java.util.concurrent.TimeUnit.SECONDS; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -71,10 +72,11 @@ public abstract class AbstractNotificationView extends VerticalLayout implements return; } - eventContainer.getEvents().stream().filter(this::noEventMatch).forEach(event -> { - notificationUnreadButton.incrementUnreadNotification(this, eventContainer); - viewUnreadNotifcations.incrementAndGet(); - }); + eventContainer.getEvents().stream().filter(Objects::nonNull).filter(event -> noEventMatch(event)) + .forEach(event -> { + notificationUnreadButton.incrementUnreadNotification(this, eventContainer); + viewUnreadNotifcations.incrementAndGet(); + }); getDashboardMenuItem().setNotificationUnreadValue(viewUnreadNotifcations); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/RolloutViewMenuItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/RolloutViewMenuItem.java index afbf585f1..6c7dcd5ca 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/RolloutViewMenuItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/RolloutViewMenuItem.java @@ -59,6 +59,6 @@ public class RolloutViewMenuItem extends AbstractDashboardMenuItemNotification { @Override public List getPermissions() { - return Arrays.asList(SpPermission.ROLLOUT_MANAGEMENT); + return Arrays.asList(SpPermission.READ_ROLLOUT); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 8da759c3a..d522ad87b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -195,8 +195,7 @@ public class RolloutListGrid extends AbstractGrid { if (!rolloutUIState.isShowRollOuts() || rolloutChangeEvent.getRolloutId() == null) { return; } - final Optional rollout = rolloutManagement - .getWithDetailedStatus(rolloutChangeEvent.getRolloutId()); + final Optional rollout = rolloutManagement.getWithDetailedStatus(rolloutChangeEvent.getRolloutId()); if (!rollout.isPresent()) { return; @@ -745,6 +744,14 @@ public class RolloutListGrid extends AbstractGrid { if (!permissionChecker.hasRolloutCreatePermission()) { modifiableColumnsList.remove(VIRT_PROP_COPY); } + if (!permissionChecker.hasRolloutDeletePermission()) { + modifiableColumnsList.remove(VIRT_PROP_DELETE); + } + if (!permissionChecker.hasRolloutHandlePermission()) { + modifiableColumnsList.remove(VIRT_PROP_PAUSE); + modifiableColumnsList.remove(VIRT_PROP_RUN); + } + setColumns(modifiableColumnsList.toArray()); }