diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index 145e3c3f3..818ff43df 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -431,7 +431,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { */ @Test @WithUser(allSpPermissions = false, authorities = { SpPermission.READ_TARGET, SpPermission.CREATE_TARGET, - SpPermission.READ_TARGET_SEC_TOKEN }) + SpPermission.READ_TARGET_SECURITY_TOKEN }) void securityTokenIsInResponseWithCorrectPermission() throws Exception { final String knownControllerId = "knownControllerId"; 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 5d1a086f6..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 @@ -71,7 +71,9 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { @Test @WithUser( principal = "targetTypeTester", allSpPermissions = true, - removeFromAllPermission = { SpPermission.READ_TARGET, SpPermission.READ_TARGET_TYPE }) + removeFromAllPermission = { + SpPermission.CREATE_TARGET, SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET, SpPermission.DELETE_TARGET, + SpPermission.READ_TARGET_TYPE }) void getTargetTypesWithoutPermission() throws Exception { mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java index fb3109d2c..32a35f25c 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java @@ -314,7 +314,7 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg // TODO - should be able to read with TENANT_CONFIGURATION but somehow here the role hierarchy doesn't play // checked in mgmt / update server runtime PreAuthorizeEnabledTest - callAs(withUser("tenant_admin", SpPermission.READ_TENANT_CONFIGURATION, SpPermission.READ_GATEWAY_SEC_TOKEN), () -> { + callAs(withUser("tenant_admin", SpPermission.READ_TENANT_CONFIGURATION, SpPermission.READ_GATEWAY_SECURITY_TOKEN), () -> { mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) .andDo(MockMvcResultPrinter.print()) .andDo(m -> System.out.println("-> 1: " + m.getResponse().getContentAsString())) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java index b625605e3..c45de6d7a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeManagement.java @@ -41,7 +41,7 @@ public interface DistributionSetTypeManagement @Override default String permissionGroup() { - return SpPermission.DISTRIBUTION_SET; + return SpPermission.DISTRIBUTION_SET_TYPE; } @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java index 739f0a7d6..3ff548a2f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeManagement.java @@ -35,7 +35,7 @@ public interface SoftwareModuleTypeManagement @Override default String permissionGroup() { - return SpPermission.SOFTWARE_MODULE; + return SpPermission.SOFTWARE_MODULE_TYPE; } /** 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 04bccfbdb..8653c7d8f 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 @@ -46,19 +46,17 @@ public interface SystemManagement { Page findTenants(@NotNull Pageable pageable); /** - * Runs consumer for each teant as + * Runs consumer for each tenant as * {@link TenantAware#runAsTenant(String, org.eclipse.hawkbit.tenancy.TenantAware.TenantRunner)} - * sliently (i.e. exceptions will be logged but operations will continue for - * further tenants). + * silently (i.e. exceptions will be logged but operations will continue for further tenants). * - * @param consumer to run as teanant + * @param consumer to run as tenant */ @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) void forEachTenant(Consumer consumer); /** - * Calculated system usage statistics, both overall for the entire system - * and per tenant; + * Calculated system usage statistics, both overall for the entire system and per tenant; * * @return SystemUsageReport of the current system */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java index db2ebcb87..43173aa15 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java @@ -61,7 +61,7 @@ public interface Target extends NamedEntity, Identifiable { /** * @return the securityToken if the current security context contains the necessary permission - * {@link org.eclipse.hawkbit.im.authentication.SpPermission#READ_TARGET_SEC_TOKEN} + * {@link org.eclipse.hawkbit.im.authentication.SpPermission#READ_TARGET_SECURITY_TOKEN} * or the current context is executed as system code, otherwise {@code null}. */ String getSecurityToken(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessControllerConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessControllerConfiguration.java index 92f195ed4..e1f29b687 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessControllerConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/acm/DefaultAccessControllerConfiguration.java @@ -9,10 +9,17 @@ */ package org.eclipse.hawkbit.repository.jpa.acm; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DistributionSetFields; +import org.eclipse.hawkbit.repository.DistributionSetTypeFields; +import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetTypeFields; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -26,18 +33,36 @@ public class DefaultAccessControllerConfiguration { @Bean @ConditionalOnProperty(name = "hawkbit.acm.access-controller.target.enabled", havingValue = "true", matchIfMissing = true) AccessController targetAccessController() { - return new DefaultAccessController<>(TargetFields.class, "TARGET"); + return new DefaultAccessController<>(TargetFields.class, SpPermission.TARGET); } @Bean - @ConditionalOnProperty(name = "hawkbit.acm.access-controller.target-type.enabled", havingValue = "true", matchIfMissing = true) + @ConditionalOnProperty(name = "hawkbit.acm.access-controller.target-type.enabled", havingValue = "true") AccessController targetTypeAccessController() { - return new DefaultAccessController<>(TargetTypeFields.class, "TARGET_TYPE"); + return new DefaultAccessController<>(TargetTypeFields.class, SpPermission.TARGET_TYPE); + } + + @Bean + @ConditionalOnProperty(name = "hawkbit.acm.access-controller.software-module.enabled", havingValue = "true", matchIfMissing = true) + AccessController softwareModuleAccessController() { + return new DefaultAccessController<>(SoftwareModuleFields.class, SpPermission.SOFTWARE_MODULE); + } + + @Bean + @ConditionalOnProperty(name = "hawkbit.acm.access-controller.software-module-type.enabled", havingValue = "true") + AccessController softwareModuleTypeAccessController() { + return new DefaultAccessController<>(SoftwareModuleTypeFields.class, SpPermission.SOFTWARE_MODULE_TYPE); } @Bean @ConditionalOnProperty(name = "hawkbit.acm.access-controller.distribution-set.enabled", havingValue = "true", matchIfMissing = true) AccessController distributionSetAccessController() { - return new DefaultAccessController<>(DistributionSetFields.class, "DISTRIBUTION_SET"); + return new DefaultAccessController<>(DistributionSetFields.class, SpPermission.DISTRIBUTION_SET); + } + + @Bean + @ConditionalOnProperty(name = "hawkbit.acm.access-controller.distribution-set-type.enabled", havingValue = "true") + AccessController distributionSetTypeAccessController() { + return new DefaultAccessController<>(DistributionSetTypeFields.class, SpPermission.DISTRIBUTION_SET_TYPE); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java index 60f333cc1..517231a83 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java @@ -51,7 +51,6 @@ import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.PollingTime; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; @@ -249,9 +248,9 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana if (AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY.equalsIgnoreCase(configurationKeyName)) { final SystemSecurityContext systemSecurityContext = SystemSecurityContextHolder.getInstance().getSystemSecurityContext(); if (!systemSecurityContext.isCurrentThreadSystemCode() && - !systemSecurityContext.hasPermission(SpPermission.READ_GATEWAY_SEC_TOKEN)) { + !systemSecurityContext.hasPermission(SpPermission.READ_GATEWAY_SECURITY_TOKEN)) { throw new InsufficientPermissionException( - "Can't read gateway security token! " + SpPermission.READ_GATEWAY_SEC_TOKEN + " is required!"); + "Can't read gateway security token! " + SpPermission.READ_GATEWAY_SECURITY_TOKEN + " is required!"); } } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 31c5f5065..ea76e53df 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -216,7 +216,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw @Override public String getSecurityToken() { final SystemSecurityContext systemSecurityContext = SystemSecurityContextHolder.getInstance().getSystemSecurityContext(); - if (systemSecurityContext.isCurrentThreadSystemCode() || systemSecurityContext.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + if (systemSecurityContext.isCurrentThreadSystemCode() || systemSecurityContext.hasPermission(SpPermission.READ_TARGET_SECURITY_TOKEN)) { return securityToken; } return null; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetTypeAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetTypeAccessControllerTest.java index f5e3c2a91..c7f261e9c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetTypeAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetTypeAccessControllerTest.java @@ -31,12 +31,14 @@ import org.eclipse.hawkbit.repository.model.TargetType; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Pageable; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; /** * Feature: Component Tests - Access Control
* Story: Test Target Type Access Controller */ @ContextConfiguration(classes = { DefaultAccessControllerConfiguration.class }) +@TestPropertySource(properties = { "hawkbit.acm.access-controller.target-type.enabled=true" }) class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest { /** @@ -92,8 +94,8 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest { final TargetType readOnlyTargetType = targetTypeManagement.create(Create.builder().name("type2").build()); runAs(withUser("user", - READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(), - DELETE_TARGET_TYPE + "/id==" + manageableTargetType.getId()), () -> { + READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(), + DELETE_TARGET_TYPE + "/id==" + manageableTargetType.getId()), () -> { // delete the manageableTargetType targetTypeManagement.delete(manageableTargetType.getId()); @@ -113,8 +115,8 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest { final TargetType readOnlyTargetType = targetTypeManagement.create(Create.builder().name("type2").build()); runAs(withUser("user", - READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(), - UPDATE_TARGET_TYPE + "/id==" + manageableTargetType.getId()), () -> { + READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(), + UPDATE_TARGET_TYPE + "/id==" + manageableTargetType.getId()), () -> { // update the manageableTargetType targetTypeManagement.update(Update.builder().id(manageableTargetType.getId()) .name(manageableTargetType.getName() + "/new").description("newDesc").build()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java index cf7ce60a6..9a0e97f64 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java @@ -139,7 +139,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest< // retrieve security token only with READ_TARGET_SEC_TOKEN permission final String securityTokenWithReadPermission = SecurityContextSwitch.getAs( - SecurityContextSwitch.withUser("OnlyTargetReadPermission", SpPermission.READ_TARGET_SEC_TOKEN), + SecurityContextSwitch.withUser("OnlyTargetReadPermission", SpPermission.READ_TARGET_SECURITY_TOKEN), createdTarget::getSecurityToken); // retrieve security token only with ROLE_TARGET_ADMIN permission final String securityTokenWithTargetAdminPermission = SecurityContextSwitch.getAs( diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java index 448d141e3..8b4eea05e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java @@ -108,8 +108,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest { */ @Test @WithUser(tenantId = "mytenant", autoCreateTenant = false, allSpPermissions = true) - void getTenanatMetdata() throws Exception { - + void getTenantMetdata() throws Exception { // logged in tenant mytenant - check if tenant default data is // autogenerated assertThat(distributionSetTypeManagement.findAll(PAGE)).isEmpty(); 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 cf9a68100..31d1f59a1 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 @@ -15,9 +15,13 @@ import lombok.NoArgsConstructor; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class Hierarchy { + // @formatter:off public static final String DEFAULT = SpPermission.TARGET_HIERARCHY + SpPermission.REPOSITORY_HIERARCHY + + SpPermission.SOFTWARE_MODULE_HIERARCHY + + SpPermission.DISTRIBUTION_SET_HIERARCHY + SpPermission.TENANT_CONFIGURATION_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 8eab32a04..1abccaec1 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 @@ -9,8 +9,6 @@ */ package org.eclipse.hawkbit.im.authentication; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -46,7 +44,9 @@ public final class SpPermission { public static final String TARGET = "TARGET"; public static final String TARGET_TYPE = "TARGET_TYPE"; public static final String SOFTWARE_MODULE = "SOFTWARE_MODULE"; + public static final String SOFTWARE_MODULE_TYPE = "SOFTWARE_MODULE_TYPE"; public static final String DISTRIBUTION_SET = "DISTRIBUTION_SET"; + public static final String DISTRIBUTION_SET_TYPE = "DISTRIBUTION_SET_TYPE"; public static final String ROLLOUT = "ROLLOUT"; public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION"; @@ -55,12 +55,10 @@ public final class SpPermission { public static final String UPDATE_TARGET = UPDATE_PREFIX + TARGET; public static final String DELETE_TARGET = DELETE_PREFIX + TARGET; /** - * Permission to read the target security token. The security token is security - * concerned and should be protected. So the combination - * {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to - * be able to read the security token of a target. + * Permission to read the target security token. The security token is security concerned and should be protected. So the combination + * {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to be able to read the security token of a target. */ - public static final String READ_TARGET_SEC_TOKEN = READ_TARGET + "_SECURITY_TOKEN"; + public static final String READ_TARGET_SECURITY_TOKEN = READ_TARGET + "_SECURITY_TOKEN"; public static final String READ_TARGET_TYPE = READ_PREFIX + TARGET_TYPE; public static final String UPDATE_TARGET_TYPE = UPDATE_PREFIX + TARGET_TYPE; @@ -73,21 +71,19 @@ public final class SpPermission { public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY"; public static final String CREATE_REPOSITORY = "CREATE_REPOSITORY"; public static final String DELETE_REPOSITORY = "DELETE_REPOSITORY"; - public static final String DOWNLOAD_REPOSITORY_ARTIFACT = "DOWNLOAD_REPOSITORY_ARTIFACT"; /** * Permission to read the tenant settings. */ public static final String READ_TENANT_CONFIGURATION = READ_PREFIX + TENANT_CONFIGURATION; - /** * Permission to read the gateway security token. The gateway security token is security * concerned and should be protected. So in addition to {@linkplain #READ_TENANT_CONFIGURATION}, * {@code READ_GATEWAY_SEC_TOKEN} is necessary to read gateway security token. {@link #TENANT_CONFIGURATION} * implies both permissions - so it is sufficient to read the gateway security token. */ - public static final String READ_GATEWAY_SEC_TOKEN = "READ_GATEWAY_SECURITY_TOKEN"; + public static final String READ_GATEWAY_SECURITY_TOKEN = "READ_GATEWAY_SECURITY_TOKEN"; public static final String CREATE_ROLLOUT = CREATE_PREFIX + ROLLOUT; public static final String READ_ROLLOUT = READ_PREFIX + ROLLOUT; @@ -101,44 +97,81 @@ public final class SpPermission { /** Permission to administrate the system on a global, i.e. tenant independent scale. That includes the deletion of tenants. */ public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN"; - public static final String TARGET_HIERARCHY = """ - CREATE_TARGET > CREATE_TARGET_TYPE - READ_TARGET > READ_TARGET_TYPE - UPDATE_TARGET > UPDATE_TARGET_TYPE - DELETE_TARGET > DELETE_TARGET_TYPE - """; - public static final String REPOSITORY_HIERARCHY = """ - CREATE_REPOSITORY > CREATE_DISTRIBUTION_SET - READ_REPOSITORY > READ_DISTRIBUTION_SET - UPDATE_REPOSITORY > UPDATE_DISTRIBUTION_SET - DELETE_REPOSITORY > DELETE_DISTRIBUTION_SET - CREATE_REPOSITORY > CREATE_SOFTWARE_MODULE - READ_REPOSITORY > READ_SOFTWARE_MODULE - UPDATE_REPOSITORY > UPDATE_SOFTWARE_MODULE - DELETE_REPOSITORY > DELETE_SOFTWARE_MODULE - """; - public static final String TENANT_CONFIGURATION_HIERARCHY = """ - TENANT_CONFIGURATION > CREATE_TENANT_CONFIGURATION - TENANT_CONFIGURATION > READ_TENANT_CONFIGURATION - TENANT_CONFIGURATION > UPDATE_TENANT_CONFIGURATION - TENANT_CONFIGURATION > DELETE_TENANT_CONFIGURATION - TENANT_CONFIGURATION > READ_GATEWAY_SECURITY_TOKEN - """; + public static final String IMPLY_CREATE = " > " + CREATE_PREFIX; + public static final String IMPLY_READ = " > " + READ_PREFIX; + public static final String IMPLY_UPDATE = " > " + UPDATE_PREFIX; + public static final String IMPLY_DELETE = " > " + DELETE_PREFIX; + // @formatter:off + public static final String TARGET_HIERARCHY = + CREATE_TARGET + IMPLY_READ + TARGET_TYPE + "\n" + + READ_TARGET + IMPLY_READ + TARGET_TYPE + "\n" + + UPDATE_TARGET + IMPLY_READ + TARGET_TYPE + "\n" + + DELETE_TARGET + IMPLY_READ + TARGET_TYPE + "\n"; + public static final String REPOSITORY_HIERARCHY = + 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"; + public static final String SOFTWARE_MODULE_HIERARCHY = + CREATE_PREFIX + SOFTWARE_MODULE + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + + READ_PREFIX + SOFTWARE_MODULE + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + + UPDATE_PREFIX + SOFTWARE_MODULE + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + + DELETE_PREFIX + SOFTWARE_MODULE + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n"; + public static final String DISTRIBUTION_SET_HIERARCHY = + CREATE_PREFIX + DISTRIBUTION_SET + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + + READ_PREFIX + DISTRIBUTION_SET + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + + UPDATE_PREFIX + DISTRIBUTION_SET + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n" + + DELETE_PREFIX + DISTRIBUTION_SET + IMPLY_READ + SOFTWARE_MODULE_TYPE + "\n"; + public static final String TENANT_CONFIGURATION_HIERARCHY = + TENANT_CONFIGURATION + IMPLY_CREATE + TENANT_CONFIGURATION + "\n" + + TENANT_CONFIGURATION + IMPLY_READ + TENANT_CONFIGURATION + "\n" + + TENANT_CONFIGURATION + IMPLY_UPDATE + TENANT_CONFIGURATION + "\n" + + TENANT_CONFIGURATION + IMPLY_DELETE + TENANT_CONFIGURATION + "\n" + + TENANT_CONFIGURATION + IMPLY_CREATE + READ_GATEWAY_SECURITY_TOKEN + "\n"; + + // @formatter:on private static final SingletonSupplier> ALL_AUTHORITIES = SingletonSupplier.of(() -> { final List allPermissions = new ArrayList<>(); - final Field[] declaredFields = SpPermission.class.getDeclaredFields(); - for (final Field field : declaredFields) { - if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && - String.class.equals(field.getType()) && !field.getName().endsWith("_HIERARCHY")) { - try { - final String role = (String) field.get(null); - allPermissions.add(role); - } catch (final IllegalAccessException e) { - log.error(e.getMessage(), e); - } + + // groups with access, canonical + for (final String group : new String[] { + TARGET, TARGET_TYPE, + SOFTWARE_MODULE, SOFTWARE_MODULE_TYPE, DISTRIBUTION_SET, DISTRIBUTION_SET_TYPE, + ROLLOUT, + TENANT_CONFIGURATION }) { + for (final String access_prefix : new String[] { CREATE_PREFIX, READ_PREFIX, UPDATE_PREFIX, DELETE_PREFIX }) { + allPermissions.add(access_prefix + group); } } + // special + allPermissions.add(READ_TARGET_SECURITY_TOKEN); + allPermissions.add(READ_GATEWAY_SECURITY_TOKEN); + allPermissions.add(DOWNLOAD_REPOSITORY_ARTIFACT); + allPermissions.add(APPROVE_ROLLOUT); + allPermissions.add(HANDLE_ROLLOUT); + + // coarse-grained - maybe to be deprecated + for (final String access_prefix : new String[] { CREATE_PREFIX, READ_PREFIX, UPDATE_PREFIX, DELETE_PREFIX }) { + allPermissions.add(access_prefix + "REPOSITORY"); + } + allPermissions.add(TENANT_CONFIGURATION); + + // system permission, (!) take care with + allPermissions.add(SYSTEM_ADMIN); + 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 376d531bb..f1d31b8fc 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 @@ -36,10 +36,14 @@ public final class SpRole { private static final String LINE_BREAK = "\n"; public static final String TARGET_ADMIN_HIERARCHY = TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET + LINE_BREAK + - TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_SEC_TOKEN + LINE_BREAK + + TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_SECURITY_TOKEN + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.UPDATE_TARGET + LINE_BREAK + TARGET_ADMIN + IMPLIES + SpPermission.CREATE_TARGET + LINE_BREAK + - TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET + LINE_BREAK; + TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET + LINE_BREAK + + TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_TYPE + LINE_BREAK + + TARGET_ADMIN + IMPLIES + SpPermission.UPDATE_TARGET_TYPE + LINE_BREAK + + TARGET_ADMIN + IMPLIES + SpPermission.CREATE_PREFIX + SpPermission.TARGET_TYPE + LINE_BREAK + + TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET_TYPE + 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 + diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java index 15aed3ea0..f6eeed20c 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java @@ -66,8 +66,7 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider { : new TenantAwareUser(username, password, credentials, user.getTenant())); }); - if (securityProperties != null && securityProperties.getUser() != null && - !securityProperties.getUser().isPasswordGenerated()) { + if (securityProperties != null && securityProperties.getUser() != null && !securityProperties.getUser().isPasswordGenerated()) { // explicitly setup system user - add is as a regular (non-tenant scoped) user userPrincipals.add(new User( securityProperties.getUser().getName(),