1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.documentoperation.web;
17
18 import java.sql.Connection;
19 import java.sql.PreparedStatement;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import javax.crypto.Cipher;
26 import javax.crypto.KeyGenerator;
27 import javax.crypto.SecretKey;
28 import javax.crypto.SecretKeyFactory;
29 import javax.crypto.spec.DESKeySpec;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32 import javax.sql.DataSource;
33
34 import org.apache.commons.codec.binary.Base64;
35 import org.apache.commons.lang.StringUtils;
36 import org.apache.log4j.Logger;
37 import org.apache.struts.action.ActionForm;
38 import org.apache.struts.action.ActionForward;
39 import org.apache.struts.action.ActionMapping;
40 import org.kuali.rice.core.api.config.property.ConfigContext;
41 import org.kuali.rice.kew.service.KEWServiceLocator;
42 import org.kuali.rice.kew.web.KewKualiAction;
43 import org.kuali.rice.kim.api.KimConstants;
44 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
45 import org.kuali.rice.krad.exception.AuthorizationException;
46 import org.kuali.rice.krad.util.GlobalVariables;
47 import org.kuali.rice.krad.util.KRADConstants;
48 import org.kuali.rice.krad.util.KRADUtils;
49 import org.springframework.dao.DataAccessException;
50 import org.springframework.jdbc.core.JdbcTemplate;
51 import org.springframework.jdbc.core.PreparedStatementCallback;
52 import org.springframework.jdbc.core.PreparedStatementCreator;
53
54 public class DocumentContentOperationAction extends KewKualiAction {
55
56 private final static String ALGORITHM = "DES/ECB/PKCS5Padding";
57 private final static String CHARSET = "UTF-8";
58 private static Logger LOG = Logger.getLogger(DocumentContentOperationAction.class);
59
60 public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
61 return mapping.findForward("basic");
62 }
63
64 public ActionForward encryptContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
65 if(checkPermissions()) {
66 DocumentContentOperationForm docContentOperationForm = (DocumentContentOperationForm)form;
67 String formDocumentId = docContentOperationForm.getDocumentId();
68 String[] documentIds = formDocumentId.split(",");
69 String encryptionKey = docContentOperationForm.getKey();
70 for(String documentId : documentIds) {
71 String docContent = getDocumentContent(documentId);
72 String encryptedDocContent = encrypt(encryptionKey, docContent);
73 saveDocumentContent(documentId, encryptedDocContent);
74 }
75 }
76 return mapping.findForward("basic");
77 }
78
79 public ActionForward decryptContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
80 if(checkPermissions()) {
81 DocumentContentOperationForm docContentOperationForm = (DocumentContentOperationForm)form;
82 String formDocumentId = docContentOperationForm.getDocumentId();
83 String[] documentIds = formDocumentId.split(",");
84 String encryptionKey = docContentOperationForm.getKey();
85 for(String documentId : documentIds) {
86 String docContent = getDocumentContent(documentId);
87 String decryptedDocContent = decrypt(encryptionKey, docContent);
88 saveDocumentContent(documentId, decryptedDocContent);
89 }
90 }
91 return mapping.findForward("basic");
92 }
93
94 private boolean checkPermissions() {
95 String principalId = GlobalVariables.getUserSession().getPrincipalId();
96 Map<String, String> permissionDetails = KRADUtils.getNamespaceAndActionClass(this.getClass());
97
98 boolean canUseScreen = KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(principalId,
99 KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.USE_SCREEN, permissionDetails,
100 new HashMap<String, String>());
101 if(canUseScreen && !ConfigContext.getCurrentContextConfig().isProductionEnvironment()) {
102 return true;
103 } else {
104 throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalName(), "encrypt or decrypt content", this.getClass().getSimpleName());
105 }
106 }
107
108 private String getDocumentContent(final String documentId) {
109 final DataSource dataSource = KEWServiceLocator.getDataSource();
110 JdbcTemplate template = new JdbcTemplate(dataSource);
111 String docContent = template.execute(
112 new PreparedStatementCreator() {
113 public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
114 String sql = "SELECT doc_cntnt_txt FROM krew_doc_hdr_cntnt_t WHERE doc_hdr_id = ?";
115 PreparedStatement statement = connection.prepareStatement(sql);
116 return statement;
117 }
118 },
119 new PreparedStatementCallback<String>() {
120 public String doInPreparedStatement(PreparedStatement statement) throws SQLException, DataAccessException {
121 String docContent = "";
122 statement.setString(1, documentId);
123 ResultSet rs = statement.executeQuery();
124 try {
125 while(rs.next()) {
126 docContent = rs.getString("doc_cntnt_txt");
127 }
128 } finally {
129 if(rs != null) {
130 rs.close();
131 }
132 }
133 return docContent;
134 }
135 });
136 return docContent;
137 }
138
139 private void saveDocumentContent(final String documentId, final String docContent) {
140 if(StringUtils.isBlank(documentId) || StringUtils.isBlank(docContent)) {
141 LOG.info("The document Id or the doc content was blank");
142 return;
143 }
144 final DataSource dataSource = KEWServiceLocator.getDataSource();
145 JdbcTemplate template = new JdbcTemplate(dataSource);
146 template.execute(
147 new PreparedStatementCreator() {
148 public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
149 String sql = "UPDATE krew_doc_hdr_cntnt_t SET doc_cntnt_txt = ? WHERE doc_hdr_id = ?";
150 PreparedStatement statement = connection.prepareStatement(sql);
151 return statement;
152 }
153 },
154 new PreparedStatementCallback<String>() {
155 public String doInPreparedStatement(PreparedStatement statement) throws SQLException, DataAccessException {
156 statement.setString(1, docContent);
157 statement.setString(2, documentId);
158 ResultSet rs = statement.executeQuery();
159 if(rs != null) {
160 rs.close();
161 }
162 return "";
163 }
164 });
165 }
166
167 private SecretKey getSecretKey(String encryptionKey) throws Exception {
168 KeyGenerator keygen = KeyGenerator.getInstance("DES");
169 SecretKey desKey = keygen.generateKey();
170
171
172 Cipher cipher = Cipher.getInstance(ALGORITHM);
173 cipher.init((Cipher.UNWRAP_MODE), desKey);
174
175 byte[] bytes = Base64.decodeBase64(encryptionKey.getBytes());
176
177 SecretKeyFactory desFactory = SecretKeyFactory.getInstance("DES");
178
179 DESKeySpec keyspec = new DESKeySpec(bytes);
180 desKey = desFactory.generateSecret(keyspec);
181
182 cipher.init((Cipher.WRAP_MODE), desKey);
183 return desKey;
184 }
185
186 private String encrypt(String encryptionKey, String value) throws Exception {
187 if (StringUtils.isBlank(value)) {
188 LOG.info("The value was was blank, returning an empty string");
189 return "";
190 }
191
192
193 Cipher cipher = Cipher.getInstance(ALGORITHM);
194 cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(encryptionKey));
195
196 try {
197
198 byte[] cleartext = value.toString().getBytes(CHARSET);
199
200
201 byte[] ciphertext = cipher.doFinal(cleartext);
202
203 return new String(Base64.encodeBase64(ciphertext), CHARSET);
204 } catch (Exception e) {
205 throw new RuntimeException(e);
206 }
207 }
208
209 private String decrypt(String encryptionKey, String value) throws Exception {
210 if (StringUtils.isBlank(value)) {
211 LOG.info("The value was was blank, returning an empty string");
212 return "";
213 }
214
215 Cipher cipher = Cipher.getInstance(ALGORITHM);
216 cipher.init(Cipher.DECRYPT_MODE, getSecretKey(encryptionKey));
217
218
219 byte[] encryptedData = Base64.decodeBase64(value.getBytes(CHARSET));
220
221
222 byte[] cleartext1 = cipher.doFinal(encryptedData);
223 return new String(cleartext1, CHARSET);
224 }
225 }