moving the JSonSerializer to a separate package
This commit is contained in:
parent
6ab67995ff
commit
f4960f260e
@ -0,0 +1,16 @@
|
|||||||
|
package org.hostsharing.hsadminng.service.accessfilter;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target({ElementType.FIELD, ElementType.TYPE_USE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface AccessFor {
|
||||||
|
Role[] init() default Role.NOBODY;
|
||||||
|
|
||||||
|
Role[] update() default Role.NOBODY;
|
||||||
|
|
||||||
|
Role[] read() default Role.NOBODY;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
package org.hostsharing.hsadminng.service.accessfilter;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
import org.hostsharing.hsadminng.security.SecurityUtils;
|
||||||
|
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
|
||||||
|
import org.springframework.boot.jackson.JsonComponent;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
@JsonComponent
|
||||||
|
public class JSonSerializerWithAccessFilter extends JsonSerializer<Object> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(Object dto, JsonGenerator jsonGenerator,
|
||||||
|
SerializerProvider serializerProvider) throws IOException {
|
||||||
|
|
||||||
|
jsonGenerator.writeStartObject();
|
||||||
|
for (Field prop : CustomerDTO.class.getDeclaredFields()) {
|
||||||
|
toJSon(dto, jsonGenerator, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonGenerator.writeEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toJSon(Object dto, JsonGenerator jsonGenerator, Field prop) throws IOException {
|
||||||
|
if (getLoginUserRole().isAllowedToRead(prop)) {
|
||||||
|
final String fieldName = prop.getName();
|
||||||
|
if (Integer.class.isAssignableFrom(prop.getType()) || int.class.isAssignableFrom(prop.getType())) {
|
||||||
|
jsonGenerator.writeNumberField(fieldName, (int) get(dto, prop));
|
||||||
|
} else if (Long.class.isAssignableFrom(prop.getType()) || long.class.isAssignableFrom(prop.getType())) {
|
||||||
|
jsonGenerator.writeNumberField(fieldName, (long) get(dto, prop));
|
||||||
|
} else if (String.class.isAssignableFrom(prop.getType())) {
|
||||||
|
jsonGenerator.writeStringField(fieldName, (String) get(dto, prop));
|
||||||
|
} else {
|
||||||
|
throw new NotImplementedException("property type not yet implemented" + prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object get(Object dto, Field field) {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(dto);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Role getLoginUserRole() {
|
||||||
|
return SecurityUtils.getCurrentUserLogin().map(u -> Role.valueOf(u.toUpperCase())).orElse(Role.ANYBODY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object invoke(Object dto, Method method) {
|
||||||
|
try {
|
||||||
|
return method.invoke(dto);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package org.hostsharing.hsadminng.service.accessfilter;
|
||||||
|
|
||||||
|
import org.hostsharing.hsadminng.security.SecurityUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public enum Role {
|
||||||
|
NOBODY(0), HOSTMASTER(1), ADMIN(2), SUPPORTER(3),
|
||||||
|
ANY_CUSTOMER_CONTACT(20), CONTRACTUAL_CONTACT(21), FINANCIAL_CONTACT(22), TECHNICAL_CONTACT(22),
|
||||||
|
ANY_CUSTOMER_USER(80),
|
||||||
|
ANYBODY(99);
|
||||||
|
|
||||||
|
private final int level;
|
||||||
|
|
||||||
|
Role(final int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean covers(final Role role) {
|
||||||
|
return this == role || this.level < role.level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowedToInit(Field field) {
|
||||||
|
|
||||||
|
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
|
||||||
|
if (accessFor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isRoleCovered(accessFor.init());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowedToUpdate(Field field) {
|
||||||
|
|
||||||
|
final Role loginUserRole = SecurityUtils.getCurrentUserLogin().map(u -> Role.valueOf(u.toUpperCase())).orElse(Role.ANYBODY);
|
||||||
|
|
||||||
|
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
|
||||||
|
if (accessFor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isRoleCovered(accessFor.update());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowedToRead(Field field) {
|
||||||
|
|
||||||
|
final Role loginUserRole = SecurityUtils.getCurrentUserLogin().map(u -> Role.valueOf(u.toUpperCase())).orElse(Role.ANYBODY);
|
||||||
|
|
||||||
|
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
|
||||||
|
if (accessFor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isRoleCovered(accessFor.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRoleCovered(Role[] requiredRoles) {
|
||||||
|
for (Role accessAllowedForRole : requiredRoles) {
|
||||||
|
if (this.covers(accessAllowedForRole)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,6 +11,8 @@ import com.fasterxml.jackson.databind.node.IntNode;
|
|||||||
import com.fasterxml.jackson.databind.node.TextNode;
|
import com.fasterxml.jackson.databind.node.TextNode;
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.hostsharing.hsadminng.security.SecurityUtils;
|
import org.hostsharing.hsadminng.security.SecurityUtils;
|
||||||
|
import org.hostsharing.hsadminng.service.accessfilter.AccessFor;
|
||||||
|
import org.hostsharing.hsadminng.service.accessfilter.Role;
|
||||||
import org.springframework.boot.jackson.JsonComponent;
|
import org.springframework.boot.jackson.JsonComponent;
|
||||||
|
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
@ -254,75 +256,3 @@ public class CustomerDTO implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Role {
|
|
||||||
NOBODY(0), HOSTMASTER(1), ADMIN(2), SUPPORTER(3),
|
|
||||||
ANY_CUSTOMER_CONTACT(20), CONTRACTUAL_CONTACT(21), FINANCIAL_CONTACT(22), TECHNICAL_CONTACT(22),
|
|
||||||
ANY_CUSTOMER_USER(80),
|
|
||||||
ANYBODY(99);
|
|
||||||
|
|
||||||
private final int level;
|
|
||||||
|
|
||||||
Role(final int level) {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean covers(final Role role) {
|
|
||||||
return this == role || this.level < role.level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowedToInit(Field field) {
|
|
||||||
|
|
||||||
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
|
|
||||||
if (accessFor == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isRoleCovered(accessFor.init());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowedToUpdate(Field field) {
|
|
||||||
|
|
||||||
final Role loginUserRole = SecurityUtils.getCurrentUserLogin().map(u -> Role.valueOf(u.toUpperCase())).orElse(Role.ANYBODY);
|
|
||||||
|
|
||||||
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
|
|
||||||
if (accessFor == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isRoleCovered(accessFor.update());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowedToRead(Field field) {
|
|
||||||
|
|
||||||
final Role loginUserRole = SecurityUtils.getCurrentUserLogin().map(u -> Role.valueOf(u.toUpperCase())).orElse(Role.ANYBODY);
|
|
||||||
|
|
||||||
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
|
|
||||||
if (accessFor == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isRoleCovered(accessFor.read());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isRoleCovered(Role[] requiredRoles) {
|
|
||||||
for (Role accessAllowedForRole : requiredRoles) {
|
|
||||||
if (this.covers(accessAllowedForRole)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target({ElementType.FIELD, ElementType.TYPE_USE})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
@interface AccessFor {
|
|
||||||
Role[] init() default Role.NOBODY;
|
|
||||||
|
|
||||||
Role[] update() default Role.NOBODY;
|
|
||||||
|
|
||||||
Role[] read() default Role.NOBODY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ import static org.junit.Assert.assertEquals;
|
|||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
public class CustomerDTOUnitTest {
|
public class CustomerDTOUnitTest {
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ObjectMapper objectMapper;
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user