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

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

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 1 Dec 2016 21:43:24 -0500

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 <(407)%20458-0017>
>>> >
>>> > [1] https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1433
>>> >
>>> >
>>> >
>>>
>>>
>