View Javadoc

1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.devtools.pdle;
17  
18  import org.apache.commons.beanutils.PropertyUtils;
19  import org.apache.log4j.Logger;
20  import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl;
21  import org.apache.ojb.broker.metadata.ClassDescriptor;
22  import org.kuali.rice.core.api.encryption.EncryptionService;
23  import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbKualiEncryptDecryptFieldConversion;
24  import org.kuali.rice.krad.bo.PersistableBusinessObject;
25  import org.kuali.rice.krad.exception.ClassNotPersistableException;
26  import org.kuali.rice.krad.service.BusinessObjectService;
27  import org.kuali.rice.krad.service.impl.PersistenceServiceImplBase;
28  
29  import java.util.Collections;
30  import java.util.Set;
31  
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Map;
36  
37  public class PostDataLoadEncryptionServiceImpl extends PersistenceServiceImplBase implements PostDataLoadEncryptionService {
38      protected Logger LOG = Logger.getLogger(PostDataLoadEncryptionServiceImpl.class);
39  
40      private BusinessObjectService businessObjectService;
41      private EncryptionService encryptionService;
42      private PostDataLoadEncryptionDao postDataLoadEncryptionDao;
43  
44      @Override
45      public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
46      	checkArguments(businessObjectClass, attributeNames, true);
47      }
48  
49      @Override
50      public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames, boolean checkOjbEncryptConfig) {
51  	if ((businessObjectClass == null) || (attributeNames == null)) {
52  	    throw new IllegalArgumentException(
53  		    "PostDataLoadEncryptionServiceImpl.encrypt does not allow a null business object Class or attributeNames Set");
54  	}
55  	final ClassDescriptor classDescriptor;
56  	try {
57  	    classDescriptor = getClassDescriptor(businessObjectClass);
58  	} catch (ClassNotPersistableException e) {
59  	    throw new IllegalArgumentException(
60  		    "PostDataLoadEncryptionServiceImpl.encrypt does not handle business object classes that do not have a corresponding ClassDescriptor defined in the OJB repository",
61  		    e);
62  	}
63  	for (String attributeName : attributeNames) {
64  	    if (classDescriptor.getFieldDescriptorByName(attributeName) == null) {
65  		throw new IllegalArgumentException(
66  			new StringBuffer("Attribute ")
67  				.append(attributeName)
68  				.append(
69  					" specified to PostDataLoadEncryptionServiceImpl.encrypt is not in the OJB repository ClassDescriptor for Class ")
70  				.append(businessObjectClass).toString());
71  	    }
72  	    if (checkOjbEncryptConfig && !(classDescriptor.getFieldDescriptorByName(attributeName).getFieldConversion() instanceof OjbKualiEncryptDecryptFieldConversion)) {
73  		throw new IllegalArgumentException(
74  			new StringBuffer("Attribute ")
75  				.append(attributeName)
76  				.append(" of business object Class ")
77  				.append(businessObjectClass)
78  				.append(
79  					" specified to PostDataLoadEncryptionServiceImpl.encrypt is not configured for encryption in the OJB repository")
80  				.toString());
81  	    }
82  	}
83      }
84  
85      @Override
86      public void createBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
87  	postDataLoadEncryptionDao.createBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
88      }
89  
90      @Override
91      public void prepClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
92  	ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
93  	for (String attributeName : attributeNames) {
94  	    classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
95  		    FieldConversionDefaultImpl.class.getName());
96  	}
97      }
98  
99      @Override
100     public void truncateTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
101 	postDataLoadEncryptionDao.truncateTable(getClassDescriptor(businessObjectClass).getFullTableName());
102     }
103 
104     @Override
105     public void encrypt(PersistableBusinessObject businessObject, Set<String> attributeNames) {
106 	for (String attributeName : attributeNames) {
107 	    try {
108 		PropertyUtils.setProperty(businessObject, attributeName, encryptionService.encrypt(PropertyUtils
109 			.getProperty(businessObject, attributeName)));
110 	    } catch (Exception e) {
111 		throw new RuntimeException(new StringBuffer(
112 			"PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt attribute ").append(
113 			attributeName).append(" of Class ").append(businessObject.getClass()).toString(), e);
114 	    }
115 	}
116 	businessObjectService.save(businessObject);
117     }
118 
119     @Override
120     public void restoreClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
121 	ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
122 	for (String attributeName : attributeNames) {
123 	    classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
124 		    OjbKualiEncryptDecryptFieldConversion.class.getName());
125 	}
126 	businessObjectService.countMatching(businessObjectClass, Collections.<String, Object>emptyMap());
127     }
128 
129     @Override
130     public void restoreTableFromBackup(Class<? extends PersistableBusinessObject> businessObjectClass) {
131 	postDataLoadEncryptionDao.restoreTableFromBackup(getClassDescriptor(businessObjectClass).getFullTableName());
132     }
133 
134     @Override
135     public void dropBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
136 	postDataLoadEncryptionDao.dropBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
137     }
138 
139     @Override
140     public boolean doesBackupTableExist(String tableName){
141         return postDataLoadEncryptionDao.doesBackupTableExist(tableName);
142     }
143     
144     @Override
145     public void createBackupTable(String tableName) {
146         postDataLoadEncryptionDao.createBackupTable(tableName);
147         postDataLoadEncryptionDao.addEncryptionIndicatorToBackupTable(tableName);
148     }
149     
150     @Override
151     public void truncateTable(String tableName) {
152         postDataLoadEncryptionDao.truncateTable(tableName);
153     }
154 
155     @Override
156     public List<Map<String, String>> retrieveUnencryptedColumnValuesFromBackupTable(String tableName, final List<String> columnNames, int numberOfRowsToCommitAfter) {
157         return postDataLoadEncryptionDao.retrieveUnencryptedColumnValuesFromBackupTable(tableName, columnNames, numberOfRowsToCommitAfter);
158     }
159 
160     @Override
161     public boolean performEncryption(final String tableName, final List<Map<String, String>> rowsToEncryptColumnsNameValueMap) throws Exception {
162         List<Map<String, List<String>>> rowsToEncryptColumnNameOldNewValuesMap = new ArrayList<Map<String, List<String>>>();
163         for(Map<String, String> columnsNameValueMap: rowsToEncryptColumnsNameValueMap){
164             rowsToEncryptColumnNameOldNewValuesMap.add(getColumnNamesEncryptedValues(tableName, columnsNameValueMap));
165         }
166         return postDataLoadEncryptionDao.performEncryption(tableName, rowsToEncryptColumnNameOldNewValuesMap); 
167     }
168 
169     public Map<String, List<String>> getColumnNamesEncryptedValues(String tableName, final Map<String, String> columnNamesValues) {
170         List<String> oldNewValues = new ArrayList<String>();
171         String columnOldValue;
172         Map<String, List<String>> columnNameOldNewValuesMap = new HashMap<String, List<String>>();
173         for (String columnName: columnNamesValues.keySet()) {
174             try {
175                 oldNewValues = new ArrayList<String>();
176                 columnOldValue = columnNamesValues.get(columnName);
177                 //List chosen over a java object (for old and new value) for better performance
178                 oldNewValues.add(PostDataLoadEncryptionDao.UNENCRYPTED_VALUE_INDEX, columnOldValue);
179                 oldNewValues.add(PostDataLoadEncryptionDao.ENCRYPTED_VALUE_INDEX, encryptionService.encrypt(columnOldValue));
180                 columnNameOldNewValuesMap.put(columnName, oldNewValues);
181             } catch (Exception e) {
182                 throw new RuntimeException(new StringBuffer(
183                 "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt Column ").append(
184                 columnName).append(" of Table ").append(tableName).toString(), e);
185             }
186         }
187         return columnNameOldNewValuesMap;
188     }
189 
190     @Override
191     public void restoreTableFromBackup(String tableName) {
192         postDataLoadEncryptionDao.dropEncryptionIndicatorFromBackupTable(tableName);
193         postDataLoadEncryptionDao.restoreTableFromBackup(tableName);
194     }
195 
196     @Override
197     public void dropBackupTable(String tableName) {
198         postDataLoadEncryptionDao.dropBackupTable(tableName);
199     }    
200 
201     public void setPostDataLoadEncryptionDao(PostDataLoadEncryptionDao postDataLoadEncryptionDao) {
202 	this.postDataLoadEncryptionDao = postDataLoadEncryptionDao;
203     }
204 
205     public void setEncryptionService(EncryptionService encryptionService) {
206 	this.encryptionService = encryptionService;
207     }
208 
209     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
210 	this.businessObjectService = businessObjectService;
211     }
212 }