diff --git a/scripts/database/upgrades/upgrade_v4.7_to_v4.7.1.sql b/scripts/database/upgrades/upgrade_v4.7_to_v4.7.1.sql index 47afecc3b96..023ba77b367 100644 --- a/scripts/database/upgrades/upgrade_v4.7_to_v4.7.1.sql +++ b/scripts/database/upgrades/upgrade_v4.7_to_v4.7.1.sql @@ -4,4 +4,22 @@ ALTER TABLE authenticateduser ADD COLUMN createdtime TIMESTAMP NOT NULL DEFAULT '01-01-2000 00:00:00'; ALTER TABLE authenticateduser ADD COLUMN lastlogintime TIMESTAMP DEFAULT NULL; ALTER TABLE authenticateduser ADD COLUMN lastapiusetime TIMESTAMP DEFAULT NULL; -ALTER TABLE authenticateduser DROP COLUMN modificationtime; \ No newline at end of file +ALTER TABLE authenticateduser DROP COLUMN modificationtime; + +/* +Add validationFormat to DatasetFieldType to + */ +ALTER TABLE datasetfieldtype +ADD COLUMN validationFormat character varying(255); + +/* +for testing display format +This adds a display format that links out to an outside site. The format of the #VALUE is +four characters alpha numeric (3fki works) + +update datasetfieldtype +set displayformat = 'PDB (RCSB) #VALUE', +fieldType= 'TEXT' +where id = xxx; + +*/ \ No newline at end of file diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java index e9a2b261381..139e9274d0b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java @@ -274,7 +274,7 @@ public List getValues() { List returnList = new ArrayList(); if (!datasetFieldValues.isEmpty()) { for (DatasetFieldValue dsfv : datasetFieldValues) { - returnList.add(dsfv.getValue()); + returnList.add(dsfv.getDisplayValue()); } } else { for (ControlledVocabularyValue cvv : controlledVocabularyValues) { diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java index f52c7ef17b0..c6c5f355817 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldCompoundValue.java @@ -5,6 +5,7 @@ */ package edu.harvard.iq.dataverse; +import edu.harvard.iq.dataverse.util.MarkupChecker; import java.io.Serializable; import java.util.ArrayList; import java.util.Comparator; @@ -143,7 +144,10 @@ public Map getDisplayValueMap() { if (StringUtils.isBlank(format)) { format = "#VALUE"; } - + String sanitizedValue = childDatasetField.getDatasetFieldType().isSanitizeHtml() ? MarkupChecker.sanitizeBasicHTML(childDatasetField.getValue()) : childDatasetField.getValue(); + if (!childDatasetField.getDatasetFieldType().isSanitizeHtml() && childDatasetField.getDatasetFieldType().isEscapeOutputText()){ + sanitizedValue = MarkupChecker.stripAllTags(sanitizedValue); + } // replace the special values in the format (note: we replace #VALUE last since we don't // want any issues if the value itself has #NAME in it) String displayValue = format @@ -151,7 +155,7 @@ public Map getDisplayValueMap() { //todo: this should be handled in more generic way for any other text that can then be internationalized // if we need to use replaceAll for regexp, then make sure to use: java.util.regex.Matcher.quoteReplacement() .replace("#EMAIL", ResourceBundle.getBundle("Bundle").getString("dataset.email.hiddenMessage")) - .replace("#VALUE", childDatasetField.getValue()); + .replace("#VALUE", sanitizedValue ); fieldMap.put(childDatasetField,displayValue); } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java index 93b5dce20ae..c3546ef44b2 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java @@ -46,10 +46,7 @@ public Long getId() { public void setId(Long id) { this.id = id; } - - public String getIdString(){ - return id.toString(); - } + /** * The internal, DDI-like name, no spaces, etc. @@ -83,6 +80,8 @@ public String getIdString(){ * A watermark to be displayed in the UI. */ private String watermark; + + private String validationFormat; @OneToMany(mappedBy = "datasetFieldType") private Set dataverseFacets; @@ -164,8 +163,23 @@ public void setDisplayFormat(String displayFormat) { this.displayFormat = displayFormat; } + public Boolean isSanitizeHtml(){ + if (this.fieldType.equals(FieldType.URL)){ + return true; + } + return this.fieldType.equals(FieldType.TEXTBOX); + } + + public Boolean isEscapeOutputText(){ + if (this.fieldType.equals(FieldType.URL)){ + return false; + } + if (this.fieldType.equals(FieldType.TEXTBOX)){ + return false; + } + return !(this.fieldType.equals(FieldType.TEXT) && this.displayFormat != null &&this.displayFormat.contains(" 9999) { - valid=false; + if (era == GregorianCalendar.AD) { + if (year > 9999) { + valid = false; } } - }catch (ParseException e) { - valid=false; + } catch (ParseException e) { + valid = false; } - if (dateString.length()>pattern.length()) { - valid=false; + if (dateString.length() > pattern.length()) { + valid = false; } return valid; } - } diff --git a/src/main/webapp/metadataFragment.xhtml b/src/main/webapp/metadataFragment.xhtml index a01a518e34b..455e20714bc 100755 --- a/src/main/webapp/metadataFragment.xhtml +++ b/src/main/webapp/metadataFragment.xhtml @@ -47,12 +47,12 @@ -
- +
+ - +
@@ -64,12 +64,10 @@

- + - +
diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTypeTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTypeTest.java new file mode 100644 index 00000000000..ed17bd229d9 --- /dev/null +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTypeTest.java @@ -0,0 +1,133 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse; + +import edu.harvard.iq.dataverse.search.SolrField; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import javax.faces.model.SelectItem; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author skraffmi + */ +public class DatasetFieldTypeTest { + + public DatasetFieldTypeTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + + + /** + * Test of setInclude method, of class DatasetFieldType. + */ + + + + + + /** + * Test of isSanitizeHtml method, of class DatasetFieldType. + */ + @Test + public void testIsSanitizeHtml() { + System.out.println("isSanitizeHtml"); + DatasetFieldType instance = new DatasetFieldType(); + instance.setFieldType(DatasetFieldType.FieldType.TEXT); + Boolean result = instance.isSanitizeHtml(); + assertFalse(result); + + //if textbox then sanitize - allow tags + instance.setFieldType(DatasetFieldType.FieldType.TEXTBOX); + result = instance.isSanitizeHtml(); + assertEquals(true, result); + + //if textbox then don't sanitize - allow tags + instance.setFieldType(DatasetFieldType.FieldType.EMAIL); + result = instance.isSanitizeHtml(); + assertEquals(false, result); + + //URL, too + instance.setFieldType(DatasetFieldType.FieldType.URL); + result = instance.isSanitizeHtml(); + assertEquals(true, result); + } + + @Test + public void testIsEscapeOutputText(){ + System.out.println("testIsEscapeOutputText"); + DatasetFieldType instance = new DatasetFieldType(); + instance.setFieldType(DatasetFieldType.FieldType.TEXT); + Boolean result = instance.isEscapeOutputText(); + assertTrue(result); + + //if Disaplay Format includes a link then don't escape + instance.setDisplayFormat("'PDB (RCSB) #VALUE'"); + result = instance.isEscapeOutputText(); + assertFalse(result); + + //if textbox then sanitize - allow tags + instance.setFieldType(DatasetFieldType.FieldType.TEXTBOX); + result = instance.isEscapeOutputText(); + assertFalse( result); + + //if textbox then don't sanitize - allow tags + instance.setFieldType(DatasetFieldType.FieldType.EMAIL); + result = instance.isEscapeOutputText(); + assertTrue(result); + + //URL, too + instance.setFieldType(DatasetFieldType.FieldType.URL); + result = instance.isEscapeOutputText(); + assertEquals(false, result); + + } + + @Test + public void testGetSolrField(){ + + DatasetFieldType instance = new DatasetFieldType(); + instance.setFieldType(DatasetFieldType.FieldType.DATE); + SolrField solrField = instance.getSolrField(); + assertEquals(SolrField.SolrType.DATE, solrField.getSolrType()); + + instance.setFieldType(DatasetFieldType.FieldType.EMAIL); + solrField = instance.getSolrField(); + assertEquals(SolrField.SolrType.EMAIL, solrField.getSolrType()); + DatasetFieldType parent = new DatasetFieldType(); + parent.setAllowMultiples(true); + instance.setParentDatasetFieldType(parent); + solrField = instance.getSolrField(); + assertEquals(true, solrField.isAllowedToBeMultivalued()); + + } + + + +} diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetFieldValidatorTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldValidatorTest.java new file mode 100644 index 00000000000..25c2163cc9f --- /dev/null +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldValidatorTest.java @@ -0,0 +1,91 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse; + +import javax.validation.ConstraintValidatorContext; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.mockito.Mockito; + +/** + * + * @author skraffmi + */ +public class DatasetFieldValidatorTest { + + public DatasetFieldValidatorTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + + /** + * Test of isValid method, of class DatasetFieldValidator. + */ + @Test + public void testIsValid() { + System.out.println("isValid"); + DatasetField value = new DatasetField(); + + final ConstraintValidatorContext ctx = + Mockito.mock(ConstraintValidatorContext.class); + DatasetFieldValidator instance = new DatasetFieldValidator(); + //If its a template field it is always valid + value.setTemplate(new Template()); + boolean expResult = true; + boolean result = instance.isValid(value, ctx); + assertEquals(expResult, result); + + + //if not template and required + value.setTemplate(null); + DatasetVersion datasetVersion = new DatasetVersion(); + Dataset dataset = new Dataset(); + Dataverse dataverse = new Dataverse(); + dataset.setOwner(dataverse); + datasetVersion.setDataset(dataset); + value.setDatasetVersion(datasetVersion); + + DatasetFieldValue dfv = new DatasetFieldValue(); + DatasetFieldType dft = new DatasetFieldType("test", DatasetFieldType.FieldType.TEXT, false); + dft.setRequired(true); + value.setDatasetFieldType(dft); + value.setSingleValue(""); + dfv.setValue(""); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + //Fill in a value - should be valid now.... + value.setSingleValue("value"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + //if not required - can be blank + dft.setRequired(false); + value.setSingleValue(""); + result = instance.isValid(value, ctx); + assertEquals(true, result); + } + +} diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetFieldValueValidatorTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldValueValidatorTest.java new file mode 100644 index 00000000000..aeceedc07f6 --- /dev/null +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldValueValidatorTest.java @@ -0,0 +1,140 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse; + +import javax.validation.ConstraintValidatorContext; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.mockito.Mockito; + +/** + * + * @author skraffmi + */ +public class DatasetFieldValueValidatorTest { + + + public DatasetFieldValueValidatorTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + + /** + * Test of isValid method, of class DatasetFieldValueValidator. + */ + @Test + public void testIsValid() { + System.out.println("isValid"); + DatasetFieldValue value = new DatasetFieldValue(); + DatasetField df = new DatasetField(); + DatasetFieldType dft = new DatasetFieldType(); + dft.setFieldType(DatasetFieldType.FieldType.TEXT); + //Test Text against regular expression that takes a 5 character string + dft.setValidationFormat("^[a-zA-Z ]{5,5}$"); + df.setDatasetFieldType(dft); + value.setDatasetField(df); + value.setValue("asdfg"); + final ConstraintValidatorContext ctx = + Mockito.mock(ConstraintValidatorContext.class); + DatasetFieldValueValidator instance = new DatasetFieldValueValidator(); + boolean expResult = true; + boolean result = instance.isValid(value, ctx); + assertEquals(expResult, result); + + //Make string too long - should fail. + value.setValue("asdfgX"); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + //Make string too long - should fail. + value.setValue("asdf"); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + //Now lets try Dates + dft.setFieldType(DatasetFieldType.FieldType.DATE); + dft.setValidationFormat(null); + value.setValue("1999AD"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("44BCE"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("2004-10-27"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("2002-08"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("[1999?]"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("Blergh"); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + //Float + dft.setFieldType(DatasetFieldType.FieldType.FLOAT); + value.setValue("44"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("44 1/2"); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + //Integer + dft.setFieldType(DatasetFieldType.FieldType.INT); + value.setValue("44"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("-44"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + value.setValue("12.14"); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + //URL + dft.setFieldType(DatasetFieldType.FieldType.URL); + value.setValue("http://cnn.com"); + result = instance.isValid(value, ctx); + assertEquals(true, result); + + + value.setValue("espn.com"); + result = instance.isValid(value, ctx); + assertEquals(false, result); + + } + +} diff --git a/src/test/java/edu/harvard/iq/dataverse/util/MarkupCheckerTest.java b/src/test/java/edu/harvard/iq/dataverse/util/MarkupCheckerTest.java index 736c44236b6..da8e9f412dc 100644 --- a/src/test/java/edu/harvard/iq/dataverse/util/MarkupCheckerTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/util/MarkupCheckerTest.java @@ -98,7 +98,12 @@ public void testSanitizeBasicHTML() { safeStr = "the \nDataverse project in a new window"; sanitized = MarkupChecker.sanitizeBasicHTML(unsafeStr); this.msgu("safeStr: " + safeStr + "\nsanitized: " + sanitized); - assertTrue(safeStr.equals(sanitized)); + assertTrue(safeStr.equals(sanitized)); + + //test null + unsafeStr = null; + sanitized = MarkupChecker.sanitizeBasicHTML(unsafeStr); + assertNull(sanitized); } @@ -107,15 +112,19 @@ public void testSanitizeBasicHTML() { */ @Test public void testStripAllTags() { - /* + System.out.println("stripAllTags"); String unsafe = ""; String expResult = ""; String result = MarkupChecker.stripAllTags(unsafe); assertEquals(expResult, result); // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - */ + + //test null + unsafe = null; + result = MarkupChecker.stripAllTags(unsafe); + assertNull(result); + } }