// Copyright 2006 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.enterprise.connector.servlet; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import com.google.enterprise.connector.common.SecurityUtils; import com.google.enterprise.connector.spi.XmlUtils; import com.google.enterprise.connector.test.ConnectorTestUtils; import com.google.enterprise.connector.util.XmlParseUtil; import junit.framework.TestCase; import org.w3c.dom.Element; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; public class ServletUtilTest extends TestCase { private static final String HIDE_KEY_ONE = "PasswordOne"; private static final String HIDE_KEY_TWO = "a_password_two"; private static final String HIDE_KEY_THREE = "imapasswordtoo"; private static final String CLEAR_KEY_ONE = "NotAPwd"; @SuppressWarnings("deprecation") // XMLTAG_STATUSID public void testWriteMessageCode() { StringWriter buffer = new StringWriter(); PrintWriter out = new PrintWriter(buffer); String message = "foo</" + ServletUtil.XMLTAG_STATUS_MESSAGE + ">bar" + "<" + ServletUtil.XMLTAG_STATUS_MESSAGE + ">"; String param = "foo\"/>bar<tag attr=\""; ServletUtil.writeMessageCode(out, new ConnectorMessageCode(42, message, new Object[] { param })); Element body = XmlParseUtil.parseAndGetRootElement( "<body>" + buffer + "</body>", "body"); assertNotNull(buffer.toString(), body); assertEquals(ServletUtil.XMLTAG_STATUSID, "42", XmlParseUtil.getFirstElementByTagName(body, ServletUtil.XMLTAG_STATUSID)); assertEquals(ServletUtil.XMLTAG_STATUS_MESSAGE, message, XmlParseUtil.getFirstElementByTagName(body, ServletUtil.XMLTAG_STATUS_MESSAGE)); assertEquals(ServletUtil.XMLTAG_STATUS_PARAM, param, XmlParseUtil.getFirstAttribute(body, ServletUtil.XMLTAG_STATUS_PARAMS, ServletUtil.XMLTAG_STATUS_PARAM)); } public void testWriteXmlElement() { StringWriter buffer = new StringWriter(); PrintWriter out = new PrintWriter(buffer); String value = "foo</tag>bar<tag>"; ServletUtil.writeXMLElement(out, 0, "tag", value); Element body = XmlParseUtil.parseAndGetRootElement( "<body>" + buffer + "</body>", "body"); assertNotNull(buffer.toString(), body); assertEquals(value, XmlParseUtil.getFirstElementByTagName(body, "tag")); } public void testWriteXmlElement_null() { StringWriter buffer = new StringWriter(); PrintWriter out = new PrintWriter(buffer); ServletUtil.writeXMLElement(out, 0, "tag", null); Element body = XmlParseUtil.parseAndGetRootElement( "<body>" + buffer + "</body>", "body"); assertNotNull(buffer.toString(), body); assertEquals("null", XmlParseUtil.getFirstElementByTagName(body, "tag")); } public void testWriteXmlElement_cdata() { StringWriter buffer = new StringWriter(); PrintWriter out = new PrintWriter(buffer); String value = "foo</tag>bar<tag>"; ServletUtil.writeXMLElement(out, 0, "tag", ServletUtil.XML_CDATA_START + value + ServletUtil.XML_CDATA_END); Element body = XmlParseUtil.parseAndGetRootElement(buffer.toString(), "tag"); assertNotNull(buffer.toString(), body); assertEquals(value, XmlParseUtil.getCdata(body)); } public void testWriteEmptyXmlElement() { StringWriter buffer = new StringWriter(); PrintWriter out = new PrintWriter(buffer); ServletUtil.writeEmptyXMLElement(out, 0, "tag"); assertEquals("<tag></tag>\n", buffer.toString()); } public void testWriteXmlTagWithAttrs() { StringWriter buffer = new StringWriter(); PrintWriter out = new PrintWriter(buffer); String name = "foo\"/>bar<tag attr=\""; ServletUtil.writeXMLTagWithAttrs(out, 0, ServletUtil.XMLTAG_SUCCESS, ImmutableMap.of(ServletUtil.XMLTAG_CONNECTOR_NAME, name), true); Element body = XmlParseUtil.parseAndGetRootElement( "<body>" + buffer + "</body>", "body"); assertNotNull(buffer.toString(), body); assertEquals(ServletUtil.XMLTAG_CONNECTOR_NAME, name, XmlParseUtil.getFirstAttribute(body, ServletUtil.XMLTAG_SUCCESS, ServletUtil.XMLTAG_CONNECTOR_NAME)); } public void testPrependCmPrefix() { onePrependTest("<foo spam=\"bar\">", "<foo spam=\"bar\">"); onePrependTest("<foo bar=\"test\" name='bar'>", "<foo bar=\"test\" name='CM_bar'>"); onePrependTest("<a name=\"bar\"><input name=\"baz\">", "<a name=\"CM_bar\"><input name=\"CM_baz\">"); onePrependTest("<a name = 'bar' > <input name = \"baz\" >", "<a name = 'CM_bar' > <input name = \"CM_baz\" >"); onePrependTest("<a name='bar'><input name=\"spam\">" + "<a name='foo'><a name=\"eggs\"><a name='foo'>", "<a name='CM_bar'><input name=\"spam\">" + "<a name='CM_foo'><a name=\"eggs\"><a name='CM_foo'>"); onePrependTest("<a name='bar'><![CDATA[<input name=\"spam\">]]>" + "<a name='foo'><![CDATA[<a name=\"eggs\">]]><a name='foo'>", "<a name='CM_bar'><![CDATA[<input name=\"spam\">]]>" + "<a name='CM_foo'><![CDATA[<a name=\"eggs\">]]><a name='CM_foo'>"); } private void onePrependTest(String original, String expected) { assertEquals(expected, ServletUtil.prependCmPrefix(original)); } public void testPercentEncode() throws Exception { StringBuilder input = new StringBuilder(); for (int i = 1; i < 256; i++) { input.append((char) i); } StringBuilder output = new StringBuilder(); ServletUtil.percentEncode(output, input.toString()); assertTrue(output.length() > 256); assertTrue(output.toString().matches("[-_\\.%~A-Za-z0-9]+")); assertEquals(input.toString(), URLDecoder.decode(output.toString(), "UTF-8")); } public void testPercentEncodeKeyValuePair() { testEncodeKeyValue("foo", "bar", "foo=bar"); testEncodeKeyValue("google:mimetype", "text/plain", "google%3Amimetype=text%2Fplain"); testEncodeKeyValue("google:displayurl", "http://test.com/test.txt", "google%3Adisplayurl=http%3A%2F%2Ftest.com%2Ftest.txt"); } private void testEncodeKeyValue(String key, String value, String expected) { StringBuilder buff = new StringBuilder(); ServletUtil.percentEncode(buff, key, value); assertEquals(expected, buff.toString()); } public void testGetRealPath() throws Exception { final String webInfDir = "/connector-manager/WEB-INF/"; Function<String, String> f = new Function<String, String>() { public String apply(String path) { // Force relative paths to be relative to WEB-INF. return new File(webInfDir, path).getAbsolutePath(); } }; // Test simple relative. assertEquals(webInfDir + "temp", ServletUtil.getRealPath("temp", f)); // Test already starts with WEB-INF. assertEquals(webInfDir + "temp", ServletUtil.getRealPath("/WEB-INF/temp", f)); assertEquals(webInfDir + "temp", ServletUtil.getRealPath("WEB-INF/temp", f)); // Test absolute paths are preserved. assertEquals("/var/tmp/temp", ServletUtil.getRealPath("/var/tmp/temp", f)); // Test file: URL paths are returned as absolute paths. assertEquals("/var/tmp/temp", ServletUtil.getRealPath("file:///var/tmp/temp", f)); } public void testEmptyTextArea() throws Exception { // Create form with character entities. String configForm = "<tr>" + "<td>Sensitive input to force parsing</td>" + "<td><input name=\"Password\" type=\"password\" value=\"protected\"/></td>" + "</tr>" + "<tr>" + "<td>Sample text</td>" + "<td><textarea cols=\"50\" name=\"SampleText\" rows=\"5\"></textarea></td>" + "</tr>"; String expectedForm = "<tr>" + "<td>Sensitive input to force parsing</td>" + "<td><input name=\"Password\" type=\"password\" value=\"*********\"></td>" + "</tr>" + "<tr>" + "<td>Sample text</td>" + "<td><textarea cols=\"50\" name=\"SampleText\" rows=\"5\"></textarea></td>" + "</tr>"; addDtdToClassLoader(); String obfuscateForm = filterSensitiveData(configForm); assertNotNull("Form returned", obfuscateForm); assertEquals("Form changed as expected", expectedForm, obfuscateForm); } public void testConvertCdataSectionsToPcdata() { String formWithMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "//<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "//]]>" + "</script>"; String expectedFormWithMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + " function foo() {" + " alert('foo');" + " }" + "</script>"; String formWithSimilarMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "]]>" + "</script>"; String expectedFormWithSimilarMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + " function foo() {" + " alert('foo');" + " }" + "</script>"; String formWithoutMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "function foo() {" + " alert('foo');" + "}" + "</script>"; String result = ServletUtil.removeNestedMarkers(formWithMarkers); assertEquals("Form with markers cleaned up", expectedFormWithMarkers, result); result = ServletUtil.removeNestedMarkers(formWithSimilarMarkers); assertEquals("Form with similar markers cleaned up", expectedFormWithSimilarMarkers, result); result = ServletUtil.removeNestedMarkers(formWithoutMarkers); assertEquals("Form without markers left alone", formWithoutMarkers, result); } public void testIssue204() { String justEndMarker = "decode( FNGETXMLPARAMS(xml_file, 'CONTENT'), ']]>' , " + "FNGETXMLPARAMS(xml_file, 'SUMMARY'), " + "FNGETXMLPARAMS(xml_file, 'CONTENT') ) as CONTENT;"; String result = ServletUtil.removeNestedMarkers(justEndMarker); assertEquals("Form with just end markers left alone", justEndMarker, result); String endBeginMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "]]>" + " function foo() {" + " alert('foo');" + " }" + "<![CDATA[" + "</script>"; result = ServletUtil.removeNestedMarkers(endBeginMarkers); assertEquals("Form with end marker before begin marker", endBeginMarkers, result); String beginBeginEndEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + "<![CDATA[" + " function foo() {" + " alert('foo<&');" + " }" + "]]>" + "]]>" + "</script>" + "<textarea><![CDATA[a<![CDATA[&<]]>b]]></textarea>"; String expectedBeginBeginEndEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function foo() {" + " alert('foo<&');" + " }" + "]]>" + "</script>" // The 'b' comes before the ']]>', because CDATA sections cannot be nested. + "<textarea>a<![CDATA[&<b]]></textarea>"; result = ServletUtil.removeNestedMarkers(beginBeginEndEndMarkers); assertEquals("Form with nested markers", expectedBeginBeginEndEndMarkers, result); String beginEndBeginEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "]]>" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "]]>" + "</script>" + "<textarea><![CDATA[<xml><</xml>]]></textarea>"; String expectedBeginEndBeginEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + " function foo() {" + " alert('foo');" + " }" + " function foo() {" + " alert('foo');" + " }" + "</script>" + "<textarea><xml>&lt;</xml></textarea>"; result = ServletUtil.removeNestedMarkers(beginEndBeginEndMarkers); assertEquals("Form with repeating markers", expectedBeginEndBeginEndMarkers, result); String unbalancedEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "]]>" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "</script>"; String expectedUnbalancedEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + " function foo() {" + " alert('foo');" + " }" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "</script>"; result = ServletUtil.removeNestedMarkers(unbalancedEndMarkers); assertEquals("Form with unbalanced markers", expectedUnbalancedEndMarkers, result); } public void testEscapeEndMarkers() { String containsEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "]]>" + "</script>"; String expectedContainsEndMarkers = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function foo() {" + " alert('foo');" + " }" + "]]>" + "</script>"; String result = ServletUtil.escapeEndMarkers(containsEndMarkers); assertEquals("Contains end markers", expectedContainsEndMarkers, result); } public void testObfuscateForm() throws Exception { // Create simple form. String protectedValue = "protected"; String clearValue = "clear"; Map<String, String> configMap = new HashMap<String, String>(); configMap.put(HIDE_KEY_ONE, protectedValue); configMap.put(HIDE_KEY_TWO, protectedValue); configMap.put(HIDE_KEY_THREE, protectedValue); configMap.put(CLEAR_KEY_ONE, clearValue); String configForm = makeConfigForm(configMap); // Filter out sensitive data. addDtdToClassLoader(); String obfuscatedForm = filterSensitiveData(configForm); assertNotNull("Form returned", obfuscatedForm); assertTrue("Form does not contain protected values", obfuscatedForm.indexOf(protectedValue) == -1); assertTrue("Form still contains clear values", obfuscatedForm.indexOf(clearValue) != -1); // Test exception cases. configForm = configForm.substring(1); obfuscatedForm = filterSensitiveData(configForm); assertNull("Null form returned when form invalid", obfuscatedForm); } public void testObfuscateEvilForm() throws Exception { // Create form with radio buttons with sensitive names. String sensitiveName = "doPasswordCheck"; assertTrue("name is still considered sensitive", SecurityUtils.isKeySensitive(sensitiveName)); String configForm = "<tr>\n" + "<td>Password Check</td>\n" + "<td><input type=\"radio\" name=\"" + sensitiveName + "\" " + "id=\"doPasswordCheck-true\" value=\"true\"/>\n" + "<label for=\"doPasswordCheck-true\">True</label><br/>\n" + "<input type=\"radio\" name=\"" + sensitiveName + "\" " + "id=\"doPasswordCheck-false\" value=\"false\" " + "checked=\"checked\"/>\n" + "<label for=\"doPasswordCheck-false\">False</label><br/>\n" + "</td>\n" + "</tr>"; addDtdToClassLoader(); String obfuscateForm = filterSensitiveData(configForm); assertNotNull("Form returned", obfuscateForm); assertEquals("Form not changed", configForm, obfuscateForm); } public void testObfuscateFormWithEntities() throws Exception { // Create form with character entities. String configForm = "<tr>" + "<td>Sensitive input to force parsing</td>" + "<td><input name=\"Password\" type=\"password\"" + " value=\"protected\"/></td>" + "</tr>" + "<tr>" + "<td>HTML and XML & <</td>" + "<td><input name=\"HtmlAndXml\" type=\"text\" value=\"clear\"/></td>" + "</tr>" + "<tr>" + "<td>Some of the other 252 © © ©</td>" + "<td><input name=\"Other252\" type=\"text\" value=\"clear\"/></td>" + "</tr>" + "<tr>" + "<td>Value has non-252 but needs to be preserved</td>" + "<td><input name=\"ValueHas\" type=\"text\"" + " value=\"clear1 clear2 clear3\"/></td>" + "</tr>" + "<tr>" + "<td>Two words</td>" + "<td><textarea rows='5' cols='40' name='url'>" + "http://www.example.com/doc?a=b&c=d" + "</textarea></td>" + "</tr>" + "<tr>" + "<td>Two words</td>" + "<td><textarea rows='5' cols='40' name='quote'>" + "Is that a † I see before me?" + "</textarea></td>" + "</tr>"; String expectedForm = "<tr>" + "<td>" + "Sensitive input to force parsing</td>" + "<td><input name=\"Password\"" + " type=\"password\" value=\"*********\"></td>" + "</tr>" + "<tr>" + "<td>HTML and XML & <</td>" + "<td><input name=\"HtmlAndXml\"" + " type=\"text\" value=\"clear\"></td>" + "</tr>" + "<tr>" + "<td>" + "Some of the other 252 © © ©</td>" + "<td><input name=\"Other252\"" + " type=\"text\" value=\"clear\"></td>" + "</tr>" + "<tr>" + "<td>" + "Value has non-252 but needs to be preserved</td>" + "<td><input name=\"ValueHas\"" + " type=\"text\" value=\"clear1" + System.getProperty("line.separator") + "clear2" + System.getProperty("line.separator") + "clear3\"></td>" + "</tr>" + "<tr>" + "<td>Two words</td>" + "<td><textarea cols=\"40\"" + " name=\"url\" rows=\"5\">" + "http://www.example.com/doc?a=b&c=d" + "</textarea></td>" + "</tr>" + "<tr>" + "<td>Two words</td>" + "<td><textarea cols=\"40\"" + " name=\"quote\" rows=\"5\">" + "Is that a † I see before me?" + "</textarea></td>" + "</tr>"; addDtdToClassLoader(); String obfuscateForm = filterSensitiveData(configForm); assertNotNull("Form returned", obfuscateForm); assertEquals("Form changed as expected", expectedForm, obfuscateForm); } public void testObfuscateFormWithScript() throws Exception { // Create form with JavaScript. String configForm = "<script language=\"JavaScript\" type=\"text/javascript\">" + "<![CDATA[" + " function checkSelect() {" + " var opt = document.getElementById('Version');" + " if (opt == 'version1') {" + " alert('Version1 Selected');" + " } else {" + " alert('Version1 Not Selected');" + " }" + " }" + "]]>" + "</script>" + "<tr>" + "<td>Sensitive input to force parsing</td>" + "<td><input name=\"Password\" type=\"password\" value=\"protected\"/></td>" + "</tr>" + "<tr>" + "<td><div style='float: left;'>Select Version</div></td>" + "<td><select id=\"SPType\" name=\"Version\" size=\"1\" onchange=\"checkSelect();\">" + " <option selected=\"\" value=\"version1\">Version 1</option>" + " <option value=\"version2\">Version 2</option>" + "</select></td>" + "</tr>"; String expectedForm = "<script language=\"JavaScript\" type=\"text/javascript\">" + " function checkSelect() {" + " var opt = document.getElementById('Version');" + " if (opt == 'version1') {" + " alert('Version1 Selected');" + " } else {" + " alert('Version1 Not Selected');" + " }" + " }" + "</script>" + "<tr>" + "<td>Sensitive input to force parsing</td>" + "<td><input name=\"Password\" type=\"password\" value=\"*********\"></td>" + "</tr>" + "<tr>" + "<td><div style=\"float: left;\">Select Version</div></td>" + "<td><select id=\"SPType\" name=\"Version\" onchange=\"checkSelect();\" size=\"1\">" + " <option selected value=\"version1\">Version 1</option>" + " <option value=\"version2\">Version 2</option></select>" + "</td>" + "</tr>"; addDtdToClassLoader(); String obfuscateForm = filterSensitiveData(configForm); assertNotNull("Form returned", obfuscateForm); // Filter out the "xml:space" attribute some DOM engines might inject. assertEquals("Form changed as expected", expectedForm, obfuscateForm.replaceAll(" xml:space=\"preserve\"", "")); } public void testObfuscateTools() { String baseClearValue = "this is open"; String baseObfuscatedValue = "************"; String clear; String obfuscated; // Simple cycle. clear = baseClearValue; obfuscated = ServletUtil.obfuscateValue(clear); assertEquals("clear was not changed", baseClearValue, clear); assertEquals("string was obfuscated", baseObfuscatedValue, obfuscated); assertTrue("obfuscated string recognized", ServletUtil.isObfuscated(obfuscated)); // isObfuscated corner cases. assertFalse(ServletUtil.isObfuscated("***n***")); assertFalse(ServletUtil.isObfuscated("***n")); assertFalse(ServletUtil.isObfuscated("n***")); // obfuscateValue corner cases. assertEquals(baseObfuscatedValue, ServletUtil.obfuscateValue("1234 56 7890")); assertEquals(baseObfuscatedValue, ServletUtil.obfuscateValue("-+=< >^ ()[]")); assertEquals(baseObfuscatedValue, ServletUtil.obfuscateValue("ABCD EF GHIJ")); assertEquals(baseObfuscatedValue, ServletUtil.obfuscateValue("**** &@ !#$%")); } public void testReplaceSensitiveData() { String clearValue = "clear value"; Map<String, String> clearConfig = new HashMap<String, String>(); clearConfig.put(HIDE_KEY_ONE, clearValue); clearConfig.put(HIDE_KEY_TWO, clearValue); clearConfig.put(HIDE_KEY_THREE, clearValue); clearConfig.put(CLEAR_KEY_ONE, clearValue); // Let's just obfuscate all the ones that should be and then revert them. String obfuscatedValue = "***********"; Map<String, String> obfuscatedConfig = new HashMap<String, String>(); obfuscateValues(clearConfig, obfuscatedConfig); assertEquals(obfuscatedValue, obfuscatedConfig.get(HIDE_KEY_ONE)); assertEquals(obfuscatedValue, obfuscatedConfig.get(HIDE_KEY_TWO)); assertEquals(obfuscatedValue, obfuscatedConfig.get(HIDE_KEY_THREE)); assertEquals(clearValue, obfuscatedConfig.get(CLEAR_KEY_ONE)); ServletUtil.replaceSensitiveData(obfuscatedConfig, clearConfig); assertEquals(clearValue, obfuscatedConfig.get(HIDE_KEY_ONE)); assertEquals(clearValue, obfuscatedConfig.get(HIDE_KEY_TWO)); assertEquals(clearValue, obfuscatedConfig.get(HIDE_KEY_THREE)); assertEquals(clearValue, obfuscatedConfig.get(CLEAR_KEY_ONE)); // Now let's obfuscate and change some of the values to make sure the // new values are preserved. String newValueOne = "new nice value"; String newValueTwo = "******n******"; String evilValue = "***"; obfuscatedConfig.clear(); obfuscateValues(clearConfig, obfuscatedConfig); obfuscatedConfig.put(HIDE_KEY_ONE, newValueOne); obfuscatedConfig.put(HIDE_KEY_TWO, newValueTwo); obfuscatedConfig.put(HIDE_KEY_THREE, evilValue); ServletUtil.replaceSensitiveData(obfuscatedConfig, clearConfig); assertEquals(newValueOne, obfuscatedConfig.get(HIDE_KEY_ONE)); assertEquals(newValueTwo, obfuscatedConfig.get(HIDE_KEY_TWO)); assertEquals(evilValue, obfuscatedConfig.get(HIDE_KEY_THREE)); assertEquals(clearValue, obfuscatedConfig.get(CLEAR_KEY_ONE)); } private static final String VALUE = "value"; private static final String NAME = "name"; private static final String TEXT = "text"; private static final String TYPE = "type"; private static final String INPUT = "input"; private static final String CLOSE_ELEMENT = "/>"; private static final String OPEN_ELEMENT = "<"; private static final String PASSWORD = "password"; private static final String TR_END = "</tr>\r\n"; private static final String TD_END = "</td>\r\n"; private static final String TD_START = "<td>"; private static final String TR_START = "<tr>\r\n"; private String makeConfigForm(Map<String, String> configMap) { StringBuilder buf = new StringBuilder(2048); for (Map.Entry<String, String> entry : configMap.entrySet()) { appendStartRow(buf, entry.getKey()); buf.append(OPEN_ELEMENT); buf.append(INPUT); if (SecurityUtils.isKeySensitive(entry.getKey())) { appendAttribute(buf, TYPE, PASSWORD); } else { appendAttribute(buf, TYPE, TEXT); } appendAttribute(buf, NAME, entry.getKey()); if (configMap != null) { String value = entry.getValue(); if (value != null) { appendAttribute(buf, VALUE, value); } } appendEndRow(buf); } return buf.toString(); } private void appendStartRow(StringBuilder buf, String key) { buf.append(TR_START); buf.append(TD_START); buf.append(key); buf.append(TD_END); buf.append(TD_START); } private void appendEndRow(StringBuilder buf) { buf.append(CLOSE_ELEMENT); buf.append(TD_END); buf.append(TR_END); } private void appendAttribute(StringBuilder buf, String attrName, String attrValue) { try { XmlUtils.xmlAppendAttr(attrName, attrValue, buf); } catch (IOException e) { // Can't happen with StringBuilder. fail("Unexpected exception: " + e.getMessage()); } } private void obfuscateValues(Map<String, String> clearConfig, Map<String, String> obfuscatedConfig) { for (Map.Entry<String, String> entry : clearConfig.entrySet()) { obfuscatedConfig.put(entry.getKey(), (SecurityUtils.isKeySensitive(entry.getKey())) ? ServletUtil.obfuscateValue(entry.getValue()) : entry.getValue()); } } private String filterSensitiveData(String form) { return ConnectorTestUtils.removeColRowSpan( ServletUtil.filterSensitiveData(form)); } private static final String DTD_DIRECTORY = "source/dtds/"; private void addDtdToClassLoader() throws Exception { // Add the DTD files to the System ClassLoader. File f = new File(DTD_DIRECTORY); URL u = f.toURI().toURL(); URLClassLoader sysClassLoader = (URLClassLoader) ServletUtil.class.getClassLoader(); Class<URLClassLoader> clazz = URLClassLoader.class; // Since the addURL() method is protected need to use reflection. Method method = clazz.getDeclaredMethod("addURL", URL.class); method.setAccessible(true); method.invoke(sysClassLoader, new Object[] {u}); } }