JSonSerializer/DeserializerWithAccessFilter: also use role in parent
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package org.hostsharing.hsadminng.service.accessfilter;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeId;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.core.TreeNode;
|
||||
@@ -18,7 +17,8 @@ import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenLoginUserWithRole;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@@ -38,7 +38,8 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
givenLoginUserWithRole(Role.ANY_CUSTOMER_USER);
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(GivenDto.class, 1234L, Role.ACTUAL_CUSTOMER_USER);
|
||||
|
||||
given(jsonParser.getCodec()).willReturn(codec);
|
||||
}
|
||||
@@ -46,7 +47,9 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
@Test
|
||||
public void shouldDeserializeStringField() throws IOException {
|
||||
// given
|
||||
givenJSonTree(asJSon(ImmutablePair.of("openStringField", "String Value")));
|
||||
givenJSonTree(asJSon(
|
||||
ImmutablePair.of("id", 1234L),
|
||||
ImmutablePair.of("openStringField", "String Value")));
|
||||
|
||||
// when
|
||||
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenDto.class).deserialize();
|
||||
@@ -58,7 +61,9 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
@Test
|
||||
public void shouldDeserializeIntegerField() throws IOException {
|
||||
// given
|
||||
givenJSonTree(asJSon(ImmutablePair.of("openIntegerField", 1234)));
|
||||
givenJSonTree(asJSon(
|
||||
ImmutablePair.of("id", 1234L),
|
||||
ImmutablePair.of("openIntegerField", 1234)));
|
||||
|
||||
// when
|
||||
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenDto.class).deserialize();
|
||||
@@ -70,7 +75,9 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
@Test
|
||||
public void shouldDeserializeLongField() throws IOException {
|
||||
// given
|
||||
givenJSonTree(asJSon(ImmutablePair.of("openLongField", 1234L)));
|
||||
givenJSonTree(asJSon(
|
||||
ImmutablePair.of("id", 1234L),
|
||||
ImmutablePair.of("openLongField", 1234L)));
|
||||
|
||||
// when
|
||||
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenDto.class).deserialize();
|
||||
@@ -82,8 +89,11 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
@Test
|
||||
public void shouldDeserializeStringFieldIfRequiredRoleIsCoveredByUser() throws IOException {
|
||||
// given
|
||||
givenLoginUserWithRole(Role.FINANCIAL_CONTACT);
|
||||
givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "Restricted String Value")));
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(GivenDto.class, 1234L, Role.FINANCIAL_CONTACT);
|
||||
givenJSonTree(asJSon(
|
||||
ImmutablePair.of("id", 1234L),
|
||||
ImmutablePair.of("restrictedField", "Restricted String Value")));
|
||||
|
||||
// when
|
||||
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenDto.class).deserialize();
|
||||
@@ -95,7 +105,8 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
@Test
|
||||
public void shouldInitializeFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
|
||||
// given
|
||||
givenLoginUserWithRole(Role.ANY_CUSTOMER_USER);
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(null, null, Role.ANY_CUSTOMER_USER);
|
||||
givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "Restricted String Value")));
|
||||
|
||||
// when
|
||||
@@ -109,9 +120,41 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
|
||||
public void shouldNotCreateIfRoleRequiredByParentEntityIsNotCoveredByUser() throws IOException {
|
||||
// given
|
||||
givenLoginUserWithRole(Role.ANY_CUSTOMER_USER);
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(GivenDto.class, 9999L, Role.CONTRACTUAL_CONTACT);
|
||||
givenJSonTree(asJSon(ImmutablePair.of("parentId", 1111L)));
|
||||
|
||||
// when
|
||||
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenChildDto.class).deserialize());
|
||||
|
||||
// then
|
||||
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
|
||||
assertThat(badRequestAlertException.getParam()).isEqualTo("GivenChildDto.parentId");
|
||||
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("referencingProhibited");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateIfRoleRequiredByReferencedEntityIsCoveredByUser() throws IOException {
|
||||
// given
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(GivenDto.class, 1111L, Role.CONTRACTUAL_CONTACT);
|
||||
givenJSonTree(asJSon(ImmutablePair.of("parentId", 1111L)));
|
||||
|
||||
// when
|
||||
final GivenChildDto actualDto = new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenChildDto.class).deserialize();
|
||||
|
||||
// then
|
||||
assertThat(actualDto.parentId).isEqualTo(1111L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotUpdateFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
|
||||
// given
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(GivenDto.class, 1234L, Role.ANY_CUSTOMER_USER);
|
||||
givenJSonTree(asJSon(
|
||||
ImmutablePair.of("id", 1234L),
|
||||
ImmutablePair.of("restrictedField", "Restricted String Value")));
|
||||
@@ -183,6 +226,20 @@ public class JSonDeserializerWithAccessFilterUnitTest {
|
||||
Long openLongField;
|
||||
}
|
||||
|
||||
public static class GivenChildDto {
|
||||
|
||||
@SelfId
|
||||
@AccessFor(read = Role.ANY_CUSTOMER_USER)
|
||||
Long id;
|
||||
|
||||
@AccessFor(init = Role.CONTRACTUAL_CONTACT, update = Role.CONTRACTUAL_CONTACT, read = Role.ACTUAL_CUSTOMER_USER)
|
||||
@ParentId(GivenDto.class)
|
||||
Long parentId;
|
||||
|
||||
@AccessFor(init = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT}, update = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT})
|
||||
String restrictedField;
|
||||
}
|
||||
|
||||
public static class GivenDtoWithMultipleSelfId {
|
||||
|
||||
@SelfId
|
||||
|
@@ -15,7 +15,6 @@ import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenLoginUserWithRole;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -31,7 +30,8 @@ public class JSonSerializerWithAccessFilterUnitTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
givenLoginUserWithRole(Role.ANY_CUSTOMER_USER);
|
||||
MockSecurityContext.givenAuthenticatedUser();
|
||||
MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -47,7 +47,8 @@ public class JSonSerializerWithAccessFilterUnitTest {
|
||||
public void shouldSerializeRestrictedFieldIfRequiredRoleIsCoveredByUser() throws IOException {
|
||||
|
||||
// given
|
||||
givenLoginUserWithRole(Role.FINANCIAL_CONTACT);
|
||||
MockSecurityContext.givenAuthenticatedUser();
|
||||
MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.FINANCIAL_CONTACT);
|
||||
|
||||
// when
|
||||
new JSonSerializerWithAccessFilter<>(jsonGenerator, null, givenDTO).serialize();
|
||||
@@ -60,7 +61,8 @@ public class JSonSerializerWithAccessFilterUnitTest {
|
||||
public void shouldNotSerializeRestrictedFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
|
||||
|
||||
// given
|
||||
givenLoginUserWithRole(Role.ANY_CUSTOMER_USER);
|
||||
MockSecurityContext.givenAuthenticatedUser();
|
||||
MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER);
|
||||
|
||||
// when
|
||||
new JSonSerializerWithAccessFilter<>(jsonGenerator, null, givenDTO).serialize();
|
||||
@@ -92,6 +94,7 @@ public class JSonSerializerWithAccessFilterUnitTest {
|
||||
|
||||
private GivenDto createSampleDto() {
|
||||
final GivenDto dto = new GivenDto();
|
||||
dto.customerId = 888L;
|
||||
dto.restrictedField = RandomStringUtils.randomAlphabetic(10);
|
||||
dto.openStringField = RandomStringUtils.randomAlphabetic(10);
|
||||
dto.openIntegerField = RandomUtils.nextInt();
|
||||
@@ -99,7 +102,15 @@ public class JSonSerializerWithAccessFilterUnitTest {
|
||||
return dto;
|
||||
}
|
||||
|
||||
private static class GivenCustomerDto {
|
||||
|
||||
}
|
||||
|
||||
private static class GivenDto {
|
||||
|
||||
@ParentId(GivenCustomerDto.class)
|
||||
Long customerId;
|
||||
|
||||
@AccessFor(read = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT})
|
||||
String restrictedField;
|
||||
|
||||
|
@@ -5,20 +5,20 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class MockSecurityContext {
|
||||
|
||||
public static void givenLoginUserWithRole(final Role userRole) {
|
||||
final String fakeUserName = userRole.name();
|
||||
|
||||
public static void givenAuthenticatedUser() {
|
||||
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
|
||||
securityContext.setAuthentication(new UsernamePasswordAuthenticationToken(fakeUserName, "dummy"));
|
||||
securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("dummyUser", "dummyPassword"));
|
||||
SecurityContextHolder.setContext(securityContext);
|
||||
Optional<String> login = SecurityUtils.getCurrentUserLogin();
|
||||
SecurityUtils.clearUserRoles();
|
||||
|
||||
assertThat(login).describedAs("precondition failed").contains(fakeUserName);
|
||||
assertThat(SecurityUtils.getCurrentUserLogin()).describedAs("precondition failed").hasValue("dummyUser");
|
||||
}
|
||||
|
||||
public static void givenUserHavingRole(final Class<?> onClass, final Long onId, final Role role) {
|
||||
SecurityUtils.addUserRole(onClass, onId, role);
|
||||
}
|
||||
}
|
||||
|
@@ -2,22 +2,18 @@ package org.hostsharing.hsadminng.service.dto;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.hostsharing.hsadminng.security.SecurityUtils;
|
||||
import org.hostsharing.hsadminng.service.accessfilter.Role;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.json.JsonTest;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenLoginUserWithRole;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser;
|
||||
import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@JsonTest
|
||||
@@ -31,7 +27,8 @@ public class CustomerDTOUnitTest {
|
||||
public void testSerializationAsContractualCustomerContact() throws JsonProcessingException {
|
||||
|
||||
// given
|
||||
givenLoginUserWithRole(Role.ANY_CUSTOMER_USER);
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(CustomerDTO.class, null, Role.ANY_CUSTOMER_USER);
|
||||
CustomerDTO given = createSomeCustomerDTO();
|
||||
|
||||
// when
|
||||
@@ -50,7 +47,8 @@ public class CustomerDTOUnitTest {
|
||||
public void testSerializationAsSupporter() throws JsonProcessingException {
|
||||
|
||||
// given
|
||||
givenLoginUserWithRole(Role.SUPPORTER);
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(CustomerDTO.class, null, Role.SUPPORTER);
|
||||
CustomerDTO given = createSomeCustomerDTO();
|
||||
|
||||
// when
|
||||
@@ -63,7 +61,8 @@ public class CustomerDTOUnitTest {
|
||||
@Test
|
||||
public void testDeserializeAsContractualCustomerContact() throws IOException {
|
||||
// given
|
||||
givenLoginUserWithRole(Role.CONTRACTUAL_CONTACT);
|
||||
givenAuthenticatedUser();
|
||||
givenUserHavingRole(CustomerDTO.class, null, Role.CONTRACTUAL_CONTACT);
|
||||
String json = "{\"id\":1234,\"contractualSalutation\":\"Hallo Updated\",\"billingSalutation\":\"Moin Updated\"}";
|
||||
|
||||
// when
|
||||
@@ -77,6 +76,8 @@ public class CustomerDTOUnitTest {
|
||||
assertThat(actual).isEqualToComparingFieldByField(expected);
|
||||
}
|
||||
|
||||
// --- only test fixture below ---
|
||||
|
||||
private String createExpectedJSon(CustomerDTO dto) {
|
||||
String json = // the fields in alphanumeric order:
|
||||
toJSonFieldDefinitionIfPresent("id", dto.getId()) +
|
||||
|
Reference in New Issue
Block a user