[#1712] Fix READ_TENANT_CONFIGURATION hierarchy and add tests (#1714)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-04-12 17:39:31 +03:00
committed by GitHub
parent 3611a8eccd
commit 1f2dd28ab6
7 changed files with 98 additions and 7 deletions

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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");

View File

@@ -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 {

View File

@@ -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()));
}
}

View File

@@ -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()));
}
}

View File

@@ -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 =