Coverage Report - org.kuali.rice.devtools.pdle.PostDataLoadEncryptionServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
PostDataLoadEncryptionServlet
0%
0/43
0%
0/8
7
 
 1  
 /*
 2  
  * Copyright 2006-2011 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.lang.StringUtils;
 19  
 import org.apache.commons.logging.Log;
 20  
 import org.apache.commons.logging.LogFactory;
 21  
 import org.kuali.rice.krad.bo.PersistableBusinessObject;
 22  
 import org.kuali.rice.krad.service.BusinessObjectService;
 23  
 import org.kuali.rice.krad.service.KRADServiceLocator;
 24  
 import org.kuali.rice.krad.service.KRADServiceLocatorInternal;
 25  
 import org.springframework.core.io.FileSystemResource;
 26  
 
 27  
 import javax.servlet.ServletException;
 28  
 import javax.servlet.ServletRequest;
 29  
 import javax.servlet.ServletResponse;
 30  
 import javax.servlet.http.HttpServlet;
 31  
 import java.io.IOException;
 32  
 import java.util.Arrays;
 33  
 import java.util.Collection;
 34  
 import java.util.HashSet;
 35  
 import java.util.Map;
 36  
 import java.util.Properties;
 37  
 import java.util.Set;
 38  
 
 39  
 /**
 40  
  * This is a servlet that can be used to invoke the PostDataLoadEncryptionService.
 41  
  * 
 42  
  * It is not recommended to leave this Servlet running at all times.  It is really only intended
 43  
  * to be made available during initial data load and then removed (from the web.xml of the
 44  
  * application) after data load and encryption is complete.
 45  
  * 
 46  
  * This was done as a Servlet for now because Rice does not have a batch runner yet similar
 47  
  * to what KFS has (which is where a lot of the code below was borrowed from).
 48  
  *
 49  
  *
 50  
  *  <code>
 51  
 
 52  
    <!--
 53  
                 Add the following to your web.xml these if you want to run the servlet in order to encrypt
 54  
         some data in the Rice database.
 55  
                 (this would most likely be used for external identifiers in KIM that require encryption)
 56  
 
 57  
                 It is not recommended to enable this service for a production instance except during initial
 58  
                 data load.  It is not secured in any way and would allow for easy corruption of data if mishandled.
 59  
         -->
 60  
 
 61  
         <servlet>
 62  
             <servlet-name>postDataLoadEncryption</servlet-name>
 63  
             <servlet-class>org.kuali.rice.devtools.pdle.PostDataLoadEncryptionServlet</servlet-class>
 64  
         </servlet>
 65  
 
 66  
         <servlet-mapping>
 67  
                 <servlet-name>postDataLoadEncryption</servlet-name>
 68  
                 <url-pattern>/postDataLoadEncryption</url-pattern>
 69  
         </servlet-mapping>
 70  
 
 71  
     </code>
 72  
  *
 73  
  *
 74  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 75  
  *
 76  
  */
 77  0
 public class PostDataLoadEncryptionServlet extends HttpServlet {
 78  
 
 79  0
         private static final Log LOG = LogFactory.getLog(PostDataLoadEncryptionServlet.class);
 80  
         
 81  
         private static final String ATTRIBUTES_TO_ENCRYPT_PROPERTIES = "attributesToEncryptProperties";
 82  
         private static final String CHECK_OJB_ENCRYPT_CONFIG = "checkOjbEncryptConfig";
 83  
         
 84  
         @Override
 85  
         public void service(ServletRequest request, ServletResponse response)
 86  
                         throws ServletException, IOException {
 87  0
                 String attributesToEncryptPropertyFileName = request.getParameter(ATTRIBUTES_TO_ENCRYPT_PROPERTIES);
 88  0
                 if (StringUtils.isBlank(attributesToEncryptPropertyFileName)) {
 89  0
                         throw new IllegalArgumentException("No valid " + ATTRIBUTES_TO_ENCRYPT_PROPERTIES + " parameter was passed to this Servlet.");
 90  
                 }
 91  0
                 boolean checkOjbEncryptConfig = true;
 92  0
                 String checkOjbEncryptConfigValue = request.getParameter(CHECK_OJB_ENCRYPT_CONFIG);
 93  0
                 if (!StringUtils.isBlank(checkOjbEncryptConfigValue)) {
 94  0
                         checkOjbEncryptConfig = Boolean.valueOf(checkOjbEncryptConfigValue).booleanValue();
 95  
                 }
 96  0
                 execute(attributesToEncryptPropertyFileName, checkOjbEncryptConfig);
 97  0
                 response.getOutputStream().write(("<html><body><p>Successfully encrypted attributes as defined in: " + attributesToEncryptPropertyFileName + "</p></body></html>").getBytes());
 98  0
         }
 99  
 
 100  
         public void execute(String attributesToEncryptPropertyFileName, boolean checkOjbEncryptConfig) {
 101  0
                 PostDataLoadEncryptionService postDataLoadEncryptionService = KRADServiceLocatorInternal.getService(PostDataLoadEncryptionService.POST_DATA_LOAD_ENCRYPTION_SERVICE);
 102  0
         Properties attributesToEncryptProperties = new Properties();
 103  
         try {
 104  0
             attributesToEncryptProperties.load(new FileSystemResource(attributesToEncryptPropertyFileName).getInputStream());
 105  
         }
 106  0
         catch (Exception e) {
 107  0
             throw new IllegalArgumentException("PostDataLoadEncrypter requires the full, absolute path to a properties file where the keys are the names of the BusinessObject classes that should be processed and the values are the list of attributes on each that require encryption", e);
 108  0
         }
 109  0
         for (Map.Entry<Object, Object> entry : attributesToEncryptProperties.entrySet()) {
 110  
             Class<? extends PersistableBusinessObject> businessObjectClass;
 111  
             try {
 112  0
                 businessObjectClass = (Class<? extends PersistableBusinessObject>) Class.forName((String) entry.getKey());
 113  
             }
 114  0
             catch (Exception e) {
 115  0
                 throw new IllegalArgumentException(new StringBuffer("Unable to load Class ").append((String) entry.getKey()).append(" specified by name in attributesToEncryptProperties file ").append(attributesToEncryptProperties).toString(), e);
 116  0
             }
 117  
             final Set<String> attributeNames;
 118  
             try {
 119  0
                 attributeNames = new HashSet<String>(Arrays.asList(StringUtils.split((String) entry.getValue(), ",")));
 120  
             }
 121  0
             catch (Exception e) {
 122  0
                 throw new IllegalArgumentException(new StringBuffer("Unable to load attributeNames Set from comma-delimited list of attribute names specified as value for property with Class name ").append(entry.getKey()).append(" key in attributesToEncryptProperties file ").append(attributesToEncryptProperties).toString(), e);
 123  0
             }
 124  0
             postDataLoadEncryptionService.checkArguments(businessObjectClass, attributeNames, checkOjbEncryptConfig);
 125  0
             postDataLoadEncryptionService.createBackupTable(businessObjectClass);
 126  0
             BusinessObjectService businessObjectService = KRADServiceLocator.getBusinessObjectService();
 127  
             try {
 128  0
                 postDataLoadEncryptionService.prepClassDescriptor(businessObjectClass, attributeNames);
 129  0
                 Collection<? extends PersistableBusinessObject> objectsToEncrypt = businessObjectService.findAll(businessObjectClass);
 130  0
                 for (Object businessObject : objectsToEncrypt) {
 131  0
                     postDataLoadEncryptionService.encrypt((PersistableBusinessObject) businessObject, attributeNames);
 132  
                 }
 133  0
                 postDataLoadEncryptionService.restoreClassDescriptor(businessObjectClass, attributeNames);
 134  0
                 LOG.info(new StringBuffer("Encrypted ").append(entry.getValue()).append(" attributes of Class ").append(entry.getKey()));
 135  
             }
 136  0
             catch (Exception e) {
 137  0
                 postDataLoadEncryptionService.restoreTableFromBackup(businessObjectClass);
 138  0
                 LOG.error(new StringBuffer("Caught exception, while encrypting ").append(entry.getValue()).append(" attributes of Class ").append(entry.getKey()).append(" and restored table from backup"), e);
 139  0
             }
 140  0
             postDataLoadEncryptionService.dropBackupTable(businessObjectClass);
 141  0
         }
 142  0
     }
 143  
         
 144  
 }