001/**
002 * Copyright 2005-2015 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.krad.devtools.pdle;
017
018import org.apache.commons.beanutils.PropertyUtils;
019import org.apache.logging.log4j.Logger;
020import org.apache.logging.log4j.LogManager;
021import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl;
022import org.apache.ojb.broker.metadata.ClassDescriptor;
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.LegacyDataAdapter;
028import org.kuali.rice.krad.service.impl.PersistenceServiceImplBase;
029
030import java.util.Set;
031
032import java.util.ArrayList;
033import java.util.HashMap;
034import java.util.List;
035import java.util.Map;
036
037@Deprecated
038public class PostDataLoadEncryptionServiceImpl extends PersistenceServiceImplBase implements PostDataLoadEncryptionService {
039    protected Logger LOG = LogManager.getLogger(PostDataLoadEncryptionServiceImpl.class);
040
041    private LegacyDataAdapter legacyDataAdapter;
042    private EncryptionService encryptionService;
043    private PostDataLoadEncryptionDao postDataLoadEncryptionDao;
044
045    @Override
046    public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
047        checkArguments(businessObjectClass, attributeNames, true);
048    }
049
050    @Override
051    public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames, boolean checkOjbEncryptConfig) {
052        if ((businessObjectClass == null) || (attributeNames == null)) {
053            throw new IllegalArgumentException(
054                    "PostDataLoadEncryptionServiceImpl.encrypt does not allow a null business object Class or attributeNames Set");
055        }
056        final ClassDescriptor classDescriptor;
057        try {
058            classDescriptor = getClassDescriptor(businessObjectClass);
059        } catch (ClassNotPersistableException e) {
060            throw new IllegalArgumentException(
061                    "PostDataLoadEncryptionServiceImpl.encrypt does not handle business object classes that do not have a corresponding ClassDescriptor defined in the OJB repository",
062                    e);
063        }
064        for (String attributeName : attributeNames) {
065            if (classDescriptor.getFieldDescriptorByName(attributeName) == null) {
066                throw new IllegalArgumentException(
067                        new StringBuffer("Attribute ")
068                                .append(attributeName)
069                                .append(
070                                        " specified to PostDataLoadEncryptionServiceImpl.encrypt is not in the OJB repository ClassDescriptor for Class ")
071                                .append(businessObjectClass).toString());
072            }
073            if (checkOjbEncryptConfig && !(classDescriptor.getFieldDescriptorByName(attributeName).getFieldConversion() instanceof OjbKualiEncryptDecryptFieldConversion)) {
074                throw new IllegalArgumentException(
075                        new StringBuffer("Attribute ")
076                                .append(attributeName)
077                                .append(" of business object Class ")
078                                .append(businessObjectClass)
079                                .append(
080                                        " specified to PostDataLoadEncryptionServiceImpl.encrypt is not configured for encryption in the OJB repository")
081                                .toString());
082            }
083        }
084    }
085
086    @Override
087    public void createBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
088        postDataLoadEncryptionDao.createBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
089    }
090
091    @Override
092    public void prepClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
093        ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
094        for (String attributeName : attributeNames) {
095            classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
096                    FieldConversionDefaultImpl.class.getName());
097        }
098    }
099
100    @Override
101    public void truncateTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
102        postDataLoadEncryptionDao.truncateTable(getClassDescriptor(businessObjectClass).getFullTableName());
103    }
104
105    @Override
106    public void encrypt(PersistableBusinessObject businessObject, Set<String> attributeNames) {
107        for (String attributeName : attributeNames) {
108            try {
109                PropertyUtils.setProperty(businessObject, attributeName, encryptionService.encrypt(PropertyUtils
110                        .getProperty(businessObject, attributeName)));
111            } catch (Exception e) {
112                throw new RuntimeException(new StringBuffer(
113                        "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt attribute ").append(
114                        attributeName).append(" of Class ").append(businessObject.getClass()).toString(), e);
115            }
116        }
117        legacyDataAdapter.save(businessObject);
118    }
119
120    @Override
121    public void restoreClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
122        ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
123        for (String attributeName : attributeNames) {
124            classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
125                    OjbKualiEncryptDecryptFieldConversion.class.getName());
126        }
127        legacyDataAdapter.findAll(businessObjectClass);
128    }
129
130    @Override
131    public void restoreTableFromBackup(Class<? extends PersistableBusinessObject> businessObjectClass) {
132        postDataLoadEncryptionDao.restoreTableFromBackup(getClassDescriptor(businessObjectClass).getFullTableName());
133    }
134
135    @Override
136    public void dropBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
137        postDataLoadEncryptionDao.dropBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
138    }
139
140    @Override
141    public boolean doesBackupTableExist(String tableName){
142        return postDataLoadEncryptionDao.doesBackupTableExist(tableName);
143    }
144    
145    @Override
146    public void createBackupTable(String tableName) {
147        postDataLoadEncryptionDao.createBackupTable(tableName);
148        postDataLoadEncryptionDao.addEncryptionIndicatorToBackupTable(tableName);
149    }
150    
151    @Override
152    public void truncateTable(String tableName) {
153        postDataLoadEncryptionDao.truncateTable(tableName);
154    }
155
156    @Override
157    public List<Map<String, String>> retrieveUnencryptedColumnValuesFromBackupTable(String tableName, final List<String> columnNames, int numberOfRowsToCommitAfter) {
158        return postDataLoadEncryptionDao.retrieveUnencryptedColumnValuesFromBackupTable(tableName, columnNames, numberOfRowsToCommitAfter);
159    }
160
161    @Override
162    public boolean performEncryption(final String tableName, final List<Map<String, String>> rowsToEncryptColumnsNameValueMap) throws Exception {
163        List<Map<String, List<String>>> rowsToEncryptColumnNameOldNewValuesMap = new ArrayList<Map<String, List<String>>>();
164        for(Map<String, String> columnsNameValueMap: rowsToEncryptColumnsNameValueMap){
165            rowsToEncryptColumnNameOldNewValuesMap.add(getColumnNamesEncryptedValues(tableName, columnsNameValueMap));
166        }
167        return postDataLoadEncryptionDao.performEncryption(tableName, rowsToEncryptColumnNameOldNewValuesMap); 
168    }
169
170    public Map<String, List<String>> getColumnNamesEncryptedValues(String tableName, final Map<String, String> columnNamesValues) {
171        List<String> oldNewValues = new ArrayList<String>();
172        String columnOldValue;
173        Map<String, List<String>> columnNameOldNewValuesMap = new HashMap<String, List<String>>();
174        for (String columnName: columnNamesValues.keySet()) {
175            try {
176                oldNewValues = new ArrayList<String>();
177                columnOldValue = columnNamesValues.get(columnName);
178                //List chosen over a java object (for old and new value) for better performance
179                oldNewValues.add(PostDataLoadEncryptionDao.UNENCRYPTED_VALUE_INDEX, columnOldValue);
180                oldNewValues.add(PostDataLoadEncryptionDao.ENCRYPTED_VALUE_INDEX, encryptionService.encrypt(columnOldValue));
181                columnNameOldNewValuesMap.put(columnName, oldNewValues);
182            } catch (Exception e) {
183                throw new RuntimeException(new StringBuffer(
184                "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt Column ").append(
185                columnName).append(" of Table ").append(tableName).toString(), e);
186            }
187        }
188        return columnNameOldNewValuesMap;
189    }
190
191    @Override
192    public void restoreTableFromBackup(String tableName) {
193        postDataLoadEncryptionDao.dropEncryptionIndicatorFromBackupTable(tableName);
194        postDataLoadEncryptionDao.restoreTableFromBackup(tableName);
195    }
196
197    @Override
198    public void dropBackupTable(String tableName) {
199        postDataLoadEncryptionDao.dropBackupTable(tableName);
200    }    
201
202    public void setPostDataLoadEncryptionDao(PostDataLoadEncryptionDao postDataLoadEncryptionDao) {
203        this.postDataLoadEncryptionDao = postDataLoadEncryptionDao;
204    }
205
206    public void setEncryptionService(EncryptionService encryptionService) {
207        this.encryptionService = encryptionService;
208    }
209
210    public void setLegacyDataAdapter(LegacyDataAdapter legacyDataAdapter) {
211        this.legacyDataAdapter = legacyDataAdapter;
212    }
213}