jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] Re: Re: Re: Re: [1433-UIInputRequiredTrue] PROPOSAL

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Mon, 5 Dec 2016 23:33:51 -0500

Hi

NG>> Getting back to my main question, can we simply change:

   if (submittedValue == null) {
       return;
   }

NG>> To this: (without a check for a global web config param)

   if ((submittedValue == null) && !isRequired()) {
       return;
   }

NG>> Or will that cause a backward compatibility problem?

As far as I know, request parameter values are never interpreted as null,
because if it is present, the value is filled with an empty string.

The javadoc of ServletRequest.setAttribute says this:

"... If the object passed in is null, the effect is the same as calling
removeAttribute(java.lang.String). ..."

So the answer is the change does not cause a backward compatibility
problem, and based on that the web config parameter is not really
necessary. Does it work in all cases? I'm not 100% sure, because we need
to check what happens for menu/radio/checkbox, but if that so, apply a
simple patch with just these lines could be a valid solution.

regards,

Leonardo Uribe

2016-12-02 14:19 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:

> +1 for avoiding context param and enforcing required=true regardless of
> submittedValue. But really nothing more than that.
>
> Cheers, B
>
> On Fri, Dec 2, 2016, 19:29 Neil Griffin <neil.griffin_at_portletfaces.org>
> wrote:
>
>> Hi again everyone,
>>
>> LU >> the case where "no value was submitted for this component" is
>> underspecified
>>
>> @Leonardo: +1 I think that you have identified an oversight in the Spec
>> language. Also, I agree with you that we should avoid a global web config
>> param if possible.
>>
>> LU >> If the value is not submitted [...] and required flag is set to
>> true, validation
>> LU >> should fail, no questions asked, without exceptions
>>
>> @Leonardo: +1 I think that you are exactly right. If required="true",
>> shouldn't the JSF developer be able to rely on the PROCESS_VALIDATIONS
>> phase to enforce that? The plain meaning would be that the value is
>> *always* required, without qualification or exception.
>>
>> @All: Also, consider the case of a custom Captcha type of component with
>> a built-in validator:
>>
>> <my:inputCaptcha required="true" value="#{myBean.captcha}" />
>>
>> public abstract class InputCaptcha extends UIInput {
>>
>> @Override
>> protected void validateValue(FacesContext context, Object value) {
>>
>> // Call super in order enforce required="true"
>> super.validateValue(context, value);
>>
>> if (isValid()) {
>> // Determine if captcha was typed correctly by
>> the user
>> ...
>> }
>> }
>> ...
>> }
>>
>> Given the current Spec language, if the Captcha's <input type="text" />
>> is removed from the DOM prior to the postback, validateValue(FacesContext,Object)
>> will not be called, and server-side validation will be bypassed for the
>> Captcha component.
>>
>> Getting back to my main question, can we simply change:
>>
>> if (submittedValue == null) {
>> return;
>> }
>>
>> To this: (without a check for a global web config param)
>>
>> if ((submittedValue == null) && !isRequired()) {
>> return;
>> }
>>
>> Or will that cause a backward compatibility problem?
>>
>>
>> Best Regards to all,
>>
>> Neil
>>
>> > On Dec 1, 2016, at 9:43 PM, Leonardo Uribe <leonardo.uribe_at_irian.at>
>> wrote:
>> >
>> > Hi
>> >
>> > BS>> Yes, but this indicaties a bad model. The normal solution would be
>> to put
>> > BS>> a @NotNull constraint on the entity or a NOT NULL constraint on
>> the column.
>> >
>> > BS>> Here's a related Stack Overflow post of mine on the subject:
>> >
>> > I agree from a conceptual perspective, but from a technical/syntax
>> perspective I
>> > disagree. In fact, I'm concern about this. The reason is the validation
>> is
>> > bound to the input component, not to the button or the action, even with
>> > Bean Validation. So, even if you have a @NotNull, the problem is the
>> > validation bypass, which is not obvious and will happen anyway. In other
>> > words @NotNull will not solve the problem.
>> >
>> > In the taglib javadoc of h:inputSecret, h:inputText and h:inputTextarea
>> about
>> > "required" says this:
>> >
>> > "... Flag indicating that the user is required to provide a submitted
>> value for
>> > this input component. ..."
>> >
>> > If the value is not submitted (decode does not call setSubmitted()) and
>> required
>> > flag is set to true, validation should fail, no questions asked, without
>> > exceptions. The reason is if the component is "executed", it is
>> expected to
>> > have a submitted value, otherwise the request is invalid.
>> >
>> > The problem is there is a confusion between "required" attribute and
>> > RequiredValidator or @NotNull.
>> >
>> > JSF 2.2 section 3.5.4 says this:
>> >
>> > "... The render-independent property required is a shorthand for the
>> function
>> > of a "required" validator. If the value of this property is true and the
>> > component has no value, the component is marked invalid and a message
>> is added
>> > to the FacesContext instance. ..."
>> >
>> > Which value? submittedValue? or localValue? or "modelValue"?.
>> >
>> > In some point of time "required" was assumed as "not null" or "empty"
>> but both
>> > are not the same concept.
>> >
>> > The problematic line is this one in the javadoc of UIInput.validate() :
>> >
>> > "... Retrieve the submitted value with getSubmittedValue(). If this
>> returns
>> > null, exit without further processing. (This indicates that no value was
>> > submitted for this component.) ..."
>> >
>> > I think that the case where "no value was submitted for this component"
>> is
>> > underspecified. "required" attribute is different to RequiredValidator,
>> which
>> > is really a NotEmptyValidador. What happens here is "required" property
>> means
>> > "submitted" and "not empty".
>> >
>> > regards,
>> >
>> > Leonardo Uribe
>> >
>> > 2016-12-01 3:27 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:
>> > Hi,
>> >
>> > Here's a related Stack Overflow post of mine on the subject:
>> http://stackoverflow.com/q/17773979/157882
>> >
>> > Cheers, B
>> >
>> > On Thu, Dec 1, 2016 at 8:30 AM, Bauke Scholtz <balusc_at_gmail.com> wrote:
>> > Hi,
>> >
>> > Yes, but this indicaties a bad model. The normal solution would be to
>> put a @NotNull constraint on the entity or a NOT NULL constraint on the
>> column.
>> >
>> > Cheers, B
>> >
>> >
>> > On Wed, Nov 30, 2016, 23:33 Neil Griffin <neil.griffin_at_portletfaces.org>
>> wrote:
>> > Dear Friends of JSF,
>> >
>> > The problem is more general than the h:inputSecret validation example.
>> >
>> > Instead, consider this example:
>> >
>> > <h:inputText id="lastName" required="true"
>> > value="#{backingBean.lastName}" />
>> >
>> > If <input type="text" name="lastName"/> is removed from the DOM prior
>> to submitting the form (hack the postback such that the "lastName" request
>> parameter is not present), then validation of the lastName value is
>> bypassed and the UPDATE_MODEL_VALUES phase will be reached. This is invalid
>> because the model will not contain a lastName value (even though the model
>> requires it).
>> >
>> > To see this problem in action, follow the instructions on this page:
>> > http://www.liferayfaces.org/web/guest/jsfspec1433
>> >
>> > The code that Ed is proposing that we fix (enabled by the proposed
>> context-parameter) can be found here:
>> > https://github.com/javaserverfaces/mojarra/blob/
>> master/jsf-api/src/main/java/javax/faces/component/UIInput.java#L991-L993
>> >
>> > if (submittedValue == null) {
>> > return;
>> > }
>> >
>> > Q: Would it cause a backward compatibility problem if we simply made
>> the following change?
>> >
>> > if ((submittedValue == null) && !isRequired()) {
>> > return;
>> > }
>> >
>> > In other words, is it necessary to introduce the context-param along
>> with the fix?
>> >
>> > Thanks,
>> >
>> > Neil
>> >
>> > > On Nov 30, 2016, at 7:35 AM, Josh Juneau <juneau001_at_gmail.com> wrote:
>> > >
>> > > I think that the proposal looks fine, but I agree with Bauke's
>> sentiments as this seems like a fairly non-standard use case.
>> > >
>> > > Josh Juneau
>> > > juneau001_at_gmail.com
>> > > http://jj-blogger.blogspot.com
>> > > https://www.apress.com/index.php/author/author/view/id/1866
>> > >
>> > >
>> > > On Wed, Nov 30, 2016 at 3:47 AM, arjan tijms <arjan.tijms_at_gmail.com>
>> wrote:
>> > > Hi,
>> > >
>> > > An "always run validator when required is true" seems okay to me. I
>> did spot a small typo in the text, as it currently says:
>> > >
>> > > " If the value of "required" is false, the required attribute is not
>> set not set"
>> > >
>> > > I assume the second "not set" should not be there.
>> > >
>> > > The example is indeed a little peculiar. I assume the user does this
>> to avoid having a separate backing bean with an action method that only
>> calls "request.authenticate", but becoming authenticated as a side-effect
>> of running validation would probably not pass code review in a lot of
>> places I think.
>> > >
>> > > Kind regards,
>> > > Arjan Tijms
>> > >
>> > >
>> > > On Wed, Nov 30, 2016 at 8:21 AM, Bauke Scholtz <balusc_at_gmail.com>
>> wrote:
>> > > Hi,
>> > >
>> > > Proposal itself looks good, but I can't think of any use case where
>> it would be used as a real solution instead of as a workaround to a design
>> problem. You?
>> > >
>> > > Cheers, B
>> > >
>> > > On Tue, Nov 29, 2016 at 6:15 PM, Edward Burns <
>> edward.burns_at_oracle.com> wrote:
>> > > Hello Volunteers,
>> > >
>> > > Neil Griffin brought this issue to my attention [1] and has been
>> ardently
>> > > advocating for it to be addressed in 2.3.
>> > >
>> > > When you say required="true" on a UIInput component, the validation
>> > > must always take place, even when there is no entry in the request
>> > > corresponding to that component.
>> > >
>> > > Background:
>> > >
>> > > Consider this login page:
>> > >
>> > > <h:inputText id="userName" required="true"
>> > > value="#{backingBean.userName}" />
>> > >
>> > > <h:inputSecret id="password" required="true"
>> > > validator="#{backingBean.validatePassword}"
>> > > value="#{backingBean.password}" />
>> > >
>> > > <h:commandButton action="/views/authenticatedUser.xhtml" />
>> > >
>> > >
>> > > If the postback is hacked such that the userName is present as a
>> request
>> > > parameter, but the password is not, the password validator would be
>> > > bypassed. If the password validator is used as the entry point to
>> > > perform authentication, this could cause problems.
>> > >
>> > > Now, it must be said that using a validator on a password field as the
>> > > entry point to perform authentication is a particular design choice.
>> > > This design choice runs a bit counter to the stated purpose of the
>> > > validation system, which is to ensure syntactic and some level of
>> > > semantic validity of fields. There are other ways to perform
>> > > authentication that do not rely on the validation system for this
>> > > purpose.
>> > >
>> > > Nonetheless, we would like to accomodate this use case.
>> > >
>> > > Proposal:
>> > >
>> > > For JSF 2.3, I propose the following.
>> > >
>> > > Modify PDF section 3.5.4 to read:
>> > >
>> > >
>> > > Spec> *The render-independent property required is a shorthand for the
>> > > Spec> function of a required validator. If the value of this property
>> is
>> > > Spec> true, **there is an entry in the request payload corresponding
>> to
>> > > Spec> this component**, and the component has no value, the component
>> is
>> > > Spec> marked invalid and a message is added to the FacesContext
>> > > Spec> instance.*
>> > >
>> > >
>> > > Modify the JavaDoc for UIInput.validate(). Modify the first bullet
>> > > point to read:
>> > >
>> > >
>> > > Spec> Retrieve the submitted value with getSubmittedValue(). If this
>> > > Spec> returns null, and the
>> > > Spec> javax.faces.component.UIInput.ALWAYS_PERFORM_VALIDATION_
>> WHEN_REQUIRED_IS_TRUE
>> > > Spec> context-parameter is set to true (ignoring case), examine the
>> > > Spec> value of the "required" property. If the value of "required" is
>> > > Spec> true, continue as below. If the value of "required" is false,
>> the
>> > > Spec> "required" attribute is not set not set, exit without further
>> > > Spec> processing. If the context-paramater is not set, or is set to
>> > > Spec> false (ignoring case) exit without further processing. (This
>> > > Spec> indicates that no value was submitted for this component.)
>> > >
>> > >
>> > > With these changes, the javadoc for UIInput.validateValue() can remain
>> > > unchanged.
>> > >
>> > > ACTION: Please let us know your thoughts about this by COB 2016-12-06.
>> > > I really hope you all can accept it as is, but I think the chance for
>> EG
>> > > discussion is warranted here.
>> > >
>> > > Ed
>> > >
>> > > --
>> > > | edward.burns_at_oracle.com | office: +1 407 458 0017
>> > >
>> > > [1] https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1433
>> > >
>> > >
>> > >
>> >
>> >
>> >
>>
>>