Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect inclusion of javax/jakarta validation annotations with groups property set #4804

Open
mc1arke opened this issue Dec 7, 2024 · 1 comment

Comments

@mc1arke
Copy link

mc1arke commented Dec 7, 2024

The javax/jakarta annotations contain a groups property that can be used to enable different combinations of validation on a model depending on which group is currently active - https://jakarta.ee/learn/docs/jakartaee-tutorial/current/beanvalidation/bean-validation-advanced/bean-validation-advanced.html#_grouping_constraints.

When executed against a model, swagger-core currently treats any of the supported javax/jakarta annotations as applying a constraint to the schema, even where the annotated field/attribute specifies groups and is therefore is not mandatory on all requests. By default, swagger-core should only set fields as mandatory/constrained based on annotations where no groups are specified, but provide a way of the end-user adding other validation groups into the constraints where they want to treat certain groups as always being enabled.

Replication Steps

        @Test
        public void shouldIncludeOnlyNonGroupedJakartaValidatedFieldsAsMandatoryByDefault() {
            ResolvedSchema schema = ModelConverters.getInstance(false).resolveAsResolvedSchema(new AnnotatedType().type(CustomClass.class));
            String expectedJson = "{\"schema\":{\"required\":[\"nonGroupValidatedField\"],\"type\":\"object\",\"properties\":{\"nonGroupValidatedField\":{\"type\":\"string\"},\"singleGroupValidatedField\":{\"type\":\"integer\",\"format\":\"int32\"},\"multipleGroupValidatedField\":{\"type\":\"number\"},\"otherGroupValidatedField\":{\"type\":\"string\"},\"singleGroupValidatedField2\":{\"type\":\"string\"}}},\"referencedSchemas\":{\"CustomClass\":{\"required\":[\"nonGroupValidatedField\"],\"type\":\"object\",\"properties\":{\"nonGroupValidatedField\":{\"type\":\"string\"},\"singleGroupValidatedField\":{\"type\":\"integer\",\"format\":\"int32\"},\"multipleGroupValidatedField\":{\"type\":\"number\"},\"otherGroupValidatedField\":{\"type\":\"string\"},\"singleGroupValidatedField2\":{\"type\":\"string\"}}}}}";
            SerializationMatchers.assertEqualsToJson(schema, expectedJson);
        }


        private interface ValidationGroup {

        }

        private interface OtherValidationGroup {

        }


        private static class CustomClass {

            @NotNull
            public String nonGroupValidatedField;

            @Min(value = 1, groups = ValidationGroup.class)
            public Integer singleGroupValidatedField;

            @DecimalMin(value = "1.0", groups = {ValidationGroup.class, OtherValidationGroup.class})
            public BigDecimal multipleGroupValidatedField;

            @Pattern(regexp = ".*", groups = OtherValidationGroup.class)
            public String otherGroupValidatedField;

            @NotEmpty(groups = ValidationGroup.class)
            public String singleGroupValidatedField2;
        }

The above replicate a validator being run in default mode, e.g. Validation.buildDefaultValidatorFactory().getValidator().validate(new CustomClass());, which is the default way that frameworks such as Spring invoke validators. Users using something similar to
Validation.buildDefaultValidatorFactory().getValidator().validate(new CustomClass(), ValidationGroup.class); would add the annotations with ValidationGroup in the groups property into the enforced validation.

mc1arke added a commit to mc1arke/swagger-core that referenced this issue Dec 7, 2024
…by default

The current process for adding constraints into the schema presumes that
all javax or jakarta validation annotations enforce a constraint, and
doesn't take into account the 'groups' property of the annotation. This
results in constrains being added to the schema that would only be
applied for certain request, so incorrectly marks fields as required in
the resulting schema where they may only be mandatory on a subset of
requests. To overcome this, a new `ValidationAnnotationFilter` is being
introduced which only treats a validation annotation as constraining the
schema where the conditions on the filter are met be the annotation. The
default implementation of this filter only treats constraints from
annotations with no groups as being enforced to bring it inline with how
the default Java Beans validation operates.
mc1arke added a commit to mc1arke/swagger-core that referenced this issue Dec 7, 2024
…by default

The current process for adding constraints into the schema presumes that
all javax or jakarta validation annotations enforce a constraint, and
doesn't take into account the 'groups' property of the annotation. This
results in constrains being added to the schema that would only be
applied for certain request, so incorrectly marks fields as required in
the resulting schema where they may only be mandatory on a subset of
requests. To overcome this, a new `ValidationAnnotationFilter` is being
introduced which only treats a validation annotation as constraining the
schema where the conditions on the filter are met be the annotation. The
default implementation of this filter only treats constraints from
annotations with no groups as being enforced to bring it inline with how
the default Java Beans validation operates.
@T3rm1
Copy link

T3rm1 commented Dec 9, 2024

There is already a PR for this issue: #4797

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants