Related to VIVO-921. Server-side validation for default data property form.
This commit is contained in:
parent
a32ee20a40
commit
0c5d69e25e
5 changed files with 170 additions and 20 deletions
|
@ -25,6 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.RdfLiteralHash;
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultDataPropEmptyField;
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultDataPropEmptyField;
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.DefaultDataPropertyFormValidator;
|
||||||
|
|
||||||
public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator {
|
public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator {
|
||||||
|
|
||||||
|
@ -97,6 +98,7 @@ public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGener
|
||||||
literalField.setValidators(list( "nonempty" ));
|
literalField.setValidators(list( "nonempty" ));
|
||||||
editConfiguration.setN3Required(Arrays.asList( dataPropN3 ));
|
editConfiguration.setN3Required(Arrays.asList( dataPropN3 ));
|
||||||
}
|
}
|
||||||
|
editConfiguration.addValidator(new DefaultDataPropertyFormValidator(rangeDatatypeUri, vreq));
|
||||||
//prepare
|
//prepare
|
||||||
prepare(vreq, editConfiguration);
|
prepare(vreq, editConfiguration);
|
||||||
return editConfiguration;
|
return editConfiguration;
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.N3ValidatorVTwo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the submitted text has potential XSS problems.
|
||||||
|
* Error messages from this validator always start with XSS_ERROR_MESSAGE
|
||||||
|
*
|
||||||
|
* @author bdc34
|
||||||
|
*/
|
||||||
|
public class DefaultDataPropertyFormValidator implements N3ValidatorVTwo{
|
||||||
|
private Log log = LogFactory.getLog(DefaultDataPropertyFormValidator.class);
|
||||||
|
|
||||||
|
VitroRequest vreq;
|
||||||
|
private String datatype;
|
||||||
|
private final I18nBundle i18n;
|
||||||
|
private final String dtRegex = "^([0-9]{4})-((0[1-9])|(1[0-2]))-((0[1-9])|([1-2][0-9])|(3[0-1]))(T|\\s)(([0-1][0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
|
||||||
|
private final Pattern dtPattern = Pattern.compile(dtRegex);
|
||||||
|
private final String dateRegex = "^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})";
|
||||||
|
private final Pattern datePattern = Pattern.compile(dateRegex);
|
||||||
|
private final String timeRegex = "^(([0-1][0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])";
|
||||||
|
private final Pattern timePattern = Pattern.compile(timeRegex);
|
||||||
|
private final String yearRegex = "^\\d{4}";
|
||||||
|
private final Pattern yearPattern = Pattern.compile(yearRegex);
|
||||||
|
private final String ymRegex = "^([0-9]{4})-(0[1-9]|1[012])";
|
||||||
|
private final Pattern ymPattern = Pattern.compile(ymRegex);
|
||||||
|
private final String monthRegex = "^--(0[1-9]|1[012])";
|
||||||
|
private final Pattern monthPattern = Pattern.compile(monthRegex);
|
||||||
|
private final String floatRegex = "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?.";
|
||||||
|
private final Pattern floatPattern = Pattern.compile(floatRegex);
|
||||||
|
private final String intRegex = "^-?\\d+$";
|
||||||
|
private final Pattern intPattern = Pattern.compile(intRegex);
|
||||||
|
|
||||||
|
public DefaultDataPropertyFormValidator(String datatype, VitroRequest vreq) {
|
||||||
|
this.datatype = datatype;
|
||||||
|
this.vreq = vreq;
|
||||||
|
this.i18n = I18n.bundle(vreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> validate(EditConfigurationVTwo editConfig,
|
||||||
|
MultiValueEditSubmission editSub) {
|
||||||
|
|
||||||
|
Map<String,List<Literal>> literalsFromForm = editSub.getLiteralsFromForm();
|
||||||
|
|
||||||
|
Map<String,String> errors = new HashMap<String,String>();
|
||||||
|
|
||||||
|
List<Literal> formLiterals = literalsFromForm.get("literal");
|
||||||
|
Literal literal = null;
|
||||||
|
if(formLiterals != null && formLiterals.size() > 0) {
|
||||||
|
literal = formLiterals.get(0);
|
||||||
|
}
|
||||||
|
String literalValue = "";
|
||||||
|
if (literal != null) {
|
||||||
|
literalValue = literal.getLexicalForm();
|
||||||
|
if( "".equals(literalValue) ) {
|
||||||
|
literal = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( literal != null ) {
|
||||||
|
|
||||||
|
if ( datatype.indexOf("#dateTime") > -1 ) {
|
||||||
|
if ( !dtPattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("dateTime", i18n.text("minimum_ymd"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( datatype.indexOf("#date") > -1 ) {
|
||||||
|
if ( !datePattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("date", i18n.text("year_month_day"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( datatype.indexOf("#time") > -1 ) {
|
||||||
|
if ( !timePattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("time", i18n.text("minimum_hour"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( datatype.indexOf("#gYearMonth") > -1 ) {
|
||||||
|
if ( !ymPattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("yearMonth", i18n.text("year_month"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( datatype.indexOf("#gYear") > -1 ) {
|
||||||
|
if ( !yearPattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("year", i18n.text("four_digit_year"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( datatype.indexOf("#float") > -1 ) {
|
||||||
|
if ( !floatPattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("float", i18n.text("decimal_only"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( datatype.indexOf("#int") > -1 ) {
|
||||||
|
if ( !intPattern.matcher(literalValue).matches() ) {
|
||||||
|
errors.put("integer", i18n.text("whole_number"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.size() != 0 ? errors : null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -296,7 +296,11 @@ ol.tinyMCENumeric li {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
margin-left: 30px;
|
margin-left: 30px;
|
||||||
}
|
}
|
||||||
img.invalidFormat {
|
img.invalidFormatImg {
|
||||||
padding-left:8px;
|
padding-left:8px;
|
||||||
vertical-align:middle;
|
vertical-align:middle;
|
||||||
|
}
|
||||||
|
.invalidFormatText {
|
||||||
|
font-size:10px;
|
||||||
|
color:#A12424;
|
||||||
}
|
}
|
|
@ -46,47 +46,57 @@
|
||||||
<#if datatype?? >
|
<#if datatype?? >
|
||||||
<#switch datatype>
|
<#switch datatype>
|
||||||
<#case "date">
|
<#case "date">
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt="${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt="${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
||||||
<#break>
|
<span class="invalidFormatText">invalid format</span>
|
||||||
|
<#break>
|
||||||
<#case "dateTime">
|
<#case "dateTime">
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
||||||
<#break>
|
<span class="invalidFormatText">invalid format</span>
|
||||||
|
<#break>
|
||||||
<#case "time">
|
<#case "time">
|
||||||
<#if !value?matches("(([0-1][0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])") >
|
<#if !value?matches("(([0-1][0-9])|(2[0-3])):([0-5][0-9]):([0-5][0-9])") >
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
||||||
|
<span class="invalidFormatText">invalid format</span>
|
||||||
</#if>
|
</#if>
|
||||||
<#break>
|
<#break>
|
||||||
<#case "gYear">
|
<#case "gYear">
|
||||||
<#if !value?matches("^\\d{4}") >
|
<#if !value?matches("^\\d{4}") >
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
||||||
|
<span class="invalidFormatText">invalid format</span>
|
||||||
</#if>
|
</#if>
|
||||||
<#break>
|
<#break>
|
||||||
<#case "gMonth">
|
<#case "gMonth">
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
||||||
<#break>
|
<span class="invalidFormatText">invalid format</span>
|
||||||
|
<#break>
|
||||||
<#case "gYearMonth">
|
<#case "gYearMonth">
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}"> <#-- validated above -->
|
||||||
<#break>
|
<span class="invalidFormatText">invalid format</span>
|
||||||
|
<#break>
|
||||||
<#case "float">
|
<#case "float">
|
||||||
<#if !value?matches("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?.") >
|
<#if !value?matches("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?.") >
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
||||||
|
<span class="invalidFormatText">invalid format</span>
|
||||||
</#if>
|
</#if>
|
||||||
<#break>
|
<#break>
|
||||||
<#case "integer">
|
<#case "integer">
|
||||||
<#if !value?matches("^-?\\d+$") >
|
<#if !value?matches("^-?\\d+$") >
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
||||||
|
<span class="invalidFormatText">invalid format</span>
|
||||||
</#if>
|
</#if>
|
||||||
<#break>
|
<#break>
|
||||||
<#case "int">
|
<#case "int">
|
||||||
<#if !value?matches("^-?\\d+$") >
|
<#if !value?matches("^-?\\d+$") >
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
||||||
|
<span class="invalidFormatText">invalid format</span>
|
||||||
</#if>
|
</#if>
|
||||||
<#break>
|
<#break>
|
||||||
<#case "boolean">
|
<#case "boolean">
|
||||||
<#if !value?matches("false") && !value?matches("true") >
|
<#if !value?matches("false") && !value?matches("true") >
|
||||||
<img class="invalidFormat" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
<img class="invalidFormatImg" src="${urls.base}/images/iconAlert.png" width="18" alt=" ${i18n().invalid_format}" title=" ${i18n().invalid_format}">
|
||||||
|
<span class="invalidFormatText">invalid format</span>
|
||||||
</#if>
|
</#if>
|
||||||
<#break>
|
<#break>
|
||||||
<#default>
|
<#default>
|
||||||
</#switch>
|
</#switch>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
|
@ -137,4 +137,16 @@ section#pubsContainer input {
|
||||||
img#indicator {
|
img#indicator {
|
||||||
padding-left:60px;
|
padding-left:60px;
|
||||||
}
|
}
|
||||||
|
/* for placeholder text */
|
||||||
|
::-webkit-input-placeholder { /* WebKit browsers */
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
::-moz-placeholder { /* Mozilla Firefox 19+ */
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
:-ms-input-placeholder { /* Internet Explorer 10+ */
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue