JSonDeserializerWithAccessFilter: shouldDetectMultipleSelfIdFields

This commit is contained in:
Michael Hoennig 2019-04-23 09:22:23 +02:00
parent d2b0f477f2
commit 1505e7bd66
3 changed files with 34 additions and 29 deletions

View File

@ -31,6 +31,24 @@ public class JSonDeserializerWithAccessFilter<T> {
// Jackson deserializes from the JsonParser, thus no input parameter needed.
public T deserialize() {
determineSelfIdField();
deserializeValues();
checkAccessToModifiedFields();
return dto;
}
private void determineSelfIdField() {
for (Field field : dto.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(SelfId.class)) {
if (selfIdField != null) {
throw new AssertionError("multiple @" + SelfId.class.getSimpleName() + " detected in " + field.getDeclaringClass().getSimpleName());
}
selfIdField = field;
}
}
}
private void deserializeValues() {
treeNode.fieldNames().forEachRemaining(fieldName -> {
try {
final Field field = dto.getClass().getDeclaredField(fieldName);
@ -41,9 +59,6 @@ public class JSonDeserializerWithAccessFilter<T> {
throw new RuntimeException("setting field " + fieldName + " failed", e);
}
});
modifiedFields.forEach(this::checkAccess);
return dto;
}
private Object readValue(final TreeNode treeNode, final Field field) {
@ -82,8 +97,9 @@ public class JSonDeserializerWithAccessFilter<T> {
return ReflectionUtil.getValue(dto, selfIdField);
}
private void checkAccess(final Field field) {
if ( !rememberSelfIdField(field) ) {
private void checkAccessToModifiedFields() {
modifiedFields.forEach(field -> {
if ( !field.equals(selfIdField) ) {
if (getId() == null) {
if (!getLoginUserRole().isAllowedToInit(field)) {
throw new BadRequestAlertException("Initialization of field prohibited for current user", toDisplay(field), "initializationProhibited");
@ -94,17 +110,7 @@ public class JSonDeserializerWithAccessFilter<T> {
}
}
}
}
private boolean rememberSelfIdField(final Field field) {
if ( field.isAnnotationPresent(SelfId.class) ) {
if ( selfIdField != null ) {
throw new AssertionError("multiple " + SelfId.class + " detected in " + field.getDeclaringClass().getSimpleName() );
}
selfIdField = field;
return true;
}
return false;
});
}
private String toDisplay(final Field field) {

View File

@ -3,7 +3,7 @@ package org.hostsharing.hsadminng.service.accessfilter;
import java.lang.annotation.*;
/**
* Used to mark a field within a DTO as containing the id of a field,
* Used to mark a field within a DTO as containing the own id,
* it's needed to identify an existing entity for update functions.
* Initialization and update rights have no meaning for such fields,
* its initialized automatically and never updated.

View File

@ -127,15 +127,15 @@ public class JSonDeserializerWithAccessFilterUnitTest {
}
@Test
public void should() throws IOException {
public void shouldDetectMultipleSelfIdFields() throws IOException {
// given
givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "Restricted String Value")));
givenJSonTree(asJSon(ImmutablePair.of("id", 1111L)));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(jsonParser, null, GivenDtoWithMultipleSelfId.class).deserialize());
// then
assertThat(exception).isInstanceOf(AssertionError.class).hasMessageContaining("xx");
assertThat(exception).isInstanceOf(AssertionError.class).hasMessage("multiple @SelfId detected in GivenDtoWithMultipleSelfId");
}
// --- only fixture code below ---
@ -183,7 +183,6 @@ public class JSonDeserializerWithAccessFilterUnitTest {
Long openLongField;
}
public static class GivenDtoWithMultipleSelfId {
@SelfId