View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.provisioning.api.serialization;
20  
21  import com.fasterxml.jackson.core.JsonParser;
22  import com.fasterxml.jackson.databind.DeserializationContext;
23  import com.fasterxml.jackson.databind.JsonDeserializer;
24  import com.fasterxml.jackson.databind.node.ObjectNode;
25  import java.io.IOException;
26  import java.lang.reflect.Field;
27  import java.util.Base64;
28  import org.identityconnectors.common.security.EncryptorFactory;
29  import org.identityconnectors.common.security.GuardedString;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  import org.springframework.util.ReflectionUtils;
33  
34  class GuardedStringDeserializer extends JsonDeserializer<GuardedString> {
35  
36      private static final Logger LOG = LoggerFactory.getLogger(GuardedStringDeserializer.class);
37  
38      private static final String READONLY = "readOnly";
39  
40      private static final String DISPOSED = "disposed";
41  
42      private static final String ENCRYPTED_BYTES = "encryptedBytes";
43  
44      private static final String BASE64_SHA1_HASH = "base64SHA1Hash";
45  
46      private static final String LOG_ERROR_MESSAGE = "Could not set field value to {}";
47      
48      @Override
49      public GuardedString deserialize(final JsonParser jp, final DeserializationContext ctx)
50              throws IOException {
51  
52          ObjectNode tree = jp.readValueAsTree();
53  
54          boolean readOnly = false;
55          if (tree.has(READONLY)) {
56              readOnly = tree.get(READONLY).asBoolean();
57          }
58          boolean disposed = false;
59          if (tree.has(DISPOSED)) {
60              disposed = tree.get(DISPOSED).asBoolean();
61          }
62          byte[] encryptedBytes = null;
63          if (tree.has(ENCRYPTED_BYTES)) {
64              encryptedBytes = Base64.getDecoder().decode(tree.get(ENCRYPTED_BYTES).asText());
65          }
66          String base64SHA1Hash = null;
67          if (tree.has(BASE64_SHA1_HASH)) {
68              base64SHA1Hash = tree.get(BASE64_SHA1_HASH).asText();
69          }
70  
71          final byte[] clearBytes = EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(encryptedBytes);
72  
73          GuardedString dest = new GuardedString(new String(clearBytes).toCharArray());
74  
75          try {
76              Field field = GuardedString.class.getDeclaredField(READONLY);
77              ReflectionUtils.makeAccessible(field);
78              ReflectionUtils.setField(field, dest, readOnly);
79          } catch (Exception e) {
80              LOG.error(LOG_ERROR_MESSAGE, readOnly, e);
81          }
82  
83          try {
84              Field field = GuardedString.class.getDeclaredField(DISPOSED);
85              ReflectionUtils.makeAccessible(field);
86              ReflectionUtils.setField(field, dest, disposed);
87          } catch (Exception e) {
88              LOG.error(LOG_ERROR_MESSAGE, disposed, e);
89          }
90  
91          if (base64SHA1Hash != null) {
92              try {
93                  Field field = GuardedString.class.getDeclaredField(BASE64_SHA1_HASH);
94                  ReflectionUtils.makeAccessible(field);
95                  ReflectionUtils.setField(field, dest, base64SHA1Hash);
96              } catch (Exception e) {
97                  LOG.error(LOG_ERROR_MESSAGE, base64SHA1Hash, e);
98              }
99          }
100 
101         return dest;
102     }
103 
104 }