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 d70eff970..e9cda6cc5 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 @@ -89,7 +89,7 @@ public interface SystemManagement { */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_CONTROLLER) TenantMetaData getTenantMetadata(); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 523a6821d..32ddeb021 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -62,22 +62,6 @@ public interface TenantConfigurationManagement { @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) Map> addOrUpdateConfiguration(Map configurations); - /** - * Build the tenant configuration by the given key - * - * @param configurationKey - * the key - * @param propertyType - * the property type - * @param tenantConfiguration - * the configuration - * @return if no default value is set and no database value available - * or returns the tenant configuration value - */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) - TenantConfigurationValue buildTenantConfigurationValueByKey( - TenantConfigurationKey configurationKey, Class propertyType, TenantConfiguration tenantConfiguration); - /** * Deletes a specific configuration for the current tenant. Does nothing in * case there is no tenant specific configuration value. @@ -106,7 +90,7 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) TenantConfigurationValue getConfigurationValue(String configurationKeyName); /** @@ -132,7 +116,7 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) TenantConfigurationValue getConfigurationValue(String configurationKeyName, Class propertyType); @@ -156,6 +140,6 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ) T getGlobalConfigurationValue(String configurationKeyName, Class propertyType); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java index 519360a8a..b5b5e6dd9 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java @@ -28,7 +28,7 @@ public interface TenantStatsManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) TenantUsage getStatsOfTenant(); 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 b0592b091..ac27eefcb 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 @@ -21,7 +21,9 @@ import java.util.Map; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.exception.TenantConfigurationValueChangeNotAllowedException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; @@ -29,6 +31,8 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration; import org.eclipse.hawkbit.repository.jpa.repository.TenantConfigurationRepository; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; @@ -75,6 +79,7 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana @Cacheable(value = "tenantConfiguration", key = "#configurationKeyName") public TenantConfigurationValue getConfigurationValue(final String configurationKeyName, final Class propertyType) { + checkAccess(configurationKeyName); final TenantConfigurationKey configurationKey = tenantConfigurationProperties.fromKeyName(configurationKeyName); @@ -86,48 +91,11 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana return buildTenantConfigurationValueByKey(configurationKey, propertyType, tenantConfiguration); } - /** - * Validates the data type of the tenant configuration. If it is possible to - * cast to the given data type. - * - * @param configurationKey - * the key - * @param propertyType - * the class - */ - static void validateTenantConfigurationDataType(final TenantConfigurationKey configurationKey, - final Class propertyType) { - - if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { - throw new TenantConfigurationValidatorException( - String.format("Cannot parse the database value of type %s into the type %s.", - configurationKey.getDataType(), propertyType)); - } - } - - @Override - public TenantConfigurationValue buildTenantConfigurationValueByKey( - final TenantConfigurationKey configurationKey, final Class propertyType, - final TenantConfiguration tenantConfiguration) { - if (tenantConfiguration != null) { - return TenantConfigurationValue. builder().global(false).createdBy(tenantConfiguration.getCreatedBy()) - .createdAt(tenantConfiguration.getCreatedAt()) - .lastModifiedAt(tenantConfiguration.getLastModifiedAt()) - .lastModifiedBy(tenantConfiguration.getLastModifiedBy()) - .value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build(); - - } else if (configurationKey.getDefaultValue() != null) { - - return TenantConfigurationValue. builder().global(true).createdBy(null).createdAt(null) - .lastModifiedAt(null).lastModifiedBy(null) - .value(getGlobalConfigurationValue(configurationKey.getKeyName(), propertyType)).build(); - } - return null; - } - @Override public TenantConfigurationValue getConfigurationValue( final String configurationKeyName) { + checkAccess(configurationKeyName); + final TenantConfigurationKey configurationKey = tenantConfigurationProperties.fromKeyName(configurationKeyName); return getConfigurationValue(configurationKeyName, (Class)configurationKey.getDataType()); @@ -135,6 +103,7 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana @Override public T getGlobalConfigurationValue(final String configurationKeyName, final Class propertyType) { + checkAccess(configurationKeyName); final TenantConfigurationKey key = tenantConfigurationProperties.fromKeyName(configurationKeyName); @@ -146,6 +115,19 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana return conversionService.convert(key.getDefaultValue(), propertyType); } + private void checkAccess(final String configurationKeyName) { + if (TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY + .equalsIgnoreCase(configurationKeyName)) { + final SystemSecurityContext systemSecurityContext = + SystemSecurityContextHolder.getInstance().getSystemSecurityContext(); + if (!systemSecurityContext.isCurrentThreadSystemCode() && + !systemSecurityContext.hasPermission(SpPermission.READ_GATEWAY_SEC_TOKEN)) { + throw new InsufficientPermissionException( + "Can't read gateway security token! " + SpPermission.READ_GATEWAY_SEC_TOKEN + " is required!"); + } + } + } + @Override @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") @Transactional @@ -217,6 +199,51 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana })); } + @Override + @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") + @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) + public void deleteConfiguration(final String configurationKeyName) { + tenantConfigurationRepository.deleteByKey(configurationKeyName); + } + + /** + * Validates the data type of the tenant configuration. If it is possible to + * cast to the given data type. + * + * @param configurationKey the key + * @param propertyType the class + */ + private static void validateTenantConfigurationDataType(final TenantConfigurationKey configurationKey, + final Class propertyType) { + + if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { + throw new TenantConfigurationValidatorException( + String.format("Cannot parse the database value of type %s into the type %s.", + configurationKey.getDataType(), propertyType)); + } + } + + private TenantConfigurationValue buildTenantConfigurationValueByKey( + final TenantConfigurationKey configurationKey, final Class propertyType, + final TenantConfiguration tenantConfiguration) { + if (tenantConfiguration != null) { + return TenantConfigurationValue. builder().global(false).createdBy(tenantConfiguration.getCreatedBy()) + .createdAt(tenantConfiguration.getCreatedAt()) + .lastModifiedAt(tenantConfiguration.getLastModifiedAt()) + .lastModifiedBy(tenantConfiguration.getLastModifiedBy()) + .value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build(); + + } else if (configurationKey.getDefaultValue() != null) { + + return TenantConfigurationValue. builder().global(true).createdBy(null).createdAt(null) + .lastModifiedAt(null).lastModifiedBy(null) + .value(getGlobalConfigurationValue(configurationKey.getKeyName(), propertyType)).build(); + } + return null; + } + /** * Asserts that the requested configuration value change is allowed. Throws * a {@link TenantConfigurationValueChangeNotAllowedException} otherwise. @@ -271,13 +298,4 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana } } } - - @Override - @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") - @Transactional - @Retryable(include = { - ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public void deleteConfiguration(final String configurationKeyName) { - tenantConfigurationRepository.deleteByKey(configurationKeyName); - } } diff --git a/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java b/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java index 3a58ce50c..d93e5369f 100644 --- a/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java +++ b/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java @@ -12,7 +12,7 @@ package org.eclipse.hawkbit.ddi.rest.resource; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE; import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS; -import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ; import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.containsString; @@ -210,7 +210,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { @Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) void pollWithModifiedGlobalPollingTime() throws Exception { - SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION_READ), () -> { tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, "00:02:00"); @@ -611,7 +611,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { void sleepTimeResponseForDifferentMaintenanceWindowParameters() throws Exception { final DistributionSet ds = testdataFactory.createDistributionSet(""); - SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION_READ), () -> { tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, "00:05:00"); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java index 47b44fbc3..bc1910123 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java @@ -45,7 +45,7 @@ public interface MgmtTenantManagementRestApi { * @return a map of all configuration values. */ @Operation(summary = "Return all tenant specific configuration values", description = "The GET request returns " + - "a list of all possible configuration keys for the tenant. Required Permission: TENANT_CONFIGURATION") + "a list of all possible configuration keys for the tenant. Required Permission: READ_TENANT_CONFIGURATION") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully retrieved"), @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", @@ -115,7 +115,7 @@ public interface MgmtTenantManagementRestApi { */ @Operation(summary = "Return a tenant specific configuration value", description = "The GET request returns the " + "configuration value of a specific configuration key for the tenant. " + - "Required Permission: TENANT_CONFIGURATION") + "Required Permission: READ_TENANT_CONFIGURATION") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully retrieved"), @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java index 736f62edc..0c0f23beb 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import java.io.Serializable; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -21,6 +22,7 @@ import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationV import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; @@ -51,14 +53,21 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi @Override public ResponseEntity> getTenantConfiguration() { - //Load and Construct default Tenant Configuration - Map tenantConfigurationValueMap = tenantConfigurationProperties.getConfigurationKeys().stream().collect( - Collectors.toMap(TenantConfigurationProperties.TenantConfigurationKey::getKeyName, - key -> loadTenantConfigurationValueBy(key.getKeyName()))); - //Load and Add Default DistributionSetType - MgmtSystemTenantConfigurationValue defaultDsTypeId = loadTenantConfigurationValueBy(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY); + // Load and Construct default Tenant Configuration + final Map tenantConfigurationValueMap = new HashMap<>(); + tenantConfigurationProperties.getConfigurationKeys().forEach(key -> { + try { + tenantConfigurationValueMap.put(key.getKeyName(), loadTenantConfigurationValueBy(key.getKeyName())); + } catch (final InsufficientPermissionException e) { + // some values as gateway token may not be accessibly for the caller - just skip them + } + }); + + // Load and Add Default DistributionSetType + final MgmtSystemTenantConfigurationValue defaultDsTypeId = loadTenantConfigurationValueBy(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY); tenantConfigurationValueMap.put(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY, defaultDsTypeId); - //return combined TenantConfiguration and TenantMetadata + + // return combined TenantConfiguration and TenantMetadata log.debug("getTenantConfiguration, return status {}", HttpStatus.OK); return ResponseEntity.ok(tenantConfigurationValueMap); } 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 162405938..cb66ab38f 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 @@ -14,6 +14,8 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.GrantedAuthority; @@ -31,6 +33,7 @@ import org.springframework.security.core.GrantedAuthority; * etc. *

*/ +@NoArgsConstructor(access = AccessLevel.PRIVATE) @Slf4j public final class SpPermission { @@ -93,6 +96,19 @@ public final class SpPermission { */ public static final String DOWNLOAD_REPOSITORY_ARTIFACT = "DOWNLOAD_REPOSITORY_ARTIFACT"; + /** + * Permission to read the tenant settings. + */ + public static final String READ_TENANT_CONFIGURATION = "READ_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"; + /** * Permission to administrate the tenant settings. */ @@ -128,10 +144,6 @@ public final class SpPermission { */ public static final String APPROVE_ROLLOUT = "APPROVE_ROLLOUT"; - private SpPermission() { - // Constants only - } - /** * Return all permission. * @return all permissions @@ -175,6 +187,7 @@ public final class SpPermission { * } *

*/ + @NoArgsConstructor(access = AccessLevel.PRIVATE) public static final class SpringEvalExpressions { /* * Spring security eval expressions. @@ -404,6 +417,14 @@ public final class SpPermission { 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 + * context contains {@link SpPermission#READ_TENANT_CONFIGURATION} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + READ_TENANT_CONFIGURATION + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#TENANT_CONFIGURATION} or @@ -414,14 +435,10 @@ public final class SpPermission { /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#IS_CONTROLLER} or + * context contains {@link #IS_CONTROLLER} or * {@link #HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET}. */ public static final String IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = IS_CONTROLLER + HAS_AUTH_OR + HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET; - - private SpringEvalExpressions() { - // utility class - } } -} +} \ No newline at end of file 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 f0c226992..585efde08 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 @@ -48,6 +48,10 @@ public final class SpRole { ROLLOUT_ADMIN + IMPLIES + SpPermission.HANDLE_ROLLOUT + LINE_BREAK + ROLLOUT_ADMIN + IMPLIES + SpPermission.APPROVE_ROLLOUT + LINE_BREAK; + public static final String TENANT_CONFIGURATION_HIERARCHY = + SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_TENANT_CONFIGURATION + LINE_BREAK + + SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_GATEWAY_SEC_TOKEN; + public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN"; public static final String TENANT_ADMIN_HIERARCHY = TENANT_ADMIN + IMPLIES + TARGET_ADMIN + LINE_BREAK + @@ -61,6 +65,8 @@ public final class SpRole { public static String DEFAULT_ROLE_HIERARCHY = TARGET_ADMIN_HIERARCHY + REPOSITORY_ADMIN_HIERARCHY + - ROLLOUT_ADMIN_HIERARCHY + TENANT_ADMIN_HIERARCHY + + ROLLOUT_ADMIN_HIERARCHY + + TENANT_CONFIGURATION_HIERARCHY + + TENANT_ADMIN_HIERARCHY + SYSTEM_ADMIN_HIERARCHY; } \ No newline at end of file diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/SpPermissionTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/SpPermissionTest.java index a72b717f2..0caff6a43 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/SpPermissionTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/SpPermissionTest.java @@ -34,7 +34,7 @@ public final class SpPermissionTest { @Test @Description("Verify the get permission function") public void testGetPermissions() { - final int allPermission = 18; + final int allPermission = 20; final Collection allAuthorities = SpPermission.getAllAuthorities(); final List allAuthoritiesList = PermissionUtils.createAllAuthorityList(); assertThat(allAuthorities).hasSize(allPermission);