You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2018/02/06 13:26:43 UTC

syncope git commit: [SYNCOPE-1267] New binary Schema validator to check MIME types

Repository: syncope
Updated Branches:
  refs/heads/2_0_X b8993d236 -> 8ebb5013b


[SYNCOPE-1267] New binary Schema validator to check MIME types


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/8ebb5013
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/8ebb5013
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/8ebb5013

Branch: refs/heads/2_0_X
Commit: 8ebb5013bd644a733a505b42d7b217faa9193150
Parents: b8993d2
Author: skylark17 <ma...@tirasa.net>
Authored: Tue Feb 6 14:22:41 2018 +0100
Committer: skylark17 <ma...@tirasa.net>
Committed: Tue Feb 6 14:25:23 2018 +0100

----------------------------------------------------------------------
 .../console/panels/PlainSchemaDetails.java      |  17 +++-
 core/persistence-jpa/pom.xml                    |   5 +
 .../attrvalue/validation/BinaryValidator.java   |  84 ++++++++++++++++
 .../java/data/AbstractAnyDataBinder.java        |   7 +-
 .../core/reference/ITImplementationLookup.java  |   2 +
 .../syncope/fit/core/PlainSchemaITCase.java     |  95 +++++++++++++++++++
 fit/core-reference/src/test/resources/test.html |  30 ++++++
 fit/core-reference/src/test/resources/test.json |   3 +
 fit/core-reference/src/test/resources/test.pdf  | Bin 0 -> 8603 bytes
 fit/core-reference/src/test/resources/test.xml  |  24 +++++
 pom.xml                                         |   8 ++
 11 files changed, 272 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
index 4cd80b7..686b1bd 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java
@@ -62,6 +62,8 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
 
     private final MultiFieldPanel<String> enumerationKeys;
 
+    private final AjaxDropDownChoicePanel<String> validatorClass;
+
     public PlainSchemaDetails(
             final String id,
             final PageReference pageReference,
@@ -228,6 +230,7 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
                         binaryParams, mimeType);
                 target.add(conversionParams);
                 target.add(typeParams);
+                target.add(validatorClass);
             }
         }
         );
@@ -241,8 +244,9 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
                 return new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getValidators());
             }
         };
-        final AjaxDropDownChoicePanel<String> validatorClass = new AjaxDropDownChoicePanel<>("validatorClass",
+        validatorClass = new AjaxDropDownChoicePanel<>("validatorClass",
                 getString("validatorClass"), new PropertyModel<String>(schemaTO, "validatorClass"));
+        validatorClass.setOutputMarkupId(true);
         ((DropDownChoice) validatorClass.getField()).setNullValid(true);
         validatorClass.setChoices(validatorsList.getObject());
         schemaForm.add(validatorClass);
@@ -324,6 +328,8 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
             binaryParams.setVisible(false);
             mimeType.setModelObject(null);
             mimeType.setChoices(null);
+
+            PlainSchemaTO.class.cast(schema).setValidatorClass(null);
         } else if (AttrSchemaType.Enum.ordinal() == typeOrdinal) {
             conversionParams.setVisible(false);
             conversionPattern.setModelObject(null);
@@ -350,6 +356,8 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
             binaryParams.setVisible(false);
             mimeType.setModelObject(null);
             mimeType.setChoices(null);
+
+            PlainSchemaTO.class.cast(schema).setValidatorClass(null);
         } else if (AttrSchemaType.Encrypted.ordinal() == typeOrdinal) {
             conversionParams.setVisible(false);
             conversionPattern.setModelObject(null);
@@ -372,6 +380,8 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
             binaryParams.setVisible(false);
             mimeType.setModelObject(null);
             mimeType.setChoices(null);
+
+            PlainSchemaTO.class.cast(schema).setValidatorClass(null);
         } else if (AttrSchemaType.Binary.ordinal() == typeOrdinal) {
             conversionParams.setVisible(false);
             conversionPattern.setModelObject(null);
@@ -395,6 +405,9 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
 
             binaryParams.setVisible(true);
             mimeType.setChoices(MIME_TYPES_LOADER.getMimeTypes());
+
+            PlainSchemaTO.class.cast(schema).
+                    setValidatorClass("org.apache.syncope.core.persistence.jpa.attrvalue.validation.BinaryValidator");
         } else {
             conversionParams.setVisible(false);
             conversionPattern.setModelObject(null);
@@ -419,6 +432,8 @@ public class PlainSchemaDetails extends AbstractSchemaDetailsPanel {
             binaryParams.setVisible(false);
             mimeType.setModelObject(null);
             mimeType.setChoices(null);
+
+            PlainSchemaTO.class.cast(schema).setValidatorClass(null);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index 8fe5e49..b197eb2 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -107,6 +107,11 @@ under the License.
       <artifactId>syncope-core-spring</artifactId>
       <version>${project.version}</version>
     </dependency>
+    
+    <dependency>
+      <groupId>org.apache.tika</groupId>
+      <artifactId>tika-core</artifactId>
+    </dependency>
         
     <!-- TEST -->
     <dependency> 

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BinaryValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BinaryValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BinaryValidator.java
new file mode 100644
index 0000000..cd0510c
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/attrvalue/validation/BinaryValidator.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.attrvalue.validation;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.tika.Tika;
+
+public class BinaryValidator extends AbstractValidator {
+
+    private static final long serialVersionUID = 1344152444666540361L;
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    public BinaryValidator(final PlainSchema schema) {
+        super(schema);
+    }
+
+    @Override
+    protected void doValidate(final PlainAttrValue attrValue) {
+        // check Binary schemas MIME Type mismatches
+        if (attrValue.getBinaryValue() != null) {
+            PlainSchema currentSchema = attrValue.getAttr().getSchema();
+            byte[] binaryValue = attrValue.getBinaryValue();
+            String mimeType = detectSchemaMimeType(binaryValue);
+            boolean valid = true;
+            if (!mimeType.equals(currentSchema.getMimeType())) {
+                if (mimeType.equals("text/plain")
+                        && currentSchema.getMimeType().equals("application/json")) {
+                    String decoded = new String(binaryValue).trim();
+                    valid = (decoded.startsWith("{") && decoded.endsWith("}"))
+                            || (decoded.startsWith("[") && decoded.endsWith("]"))
+                            && isValidJSON(decoded);
+                } else {
+                    valid = false;
+                }
+            }
+            if (!valid) {
+                throw new InvalidPlainAttrValueException(
+                        "Found MIME type: '"
+                        + mimeType
+                        + "', expecting: '"
+                        + currentSchema.getMimeType()
+                        + "'");
+            }
+        }
+    }
+
+    private String detectSchemaMimeType(final byte[] value) {
+        Tika tika = new Tika();
+        tika.setMaxStringLength(-1);
+        return tika.detect(value);
+    }
+
+    private boolean isValidJSON(final String value) {
+        try {
+            final JsonParser parser = MAPPER.getFactory().createParser(value);
+            while (parser.nextToken() != null) {
+            }
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 8e2b83c..9740c53 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -190,9 +190,12 @@ abstract class AbstractAnyDataBinder {
                 try {
                     attr.add(value, anyUtils);
                 } catch (InvalidPlainAttrValueException e) {
-                    LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e);
+                    String valueToPrint = value.length() > 40
+                            ? value.substring(0, 20) + "..."
+                            : value;
+                    LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + valueToPrint, e);
 
-                    invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage());
+                    invalidValues.getElements().add(schema.getKey() + ": " + valueToPrint + " - " + e.getMessage());
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
index 4209734..6f552da 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.dao.PasswordRule;
 import org.apache.syncope.core.persistence.api.dao.Reportlet;
 import org.apache.syncope.core.persistence.jpa.attrvalue.validation.AlwaysTrueValidator;
 import org.apache.syncope.core.persistence.jpa.attrvalue.validation.BasicValidator;
+import org.apache.syncope.core.persistence.jpa.attrvalue.validation.BinaryValidator;
 import org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator;
 import org.apache.syncope.core.persistence.jpa.dao.DefaultAccountRule;
 import org.apache.syncope.core.persistence.jpa.dao.DefaultPasswordRule;
@@ -141,6 +142,7 @@ public class ITImplementationLookup implements ImplementationLookup {
             classNames.add(BasicValidator.class.getName());
             classNames.add(EmailAddressValidator.class.getName());
             classNames.add(AlwaysTrueValidator.class.getName());
+            classNames.add(BinaryValidator.class.getName());
             put(Type.VALIDATOR, classNames);
 
             classNames = new HashSet<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
index 8841851..e36c8e5 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PlainSchemaITCase.java
@@ -25,13 +25,18 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.IOException;
 import java.util.List;
 import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.IOUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
@@ -41,6 +46,7 @@ import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PatchOperation;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.beans.SchemaQuery;
 import org.apache.syncope.fit.AbstractITCase;
@@ -144,6 +150,95 @@ public class PlainSchemaITCase extends AbstractITCase {
     }
 
     @Test
+    public void testBinaryValidation() throws IOException {
+        // pdf - with validator
+        PlainSchemaTO schemaTOpdf = new PlainSchemaTO();
+        schemaTOpdf.setKey("BinaryPDF");
+        schemaTOpdf.setType(AttrSchemaType.Binary);
+        schemaTOpdf.setMimeType("application/pdf");
+        schemaTOpdf.setValidatorClass("org.apache.syncope.core.persistence.jpa.attrvalue.validation.BinaryValidator");
+        schemaTOpdf.setAnyTypeClass("minimal user");
+
+        createSchema(SchemaType.PLAIN, schemaTOpdf);
+
+        // json - with validator
+        PlainSchemaTO schemaTOjson = new PlainSchemaTO();
+        schemaTOjson.setKey("BinaryJSON");
+        schemaTOjson.setType(AttrSchemaType.Binary);
+        schemaTOjson.setMimeType("application/json");
+        schemaTOjson.setValidatorClass("org.apache.syncope.core.persistence.jpa.attrvalue.validation.BinaryValidator");
+        schemaTOjson.setAnyTypeClass("minimal user");
+
+        createSchema(SchemaType.PLAIN, schemaTOjson);
+
+        // json - no validator
+        PlainSchemaTO schemaTOjson2 = new PlainSchemaTO();
+        schemaTOjson2.setKey("BinaryJSON2");
+        schemaTOjson2.setType(AttrSchemaType.Binary);
+        schemaTOjson2.setMimeType("application/json");
+        schemaTOjson2.setAnyTypeClass("minimal user");
+
+        createSchema(SchemaType.PLAIN, schemaTOjson2);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("test@syncope.apache.org");
+
+        userTO = createUser(userTO).getEntity();
+        assertNotNull(userTO);
+
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        // validation OK - application/pdf -> application/pdf
+        userPatch.getPlainAttrs().add(new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).
+                attrTO(attrTO("BinaryPDF",
+                        Base64Utility.encode(
+                                IOUtils.readBytesFromStream(getClass().getResourceAsStream("/test.pdf"))))).
+                build());
+
+        updateUser(userPatch);
+        assertNotNull(userService.read(userTO.getKey()).getPlainAttr("BinaryPDF"));
+
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        // validation KO - text/html -> application/pdf
+        try {
+            userPatch.getPlainAttrs().add(new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).
+                    attrTO(attrTO("BinaryPDF",
+                            Base64Utility.encode(
+                                    IOUtils.readBytesFromStream(getClass().getResourceAsStream("/test.html"))))).
+                    build());
+
+            updateUser(userPatch);
+            fail("This should not be reacheable");
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidValues, e.getType());
+        }
+
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        // validation ok - application/json -> application/json
+        userPatch.getPlainAttrs().add(new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).
+                attrTO(attrTO("BinaryJSON",
+                        Base64Utility.encode(
+                                IOUtils.readBytesFromStream(getClass().getResourceAsStream("/test.json"))))).
+                build());
+
+        updateUser(userPatch);
+        assertNotNull(userService.read(userTO.getKey()).getPlainAttr("BinaryJSON"));
+
+        userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        // no validation - application/xml -> application/json
+        userPatch.getPlainAttrs().add(new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).
+                attrTO(attrTO("BinaryJSON2",
+                        Base64Utility.encode(
+                                IOUtils.readBytesFromStream(getClass().getResourceAsStream("/test.xml"))))).
+                build());
+
+        updateUser(userPatch);
+        assertNotNull(userService.read(userTO.getKey()).getPlainAttr("BinaryJSON2"));
+    }
+
+    @Test
     public void delete() {
         PlainSchemaTO schemaTO = buildPlainSchemaTO("todelete", AttrSchemaType.String);
         schemaTO.setMandatoryCondition("false");

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/fit/core-reference/src/test/resources/test.html
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/test.html b/fit/core-reference/src/test/resources/test.html
new file mode 100644
index 0000000..d55d628
--- /dev/null
+++ b/fit/core-reference/src/test/resources/test.html
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!doctype html>
+
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+  <meta name="description" content="">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+</head>
+<body>
+  <p> Syncope is Magic </p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/fit/core-reference/src/test/resources/test.json
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/test.json b/fit/core-reference/src/test/resources/test.json
new file mode 100644
index 0000000..fd88c8d
--- /dev/null
+++ b/fit/core-reference/src/test/resources/test.json
@@ -0,0 +1,3 @@
+{
+  "message": "Syncope is Magic"
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/fit/core-reference/src/test/resources/test.pdf
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/test.pdf b/fit/core-reference/src/test/resources/test.pdf
new file mode 100644
index 0000000..bed69a7
Binary files /dev/null and b/fit/core-reference/src/test/resources/test.pdf differ

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/fit/core-reference/src/test/resources/test.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/test.xml b/fit/core-reference/src/test/resources/test.xml
new file mode 100644
index 0000000..66cad36
--- /dev/null
+++ b/fit/core-reference/src/test/resources/test.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<Tests xmlns="http://www.test.com">  
+  <Test>  
+    <Name>Syncope is Magic</Name>  
+  </Test>
+</Tests>  
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/8ebb5013/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 339dcc2..7af96f0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -405,6 +405,8 @@ under the License.
     <commons-text.version>1.2</commons-text.version>
     <commons-collection.version>4.1</commons-collection.version>
     <commons-logging.version>1.1.3</commons-logging.version>
+    
+    <tika.version>1.17</tika.version>
 
     <joda.version>2.9.9</joda.version>
 
@@ -1578,6 +1580,12 @@ under the License.
         <artifactId>httpmime</artifactId>
         <version>${httpclient.version}</version>
       </dependency>
+      
+      <dependency>
+        <groupId>org.apache.tika</groupId>
+        <artifactId>tika-core</artifactId>
+        <version>${tika.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>org.netbeans.api</groupId>