diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java index 40fefefbf..2121e0f7f 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java @@ -17,7 +17,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import jakarta.validation.ValidationException; @@ -88,7 +88,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { private final DeploymentManagement deployManagement; private final SystemManagement systemManagement; private final MgmtDistributionSetMapper mgmtDistributionSetMapper; - private final SystemSecurityContext systemSecurityContext; private final TenantConfigHelper tenantConfigHelper; @SuppressWarnings("java:S107") @@ -112,7 +111,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { this.tenantConfigHelper = TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement); this.mgmtDistributionSetMapper = mgmtDistributionSetMapper; this.systemManagement = systemManagement; - this.systemSecurityContext = systemSecurityContext; } @Override @@ -144,23 +142,27 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { public ResponseEntity> createDistributionSets(final List sets) { log.debug("creating {} distribution sets", sets.size()); // set default Ds type if ds type is null - final String defaultDsKey = systemSecurityContext.runAsSystem(systemManagement.getTenantMetadata().getDefaultDsType()::getKey); + final String defaultDsKey = systemManagement.getTenantMetadata().getDefaultDsType().getKey(); sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey)); - //check if there is already deleted DS Type - for (final MgmtDistributionSetRequestBodyPost ds : sets) { - final Optional opt = distributionSetTypeManagement.findByKey(ds.getType()); - opt.ifPresent(dsType -> { - if (dsType.isDeleted()) { - final String text = "Cannot create Distribution Set from type with key {0}. Distribution Set Type already deleted!"; - final String message = MessageFormat.format(text, dsType.getKey()); - throw new ValidationException(message); - } - }); - } + // check if target ds types exist and are not deleted, also caches them + final Map dsTypeKeyToDsType = sets.stream() + .map(MgmtDistributionSetRequestBodyPost::getType) + .distinct() + .collect(Collectors.toMap( + Function.identity(), + dsTypeKey -> + distributionSetTypeManagement.findByKey(dsTypeKey).map(dsType -> { + if (dsType.isDeleted()) { + throw new ValidationException(MessageFormat.format( + "Cannot create Distribution Set from type with key {0}. Distribution Set Type already deleted!", + dsTypeKey)); + } + return dsType; + }).orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, dsTypeKey)))); - final Collection createdDSets = distributionSetManagement - .create(mgmtDistributionSetMapper.fromRequest(sets)); + final Collection createdDSets = + distributionSetManagement.create(mgmtDistributionSetMapper.fromRequest(sets, defaultDsKey, dsTypeKeyToDsType)); log.debug("{} distribution sets created, return status {}", sets.size(), HttpStatus.CREATED); return new ResponseEntity<>(MgmtDistributionSetMapper.toResponseDistributionSets(createdDSets), HttpStatus.CREATED); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtDistributionSetMapper.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtDistributionSetMapper.java index 2f9a68877..f4882e63b 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtDistributionSetMapper.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/mapper/MgmtDistributionSetMapper.java @@ -17,6 +17,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -63,8 +64,38 @@ public class MgmtDistributionSetMapper { this.systemManagement = systemManagement; } - public List fromRequest(final Collection sets) { - return sets.stream().map(this::fromRequest).toList(); + public List fromRequest( + final Collection sets, + final String defaultDsKey, final Map dsTypeKeyToDsType) { + return sets.stream().map(dsRest -> { + final Set modules = new HashSet<>(); + if (dsRest.getOs() != null) { + modules.add(dsRest.getOs().getId()); + } + if (dsRest.getApplication() != null) { + modules.add(dsRest.getApplication().getId()); + } + if (dsRest.getRuntime() != null) { + modules.add(dsRest.getRuntime().getId()); + } + if (dsRest.getModules() != null) { + dsRest.getModules().forEach(module -> modules.add(module.getId())); + } + // distribution set type, if null by the REST call shall be replaced with the default tenant DS type + final String dsTypeKey = Objects.requireNonNull(dsRest.getType(), "Distribution set type must not be null"); + final DistributionSetType dsType = dsTypeKeyToDsType.get(dsTypeKey); + if (dsType == null) { + // type should never null, cache is prefilled with all types + throw new EntityNotFoundException(DistributionSetType.class, defaultDsKey); + } + return DistributionSetManagement.Create.builder() + .type(dsType) + .name(dsRest.getName()).version(dsRest.getVersion()) + .description(dsRest.getDescription()) + .modules(findSoftwareModuleWithExceptionIfNotFound(modules)) + .requiredMigrationStep(dsRest.getRequiredMigrationStep()) + .build(); + }).toList(); } public static MgmtDistributionSet toResponse(final DistributionSet distributionSet) { @@ -170,36 +201,6 @@ public class MgmtDistributionSetMapper { return sets.stream().map(MgmtDistributionSetMapper::toResponse).toList(); } - private DistributionSetManagement.Create fromRequest(final MgmtDistributionSetRequestBodyPost dsRest) { - final Set modules = new HashSet<>(); - if (dsRest.getOs() != null) { - modules.add(dsRest.getOs().getId()); - } - if (dsRest.getApplication() != null) { - modules.add(dsRest.getApplication().getId()); - } - if (dsRest.getRuntime() != null) { - modules.add(dsRest.getRuntime().getId()); - } - if (dsRest.getModules() != null) { - dsRest.getModules().forEach(module -> modules.add(module.getId())); - } - return DistributionSetManagement.Create.builder() - .type(Optional.ofNullable(dsRest.getType()) - // if the type is supplied the type MUST exist - .map(typeKey -> distributionSetTypeManagement - .findByKey(typeKey) - .orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, typeKey))) - .map(DistributionSetType.class::cast) - // if here, the type is not supplied, use the default type - .orElseGet(() -> systemManagement.getTenantMetadata().getDefaultDsType())) - .name(dsRest.getName()).version(dsRest.getVersion()) - .description(dsRest.getDescription()) - .modules(findSoftwareModuleWithExceptionIfNotFound(modules)) - .requiredMigrationStep(dsRest.getRequiredMigrationStep()) - .build(); - } - private Set findSoftwareModuleWithExceptionIfNotFound(final Set softwareModuleIds) { if (CollectionUtils.isEmpty(softwareModuleIds)) { return Collections.emptySet(); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java index d645d017d..9388894c2 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java @@ -73,7 +73,6 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { principal = "targetTypeTester", allSpPermissions = true, removeFromAllPermission = { SpPermission.CREATE_TARGET, SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET, SpPermission.DELETE_TARGET, - SpPermission.CREATE_REPOSITORY, SpPermission.READ_REPOSITORY, SpPermission.UPDATE_REPOSITORY, SpPermission.DELETE_REPOSITORY, SpPermission.READ_TARGET_TYPE }) void getTargetTypesWithoutPermission() throws Exception { mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON)) diff --git a/hawkbit-mgmt/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java b/hawkbit-mgmt/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java index 38bc808f7..1fea696d6 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java @@ -28,6 +28,16 @@ import org.springframework.http.HttpStatus; */ class PreAuthorizeEnabledTest extends AbstractSecurityTest { + /** + * Tests whether request succeed if a role is granted for the user + */ + @Test + @WithUser(authorities = { SpPermission.READ_DISTRIBUTION_SET }, autoCreateTenant = false) + void successIfHasRole() throws Exception { + mvc.perform(get("/rest/v1/distributionsets")).andExpect(result -> + assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); + } + /** * Tests whether request fail if a role is forbidden for the user */ @@ -38,23 +48,12 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value())); } - /** - * Tests whether request succeed if a role is granted for the user - */ - @Test - @WithUser(authorities = { SpPermission.READ_REPOSITORY }, autoCreateTenant = false) - void successIfHasRole() throws Exception { - mvc.perform(get("/rest/v1/distributionsets")).andExpect(result -> - assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); - } - /** * Tests whether request returns distribution set if a role with scope is granted for the user */ @Test @WithUser(authorities = { - SpPermission.CREATE_REPOSITORY, - SpPermission.READ_REPOSITORY, + "CREATE_DISTRIBUTION_SET", "READ_DISTRIBUTION_SET_TYPE", SpPermission.READ_DISTRIBUTION_SET + "/name==DsOne" }, autoCreateTenant = false) void successIfHasRoleWithScope() throws Exception { createDsOne("successIfHasRoleWithScope"); @@ -69,8 +68,7 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { */ @Test @WithUser(authorities = { - SpPermission.CREATE_REPOSITORY, - SpPermission.READ_REPOSITORY, + "CREATE_DISTRIBUTION_SET", "READ_DISTRIBUTION_SET_TYPE", SpPermission.READ_DISTRIBUTION_SET + "/name==DsOne2" }, autoCreateTenant = false) void failIfHasNoForbiddingScope() throws Exception { createDsOne("failIfHasNoForbiddingScope"); @@ -99,8 +97,7 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> { // returns default DS type because of READ_TARGET assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value()); - assertThat(new ObjectMapper().reader().readValue(result.getResponse().getContentAsString(), HashMap.class)) - .hasSize(1); + assertThat(new ObjectMapper().reader().readValue(result.getResponse().getContentAsString(), HashMap.class)).hasSize(1); }); } diff --git a/hawkbit-monolith/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java b/hawkbit-monolith/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java index 6ee8464bf..5678bd3e4 100644 --- a/hawkbit-monolith/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java +++ b/hawkbit-monolith/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java @@ -28,6 +28,16 @@ import org.springframework.http.HttpStatus; */ class PreAuthorizeEnabledTest extends AbstractSecurityTest { + /** + * Tests whether request succeed if a role is granted for the user + */ + @Test + @WithUser(authorities = { SpPermission.READ_DISTRIBUTION_SET }, autoCreateTenant = false) + void successIfHasRole() throws Exception { + mvc.perform(get("/rest/v1/distributionsets")) + .andExpect(result -> assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); + } + /** * Tests whether request fail if a role is forbidden for the user */ @@ -38,23 +48,12 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { .andExpect(result -> assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value())); } - /** - * Tests whether request succeed if a role is granted for the user - */ - @Test - @WithUser(authorities = { SpPermission.READ_REPOSITORY }, autoCreateTenant = false) - void successIfHasRole() throws Exception { - mvc.perform(get("/rest/v1/distributionsets")) - .andExpect(result -> assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); - } - /** * Tests whether request returns distribution set if a role with scope is granted for the user */ @Test @WithUser(authorities = { - SpPermission.CREATE_REPOSITORY, - SpPermission.READ_REPOSITORY, + "CREATE_DISTRIBUTION_SET", "READ_DISTRIBUTION_SET_TYPE", SpPermission.READ_DISTRIBUTION_SET + "/name==DsOne" }, autoCreateTenant = false) void successIfHasRoleWithScope() throws Exception { createDsOne("successIfHasRoleWithScope"); @@ -69,8 +68,7 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { */ @Test @WithUser(authorities = { - SpPermission.CREATE_REPOSITORY, - SpPermission.READ_REPOSITORY, + "CREATE_DISTRIBUTION_SET", "READ_DISTRIBUTION_SET_TYPE", SpPermission.READ_DISTRIBUTION_SET + "/name==DsOne2" }, autoCreateTenant = false) void failIfHasNoForbiddingScope() throws Exception { createDsOne("failIfHasNoForbiddingScope"); @@ -100,8 +98,7 @@ class PreAuthorizeEnabledTest extends AbstractSecurityTest { .andExpect(result -> { // returns default DS type because of READ_TARGET assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value()); - assertThat(new ObjectMapper().reader().readValue(result.getResponse().getContentAsString(), HashMap.class)) - .hasSize(1); + assertThat(new ObjectMapper().reader().readValue(result.getResponse().getContentAsString(), HashMap.class)).hasSize(1); }); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java index 6e1d44040..83303c8d9 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java @@ -62,7 +62,7 @@ public interface ArtifactManagement extends PermissionSupport { * @param isEncrypted flag to indicate if artifact is encrypted. * @return loaded {@link StoredArtifactInfo} */ - @PreAuthorize("hasAuthority('" + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) + @PreAuthorize("hasAuthority('DOWNLOAD_REPOSITORY_ARTIFACT') or hasAuthority('" + SpPermission.SOFTWARE_MODULE_DOWNLOAD_ARTIFACT + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) ArtifactStream getArtifactStream(@NotEmpty String sha1Hash, long softwareModuleId, final boolean isEncrypted); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 8653c7d8f..d0704d707 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -74,7 +74,7 @@ public interface SystemManagement { /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} */ - @PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or " + @PreAuthorize("hasAuthority('" + SpPermission.READ_DISTRIBUTION_SET + "')" + " or " + "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or " + "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) @@ -83,7 +83,7 @@ public interface SystemManagement { /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()}) */ - @PreAuthorize("hasAuthority('" + SpPermission.READ_REPOSITORY + "')" + " or " + @PreAuthorize("hasAuthority('" + SpPermission.READ_DISTRIBUTION_SET + "')" + " or " + "hasAuthority('READ_" + SpPermission.TARGET + "')" + " or " + "hasAuthority('READ_" + SpPermission.TENANT_CONFIGURATION + "')" + " or " + SpringEvalExpressions.IS_CONTROLLER) diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java index 02c886423..dd67611e5 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/RepositoryConfiguration.java @@ -19,6 +19,7 @@ import org.aopalliance.intercept.MethodInvocation; import org.eclipse.hawkbit.im.authentication.Hierarchy; import org.eclipse.hawkbit.tenancy.configuration.ControllerPollProperties; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -38,6 +39,7 @@ import org.springframework.security.config.annotation.method.configuration.Enabl import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.util.ObjectUtils; import org.springframework.util.function.SingletonSupplier; /** @@ -52,8 +54,16 @@ public class RepositoryConfiguration { @Bean @ConditionalOnMissingBean - static RoleHierarchy roleHierarchy() { - return RoleHierarchyImpl.fromHierarchy(Hierarchy.DEFAULT); + @SuppressWarnings("java:S3358") // java:S3358 better readable this way + RoleHierarchy roleHierarchy( + // if configured replaces the hierarchy completely + @Value("${org.eclipse.hawkbit.hierarchy:}") final String hierarchy, + // if the "hierarchy" property is empty, and this property is configured it is appended to the default hierarchy + @Value("${org.eclipse.hawkbit.hierarchy.ext:}") final String hierarchyExt) { + return RoleHierarchyImpl.fromHierarchy( + ObjectUtils.isEmpty(hierarchy) + ? (ObjectUtils.isEmpty(hierarchyExt) ? Hierarchy.DEFAULT : Hierarchy.DEFAULT + hierarchyExt) + : hierarchy); } @Bean diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java index b8011d8e7..d7c902e0e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java @@ -13,7 +13,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET; -import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_REPOSITORY; import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET; import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_DISTRIBUTION_SET; import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET; @@ -61,7 +60,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { final Action permittedAction = testdataFactory.performAssignment(permitted); runAs(withUser("user", - READ_REPOSITORY, READ_DISTRIBUTION_SET + "/id==" + permitted.getId(), READ_TARGET +"/controllerId==" + permittedAction.getTarget().getControllerId()), () -> { final Long permittedActionId = permitted.getId(); @@ -114,7 +112,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { final SoftwareModule swModule = testdataFactory.createSoftwareModuleOs(); runAs(withUser("user", - READ_REPOSITORY, READ_DISTRIBUTION_SET + "/id==" + permitted.getId() + " or id==" + readOnly.getId(), UPDATE_DISTRIBUTION_SET + "/id==" + permitted.getId()), () -> { // verify distributionSetManagement#assignSoftwareModules @@ -177,7 +174,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { distributionSetManagement.assignTag(Arrays.asList(permitted.getId(), readOnly.getId(), hidden.getId()), dsTagId); runAs(withUser("user", - READ_REPOSITORY, READ_DISTRIBUTION_SET + "/id==" + permitted.getId() + " or id==" + readOnly.getId(), UPDATE_DISTRIBUTION_SET + "/id==" + permitted.getId()), () -> { assertThat(distributionSetManagement.findByTag(dsTagId, Pageable.unpaged()).get().map(Identifiable::getId) @@ -245,7 +241,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { .create(TargetFilterQueryManagement.Create.builder().name("test").query("id==*").build()); runAs(withUser("user", - READ_REPOSITORY, READ_DISTRIBUTION_SET + "/id==" + permitted.getId() + " or id==" + readOnly.getId(), UPDATE_DISTRIBUTION_SET + "/id==" + permitted.getId(), // read / update target needed to update target filter query diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java index 29883f452..c1995a45f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java @@ -13,7 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_ROLLOUT; -import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_REPOSITORY; +import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET; import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_ROLLOUT; import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET; import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET; @@ -126,8 +126,7 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { runAs(withUser("user", READ_TARGET + "/controllerId==" + permittedTarget.getControllerId() + " or controllerId==" + readOnlyTargetControllerId, - UPDATE_TARGET + "/controllerId==" + permittedTarget.getControllerId(), - READ_REPOSITORY), + UPDATE_TARGET + "/controllerId==" + permittedTarget.getControllerId()), () -> { // verify targetManagement#findByTag assertThat( @@ -194,9 +193,9 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { .getControllerId(); runAs(withUser("user", + READ_DISTRIBUTION_SET, READ_TARGET + "/controllerId==" + permittedTarget.getControllerId(), - UPDATE_TARGET + "/controllerId==" + permittedTarget.getControllerId(), - READ_REPOSITORY), () -> { + UPDATE_TARGET + "/controllerId==" + permittedTarget.getControllerId()), () -> { final Long dsId = ds.getId(); assertThat(assignDistributionSet(dsId, permittedTarget.getControllerId()).getAssigned()).isEqualTo(1); // assigning of not allowed target behaves as not found @@ -220,9 +219,9 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { .create(Create.builder().controllerId("device02").updateStatus(TargetUpdateStatus.REGISTERED).build()); runAs(withUser("user", + READ_DISTRIBUTION_SET, READ_TARGET + "/controllerId==" + manageableTarget.getControllerId() + " or controllerId==" + readOnlyTarget.getControllerId(), - UPDATE_TARGET + "/controllerId==" + manageableTarget.getControllerId(), - READ_REPOSITORY), () -> { + UPDATE_TARGET + "/controllerId==" + manageableTarget.getControllerId()), () -> { final Long firstDsId = firstDs.getId(); // assignment is permitted for manageableTarget assertThat(assignDistributionSet(firstDsId, manageableTarget.getControllerId()).getAssigned()).isEqualTo(1); @@ -253,10 +252,10 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { final List hiddenTargets = testdataFactory.createTargets("hidden1", "hidden2", "hidden3", "hidden4", "hidden5"); runAs(withUser("user", + READ_DISTRIBUTION_SET, READ_TARGET + "/controllerId=in=(" + String.join(", ", List.of(updateTargetControllerIds)) + ")" + " or controllerId=in=(" + String.join(", ", List.of(readTargetControllerIds)) + ")", UPDATE_TARGET + "/controllerId=in=(" + String.join(", ", List.of(updateTargetControllerIds)) + ")", - READ_REPOSITORY, CREATE_ROLLOUT, READ_ROLLOUT), () -> { final Rollout rollout = testdataFactory.createRolloutByVariables( "testRollout", "description", updateTargets.size(), "id==*", ds, "50", "5"); @@ -299,7 +298,7 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { READ_TARGET + "/controllerId=in=(" + String.join(", ", List.of(updateTargetControllerIds)) + ")" + " or controllerId=in=(" + String.join(", ", List.of(readTargetControllerIds)) + ")", UPDATE_TARGET + "/controllerId=in=(" + String.join(", ", List.of(updateTargetControllerIds)) + ")", - READ_REPOSITORY + "/id==" + distributionSet.getId()), () -> { + READ_DISTRIBUTION_SET + "/id==" + distributionSet.getId()), () -> { targetFilterQueryManagement.updateAutoAssignDS( new AutoAssignDistributionSetUpdate(targetFilterQuery.getId()).ds(distributionSet.getId())); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java index 3826efd47..f0537a980 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ArtifactManagementTest.java @@ -400,7 +400,8 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest { */ @Test @WithUser(allSpPermissions = true, removeFromAllPermission = { - SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT, SpRole.CONTROLLER_ROLE, SpRole.CONTROLLER_ROLE_ANONYMOUS }) + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT, SpPermission.SOFTWARE_MODULE_DOWNLOAD_ARTIFACT, + SpRole.CONTROLLER_ROLE, SpRole.CONTROLLER_ROLE_ANONYMOUS }) void getArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() { assertThatExceptionOfType(InsufficientPermissionException.class) .as("Should not have worked with missing permission.") diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java index 365c06fd9..6a7ff2d7a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetInvalidationManagementTest.java @@ -16,7 +16,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; @@ -56,21 +55,20 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe final InvalidationTestData invalidationTestData = createInvalidationTestData("verifyInvalidateDistributionSetStopAutoAssignment"); final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.NONE); + Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.NONE); final DistributionSetInvalidationCount distributionSetInvalidationCount = countEntitiesForInvalidation(distributionSetInvalidation); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 0); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); rolloutHandler.handleAll(); - assertThat(targetFilterQueryManagement.find(invalidationTestData.getTargetFilterQuery().getId()).get() + assertThat(targetFilterQueryManagement.find(invalidationTestData.targetFilterQuery().getId()).orElseThrow() .getAutoAssignDistributionSet()).isNull(); - assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus()) + assertThat(rolloutRepository.findById(invalidationTestData.rollout().getId()).orElseThrow().getStatus()) .isNotIn(RolloutStatus.STOPPING, RolloutStatus.FINISHED); - for (final Target target : invalidationTestData.getTargets()) { + for (final Target target : invalidationTestData.targets()) { // if status is pending, the assignment has not been canceled - assertThat(targetRepository.findById(target.getId()).get().getUpdateStatus()) - .isEqualTo(TargetUpdateStatus.PENDING); + assertThat(targetRepository.findById(target.getId()).orElseThrow().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING); assertThat(findActionsByTarget(target)).hasSize(1); assertThat(findActionsByTarget(target).get(0).getStatus()).isEqualTo(Status.RUNNING); } @@ -81,27 +79,25 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe */ @Test void verifyInvalidateDistributionSetDoesNotStopRollouts() { - final InvalidationTestData invalidationTestData = createInvalidationTestData( - "verifyInvalidateDistributionSetStopRollouts"); + final InvalidationTestData invalidationTestData = createInvalidationTestData("verifyInvalidateDistributionSetStopRollouts"); final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.NONE); + Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.NONE); final DistributionSetInvalidationCount distributionSetInvalidationCount = countEntitiesForInvalidation(distributionSetInvalidation); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 0); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); rolloutHandler.handleAll(); - assertThat(targetFilterQueryManagement.find(invalidationTestData.getTargetFilterQuery().getId()).get() + assertThat(targetFilterQueryManagement.find(invalidationTestData.targetFilterQuery().getId()).orElseThrow() .getAutoAssignDistributionSet()).isNull(); - assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus()) + assertThat(rolloutRepository.findById(invalidationTestData.rollout().getId()).orElseThrow().getStatus()) .isEqualTo(RolloutStatus.READY); - assertNoScheduledActionsExist(invalidationTestData.getRollout()); - for (final Target target : invalidationTestData.getTargets()) { + assertNoScheduledActionsExist(invalidationTestData.rollout()); + for (final Target target : invalidationTestData.targets()) { // if status is pending, the assignment has not been canceled - assertThat( - targetRepository.findById(invalidationTestData.getTargets().get(0).getId()).get().getUpdateStatus()) + assertThat(targetRepository.findById(invalidationTestData.targets().get(0).getId()).orElseThrow().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.PENDING); assertThat(findActionsByTarget(target)).hasSize(1); assertThat(findActionsByTarget(target).get(0).getStatus()).isEqualTo(Status.RUNNING); @@ -113,23 +109,22 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe */ @Test void verifyInvalidateDistributionSetStopAllAndForceCancel() { - final InvalidationTestData invalidationTestData = createInvalidationTestData( - "verifyInvalidateDistributionSetStopAllAndForceCancel"); + final InvalidationTestData invalidationTestData = createInvalidationTestData("verifyInvalidateDistributionSetStopAllAndForceCancel"); final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.FORCE); + Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.FORCE); final DistributionSetInvalidationCount distributionSetInvalidationCount = countEntitiesForInvalidation(distributionSetInvalidation); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); rolloutHandler.handleAll(); - assertThat(targetFilterQueryManagement.find(invalidationTestData.getTargetFilterQuery().getId()).get() + assertThat(targetFilterQueryManagement.find(invalidationTestData.targetFilterQuery().getId()).orElseThrow() .getAutoAssignDistributionSet()).isNull(); // rollout should be deleted when force invalidation - assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId())).isEmpty(); - assertNoScheduledActionsExist(invalidationTestData.getRollout()); - assertAllRolloutActionsAreCancelled(invalidationTestData.getRollout()); + assertThat(rolloutRepository.findById(invalidationTestData.rollout().getId())).isEmpty(); + assertNoScheduledActionsExist(invalidationTestData.rollout()); + assertAllRolloutActionsAreCancelled(invalidationTestData.rollout()); } /** @@ -140,19 +135,18 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe final InvalidationTestData invalidationTestData = createInvalidationTestData("verifyInvalidateDistributionSetStopAll"); final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.SOFT); + Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.SOFT); final DistributionSetInvalidationCount distributionSetInvalidationCount = countEntitiesForInvalidation(distributionSetInvalidation); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); - assertThat(targetFilterQueryManagement.find(invalidationTestData.getTargetFilterQuery().getId()).get() + assertThat(targetFilterQueryManagement.find(invalidationTestData.targetFilterQuery().getId()).orElseThrow() .getAutoAssignDistributionSet()).isNull(); - assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus()) + assertThat(rolloutRepository.findById(invalidationTestData.rollout().getId()).orElseThrow().getStatus()) .isIn(RolloutStatus.STOPPING, RolloutStatus.FINISHED); - for (final Target target : invalidationTestData.getTargets()) { - assertThat(targetRepository.findById(target.getId()).get().getUpdateStatus()) - .isEqualTo(TargetUpdateStatus.PENDING); + for (final Target target : invalidationTestData.targets()) { + assertThat(targetRepository.findById(target.getId()).orElseThrow().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING); assertThat(findActionsByTarget(target)).hasSize(1); assertThat(findActionsByTarget(target).get(0).getStatus()).isEqualTo(Status.CANCELING); } @@ -182,74 +176,63 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe void verifyInvalidateInvalidatedDistributionSetDontThrowsException() { final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet(); distributionSetInvalidationManagement.invalidateDistributionSet( - new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()), - ActionCancellationType.SOFT)); + new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()), ActionCancellationType.SOFT)); } /** - * Verify that a user that has authority READ_REPOSITORY and UPDATE_REPOSITORY is allowed to invalidate a distribution set + * Verify that a user that has authority READ_DISTRIBUTION_SET and UPDATE_DISTRIBUTION_SET is allowed to invalidate a distribution set */ @Test - @WithUser(authorities = { "READ_REPOSITORY", "UPDATE_REPOSITORY" }) + @WithUser(authorities = { "READ_DISTRIBUTION_SET", "UPDATE_DISTRIBUTION_SET" }) void verifyInvalidateWithReadAndUpdateRepoAuthority() { final InvalidationTestData invalidationTestData = systemSecurityContext .runAsSystem(() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAuthority")); distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.NONE)); - assertThat( - distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid()) - .isFalse(); + Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.NONE)); + assertThat(distributionSetRepository.findById(invalidationTestData.distributionSet().getId()).orElseThrow().isValid()).isFalse(); } /** - * Verify that a user that has authority READ_REPOSITORY, UPDATE_REPOSITORY and UPDATE_TARGET is allowed to invalidate a distribution set only without canceling rollouts + * Verify that a user that has authority READ_DISTRIBUTION_SET, UPDATE_DISTRIBUTION_SET and UPDATE_TARGET is allowed to invalidate a distribution set only without canceling rollouts */ @Test - @WithUser(authorities = { "READ_REPOSITORY", "UPDATE_REPOSITORY", "UPDATE_TARGET" }) + @WithUser(authorities = { "READ_DISTRIBUTION_SET", "UPDATE_DISTRIBUTION_SET", "UPDATE_TARGET" }) void verifyInvalidateWithReadAndUpdateRepoAndUpdateTargetAuthority() { final InvalidationTestData invalidationTestData = systemSecurityContext.runAsSystem( () -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAndUpdateTargetAuthority")); final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( - List.of(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.SOFT); + List.of(invalidationTestData.distributionSet().getId()), ActionCancellationType.SOFT); assertThatExceptionOfType(InsufficientPermissionException.class) .as("Insufficient permission exception expected") .isThrownBy(() -> distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation)); distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.NONE)); - assertThat( - distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid()) - .isFalse(); + Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.NONE)); + assertThat(distributionSetRepository.findById(invalidationTestData.distributionSet().getId()).orElseThrow().isValid()).isFalse(); } /** - * Verify that a user that has authority READ_REPOSITORY, UPDATE_REPOSITORY, UPDATE_ROLLOUT and UPDATE_TARGET is allowed to invalidate a distribution + * Verify that a user that has authority READ_DISTRIBUTION_SET, UPDATE_DISTRIBUTION_SET, UPDATE_ROLLOUT and UPDATE_TARGET is allowed to invalidate a distribution */ @Test - @WithUser(authorities = { "READ_REPOSITORY", "UPDATE_REPOSITORY", "UPDATE_TARGET", "UPDATE_ROLLOUT" }) + @WithUser(authorities = { "READ_DISTRIBUTION_SET", "UPDATE_DISTRIBUTION_SET", "UPDATE_TARGET", "UPDATE_ROLLOUT" }) void verifyInvalidateWithReadAndUpdateRepoAndUpdateTargetAndUpdateRolloutAuthority() { final InvalidationTestData invalidationTestData = systemSecurityContext.runAsSystem( () -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAndUpdateTargetAuthority")); distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation( - Collections.singletonList(invalidationTestData.getDistributionSet().getId()), ActionCancellationType.SOFT)); - assertThat( - distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid()) - .isFalse(); + List.of(invalidationTestData.distributionSet().getId()), ActionCancellationType.SOFT)); + assertThat(distributionSetRepository.findById(invalidationTestData.distributionSet().getId()).orElseThrow().isValid()).isFalse(); } private void assertNoScheduledActionsExist(final Rollout rollout) { - assertThat( - actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Status.SCHEDULED).getTotalElements()) - .isZero(); + assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Status.SCHEDULED).getTotalElements()).isZero(); } private void assertAllRolloutActionsAreCancelled(final Rollout rollout) { - assertThat( - actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Status.CANCELED).getTotalElements()) - .isZero(); + assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Status.CANCELED).getTotalElements()).isZero(); } private InvalidationTestData createInvalidationTestData(final String testName) { @@ -276,8 +259,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe return actionRepository.findAll(ActionSpecifications.byTargetControllerId(target.getControllerId())); } - private DistributionSetInvalidationCount countEntitiesForInvalidation( - final DistributionSetInvalidation distributionSetInvalidation) { + private DistributionSetInvalidationCount countEntitiesForInvalidation(final DistributionSetInvalidation distributionSetInvalidation) { return systemSecurityContext.runAsSystem(() -> { final Collection setIds = distributionSetInvalidation.getDistributionSetIds(); final long rolloutsCount = distributionSetInvalidation.getActionCancellationType() != ActionCancellationType.NONE ? countRolloutsForInvalidation(setIds) : 0; @@ -317,22 +299,6 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe .sum(); } - @Data - private static class InvalidationTestData { - - private final DistributionSet distributionSet; - private final List targets; - private final TargetFilterQuery targetFilterQuery; - private final Rollout rollout; - - public InvalidationTestData( - final DistributionSet distributionSet, final List targets, - final TargetFilterQuery targetFilterQuery, final Rollout rollout) { - super(); - this.distributionSet = distributionSet; - this.targets = targets; - this.targetFilterQuery = targetFilterQuery; - this.rollout = rollout; - } - } -} + private record InvalidationTestData( + DistributionSet distributionSet, List targets, TargetFilterQuery targetFilterQuery, Rollout rollout) {} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java index 275f96ac4..64124eae8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java @@ -1393,10 +1393,10 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest { final WithUser userWithoutHandleRollout = SecurityContextSwitch.withUser( "user_without_handle_rollout", - SpPermission.READ_REPOSITORY, SpPermission.READ_TARGET, SpPermission.CREATE_ROLLOUT); + SpPermission.READ_DISTRIBUTION_SET, SpPermission.READ_TARGET, SpPermission.CREATE_ROLLOUT); final WithUser userWithHandleRollout = SecurityContextSwitch.withUser( "user_with_handle_rollout", - SpPermission.READ_REPOSITORY, SpPermission.READ_TARGET, SpPermission.CREATE_ROLLOUT, SpPermission.HANDLE_ROLLOUT); + SpPermission.READ_DISTRIBUTION_SET, SpPermission.READ_TARGET, SpPermission.CREATE_ROLLOUT, SpPermission.HANDLE_ROLLOUT); final WithUser userWithSystemRole = SecurityContextSwitch.withUser( "user_with_system_role", SpRole.SYSTEM_ROLE); diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/Hierarchy.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/Hierarchy.java index 19b381657..8e5db9578 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/Hierarchy.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/Hierarchy.java @@ -21,7 +21,6 @@ public class Hierarchy { SpPermission.SOFTWARE_MODULE_HIERARCHY + SpPermission.DISTRIBUTION_SET_HIERARCHY + SpPermission.TENANT_CONFIGURATION_HIERARCHY + - SpRole.DEFAULT_ROLE_HIERARCHY + - SpPermission.REPOSITORY_HIERARCHY; + SpRole.DEFAULT_ROLE_HIERARCHY; // @formatter:on } \ No newline at end of file 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 324f495e5..7a44dc919 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 @@ -67,11 +67,14 @@ public final class SpPermission { public static final String READ_DISTRIBUTION_SET = READ_PREFIX + DISTRIBUTION_SET; public static final String UPDATE_DISTRIBUTION_SET = UPDATE_PREFIX + DISTRIBUTION_SET; - public static final String CREATE_REPOSITORY = "CREATE_REPOSITORY"; - public static final String READ_REPOSITORY = "READ_REPOSITORY"; - public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY"; - public static final String DELETE_REPOSITORY = "DELETE_REPOSITORY"; + /** + * Deprecated since 0.10.0, use {@link #SOFTWARE_MODULE_DOWNLOAD_ARTIFACT} instead + * + * @deprecated since 0.10.0, use {@link #SOFTWARE_MODULE_DOWNLOAD_ARTIFACT} instead + */ + @Deprecated(since = "0.10.0", forRemoval = true) public static final String DOWNLOAD_REPOSITORY_ARTIFACT = "DOWNLOAD_REPOSITORY_ARTIFACT"; + public static final String SOFTWARE_MODULE_DOWNLOAD_ARTIFACT = SOFTWARE_MODULE + "_DOWNLOAD_ARTIFACT"; /** * Permission to read the tenant settings. @@ -124,27 +127,6 @@ public final class SpPermission { TENANT_CONFIGURATION + IMPLY_UPDATE + TENANT_CONFIGURATION + "\n" + TENANT_CONFIGURATION + IMPLY_DELETE + TENANT_CONFIGURATION + "\n" + TENANT_CONFIGURATION + " > " + READ_GATEWAY_SECURITY_TOKEN + "\n"; - public static final String REPOSITORY_HIERARCHY = - CREATE_REPOSITORY + IMPLY_CREATE + TARGET_TYPE + "\n" + - READ_REPOSITORY + IMPLY_READ + TARGET_TYPE + "\n" + - UPDATE_REPOSITORY + IMPLY_UPDATE + TARGET_TYPE + "\n" + - DELETE_REPOSITORY + IMPLY_DELETE + TARGET_TYPE + "\n" + - CREATE_REPOSITORY + IMPLY_CREATE + SOFTWARE_MODULE + "\n" + - READ_REPOSITORY + IMPLY_READ + SOFTWARE_MODULE + "\n" + - UPDATE_REPOSITORY + IMPLY_UPDATE + SOFTWARE_MODULE + "\n" + - DELETE_REPOSITORY + IMPLY_DELETE + SOFTWARE_MODULE + "\n" + - CREATE_REPOSITORY + IMPLY_CREATE + SOFTWARE_MODULE_TYPE + "\n" + - READ_REPOSITORY + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + - UPDATE_REPOSITORY + IMPLY_UPDATE + SOFTWARE_MODULE_TYPE + "\n" + - DELETE_REPOSITORY + IMPLY_DELETE + SOFTWARE_MODULE_TYPE + "\n" + - CREATE_REPOSITORY + IMPLY_CREATE + DISTRIBUTION_SET + "\n" + - READ_REPOSITORY + IMPLY_READ + DISTRIBUTION_SET + "\n" + - UPDATE_REPOSITORY + IMPLY_UPDATE + DISTRIBUTION_SET + "\n" + - DELETE_REPOSITORY + IMPLY_DELETE + DISTRIBUTION_SET + "\n" + - CREATE_REPOSITORY + IMPLY_CREATE + DISTRIBUTION_SET_TYPE + "\n" + - READ_REPOSITORY + IMPLY_READ + DISTRIBUTION_SET_TYPE + "\n" + - UPDATE_REPOSITORY + IMPLY_UPDATE + DISTRIBUTION_SET_TYPE + "\n" + - DELETE_REPOSITORY + IMPLY_DELETE + DISTRIBUTION_SET_TYPE + "\n"; // @formatter:on private static final SingletonSupplier> ALL_AUTHORITIES = SingletonSupplier.of(() -> { @@ -163,7 +145,7 @@ public final class SpPermission { // special allPermissions.add(READ_TARGET_SECURITY_TOKEN); allPermissions.add(READ_GATEWAY_SECURITY_TOKEN); - allPermissions.add(DOWNLOAD_REPOSITORY_ARTIFACT); + allPermissions.add(SOFTWARE_MODULE_DOWNLOAD_ARTIFACT); allPermissions.add(APPROVE_ROLLOUT); allPermissions.add(HANDLE_ROLLOUT); @@ -176,6 +158,9 @@ public final class SpPermission { // system permission, (!) take care with allPermissions.add(SYSTEM_ADMIN); + // add deprecated permissions + allPermissions.add(DOWNLOAD_REPOSITORY_ARTIFACT); + return Collections.unmodifiableList(allPermissions); }); diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java index a01539f91..311799418 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java @@ -46,6 +46,24 @@ public final class SpRole { TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_TYPE + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.UPDATE_TARGET_TYPE + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET_TYPE + LINE_BREAK; + public static final String REPOSITORY_ADMIN_HIERARCHY = + REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_PREFIX + SpPermission.SOFTWARE_MODULE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_PREFIX + SpPermission.SOFTWARE_MODULE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_PREFIX + SpPermission.SOFTWARE_MODULE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_PREFIX + SpPermission.SOFTWARE_MODULE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.SOFTWARE_MODULE_DOWNLOAD_ARTIFACT + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_PREFIX + SpPermission.SOFTWARE_MODULE_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_PREFIX + SpPermission.SOFTWARE_MODULE_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_PREFIX + SpPermission.SOFTWARE_MODULE_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_PREFIX + SpPermission.SOFTWARE_MODULE_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_PREFIX + SpPermission.DISTRIBUTION_SET + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_PREFIX + SpPermission.DISTRIBUTION_SET + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_PREFIX + SpPermission.DISTRIBUTION_SET + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_PREFIX + SpPermission.DISTRIBUTION_SET + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_PREFIX + SpPermission.DISTRIBUTION_SET_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_PREFIX + SpPermission.DISTRIBUTION_SET_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_PREFIX + SpPermission.DISTRIBUTION_SET_TYPE + LINE_BREAK + + REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_PREFIX + SpPermission.DISTRIBUTION_SET_TYPE + LINE_BREAK; public static final String ROLLOUT_ADMIN_HIERARCHY = ROLLOUT_ADMIN + IMPLIES + SpPermission.CREATE_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.READ_ROLLOUT + LINE_BREAK + @@ -56,23 +74,17 @@ public final class SpRole { public static final String TENANT_ADMIN_HIERARCHY = TENANT_ADMIN + IMPLIES + TARGET_ADMIN + LINE_BREAK + TENANT_ADMIN + IMPLIES + REPOSITORY_ADMIN + LINE_BREAK + - TENANT_ADMIN + IMPLIES + SpPermission.TENANT_CONFIGURATION + LINE_BREAK + - TENANT_ADMIN + IMPLIES + ROLLOUT_ADMIN + LINE_BREAK; + TENANT_ADMIN + IMPLIES + ROLLOUT_ADMIN + LINE_BREAK + + TENANT_ADMIN + IMPLIES + SpPermission.TENANT_CONFIGURATION + LINE_BREAK; public static final String SYSTEM_ROLE_HIERARCHY = SYSTEM_ROLE + IMPLIES + TENANT_ADMIN + LINE_BREAK + SYSTEM_ROLE + IMPLIES + SpPermission.SYSTEM_ADMIN + LINE_BREAK; - public static final String REPOSITORY_ADMIN_HIERARCHY = - REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_REPOSITORY + LINE_BREAK + - REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_REPOSITORY + LINE_BREAK + - REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_REPOSITORY + LINE_BREAK + - REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_REPOSITORY + LINE_BREAK + - REPOSITORY_ADMIN + IMPLIES + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + LINE_BREAK; public static final String DEFAULT_ROLE_HIERARCHY = TARGET_ADMIN_HIERARCHY + + REPOSITORY_ADMIN_HIERARCHY + ROLLOUT_ADMIN_HIERARCHY + TENANT_ADMIN_HIERARCHY + - SYSTEM_ROLE_HIERARCHY + - REPOSITORY_ADMIN_HIERARCHY; + SYSTEM_ROLE_HIERARCHY; // @formatter:on } \ No newline at end of file