1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.attrvalue.validation;
20
21 import com.fasterxml.jackson.databind.json.JsonMapper;
22 import java.io.IOException;
23 import javax.ws.rs.core.MediaType;
24 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
25 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
26 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
27 import org.apache.tika.Tika;
28
29 public class BinaryValidator extends AbstractValidator {
30
31 private static final long serialVersionUID = 1344152444666540361L;
32
33 private static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
34
35 private static final Tika TIKA = new Tika();
36
37 static {
38 TIKA.setMaxStringLength(-1);
39 }
40
41 @Override
42 protected void doValidate(final PlainSchema schema, final PlainAttrValue attrValue) {
43
44 if (attrValue.getBinaryValue() != null) {
45 byte[] binaryValue = attrValue.getBinaryValue();
46 String mimeType = TIKA.detect(binaryValue);
47
48 boolean valid = true;
49 if (!mimeType.equals(attrValue.getAttr().getSchema().getMimeType())) {
50 if (MediaType.TEXT_PLAIN.equals(mimeType)
51 && MediaType.APPLICATION_JSON.equals(attrValue.getAttr().getSchema().getMimeType())) {
52
53 String decoded = new String(binaryValue).trim();
54 valid = (decoded.startsWith("{") && decoded.endsWith("}"))
55 || (decoded.startsWith("[") && decoded.endsWith("]"))
56 && isValidJSON(decoded);
57 } else {
58 valid = false;
59 }
60 }
61 if (!valid) {
62 throw new InvalidPlainAttrValueException(
63 "Found MIME type: '" + mimeType + "', expecting: '"
64 + attrValue.getAttr().getSchema().getMimeType() + '\'');
65 }
66 }
67 }
68
69 private static boolean isValidJSON(final String value) {
70 try {
71 MAPPER.readTree(value);
72 return true;
73 } catch (IOException e) {
74 LOG.debug("Invalid JSON string: {}", value, e);
75 return false;
76 }
77 }
78 }