javaspring-roogvnix

gvNIX Typical security: no feedback in signup form UI of binding errors


When using Typical security, errors in the signup form are not shown in the form. There is no feedback on what went wrong, only an empty screen.

A solution for empty form have I provided at the bottom of this question.

Yet the question remains of how to get the Binding result Validation errors displayed in the form. like in the "Create New user" form.

I'm using Spring 2.0.0.M1 with gvNIX added!

I already created an issue at github

My question: is there a simple workaround to get it to work.

Test script:

// Create a new project
project setup --topLevelPackage com.springsource.pizzashop --projectName pizzashop

jpa setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY

entity jpa --class ~.domain.Pizza
field string --fieldName name --notNull --sizeMin 10
field number --fieldName price --notNull --type java.math.BigDecimal

// Adding web layers
web mvc setup
web mvc all --package ~.web

// Adding Spring security
typicalsecurity setup

// Adding JQuery, Datatables and Bootstrap
web mvc jquery setup
web mvc jquery all
web mvc datatables setup
web mvc bootstrap setup

web mvc bootstrap update

Change the required length of the password field:

In file ...\src\main\java\com\springsource\pizzashop\domain\User.java

@NotNull
@Size(min = 8) // was (min = 1)
private String password;

In file ..\src\main\java\com\springsource\pizzashop\web\UserRegistrationForm.java apply the same change as above.

@NotNull
@Size(min = 8) // was (min = 1)
private String password;

Add a 1 line of debug information in file ...\src\main\java\com\springsource\pizzashop\web\SignUpController.java

@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid UserRegistrationForm userRegistration, BindingResult result, Model model, HttpServletRequest request) {
    validator.validate(userRegistration, result);

    System.out.println("Has binding errors: " + result.toString());  // added

    if (result.hasErrors()) {

        return createForm(model);
    } else {

    // Rest of the code

When the password field in the signup form is filled with only one letter instead of 8 an the Recaptcha is wrong the debug line shows the following message:

Has binding errors: org.springframework.validation.BeanPropertyBindingResult: 3 errors

Field error in object 'userRegistrationForm' on field 'repeatPassword': rejected value [a]; codes [Size.userRegistrationForm.repeatPassword,Size.repeatPassword,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userRegistrationForm.repeatPassword,repeatPassword]; arguments []; default message [repeatPassword],2147483647,8]; default message [size must be between 8 and 2147483647]

Field error in object 'userRegistrationForm' on field 'password': rejected value [a]; codes [Size.userRegistrationForm.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userRegistrationForm.password,password]; arguments []; default message [password],2147483647,8]; default message [size must be between 8 and 2147483647]

Error in object 'userRegistrationForm': codes [recaptcha.mismatch.userRegistrationForm,recaptcha.mismatch]; arguments []; default message [null]

This is correct, however no feedback is shown in the form the user sees on screen! So for the user it is not clear what went wrong and why the form does not save, but comes back. All the user sees is an empty signup form with no information.

enter image description here

What I expect is a message like the one that is shown when in the "Create New User" this password field is also filled with one letter. Than in red the message is shown: size must be between 8 and 2147483647

enter image description here

Solution for empty screen: Solution for the empty screen is to return to the form with the information the user supplied when he/she pushed "Save". This is the same behavior as in the other create and update methods of Spring Roo / gvNIX.

@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid UserRegistrationForm userRegistration, BindingResult result, Model model, HttpServletRequest request) {
    validator.validate(userRegistration, result);
    if (result.hasErrors()) {
            model.addAttribute("User", userRegistration);  // Added: the original info
        return "signup/index";
        //return createForm(model);  // original, commented out.
    } else {

This solves the problem of empty screen, the user sees his/her suppplied info. However, still the feedback in red of the binding result I do not get to see.

How can I make that visible?


Solution

  • That's an error found on gvNIX 2.0.0.M1 that will be fixed on future version of gvNIX project.

    To show those error messages, you must do the following changes on project:

    On file ~/webapp/WEB-INF/tags/jquery/form/create.tagx (line ~30) you must edit the cssClass property of form element like this:

    <form:form cssClass="form-horizontal validate" ... >
    

    Add the red style to error spans, adding the following code on file ~/webapp/styles/standard.css:

    .errors {
        color: #b94a48;
        display: block;
    }
    

    To apply this options to password inputs, you have to edit file ~/WEB-INF/tags/jquery/form/fields/input.tagx, adding all this options to passwords inputs. Just write'em all on line ~112 like this:

              <form:password class="form-control input-sm" id="_${sec_field}_id" path="${sec_field}" disabled="${disabled}" size="${size}"
              data-required="${required}" data-invalid="${field_invalid}" data-missing="${sec_field_required}"
              data-regex="${validationRegex}" data-minlength="${min}" data-maxlength="${max}"
              data-mindecimal="${decimalMin}" data-maxdecimal="${decimalMax}" value="${value}"/>
    

    Please try it and tell me if it worked to you.

    We will take in mind this problems for future versions of gvNIX

    Hope this helps. Regards.