From 063683fb7427e85329570350dbdc3feb26d84a71 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Wed, 25 Oct 2023 18:33:09 +0200 Subject: [PATCH 01/10] ENG-4362: profile full name validation --- .../web/userprofile/ProfileController.java | 1 + .../validator/ProfileValidator.java | 22 ++++++++ .../main/resources/rest/messages.properties | 2 + .../validator/ProfileValidatorTest.java | 53 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java b/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java index 7a4e624e45..0d038d4722 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java @@ -169,6 +169,7 @@ public ResponseEntity> updateMyUserProfile(@Reques @Valid @RequestBody EntityDto bodyRequest, BindingResult bindingResult) { logger.debug("Update profile for the logged user {} -> {}", user.getUsername(), bodyRequest); this.getProfileValidator().validateBodyName(user.getUsername(), bodyRequest, bindingResult); + this.getProfileValidator().validateFullName(bodyRequest,bindingResult); if (bindingResult.hasErrors()) { throw new ValidationGenericException(bindingResult); } diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java index b48245b58a..b187500eec 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java @@ -14,10 +14,13 @@ package org.entando.entando.web.userprofile.validator; import com.agiletec.aps.system.common.entity.IEntityManager; +import org.entando.entando.aps.system.services.entity.model.EntityDto; import org.entando.entando.aps.system.services.userprofile.IUserProfileManager; +import org.entando.entando.web.common.exceptions.ValidationConflictException; import org.entando.entando.web.entity.validator.EntityValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; /** * @author E.Santoboni @@ -25,6 +28,12 @@ @Component public class ProfileValidator extends EntityValidator { + public static final String PROFILE_NAME_VALIDATOR_REGEX = "^(?=.{2,70}$)^\\S[A-Za-z0-9À-ÿ_-]*([ ]*[A-Za-z0-9À-ÿ_-]+)*$"; + public static final String ERRCODE_PROFILE_NAME_NOT_FOUND = "5"; + public static final String ERRCODE_PROFILE_NAME_NOT_VALID = "6"; + public static final String FULLNAME = "fullname"; + public static final String ATTRIBUTES = "attributes"; + @Autowired private IUserProfileManager userProfileManager; @@ -37,4 +46,17 @@ protected IEntityManager getEntityManager() { return this.userProfileManager; } + public void validateFullName(EntityDto bodyRequest, BindingResult bindingResult) { + String fullName = (String) bodyRequest.getAttributes().stream().filter(e -> e.getCode().equals(FULLNAME)) + .findFirst() + .orElseThrow(() -> { + bindingResult.rejectValue(ATTRIBUTES, ERRCODE_PROFILE_NAME_NOT_FOUND, "user.fullName.notFound"); + return new ValidationConflictException(bindingResult); + }).getValue(); + if (!fullName.matches(PROFILE_NAME_VALIDATOR_REGEX)) { + bindingResult.rejectValue(ATTRIBUTES, ERRCODE_PROFILE_NAME_NOT_VALID, "user.fullName.invalid"); + throw new ValidationConflictException(bindingResult); + } + } + } diff --git a/engine/src/main/resources/rest/messages.properties b/engine/src/main/resources/rest/messages.properties index 7eda70d3d0..6a35dc0a68 100644 --- a/engine/src/main/resources/rest/messages.properties +++ b/engine/src/main/resources/rest/messages.properties @@ -256,6 +256,8 @@ user.self.delete.error=Sorry. You can't delete yourself user.preferences.update.other=Cannot update other users'' preferences user.password-confirm.mismatch=The password confirmation is different from the password. user.profile-only.unsupported=The requested operation can't be performed on a user having only the profile +user.fullName.notFound=The Full Name is required +user.fullName.invalid=The Full Name is invalid. The name must be between 2 and 70 characters in length. Allowable characters include letters, accented letters, numbers, hyphens, spaces, and underscores #labels labelRequest.key.required=Key is required diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java new file mode 100644 index 0000000000..9daba59d8d --- /dev/null +++ b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java @@ -0,0 +1,53 @@ +package org.entando.entando.web.userprofile.validator; + +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import org.entando.entando.aps.system.services.entity.model.EntityAttributeDto; +import org.entando.entando.aps.system.services.entity.model.EntityDto; +import org.entando.entando.web.common.exceptions.ValidationConflictException; +import org.junit.jupiter.api.Assertions; +import org.mockito.Mockito; +import org.junit.jupiter.api.Test; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.BindingResult; + +class ProfileValidatorTest { + + @Test + void validateFullNameShouldThrowExceptionIfFullNameIsNotValid() { + + // --Given + EntityDto entityDto = new EntityDto(); + EntityAttributeDto entityAttributeDto = new EntityAttributeDto(); + entityAttributeDto.setCode("fullname"); + entityAttributeDto.setValue(" Not Valid Full Name"); + entityDto.setAttributes(List.of(entityAttributeDto)); + BindingResult bindingResult = new BeanPropertyBindingResult(entityDto, "entityDto"); + + // Then + ProfileValidator profileValidator = new ProfileValidator(); + Assertions.assertThrows(ValidationConflictException.class, + () -> profileValidator.validateFullName(entityDto, bindingResult)); + + } + + @Test + void validateFullNameShouldNotThrowExceptionIfFullNameIsValid() { + + // --Given + EntityDto entityDto = new EntityDto(); + EntityAttributeDto entityAttributeDto = new EntityAttributeDto(); + entityAttributeDto.setCode("fullname"); + entityAttributeDto.setValue("Valid Full-Name"); + entityDto.setAttributes(List.of(entityAttributeDto)); + BindingResult bindingResult = new BeanPropertyBindingResult(entityDto, "entityDto"); + + // Then + ProfileValidator profileValidator = new ProfileValidator(); + Assertions.assertDoesNotThrow(() -> profileValidator.validateFullName(entityDto, bindingResult)); + + } + +} From 1a6207a9c1dcf7a00e3fed52f2396663682b66b3 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Thu, 26 Oct 2023 10:49:20 +0200 Subject: [PATCH 02/10] ENG-4362: fix test input --- .../entando/entando/web/userprofile/11_POST_type_valid.json | 6 ++++++ .../org/entando/entando/web/userprofile/11_PUT_valid.json | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json b/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json index f6138bb70d..c25ef9fbf7 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json +++ b/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json @@ -7,6 +7,12 @@ "type": "Monotext", "name": "Description of text attribute", "mandatory": true + }, + { + "code": "fullname", + "type": "Monotext", + "name": "Description of text attribute", + "mandatory": false } ] } diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json b/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json index 81a4825129..1c4d73e44d 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json +++ b/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json @@ -12,6 +12,10 @@ { "code": "Name", "value": "Name" + }, + { + "code": "fullname", + "value": "Valid Name" } ] } From 5e3351eb38d84610f8fb7219f132d1daa06b7fa2 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Thu, 26 Oct 2023 13:10:27 +0200 Subject: [PATCH 03/10] ENG-4362: fix code smells --- .../entando/web/userprofile/validator/ProfileValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java index b187500eec..d1c9f5af65 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java @@ -28,7 +28,7 @@ @Component public class ProfileValidator extends EntityValidator { - public static final String PROFILE_NAME_VALIDATOR_REGEX = "^(?=.{2,70}$)^\\S[A-Za-z0-9À-ÿ_-]*([ ]*[A-Za-z0-9À-ÿ_-]+)*$"; + public static final String PROFILE_NAME_VALIDATOR_REGEX = "^(?=.{2,70}$)\\S[a-zA-ZÀ-ÿ0-9 _-]*\\S$"; public static final String ERRCODE_PROFILE_NAME_NOT_FOUND = "5"; public static final String ERRCODE_PROFILE_NAME_NOT_VALID = "6"; public static final String FULLNAME = "fullname"; From edebf5e461d30c1131395d4cb780bc2250cae2f1 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Thu, 26 Oct 2023 13:25:16 +0200 Subject: [PATCH 04/10] ENG-4362: changed string.matches in favour of Pattern matcher for performance reason --- .../web/userprofile/validator/ProfileValidator.java | 7 ++++++- .../web/userprofile/validator/ProfileValidatorTest.java | 4 ---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java index d1c9f5af65..ca1f4febd7 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java @@ -14,6 +14,8 @@ package org.entando.entando.web.userprofile.validator; import com.agiletec.aps.system.common.entity.IEntityManager; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.entando.entando.aps.system.services.entity.model.EntityDto; import org.entando.entando.aps.system.services.userprofile.IUserProfileManager; import org.entando.entando.web.common.exceptions.ValidationConflictException; @@ -53,7 +55,10 @@ public void validateFullName(EntityDto bodyRequest, BindingResult bindingResult) bindingResult.rejectValue(ATTRIBUTES, ERRCODE_PROFILE_NAME_NOT_FOUND, "user.fullName.notFound"); return new ValidationConflictException(bindingResult); }).getValue(); - if (!fullName.matches(PROFILE_NAME_VALIDATOR_REGEX)) { + Pattern pattern = Pattern.compile(PROFILE_NAME_VALIDATOR_REGEX); + Matcher matcher = pattern.matcher(fullName); + + if (!matcher.matches()) { bindingResult.rejectValue(ATTRIBUTES, ERRCODE_PROFILE_NAME_NOT_VALID, "user.fullName.invalid"); throw new ValidationConflictException(bindingResult); } diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java index 9daba59d8d..431014d356 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java +++ b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java @@ -1,14 +1,10 @@ package org.entando.entando.web.userprofile.validator; -import static org.mockito.Mockito.*; - import java.util.List; -import java.util.Map; import org.entando.entando.aps.system.services.entity.model.EntityAttributeDto; import org.entando.entando.aps.system.services.entity.model.EntityDto; import org.entando.entando.web.common.exceptions.ValidationConflictException; import org.junit.jupiter.api.Assertions; -import org.mockito.Mockito; import org.junit.jupiter.api.Test; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; From 1c65d7eb87a606fdb2c5716ce6b20f2503794e0a Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Thu, 26 Oct 2023 14:57:59 +0200 Subject: [PATCH 05/10] ENG-4362: code coverage --- .../validator/ProfileValidatorTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java index 431014d356..5f4dec6768 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java +++ b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java @@ -1,6 +1,7 @@ package org.entando.entando.web.userprofile.validator; import java.util.List; +import java.util.Objects; import org.entando.entando.aps.system.services.entity.model.EntityAttributeDto; import org.entando.entando.aps.system.services.entity.model.EntityDto; import org.entando.entando.web.common.exceptions.ValidationConflictException; @@ -26,6 +27,28 @@ void validateFullNameShouldThrowExceptionIfFullNameIsNotValid() { ProfileValidator profileValidator = new ProfileValidator(); Assertions.assertThrows(ValidationConflictException.class, () -> profileValidator.validateFullName(entityDto, bindingResult)); + Assertions.assertTrue(bindingResult.getAllErrors().stream() + .anyMatch(objectError -> Objects.equals(objectError.getDefaultMessage(), "user.fullName.invalid"))); + + } + + @Test + void validateFullNameShouldThrowExceptionIfFullNameIsNotPresent() { + + // --Given + EntityDto entityDto = new EntityDto(); + EntityAttributeDto entityAttributeDto = new EntityAttributeDto(); + entityAttributeDto.setCode("otherCode"); + entityAttributeDto.setValue("xxx"); + entityDto.setAttributes(List.of(entityAttributeDto)); + BindingResult bindingResult = new BeanPropertyBindingResult(entityDto, "entityDto"); + + // Then + ProfileValidator profileValidator = new ProfileValidator(); + Assertions.assertThrows(ValidationConflictException.class, + () -> profileValidator.validateFullName(entityDto, bindingResult)); + Assertions.assertTrue(bindingResult.getAllErrors().stream() + .anyMatch(objectError -> Objects.equals(objectError.getDefaultMessage(), "user.fullName.notFound"))); } From 2292c920bc9d3340a6f55ecd9219744b9a1b93b5 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Thu, 26 Oct 2023 20:54:15 +0200 Subject: [PATCH 06/10] ENG-4362: code refactoring --- .../web/userprofile/ProfileController.java | 1 - .../validator/ProfileValidator.java | 21 ------ .../port/clob/production/sysconfig_3.xml | 1 + .../liquibase/port/clob/test/sysconfig_3.xml | 1 + .../main/resources/rest/messages.properties | 2 - .../web/userprofile/11_POST_type_valid.json | 6 -- .../entando/web/userprofile/11_PUT_valid.json | 4 -- .../web/userprofile/13_POST_regex.json | 19 +++++ .../web/userprofile/13_POST_valid.json | 17 +++++ .../web/userprofile/13_PUT_invalid.json | 17 +++++ .../entando/web/userprofile/13_PUT_valid.json | 17 +++++ .../UserProfileControllerIntegrationTest.java | 68 ++++++++++++++++++ .../validator/ProfileValidatorTest.java | 72 ------------------- 13 files changed, 140 insertions(+), 106 deletions(-) create mode 100644 engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json create mode 100644 engine/src/test/java/org/entando/entando/web/userprofile/13_POST_valid.json create mode 100644 engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_invalid.json create mode 100644 engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_valid.json delete mode 100644 engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java b/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java index 0d038d4722..7a4e624e45 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/ProfileController.java @@ -169,7 +169,6 @@ public ResponseEntity> updateMyUserProfile(@Reques @Valid @RequestBody EntityDto bodyRequest, BindingResult bindingResult) { logger.debug("Update profile for the logged user {} -> {}", user.getUsername(), bodyRequest); this.getProfileValidator().validateBodyName(user.getUsername(), bodyRequest, bindingResult); - this.getProfileValidator().validateFullName(bodyRequest,bindingResult); if (bindingResult.hasErrors()) { throw new ValidationGenericException(bindingResult); } diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java index ca1f4febd7..0bb9c765db 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java @@ -30,11 +30,6 @@ @Component public class ProfileValidator extends EntityValidator { - public static final String PROFILE_NAME_VALIDATOR_REGEX = "^(?=.{2,70}$)\\S[a-zA-ZÀ-ÿ0-9 _-]*\\S$"; - public static final String ERRCODE_PROFILE_NAME_NOT_FOUND = "5"; - public static final String ERRCODE_PROFILE_NAME_NOT_VALID = "6"; - public static final String FULLNAME = "fullname"; - public static final String ATTRIBUTES = "attributes"; @Autowired private IUserProfileManager userProfileManager; @@ -48,20 +43,4 @@ protected IEntityManager getEntityManager() { return this.userProfileManager; } - public void validateFullName(EntityDto bodyRequest, BindingResult bindingResult) { - String fullName = (String) bodyRequest.getAttributes().stream().filter(e -> e.getCode().equals(FULLNAME)) - .findFirst() - .orElseThrow(() -> { - bindingResult.rejectValue(ATTRIBUTES, ERRCODE_PROFILE_NAME_NOT_FOUND, "user.fullName.notFound"); - return new ValidationConflictException(bindingResult); - }).getValue(); - Pattern pattern = Pattern.compile(PROFILE_NAME_VALIDATOR_REGEX); - Matcher matcher = pattern.matcher(fullName); - - if (!matcher.matches()) { - bindingResult.rejectValue(ATTRIBUTES, ERRCODE_PROFILE_NAME_NOT_VALID, "user.fullName.invalid"); - throw new ValidationConflictException(bindingResult); - } - } - } diff --git a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml index 8786c502a8..22d44cba5e 100644 --- a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml +++ b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml @@ -8,6 +8,7 @@ userprofile:fullname + diff --git a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml index a0c63d7a78..ac16bee6cd 100644 --- a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml +++ b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml @@ -7,6 +7,7 @@ userprofile:fullname + diff --git a/engine/src/main/resources/rest/messages.properties b/engine/src/main/resources/rest/messages.properties index 6a35dc0a68..7eda70d3d0 100644 --- a/engine/src/main/resources/rest/messages.properties +++ b/engine/src/main/resources/rest/messages.properties @@ -256,8 +256,6 @@ user.self.delete.error=Sorry. You can't delete yourself user.preferences.update.other=Cannot update other users'' preferences user.password-confirm.mismatch=The password confirmation is different from the password. user.profile-only.unsupported=The requested operation can't be performed on a user having only the profile -user.fullName.notFound=The Full Name is required -user.fullName.invalid=The Full Name is invalid. The name must be between 2 and 70 characters in length. Allowable characters include letters, accented letters, numbers, hyphens, spaces, and underscores #labels labelRequest.key.required=Key is required diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json b/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json index c25ef9fbf7..f6138bb70d 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json +++ b/engine/src/test/java/org/entando/entando/web/userprofile/11_POST_type_valid.json @@ -7,12 +7,6 @@ "type": "Monotext", "name": "Description of text attribute", "mandatory": true - }, - { - "code": "fullname", - "type": "Monotext", - "name": "Description of text attribute", - "mandatory": false } ] } diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json b/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json index 1c4d73e44d..81a4825129 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json +++ b/engine/src/test/java/org/entando/entando/web/userprofile/11_PUT_valid.json @@ -12,10 +12,6 @@ { "code": "Name", "value": "Name" - }, - { - "code": "fullname", - "value": "Valid Name" } ] } diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json b/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json new file mode 100644 index 0000000000..fa6e3f1238 --- /dev/null +++ b/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json @@ -0,0 +1,19 @@ +{ + "code": "RX2", + "name": "Profile Type RX2", + "attributes": [ + { + "code": "fullname", + "type": "Monotext", + "name": "Description of full name attribute", + "mandatory": false, + "validationRules": { + "regex":"^(?=.{2,70}$)\\S[a-zA-ZÀ-ÿ0-9 _-]*\\S$" + }, + "roles": [{ + "code": "userprofile:fullname", + "descr": "The Attribute containing the full name" + }] + } + ] +} \ No newline at end of file diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_valid.json b/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_valid.json new file mode 100644 index 0000000000..7d6746516d --- /dev/null +++ b/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_valid.json @@ -0,0 +1,17 @@ +{ + "id": "new_user", + "typeCode": "RX2", + "typeDescription": "Type for test", + "description": "Profile of user", + "mainGroup": "free", + "groups": [ + "group1", + "group2" + ], + "attributes": [ + { + "code": "fullname", + "value": "Name" + } + ] +} diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_invalid.json b/engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_invalid.json new file mode 100644 index 0000000000..4a9e90da46 --- /dev/null +++ b/engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_invalid.json @@ -0,0 +1,17 @@ +{ + "id": "new_user", + "typeCode": "RX2", + "typeDescription": "Type for test RX2", + "description": "Profile of user", + "mainGroup": "free", + "groups": [ + "group1", + "group2" + ], + "attributes": [ + { + "code": "fullname", + "value": "John Doe. " + } + ] +} diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_valid.json b/engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_valid.json new file mode 100644 index 0000000000..a39fe77ad4 --- /dev/null +++ b/engine/src/test/java/org/entando/entando/web/userprofile/13_PUT_valid.json @@ -0,0 +1,17 @@ +{ + "id": "new_user", + "typeCode": "RX2", + "typeDescription": "Type for test RX2", + "description": "Profile of user", + "mainGroup": "free", + "groups": [ + "group1", + "group2" + ], + "attributes": [ + { + "code": "fullname", + "value": "John Doe" + } + ] +} diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java index 4dd91d152d..4c2ef8522f 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java +++ b/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java @@ -42,6 +42,7 @@ import java.util.Arrays; import java.util.Date; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -531,6 +532,73 @@ void testAddUserProfileWithProfilePicture() throws Exception { } } + @Test + void testPutMyProfileRegexAccept() throws Exception { + try { + Assertions.assertNull(this.userProfileManager.getEntityPrototype("RX2")); + String accessToken = this.createAccessToken(); + + this.executeProfileTypePost("13_POST_regex.json", accessToken, status().isOk()); + + Assertions.assertNotNull(this.userProfileManager.getEntityPrototype("RX2")); + + this.executeProfilePost("13_POST_valid.json", accessToken, status().isOk()).andDo(resultPrint()) + .andExpect(jsonPath("$.payload.id", is("new_user"))) + .andExpect(jsonPath("$.errors.size()", is(0))) + .andExpect(jsonPath("$.metaData.size()", is(0))); + + UserDetails userEditMyProfile = new OAuth2TestUtils.UserBuilder("new_user", "0x24") + .withAuthorization(Group.FREE_GROUP_NAME, "editor", Permission.ENTER_BACKEND) + .build(); + String userEditMyProfileToken = mockOAuthInterceptor(userEditMyProfile); + + this.executePutUpdateMyProfile("13_PUT_valid.json", userEditMyProfile, userEditMyProfileToken, + status().isOk()) + .andExpect(jsonPath("$.payload.id", is("new_user"))) + .andExpect(jsonPath("$.payload.typeCode", is("RX2"))) + .andExpect(jsonPath("$.payload.typeDescription", is("Type for test RX2"))); + + } finally { + this.userManager.removeUser("new_user"); + if (null != this.userProfileManager.getEntityPrototype("RX2")) { + ((IEntityTypesConfigurer) this.userProfileManager).removeEntityPrototype("RX2"); + } + } + } + + @Test + void testPutMyProfileRegexReject() throws Exception { + try { + Assertions.assertNull(this.userProfileManager.getEntityPrototype("RX2")); + String accessToken = this.createAccessToken(); + + this.executeProfileTypePost("13_POST_regex.json", accessToken, status().isOk()); + + Assertions.assertNotNull(this.userProfileManager.getEntityPrototype("RX2")); + + this.executeProfilePost("13_POST_valid.json", accessToken, status().isOk()).andDo(resultPrint()) + .andExpect(jsonPath("$.payload.id", is("new_user"))) + .andExpect(jsonPath("$.errors.size()", is(0))) + .andExpect(jsonPath("$.metaData.size()", is(0))); + + UserDetails userEditMyProfile = new OAuth2TestUtils.UserBuilder("new_user", "0x24") + .withAuthorization(Group.FREE_GROUP_NAME, "editor", Permission.ENTER_BACKEND) + .build(); + String userEditMyProfileToken = mockOAuthInterceptor(userEditMyProfile); + + this.executePutUpdateMyProfile("13_PUT_invalid.json", userEditMyProfile, userEditMyProfileToken, + status().isBadRequest()) + .andExpect(jsonPath("$.errors.size()", is(1))) + .andExpect(jsonPath("$.errors[0].message", + containsString("Attribute 'fullname' Invalid format"))); + } finally { + this.userManager.removeUser("new_user"); + if (null != this.userProfileManager.getEntityPrototype("RX2")) { + ((IEntityTypesConfigurer) this.userProfileManager).removeEntityPrototype("RX2"); + } + } + } + private String createAccessToken() throws Exception { UserDetails user = new OAuth2TestUtils.UserBuilder("jack_bauer", "0x24") .withAuthorization(Group.FREE_GROUP_NAME, "manageUserProfile", Permission.MANAGE_USER_PROFILES) diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java deleted file mode 100644 index 5f4dec6768..0000000000 --- a/engine/src/test/java/org/entando/entando/web/userprofile/validator/ProfileValidatorTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.entando.entando.web.userprofile.validator; - -import java.util.List; -import java.util.Objects; -import org.entando.entando.aps.system.services.entity.model.EntityAttributeDto; -import org.entando.entando.aps.system.services.entity.model.EntityDto; -import org.entando.entando.web.common.exceptions.ValidationConflictException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.BindingResult; - -class ProfileValidatorTest { - - @Test - void validateFullNameShouldThrowExceptionIfFullNameIsNotValid() { - - // --Given - EntityDto entityDto = new EntityDto(); - EntityAttributeDto entityAttributeDto = new EntityAttributeDto(); - entityAttributeDto.setCode("fullname"); - entityAttributeDto.setValue(" Not Valid Full Name"); - entityDto.setAttributes(List.of(entityAttributeDto)); - BindingResult bindingResult = new BeanPropertyBindingResult(entityDto, "entityDto"); - - // Then - ProfileValidator profileValidator = new ProfileValidator(); - Assertions.assertThrows(ValidationConflictException.class, - () -> profileValidator.validateFullName(entityDto, bindingResult)); - Assertions.assertTrue(bindingResult.getAllErrors().stream() - .anyMatch(objectError -> Objects.equals(objectError.getDefaultMessage(), "user.fullName.invalid"))); - - } - - @Test - void validateFullNameShouldThrowExceptionIfFullNameIsNotPresent() { - - // --Given - EntityDto entityDto = new EntityDto(); - EntityAttributeDto entityAttributeDto = new EntityAttributeDto(); - entityAttributeDto.setCode("otherCode"); - entityAttributeDto.setValue("xxx"); - entityDto.setAttributes(List.of(entityAttributeDto)); - BindingResult bindingResult = new BeanPropertyBindingResult(entityDto, "entityDto"); - - // Then - ProfileValidator profileValidator = new ProfileValidator(); - Assertions.assertThrows(ValidationConflictException.class, - () -> profileValidator.validateFullName(entityDto, bindingResult)); - Assertions.assertTrue(bindingResult.getAllErrors().stream() - .anyMatch(objectError -> Objects.equals(objectError.getDefaultMessage(), "user.fullName.notFound"))); - - } - - @Test - void validateFullNameShouldNotThrowExceptionIfFullNameIsValid() { - - // --Given - EntityDto entityDto = new EntityDto(); - EntityAttributeDto entityAttributeDto = new EntityAttributeDto(); - entityAttributeDto.setCode("fullname"); - entityAttributeDto.setValue("Valid Full-Name"); - entityDto.setAttributes(List.of(entityAttributeDto)); - BindingResult bindingResult = new BeanPropertyBindingResult(entityDto, "entityDto"); - - // Then - ProfileValidator profileValidator = new ProfileValidator(); - Assertions.assertDoesNotThrow(() -> profileValidator.validateFullName(entityDto, bindingResult)); - - } - -} From dcccdd73e41a682ef6600c8b427b6a203118f19c Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Thu, 26 Oct 2023 21:09:51 +0200 Subject: [PATCH 07/10] ENG-4362: fix on xml validations --- .../entando/web/userprofile/validator/ProfileValidator.java | 5 ----- .../resources/liquibase/port/clob/production/sysconfig_3.xml | 2 +- .../main/resources/liquibase/port/clob/test/sysconfig_3.xml | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java index 0bb9c765db..f39896981c 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java @@ -14,15 +14,10 @@ package org.entando.entando.web.userprofile.validator; import com.agiletec.aps.system.common.entity.IEntityManager; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.entando.entando.aps.system.services.entity.model.EntityDto; import org.entando.entando.aps.system.services.userprofile.IUserProfileManager; -import org.entando.entando.web.common.exceptions.ValidationConflictException; import org.entando.entando.web.entity.validator.EntityValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.validation.BindingResult; /** * @author E.Santoboni diff --git a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml index 22d44cba5e..c78db9ff7c 100644 --- a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml +++ b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml @@ -5,10 +5,10 @@ true + userprofile:fullname - diff --git a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml index ac16bee6cd..025f252739 100644 --- a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml +++ b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml @@ -4,10 +4,10 @@ true + userprofile:fullname - From e19c1072ebef667b0bac24bb97d0f4f0f32574c3 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Fri, 27 Oct 2023 11:01:25 +0200 Subject: [PATCH 08/10] ENG-4362: updated changeset --- .../validator/ProfileValidator.java | 1 - .../resources/liquibase/changeSetPort.xml | 1 + ...0000_mfe_communication_mediator_object.xml | 2 +- .../20231027000000_update_profile_types.xml | 16 ++ .../port/clob/production/sysconfig_3.xml | 1 - .../port/clob/production/sysconfig_3_1.xml | 29 +++ .../liquibase/port/clob/test/sysconfig_3.xml | 1 - .../port/clob/test/sysconfig_3_1.xml | 172 ++++++++++++++++++ 8 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 engine/src/main/resources/liquibase/port/20231027000000_update_profile_types.xml create mode 100644 engine/src/main/resources/liquibase/port/clob/production/sysconfig_3_1.xml create mode 100644 engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml diff --git a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java index f39896981c..b48245b58a 100644 --- a/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java +++ b/engine/src/main/java/org/entando/entando/web/userprofile/validator/ProfileValidator.java @@ -25,7 +25,6 @@ @Component public class ProfileValidator extends EntityValidator { - @Autowired private IUserProfileManager userProfileManager; diff --git a/engine/src/main/resources/liquibase/changeSetPort.xml b/engine/src/main/resources/liquibase/changeSetPort.xml index 95140223cb..4692adaa69 100644 --- a/engine/src/main/resources/liquibase/changeSetPort.xml +++ b/engine/src/main/resources/liquibase/changeSetPort.xml @@ -27,5 +27,6 @@ + \ No newline at end of file diff --git a/engine/src/main/resources/liquibase/port/20230626000000_mfe_communication_mediator_object.xml b/engine/src/main/resources/liquibase/port/20230626000000_mfe_communication_mediator_object.xml index 490b1a109c..a98a66efa0 100644 --- a/engine/src/main/resources/liquibase/port/20230626000000_mfe_communication_mediator_object.xml +++ b/engine/src/main/resources/liquibase/port/20230626000000_mfe_communication_mediator_object.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.4.xsd"> - + diff --git a/engine/src/main/resources/liquibase/port/20231027000000_update_profile_types.xml b/engine/src/main/resources/liquibase/port/20231027000000_update_profile_types.xml new file mode 100644 index 0000000000..8933e74ba1 --- /dev/null +++ b/engine/src/main/resources/liquibase/port/20231027000000_update_profile_types.xml @@ -0,0 +1,16 @@ + + + + + + + item='userProfileTypes' + + + + diff --git a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml index c78db9ff7c..8786c502a8 100644 --- a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml +++ b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3.xml @@ -5,7 +5,6 @@ true - userprofile:fullname diff --git a/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3_1.xml b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3_1.xml new file mode 100644 index 0000000000..f8a07440dd --- /dev/null +++ b/engine/src/main/resources/liquibase/port/clob/production/sysconfig_3_1.xml @@ -0,0 +1,29 @@ + + + + + + + true + + + + userprofile:fullname + + + + + true + + + userprofile:email + + + + + userprofile:profilepicture + + + + + \ No newline at end of file diff --git a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml index 025f252739..a0c63d7a78 100644 --- a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml +++ b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3.xml @@ -4,7 +4,6 @@ true - userprofile:fullname diff --git a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml new file mode 100644 index 0000000000..02c28eface --- /dev/null +++ b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml @@ -0,0 +1,172 @@ + + + + + + true + + + + userprofile:fullname + + + + + true + + + + userprofile:email + + + + + + + + + + + + + true + + + userprofile:firstname + + + + + true + + + userprofile:surname + + + + + true + + + userprofile:email + + + + + userprofile:profilepicture + + + + + + + + true + + + true + + + true + + + + + 25/11/2026 + + + + true + + + + true + + + + true + + + true + + + true + + + true + + + + true + 15 + 30 + + + + + true + + + + true + 50 + 300 + + + + true + + jacms:title + + + + + true + 15 + 30 + + + + + true + + + true + + + true + + + + + + + 10/10/2030 + + + + + + + + + + #entity.getAttribute('Number').value)]]> + + + + + + + + + + + + + true + + + + + \ No newline at end of file From dd6e4900bf8f3a32310f008e8269823ee57b6f8a Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Fri, 27 Oct 2023 15:13:10 +0200 Subject: [PATCH 09/10] ENG-4362: regex test fix --- .../{13_POST_regex.json => 13_POST_type_regex.json} | 2 +- .../web/userprofile/UserProfileControllerIntegrationTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename engine/src/test/java/org/entando/entando/web/userprofile/{13_POST_regex.json => 13_POST_type_regex.json} (79%) diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json b/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_type_regex.json similarity index 79% rename from engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json rename to engine/src/test/java/org/entando/entando/web/userprofile/13_POST_type_regex.json index fa6e3f1238..95e790ac47 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_regex.json +++ b/engine/src/test/java/org/entando/entando/web/userprofile/13_POST_type_regex.json @@ -8,7 +8,7 @@ "name": "Description of full name attribute", "mandatory": false, "validationRules": { - "regex":"^(?=.{2,70}$)\\S[a-zA-ZÀ-ÿ0-9 _-]*\\S$" + "regex":"^(?=.{2,70}$)[a-zA-ZÀ-ÿ0-9_-]{1}[a-zA-ZÀ-ÿ0-9 _-]*[a-zA-ZÀ-ÿ0-9_-]{1}$" }, "roles": [{ "code": "userprofile:fullname", diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java index 4c2ef8522f..e6b529bfa8 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java +++ b/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java @@ -538,7 +538,7 @@ void testPutMyProfileRegexAccept() throws Exception { Assertions.assertNull(this.userProfileManager.getEntityPrototype("RX2")); String accessToken = this.createAccessToken(); - this.executeProfileTypePost("13_POST_regex.json", accessToken, status().isOk()); + this.executeProfileTypePost("13_POST_type_regex.json", accessToken, status().isOk()); Assertions.assertNotNull(this.userProfileManager.getEntityPrototype("RX2")); @@ -572,7 +572,7 @@ void testPutMyProfileRegexReject() throws Exception { Assertions.assertNull(this.userProfileManager.getEntityPrototype("RX2")); String accessToken = this.createAccessToken(); - this.executeProfileTypePost("13_POST_regex.json", accessToken, status().isOk()); + this.executeProfileTypePost("13_POST_type_regex.json", accessToken, status().isOk()); Assertions.assertNotNull(this.userProfileManager.getEntityPrototype("RX2")); From 6fa07e00f341f6c002b45a0a64c8c4d4f1891fa0 Mon Sep 17 00:00:00 2001 From: "m.panagrosso" Date: Fri, 27 Oct 2023 17:32:45 +0200 Subject: [PATCH 10/10] ENG-4362: cleaning --- .../port/clob/test/sysconfig_3_1.xml | 172 ------------------ .../UserProfileControllerIntegrationTest.java | 2 + 2 files changed, 2 insertions(+), 172 deletions(-) delete mode 100644 engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml diff --git a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml b/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml deleted file mode 100644 index 02c28eface..0000000000 --- a/engine/src/main/resources/liquibase/port/clob/test/sysconfig_3_1.xml +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - true - - - - userprofile:fullname - - - - - true - - - - userprofile:email - - - - - - - - - - - - - true - - - userprofile:firstname - - - - - true - - - userprofile:surname - - - - - true - - - userprofile:email - - - - - userprofile:profilepicture - - - - - - - - true - - - true - - - true - - - - - 25/11/2026 - - - - true - - - - true - - - - true - - - true - - - true - - - true - - - - true - 15 - 30 - - - - - true - - - - true - 50 - 300 - - - - true - - jacms:title - - - - - true - 15 - 30 - - - - - true - - - true - - - true - - - - - - - 10/10/2030 - - - - - - - - - - #entity.getAttribute('Number').value)]]> - - - - - - - - - - - - - true - - - - - \ No newline at end of file diff --git a/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java b/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java index e6b529bfa8..3569cd2e64 100644 --- a/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java +++ b/engine/src/test/java/org/entando/entando/web/userprofile/UserProfileControllerIntegrationTest.java @@ -563,6 +563,7 @@ void testPutMyProfileRegexAccept() throws Exception { if (null != this.userProfileManager.getEntityPrototype("RX2")) { ((IEntityTypesConfigurer) this.userProfileManager).removeEntityPrototype("RX2"); } + Assertions.assertNull(this.userProfileManager.getEntityPrototype("RX2")); } } @@ -596,6 +597,7 @@ void testPutMyProfileRegexReject() throws Exception { if (null != this.userProfileManager.getEntityPrototype("RX2")) { ((IEntityTypesConfigurer) this.userProfileManager).removeEntityPrototype("RX2"); } + Assertions.assertNull(this.userProfileManager.getEntityPrototype("RX2")); } }