Story
Some times ago, I was taking with my friend about problems. One of them interesed me.
The problem can be expresed in sentence "How to protect yourself against SQL injection".
I wasn't interested in protection as protection, because it's a set of rules to check.
I wanted check anything on any object.
Analysis
Object or JSON or something else. This is not important. All of them have a fields. Fields have infinite number of types and names. So I thought few days. Solution is easy all fields == (key,value) and not problem.
Step of work.
1. Change object to List of (key,value)
2. Load rules
3. Check all element by rules*
4. Return result
* One rule should check one type for example. "Check all number. Number must be not negative.
Language:
I prefer java, but good choose is too JS,C#, python but not C++( I think so, but I may be wrong)
Implementation
Abstract Code have few line. Used is in source.
--------------------------------------------------------
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public abstract class ObjectChecker {
private List<Validator> validators;
private final ObjectMapper mapper;
public ObjectChecker() {
mapper=new ObjectMapper();
validators=new ArrayList<>();
initValidators();
}
public boolean checkFields(Object object) {
Map map = mapper.convertValue(object, Map.class);
return map.keySet().stream().allMatch(key -> {
Object o = map.get(key);
if (isMap(o)) {
if (!checkFields(o)) {
return false;
}
}
return checkField(""+key,o);
});
}
private boolean checkField(String key,Object value){
return validators.stream().allMatch(el->el.valid(key,value));
}
private boolean isMap(Object o){
if(o instanceof Map<?,?>){
return true;
}
return false;
}
protected abstract void initValidators();
protected void addValidator(Validator validator){
validators.add(validator);
}
}
------------------------------------------------------------------------------------
public interface Validator {
boolean valid(String key,Object value);
}
Code