JSonDeserializerWithAccessFilter: shouldDetectMultipleSelfIdFields
This commit is contained in:
parent
d2b0f477f2
commit
1505e7bd66
@ -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,29 +97,20 @@ public class JSonDeserializerWithAccessFilter<T> {
|
||||
return ReflectionUtil.getValue(dto, selfIdField);
|
||||
}
|
||||
|
||||
private void checkAccess(final Field field) {
|
||||
if ( !rememberSelfIdField(field) ) {
|
||||
if (getId() == null) {
|
||||
if (!getLoginUserRole().isAllowedToInit(field)) {
|
||||
throw new BadRequestAlertException("Initialization of field prohibited for current user", toDisplay(field), "initializationProhibited");
|
||||
}
|
||||
} else if (getId() != null) {
|
||||
if (!getLoginUserRole().isAllowedToUpdate(field)) {
|
||||
throw new BadRequestAlertException("Update of field prohibited for current user", toDisplay(field), "updateProhibited");
|
||||
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");
|
||||
}
|
||||
} else if (getId() != null) {
|
||||
if (!getLoginUserRole().isAllowedToUpdate(field)) {
|
||||
throw new BadRequestAlertException("Update of field prohibited for current user", toDisplay(field), "updateProhibited");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user