diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java index cbcf2874b..d2ed12f80 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java @@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; 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.IS_CONTROLLER; import static org.eclipse.hawkbit.repository.jpa.configuration.Constants.TX_RT_MAX; import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY; import static org.eclipse.hawkbit.repository.test.util.TestdataFactory.DEFAULT_CONTROLLER_ID; @@ -38,6 +39,7 @@ import jakarta.validation.ConstraintViolationException; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; import org.assertj.core.api.Assertions; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.UpdateMode; import org.eclipse.hawkbit.repository.builder.ActionStatusCreate; @@ -979,7 +981,9 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final String controllerId = "test123"; final Target target = testdataFactory.createTarget(controllerId); - SecurityContextSwitch.runAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> { + SecurityContextSwitch.runAs(SecurityContextSwitch.withController( + "controller", + CONTROLLER_ROLE_ANONYMOUS, SpPermission.READ_TARGET), () -> { addAttributeAndVerify(controllerId); addSecondAttributeAndVerify(controllerId); updateAttributeAndVerify(controllerId); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java index 28dfb7674..aceabe7fd 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java @@ -64,11 +64,11 @@ public class SecurityContextSwitch { } public static WithUser withController(final String principal, final String... authorities) { - return withUserAndTenant(principal, DEFAULT_TENANT, true, true, true, authorities); + return withUserAndTenant(principal, DEFAULT_TENANT, true, false, true, authorities); } public static WithUser withUser(final String principal, final String... authorities) { - return withUserAndTenant(principal, DEFAULT_TENANT, true, true, false, authorities); + return withUserAndTenant(principal, DEFAULT_TENANT, true, false, false, authorities); } public static WithUser withUser(final String principal, final boolean allSpPermision, final String... authorities) { 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 d93e5369f..94b510662 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,8 +12,8 @@ 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_READ; import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE; +import static org.eclipse.hawkbit.im.authentication.SpPermission.TENANT_CONFIGURATION; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThanOrEqualTo; @@ -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_READ), + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", TENANT_CONFIGURATION), () -> { 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_READ), + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", TENANT_CONFIGURATION), () -> { tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, "00:05:00"); diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java index c15c56ca1..6e7a3426a 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java @@ -18,9 +18,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch; import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.json.JSONObject; @@ -62,6 +64,37 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg } + @Test + @Description("Handles GET request for receiving all tenant specific configurations depending on read gateway token permissions.") + void getTenantConfigurationReadGWToken() throws Exception { + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_admin", SpPermission.TENANT_CONFIGURATION), () -> { + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, + "123"); + return null; + }); + + // 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 + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_admin", SpPermission.READ_TENANT_CONFIGURATION, SpPermission.READ_GATEWAY_SEC_TOKEN), () -> { + mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) + .andDo(MockMvcResultPrinter.print()) + .andDo(m -> System.out.println("-> 1: " + m.getResponse().getContentAsString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "']").exists()) + .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "'].value", equalTo("123"))); + return null; + }); + + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_read", SpPermission.READ_TENANT_CONFIGURATION), () -> { + mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) + .andDo(MockMvcResultPrinter.print()) + .andDo(m -> System.out.println("-> 2: " + m.getResponse().getContentAsString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "']").doesNotExist()); + return null; + }); + } + @Test @Description("Handles GET request for receiving a tenant specific configuration.") public void getTenantConfiguration() throws Exception { diff --git a/hawkbit-runtime/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java b/hawkbit-runtime/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java index e42d61273..8c3f5b070 100644 --- a/hawkbit-runtime/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java +++ b/hawkbit-runtime/hawkbit-mgmt-server/src/test/java/org/eclipse/hawkbit/app/mgmt/PreAuthorizeEnabledTest.java @@ -9,6 +9,7 @@ */ package org.eclipse.hawkbit.app.mgmt; +import com.fasterxml.jackson.databind.ObjectMapper; import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; @@ -18,6 +19,8 @@ import org.eclipse.hawkbit.repository.test.util.WithUser; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; +import java.util.HashMap; + import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -50,4 +53,28 @@ public class PreAuthorizeEnabledTest extends AbstractSecurityTest { assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value()); }); } + + @Test + @Description("Tests whether read tenant config request fail if a tenant config (or read read) is not " + + "granted for the user") + @WithUser(authorities = { SpPermission.READ_TARGET } ) + public void onlyDSIfNoTenantConfig() throws Exception { + 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) + .size()) + .isEqualTo(1); + }); + } + + @Test + @Description("Tests whether read tenant config request succeed if a tenant config (not read explicitly) is " + + "granted for the user") + @WithUser(authorities = { SpPermission.TENANT_CONFIGURATION }) + public void successIfHasTenantConfig() throws Exception { + mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> + assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); + } } \ No newline at end of file diff --git a/hawkbit-runtime/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java b/hawkbit-runtime/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java index da842e1fe..8a9316096 100644 --- a/hawkbit-runtime/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java +++ b/hawkbit-runtime/hawkbit-update-server/src/test/java/org/eclipse/hawkbit/app/PreAuthorizeEnabledTest.java @@ -9,6 +9,7 @@ */ package org.eclipse.hawkbit.app; +import com.fasterxml.jackson.databind.ObjectMapper; import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; @@ -18,6 +19,8 @@ import org.eclipse.hawkbit.repository.test.util.WithUser; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; +import java.util.HashMap; + import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -50,4 +53,28 @@ public class PreAuthorizeEnabledTest extends AbstractSecurityTest { assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value()); }); } + + @Test + @Description("Tests whether read tenant config request fail if a tenant config (or read read) is not " + + "granted for the user") + @WithUser(authorities = { SpPermission.READ_TARGET } ) + public void onlyDSIfNoTenantConfig() throws Exception { + 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) + .size()) + .isEqualTo(1); + }); + } + + @Test + @Description("Tests whether read tenant config request succeed if a tenant config (not read explicitly) is " + + "granted for the user") + @WithUser(authorities = { SpPermission.TENANT_CONFIGURATION }) + public void successIfHasTenantConfig() throws Exception { + mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> + assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.OK.value())); + } } \ 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 585efde08..ac119de1f 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 @@ -50,7 +50,7 @@ public final class SpRole { 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; + SpPermission.TENANT_CONFIGURATION + IMPLIES + SpPermission.READ_GATEWAY_SEC_TOKEN + LINE_BREAK; public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN"; public static final String TENANT_ADMIN_HIERARCHY =