001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.devtools.pdle; 017 018import org.apache.commons.beanutils.PropertyUtils; 019import org.apache.log4j.Logger; 020import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl; 021import org.apache.ojb.broker.metadata.ClassDescriptor; 022import org.kuali.rice.core.api.CoreApiServiceLocator; 023import org.kuali.rice.core.api.encryption.EncryptionService; 024import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbKualiEncryptDecryptFieldConversion; 025import org.kuali.rice.krad.bo.PersistableBusinessObject; 026import org.kuali.rice.krad.exception.ClassNotPersistableException; 027import org.kuali.rice.krad.service.BusinessObjectService; 028import org.kuali.rice.krad.service.impl.PersistenceServiceImplBase; 029 030import java.util.Collections; 031import java.util.Set; 032 033import java.util.ArrayList; 034import java.util.HashMap; 035import java.util.List; 036import java.util.Map; 037import java.util.Set; 038 039public class PostDataLoadEncryptionServiceImpl extends PersistenceServiceImplBase implements PostDataLoadEncryptionService { 040 protected Logger LOG = Logger.getLogger(PostDataLoadEncryptionServiceImpl.class); 041 042 private BusinessObjectService businessObjectService; 043 private EncryptionService encryptionService; 044 private PostDataLoadEncryptionDao postDataLoadEncryptionDao; 045 046 @Override 047 public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) { 048 checkArguments(businessObjectClass, attributeNames, true); 049 } 050 051 @Override 052 public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames, boolean checkOjbEncryptConfig) { 053 if ((businessObjectClass == null) || (attributeNames == null)) { 054 throw new IllegalArgumentException( 055 "PostDataLoadEncryptionServiceImpl.encrypt does not allow a null business object Class or attributeNames Set"); 056 } 057 final ClassDescriptor classDescriptor; 058 try { 059 classDescriptor = getClassDescriptor(businessObjectClass); 060 } catch (ClassNotPersistableException e) { 061 throw new IllegalArgumentException( 062 "PostDataLoadEncryptionServiceImpl.encrypt does not handle business object classes that do not have a corresponding ClassDescriptor defined in the OJB repository", 063 e); 064 } 065 for (String attributeName : attributeNames) { 066 if (classDescriptor.getFieldDescriptorByName(attributeName) == null) { 067 throw new IllegalArgumentException( 068 new StringBuffer("Attribute ") 069 .append(attributeName) 070 .append( 071 " specified to PostDataLoadEncryptionServiceImpl.encrypt is not in the OJB repository ClassDescriptor for Class ") 072 .append(businessObjectClass).toString()); 073 } 074 if (checkOjbEncryptConfig && !(classDescriptor.getFieldDescriptorByName(attributeName).getFieldConversion() instanceof OjbKualiEncryptDecryptFieldConversion)) { 075 throw new IllegalArgumentException( 076 new StringBuffer("Attribute ") 077 .append(attributeName) 078 .append(" of business object Class ") 079 .append(businessObjectClass) 080 .append( 081 " specified to PostDataLoadEncryptionServiceImpl.encrypt is not configured for encryption in the OJB repository") 082 .toString()); 083 } 084 } 085 } 086 087 @Override 088 public void createBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) { 089 postDataLoadEncryptionDao.createBackupTable(getClassDescriptor(businessObjectClass).getFullTableName()); 090 } 091 092 @Override 093 public void prepClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) { 094 ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass); 095 for (String attributeName : attributeNames) { 096 classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName( 097 FieldConversionDefaultImpl.class.getName()); 098 } 099 } 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}