View Javadoc

1   /**
2    * Copyright 2005-2013 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.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.CoreApiServiceLocator;
23  import org.kuali.rice.core.api.encryption.EncryptionService;
24  import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbKualiEncryptDecryptFieldConversion;
25  import org.kuali.rice.krad.bo.PersistableBusinessObject;
26  import org.kuali.rice.krad.exception.ClassNotPersistableException;
27  import org.kuali.rice.krad.service.BusinessObjectService;
28  import org.kuali.rice.krad.service.impl.PersistenceServiceImplBase;
29  
30  import java.util.Collections;
31  import java.util.Set;
32  
33  import java.util.ArrayList;
34  import java.util.HashMap;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Set;
38  
39  public class PostDataLoadEncryptionServiceImpl extends PersistenceServiceImplBase implements PostDataLoadEncryptionService {
40      protected Logger LOG = Logger.getLogger(PostDataLoadEncryptionServiceImpl.class);
41  
42      private BusinessObjectService businessObjectService;
43      private EncryptionService encryptionService;
44      private PostDataLoadEncryptionDao postDataLoadEncryptionDao;
45  
46      @Override
47      public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
48      	checkArguments(businessObjectClass, attributeNames, true);
49      }
50  
51      @Override
52      public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames, boolean checkOjbEncryptConfig) {
53  	if ((businessObjectClass == null) || (attributeNames == null)) {
54  	    throw new IllegalArgumentException(
55  		    "PostDataLoadEncryptionServiceImpl.encrypt does not allow a null business object Class or attributeNames Set");
56  	}
57  	final ClassDescriptor classDescriptor;
58  	try {
59  	    classDescriptor = getClassDescriptor(businessObjectClass);
60  	} catch (ClassNotPersistableException e) {
61  	    throw new IllegalArgumentException(
62  		    "PostDataLoadEncryptionServiceImpl.encrypt does not handle business object classes that do not have a corresponding ClassDescriptor defined in the OJB repository",
63  		    e);
64  	}
65  	for (String attributeName : attributeNames) {
66  	    if (classDescriptor.getFieldDescriptorByName(attributeName) == null) {
67  		throw new IllegalArgumentException(
68  			new StringBuffer("Attribute ")
69  				.append(attributeName)
70  				.append(
71  					" specified to PostDataLoadEncryptionServiceImpl.encrypt is not in the OJB repository ClassDescriptor for Class ")
72  				.append(businessObjectClass).toString());
73  	    }
74  	    if (checkOjbEncryptConfig && !(classDescriptor.getFieldDescriptorByName(attributeName).getFieldConversion() instanceof OjbKualiEncryptDecryptFieldConversion)) {
75  		throw new IllegalArgumentException(
76  			new StringBuffer("Attribute ")
77  				.append(attributeName)
78  				.append(" of business object Class ")
79  				.append(businessObjectClass)
80  				.append(
81  					" specified to PostDataLoadEncryptionServiceImpl.encrypt is not configured for encryption in the OJB repository")
82  				.toString());
83  	    }
84  	}
85      }
86  
87      @Override
88      public void createBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
89  	postDataLoadEncryptionDao.createBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
90      }
91  
92      @Override
93      public void prepClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
94  	ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
95  	for (String attributeName : attributeNames) {
96  	    classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
97  		    FieldConversionDefaultImpl.class.getName());
98  	}
99      }
100 
101     @Override
102     public void truncateTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
103 	postDataLoadEncryptionDao.truncateTable(getClassDescriptor(businessObjectClass).getFullTableName());
104     }
105 
106     @Override
107     public void encrypt(PersistableBusinessObject businessObject, Set<String> attributeNames) {
108 	for (String attributeName : attributeNames) {
109 	    try {
110             if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
111         		PropertyUtils.setProperty(businessObject, attributeName, encryptionService.encrypt(PropertyUtils
112         			.getProperty(businessObject, attributeName)));
113             }
114 	    } catch (Exception e) {
115 		throw new RuntimeException(new StringBuffer(
116 			"PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt attribute ").append(
117 			attributeName).append(" of Class ").append(businessObject.getClass()).toString(), e);
118 	    }
119 	}
120 	businessObjectService.save(businessObject);
121     }
122 
123     @Override
124     public void restoreClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
125 	ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
126 	for (String attributeName : attributeNames) {
127 	    classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
128 		    OjbKualiEncryptDecryptFieldConversion.class.getName());
129 	}
130 	businessObjectService.countMatching(businessObjectClass, Collections.<String, Object>emptyMap());
131     }
132 
133     @Override
134     public void restoreTableFromBackup(Class<? extends PersistableBusinessObject> businessObjectClass) {
135 	postDataLoadEncryptionDao.restoreTableFromBackup(getClassDescriptor(businessObjectClass).getFullTableName());
136     }
137 
138     @Override
139     public void dropBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
140 	postDataLoadEncryptionDao.dropBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
141     }
142 
143     @Override
144     public boolean doesBackupTableExist(String tableName){
145         return postDataLoadEncryptionDao.doesBackupTableExist(tableName);
146     }
147     
148     @Override
149     public void createBackupTable(String tableName) {
150         postDataLoadEncryptionDao.createBackupTable(tableName);
151         postDataLoadEncryptionDao.addEncryptionIndicatorToBackupTable(tableName);
152     }
153     
154     @Override
155     public void truncateTable(String tableName) {
156         postDataLoadEncryptionDao.truncateTable(tableName);
157     }
158 
159     @Override
160     public List<Map<String, String>> retrieveUnencryptedColumnValuesFromBackupTable(String tableName, final List<String> columnNames, int numberOfRowsToCommitAfter) {
161         return postDataLoadEncryptionDao.retrieveUnencryptedColumnValuesFromBackupTable(tableName, columnNames, numberOfRowsToCommitAfter);
162     }
163 
164     @Override
165     public boolean performEncryption(final String tableName, final List<Map<String, String>> rowsToEncryptColumnsNameValueMap) throws Exception {
166         List<Map<String, List<String>>> rowsToEncryptColumnNameOldNewValuesMap = new ArrayList<Map<String, List<String>>>();
167         for(Map<String, String> columnsNameValueMap: rowsToEncryptColumnsNameValueMap){
168             rowsToEncryptColumnNameOldNewValuesMap.add(getColumnNamesEncryptedValues(tableName, columnsNameValueMap));
169         }
170         return postDataLoadEncryptionDao.performEncryption(tableName, rowsToEncryptColumnNameOldNewValuesMap); 
171     }
172 
173     public Map<String, List<String>> getColumnNamesEncryptedValues(String tableName, final Map<String, String> columnNamesValues) {
174         List<String> oldNewValues = new ArrayList<String>();
175         String columnOldValue;
176         Map<String, List<String>> columnNameOldNewValuesMap = new HashMap<String, List<String>>();
177         for (String columnName: columnNamesValues.keySet()) {
178             try {
179                 oldNewValues = new ArrayList<String>();
180                 columnOldValue = columnNamesValues.get(columnName);
181                 //List chosen over a java object (for old and new value) for better performance
182                 oldNewValues.add(PostDataLoadEncryptionDao.UNENCRYPTED_VALUE_INDEX, columnOldValue);
183                 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
184                     oldNewValues.add(PostDataLoadEncryptionDao.ENCRYPTED_VALUE_INDEX, encryptionService.encrypt(columnOldValue));
185                 }
186                 columnNameOldNewValuesMap.put(columnName, oldNewValues);
187             } catch (Exception e) {
188                 throw new RuntimeException(new StringBuffer(
189                 "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt Column ").append(
190                 columnName).append(" of Table ").append(tableName).toString(), e);
191             }
192         }
193         return columnNameOldNewValuesMap;
194     }
195 
196     @Override
197     public void restoreTableFromBackup(String tableName) {
198         postDataLoadEncryptionDao.dropEncryptionIndicatorFromBackupTable(tableName);
199         postDataLoadEncryptionDao.restoreTableFromBackup(tableName);
200     }
201 
202     @Override
203     public void dropBackupTable(String tableName) {
204         postDataLoadEncryptionDao.dropBackupTable(tableName);
205     }    
206 
207     public void setPostDataLoadEncryptionDao(PostDataLoadEncryptionDao postDataLoadEncryptionDao) {
208 	this.postDataLoadEncryptionDao = postDataLoadEncryptionDao;
209     }
210 
211     public void setEncryptionService(EncryptionService encryptionService) {
212 	this.encryptionService = encryptionService;
213     }
214 
215     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
216 	this.businessObjectService = businessObjectService;
217     }
218 }