From 6e0ea0b4d7dd3da3bf12d791a71da9ea02e3acaa Mon Sep 17 00:00:00 2001 From: oussamasic Date: Mon, 3 Apr 2023 12:01:28 +0200 Subject: [PATCH] [VAS] 11330 : add sanity on html injection --- .../ArchivesSearchExternalControllerTest.java | 14 ++-- ...jectArchiveUnitExternalControllerTest.java | 10 +-- .../rest/TenantExternalControllerTest.java | 32 +++++++- .../common/security/SafeFileChecker.java | 6 +- .../common/security/SanityChecker.java | 53 ++++--------- .../commons/security/SafeFileCheckerTest.java | 8 +- .../commons/security/SanityCheckerTest.java | 77 ++++++++++++++++--- .../resources/{bad_json => bad_json.json} | 0 ...good_json_sanity => good_json_sanity.json} | 3 +- .../resources/object_with_correct_values.json | 12 +++ .../test/resources/object_with_html_tag.json | 12 +++ .../test/resources/object_with_xml_tag.json | 13 ++++ .../identity/src/app/user/user.service.ts | 23 +++--- .../identity/rest/UserControllerTest.java | 9 +-- 14 files changed, 182 insertions(+), 90 deletions(-) rename commons/commons-security/src/test/resources/{bad_json => bad_json.json} (100%) rename commons/commons-security/src/test/resources/{good_json_sanity => good_json_sanity.json} (80%) create mode 100644 commons/commons-security/src/test/resources/object_with_correct_values.json create mode 100644 commons/commons-security/src/test/resources/object_with_html_tag.json create mode 100644 commons/commons-security/src/test/resources/object_with_xml_tag.json diff --git a/api/api-archive-search/archive-search-external/src/test/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalControllerTest.java b/api/api-archive-search/archive-search-external/src/test/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalControllerTest.java index 3316193d08e..6f56d5682da 100644 --- a/api/api-archive-search/archive-search-external/src/test/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalControllerTest.java +++ b/api/api-archive-search/archive-search-external/src/test/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalControllerTest.java @@ -31,7 +31,6 @@ import fr.gouv.vitam.common.exception.InvalidParseOperationException; import fr.gouv.vitam.common.model.export.transfer.TransferRequestParameters; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; -import fr.gouv.vitamui.commons.api.dtos.OntologyDto; import fr.gouv.vitamui.archives.search.common.dto.RuleSearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.TransferRequestDto; import fr.gouv.vitamui.archives.search.common.rest.RestApi; @@ -40,9 +39,9 @@ import fr.gouv.vitamui.commons.api.domain.IdDto; import fr.gouv.vitamui.commons.api.domain.ServicesData; import fr.gouv.vitamui.commons.api.dtos.CriteriaValue; +import fr.gouv.vitamui.commons.api.dtos.OntologyDto; import fr.gouv.vitamui.commons.api.dtos.SearchCriteriaDto; import fr.gouv.vitamui.commons.api.dtos.SearchCriteriaEltDto; -import fr.gouv.vitamui.commons.api.exception.InvalidSanitizeCriteriaException; import fr.gouv.vitamui.commons.api.exception.PreconditionFailedException; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; @@ -76,7 +75,7 @@ @ExtendWith(MockitoExtension.class) @WebMvcTest(controllers = {ArchivesSearchExternalController.class}) -public class ArchivesSearchExternalControllerTest extends ApiArchiveSearchExternalControllerTest { +class ArchivesSearchExternalControllerTest extends ApiArchiveSearchExternalControllerTest { private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(ArchivesSearchExternalControllerTest.class); @@ -143,7 +142,7 @@ protected String getRessourcePrefix() { @Test - void when_searchArchiveUnitsByCriteria_Srvc_ok_should_return_ok() throws InvalidParseOperationException, + void test_searchArchiveUnitsByCriteria_with_ok_criteria_should_return_ok() throws InvalidParseOperationException, PreconditionFailedException { SearchCriteriaDto query = new SearchCriteriaDto(); @@ -156,7 +155,7 @@ void when_searchArchiveUnitsByCriteria_Srvc_ok_should_return_ok() throws Invalid } @Test - void when_searchArchiveUnitsByCriteria_Srvc_ok_should_return_ko() { + void test_searchArchiveUnitsByCriteria_with_invalid_criteria_should_return_ko() { SearchCriteriaDto query = new SearchCriteriaDto(); SearchCriteriaEltDto nodeCriteria = new SearchCriteriaEltDto(); @@ -171,7 +170,8 @@ void when_searchArchiveUnitsByCriteria_Srvc_ok_should_return_ko() { .thenReturn(expectedResponse); assertThatCode(() -> archivesSearchExternalController.searchArchiveUnitsByCriteria(query)) - .isInstanceOf(InvalidSanitizeCriteriaException.class); + .isInstanceOf(PreconditionFailedException.class) + .hasMessage("The object is not valid "); } @Test @@ -191,7 +191,7 @@ void testSearchFilingHoldingSchemeResultsThanReturnVitamUISearchResponseDto() { @Test - void when_exportCsvArchiveUnitsByCriteria_Srvc_ok_should_return_ok() + void test_exportCsvArchiveUnitsByCriteria_with_valid_criteria_should_return_ok() throws InvalidParseOperationException, PreconditionFailedException, IOException { // Given SearchCriteriaDto query = new SearchCriteriaDto(); diff --git a/api/api-collect/collect-external/src/test/java/fr/gouv/vitamui/collect/external/server/rest/ProjectArchiveUnitExternalControllerTest.java b/api/api-collect/collect-external/src/test/java/fr/gouv/vitamui/collect/external/server/rest/ProjectArchiveUnitExternalControllerTest.java index 37c79061eab..eeea0083b75 100644 --- a/api/api-collect/collect-external/src/test/java/fr/gouv/vitamui/collect/external/server/rest/ProjectArchiveUnitExternalControllerTest.java +++ b/api/api-collect/collect-external/src/test/java/fr/gouv/vitamui/collect/external/server/rest/ProjectArchiveUnitExternalControllerTest.java @@ -38,7 +38,6 @@ import fr.gouv.vitamui.commons.api.dtos.OntologyDto; import fr.gouv.vitamui.commons.api.dtos.SearchCriteriaDto; import fr.gouv.vitamui.commons.api.dtos.SearchCriteriaEltDto; -import fr.gouv.vitamui.commons.api.exception.InvalidSanitizeCriteriaException; import fr.gouv.vitamui.commons.api.exception.PreconditionFailedException; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; @@ -61,7 +60,7 @@ @ExtendWith(MockitoExtension.class) @WebMvcTest(controllers = {TransactionArchiveUnitExternalController.class}) -public class ProjectArchiveUnitExternalControllerTest extends ApiCollectExternalControllerTest { +class ProjectArchiveUnitExternalControllerTest extends ApiCollectExternalControllerTest { private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(ProjectArchiveUnitExternalControllerTest.class); @@ -109,7 +108,7 @@ protected String getRessourcePrefix() { } @Test - void when_searchCollectUnitsByCriteria_Service_ko_should_return_ko() { + void test_searchCollectUnitsByCriteria_with_invalid_criteria_should_return_ko() { SearchCriteriaDto query = new SearchCriteriaDto(); SearchCriteriaEltDto nodeCriteria = new SearchCriteriaEltDto(); @@ -124,11 +123,12 @@ void when_searchCollectUnitsByCriteria_Service_ko_should_return_ko() { .thenReturn(expectedResponse); assertThatCode(() -> transactionArchiveUnitExternalController.searchArchiveUnits("projectId", query)) - .isInstanceOf(InvalidSanitizeCriteriaException.class); + .isInstanceOf(PreconditionFailedException.class) + .hasMessage("The object is not valid "); } @Test - void when_searchArchiveUnitsByCriteria_Srvc_ok_should_return_ok() throws InvalidParseOperationException, + void test_searchArchiveUnitsByCriteria_with_valid_criteria_should_return_ok() throws InvalidParseOperationException, PreconditionFailedException { SearchCriteriaDto query = new SearchCriteriaDto(); diff --git a/api/api-iam/iam-external/src/test/java/fr/gouv/vitamui/iam/external/server/rest/TenantExternalControllerTest.java b/api/api-iam/iam-external/src/test/java/fr/gouv/vitamui/iam/external/server/rest/TenantExternalControllerTest.java index 285f13d3db8..c9cf4e34cb8 100644 --- a/api/api-iam/iam-external/src/test/java/fr/gouv/vitamui/iam/external/server/rest/TenantExternalControllerTest.java +++ b/api/api-iam/iam-external/src/test/java/fr/gouv/vitamui/iam/external/server/rest/TenantExternalControllerTest.java @@ -1,3 +1,33 @@ +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2022) + * + * contact.vitam@culture.gouv.fr + * + * This software is a computer program whose purpose is to implement a digital archiving back-office system managing + * high volumetry securely and efficiently. + * + * This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free + * software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as + * circulated by CEA, CNRS and INRIA at the following URL "https://cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, + * users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the + * successive licensors have only limited liability. + * + * In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or + * developing or reproducing the software by the user in light of its specific status of free software, that may mean + * that it is complicated to manipulate, and that also therefore means that it is reserved for developers and + * experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the + * software's suitability as regards their requirements in conditions enabling the security of their systems and/or data + * to be ensured and, more generally, to use and operate it in the same conditions as regards security. + * + * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you + * accept its terms. + * + * + */ + + package fr.gouv.vitamui.iam.external.server.rest; import com.google.common.collect.ImmutableMap; @@ -63,7 +93,7 @@ public void testCheckExistByName() { public void testCheckExistByBadCriteriaScriptThenReturnBadRequest() { Mockito.when(tenantExternalService.checkExists(any(String.class))).thenReturn(true); final QueryDto criteria = QueryDto.criteria().addCriterion("name", "tenantName", CriterionOperator.EQUALS); - super.performHead(CommonConstants.PATH_CHECK, ImmutableMap.of("criteria", criteria.toJson()), status().isBadRequest()); + super.performHead(CommonConstants.PATH_CHECK, ImmutableMap.of("criteria", criteria.toJson()), status().isPreconditionFailed()); } @Test diff --git a/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SafeFileChecker.java b/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SafeFileChecker.java index 98c182607c6..56c967c50ea 100644 --- a/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SafeFileChecker.java +++ b/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SafeFileChecker.java @@ -77,7 +77,7 @@ public static void checkSafeFilePath(String path) { * using File.separator FileSystem String * @throws IOException thrown when any check fails with UnChecked or Runtime exception */ - public static void checkSafeFilePath(String rootPath, String... subPaths) { + public static void checkSafeFilePath(String rootPath, String... subPaths) throws InvalidFileSanitizeException { try { checkNullParameter(rootPath); String finalPath = rootPath; @@ -86,7 +86,7 @@ public static void checkSafeFilePath(String rootPath, String... subPaths) { } checkSafeFilePath(finalPath); } catch (Exception e) { - throw e; + throw new InvalidFileSanitizeException(e.getMessage()); } } @@ -145,7 +145,7 @@ private static void doFilenameCheck(String pathName) { if(!pathName.matches(FILENAME_PATTERN)) { LOGGER.error("Invalid pathName {} ", pathName); throw new InvalidFileSanitizeException(String - .format("Invalid filename (%s) (has unauthorized characters in part %s", pathName)); + .format("Invalid filename (%s) : has unauthorized characters", pathName)); } } diff --git a/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java b/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java index 22a4b4720a9..50d144709ab 100644 --- a/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java +++ b/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java @@ -53,8 +53,6 @@ */ public class SanityChecker { - private static final String INVALID_IDENTIFIER_SANITIZE = "Sanitizing failed; Invalid input identifier : "; - private static final String INVALID_HEADER_SANITIZE = "Sanitizing failed; Invalid request header : "; private static final String INVALID_CRITERIA = "Criteria failed when sanitizing, it may contains insecure data : "; private static final String JSON_IS_NOT_VALID_FROM_SANITIZE_CHECK = "Json is not valid from Sanitize check"; private static final int DEFAULT_LIMIT_PARAMETER_SIZE = 5000; @@ -63,11 +61,7 @@ public class SanityChecker { private static final long DEFAULT_LIMIT_FILE_SIZE = 8000000000L; public static final String HTTP_PARAMETER_VALUE = "HTTPParameterValue"; - private static final String HTTP_PARAMETER_NAME = "HTTPParameterName"; - private static final String HTTP_HEADER_NAME = "HTTPHeaderName"; - private static final String HTTP_HEADER_VALUE = "HTTPHeaderValue"; - // TODO : verify the difference between this defined limit and the previous ones private static final int REQUEST_LIMIT = 10000; /** @@ -108,14 +102,10 @@ public static boolean isValidParameter(String value) { return !isStringInfected(value, HTTP_PARAMETER_VALUE) || PARAMETERS_KEYS_OF_DSL_QUERY_WHITELIST.contains(value); } - public static boolean isValidParameterName(String value) { - return !isStringInfected(value, HTTP_PARAMETER_NAME); - } - /** * Sanitize the fileName * - * @param fileName + * @param fileName : name of a file * @return true/false */ public static void isValidFileName(String fileName) throws PreconditionFailedException { @@ -170,7 +160,7 @@ public static void checkJsonAll(String json) throws InvalidParseOperationExcepti * checkSecureParameter : Check sanity of String: no javascript/xml tag, neither html tag * check if the string is not infected or contains illegal characters * - * @param params + * @param params : sequence of strings de check * @throws PreconditionFailedException * @throws InvalidParseOperationException */ @@ -227,11 +217,11 @@ private static void checkSecureParam(String param) try { checkSanityTags(param, getLimitParamSize()); checkHtmlPattern(param); - } catch (InvalidParseOperationException exception) { + } catch (InvalidParseOperationException | PreconditionFailedException exception) { throw new InvalidParseOperationException("Error with the parameter ", exception); } } else { - throw new PreconditionFailedException("the parameter is not valid"); + throw new PreconditionFailedException("the parameter " + param + " is not valid"); } } @@ -299,11 +289,11 @@ private static void checkSanityTags(String dataLine, String invalidTag) * checkHtmlPattern : check against Html Pattern within value (not allowed) * * @param param - * @throws InvalidParseOperationException when Sanity Check is in error + * @throws PreconditionFailedException when Sanity Check is in error */ - private static void checkHtmlPattern(String param) throws InvalidParseOperationException { + public static void checkHtmlPattern(String param) throws PreconditionFailedException { if (StringUtils.HTML_PATTERN.matcher(param).find()) { - throw new InvalidParseOperationException("HTML PATTERN found"); + throw new PreconditionFailedException("the parameter : " + param + " is not valid"); } } @@ -334,7 +324,7 @@ public static void checkJsonSanity(JsonNode json) throws InvalidParseOperationEx while (fields.hasNext()) { final Map.Entry entry = fields.next(); final String key = entry.getKey(); - if (isValidParameterName(key) || PARAMETERS_KEYS_OF_DSL_QUERY_WHITELIST.contains(key)) { + if (isValidParameter(key)) { checkSanityTags(key, getLimitFieldSize()); } else { throw new PreconditionFailedException("Invalid JSON key: " + key); @@ -352,7 +342,11 @@ public static void checkJsonSanity(JsonNode json) throws InvalidParseOperationEx } } else if (!value.isValueNode()) { checkJsonSanity(value); - } else { + } else if(value.isTextual()) { + checkHtmlPattern(value.textValue()); + checkSanityTags(value.textValue(), getLimitParamSize()); + } + else { validateJSONField(value); } } @@ -378,20 +372,6 @@ private static void checkJsonFileSize(String json) throws InvalidParseOperationE } } - /* - * @return the limit File Size (XML or JSON) - */ - public static long getLimitFileSize() { - return limitFileSize; - } - - /** - * @param limitFileSize the limit File Size to set (XML or JSON) - */ - public static void setLimitFileSize(long limitFileSize) { - SanityChecker.limitFileSize = limitFileSize; - } - /** * @return the limit Size of a Json */ @@ -413,13 +393,6 @@ public static int getLimitFieldSize() { return limitFieldSize; } - /** - * @param limitFieldSize the limit Size of a Field in a Json to set - */ - public static void setLimitFieldSize(int limitFieldSize) { - SanityChecker.limitFieldSize = limitFieldSize; - } - /** * @return the limit Size of a parameter */ diff --git a/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SafeFileCheckerTest.java b/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SafeFileCheckerTest.java index 2250bea5e8e..823cb24b000 100644 --- a/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SafeFileCheckerTest.java +++ b/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SafeFileCheckerTest.java @@ -47,12 +47,12 @@ public class SafeFileCheckerTest { private final String VALID_ROOT_PATH = "mydirectory"; private final String INVALID_ROOT_PATH = "my|filena?me?query=danger.json"; - private final String VALID_SUBPATH = "good_json_sanity"; + private final String VALID_SUBPATH = "good_json_sanity.json"; private final String INVALID_PATH = "file#..$$/text"; - private static List validPaths = new ArrayList<>(); - private static List invalidPaths = new ArrayList<>(); - private static List validFilenames = new ArrayList<>(); + private static final List validPaths = new ArrayList<>(); + private static final List invalidPaths = new ArrayList<>(); + private static final List validFilenames = new ArrayList<>(); @BeforeClass public static void setUpBeforeClass() { diff --git a/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java b/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java index ae3940bb064..3a6c6623a9e 100644 --- a/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java +++ b/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java @@ -45,14 +45,12 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; public class SanityCheckerTest { - private final String TEST_BAD_JSON = "bad_json"; - private final String TEST_GOOD_JSON = "good_json_sanity"; - private final String TEST_GOOD_JSON_CRITERIA = "good_criteria.json"; + private final String TEST_BAD_JSON = "bad_json.json"; @Before public void setUp() { @@ -60,12 +58,12 @@ public void setUp() { @Test public void givenJsonWhenValueIsTooBigORContainXMLTag() - throws InvalidParseOperationException, IOException { + throws InvalidParseOperationException, PreconditionFailedException, IOException { final File file = PropertiesUtils.findFile(TEST_BAD_JSON); final JsonNode json = JsonHandler.getFromFile(file); Assertions.assertThat(json).isNotNull(); assertThatCode(() -> SanityChecker.checkJsonSanity(json)). - isInstanceOf(InvalidParseOperationException.class); + isInstanceOf(PreconditionFailedException.class); } @Test @@ -103,14 +101,14 @@ public void givenJsonStringWhenValueIsTooBigORContainXMLTagUsingAll() public void givenJsonWhenGoodSanityThenReturnTrue() throws FileNotFoundException, InvalidParseOperationException { final long limit = SanityChecker.getLimitJsonSize(); + final String TEST_GOOD_JSON = "good_json_sanity.json"; try { SanityChecker.setLimitJsonSize(100); final File file = PropertiesUtils.findFile(TEST_GOOD_JSON); final JsonNode json = JsonHandler.getFromFile(file); try { SanityChecker.checkJsonAll(json); - fail("Should failed with an exception"); - } catch (final InvalidParseOperationException e) { + } catch (final InvalidParseOperationException ignored) { } SanityChecker.setLimitJsonSize(10000); SanityChecker.checkJsonAll(json); @@ -129,6 +127,7 @@ public void givenStringNotValidParam() throws InvalidParseOperationException, Pr @Test public void givenCriteriaWhenGoodSanityThenReturnTrue() throws FileNotFoundException, InvalidParseOperationException, PreconditionFailedException { + final String TEST_GOOD_JSON_CRITERIA = "good_criteria.json"; final File file = PropertiesUtils.findFile(TEST_GOOD_JSON_CRITERIA); final JsonNode json = JsonHandler.getFromFile(file); assertThatCode(() -> @@ -163,7 +162,7 @@ public void testCheckSecureParameterWithXmlString() @Test public void testCheckSecureParameterWithBadStringAndThrowException() { assertThatCode(() -> SanityChecker.checkSecureParameter("§§§§§***ù^65")). - hasMessage("the parameter is not valid"); + hasMessage("the parameter §§§§§***ù^65 is not valid"); } @Test(expected = PreconditionFailedException.class) @@ -266,7 +265,7 @@ public void testCheckSecureParameterWithIdAsParameter() { @Test public void isValidParameterName_tests() { - assertTrue(SanityChecker.isValidParameterName("vitamui-primary")); + assertTrue(SanityChecker.isValidParameter("vitamui-primary")); } @Test @@ -313,4 +312,62 @@ public void sanitizeJson_should_not_fail_with_ingest_search_keys() doesNotThrowAnyException(); } + @Test + public void test_isValidParameterName_with_html_code() { + assertFalse(SanityChecker.isValidParameter("aa")); + } + + @Test + public void test_sanitizeCriteria_with_object_contains_xml_tag() + throws InvalidParseOperationException, PreconditionFailedException, IOException { + final String OBJECT_XML_TAG = "object_with_xml_tag.json"; + final File file = PropertiesUtils.findFile(OBJECT_XML_TAG); + final JsonNode json = JsonHandler.getFromFile(file); + Assertions.assertThat(json).isNotNull(); + assertThatCode(() -> SanityChecker.sanitizeCriteria(json)). + isInstanceOf(PreconditionFailedException.class); + } + + @Test + public void test_checkHtmlPattern_with_html_text() { + assertThatCode(() -> SanityChecker.checkHtmlPattern("

bla bla bla

")) + .isInstanceOf(PreconditionFailedException.class) + .hasMessageContaining("the parameter :"); + } + + @Test + public void test_sanitizeCriteria_with_object_contains_html_tag() + throws InvalidParseOperationException, PreconditionFailedException, IOException { + final String OBJECT_HTML_TAG = "object_with_html_tag.json"; + final File file = PropertiesUtils.findFile(OBJECT_HTML_TAG); + final JsonNode json = JsonHandler.getFromFile(file); + Assertions.assertThat(json).isNotNull(); + assertThatCode(() -> SanityChecker.sanitizeCriteria(json)). + isInstanceOf(PreconditionFailedException.class); + } + + @Test + public void test_checkHtmlPattern_with_correct_text() { + assertThatCode(() -> SanityChecker.checkHtmlPattern("test test good values")) + .doesNotThrowAnyException(); + } + + @Test + public void test_sanitizeCriteria_with_object_contains_correct_values() + throws InvalidParseOperationException, PreconditionFailedException, IOException { + final String OBJECT_WITH_CORRECT_VALUES = "object_with_correct_values.json"; + final File file = PropertiesUtils.findFile(OBJECT_WITH_CORRECT_VALUES); + final JsonNode json = JsonHandler.getFromFile(file); + Assertions.assertThat(json).isNotNull(); + assertThatCode(() -> SanityChecker.sanitizeCriteria(json)). + doesNotThrowAnyException(); + } + + @Test + public void test_checkJsonAll_with_null_object() { + assertThatCode(() -> SanityChecker.checkJsonAll((JsonNode) null)). + isInstanceOf(InvalidParseOperationException.class) + .hasMessage("Json is not valid from Sanitize check"); + } + } diff --git a/commons/commons-security/src/test/resources/bad_json b/commons/commons-security/src/test/resources/bad_json.json similarity index 100% rename from commons/commons-security/src/test/resources/bad_json rename to commons/commons-security/src/test/resources/bad_json.json diff --git a/commons/commons-security/src/test/resources/good_json_sanity b/commons/commons-security/src/test/resources/good_json_sanity.json similarity index 80% rename from commons/commons-security/src/test/resources/good_json_sanity rename to commons/commons-security/src/test/resources/good_json_sanity.json index 287a9f13398..6071e408f8a 100644 --- a/commons/commons-security/src/test/resources/good_json_sanity +++ b/commons/commons-security/src/test/resources/good_json_sanity.json @@ -3,12 +3,11 @@ "firstname" : "nabil", "surname" : "CHEN" }, - "id": "$id_async$", "type": "vitamui", "state": "done", "task_status": "commit", "start_date": "2020-08-11T03:06:17.396Z", "end_date": "2020-08-11T03:06:17.396Z", "expiration_date": "2020-08-11T03:06:17.396Z", - "result_link": "https://xxx/v1/vitamui/456" + "result_link": "link link" } diff --git a/commons/commons-security/src/test/resources/object_with_correct_values.json b/commons/commons-security/src/test/resources/object_with_correct_values.json new file mode 100644 index 00000000000..c6456d7d70a --- /dev/null +++ b/commons/commons-security/src/test/resources/object_with_correct_values.json @@ -0,0 +1,12 @@ +{ + "firstName" : "John", + "lastName" : "Doe", + "id": "PersonId", + "type": "vitamui", + "state": "done", + "task_status": "commit", + "start_date": "2020-08-11T03:06:17.396Z", + "end_date": "2020-08-11T03:06:17.396Z", + "expiration_date": "2020-08-11T03:06:17.396Z", + "result_link": "link to link" +} diff --git a/commons/commons-security/src/test/resources/object_with_html_tag.json b/commons/commons-security/src/test/resources/object_with_html_tag.json new file mode 100644 index 00000000000..3208732e737 --- /dev/null +++ b/commons/commons-security/src/test/resources/object_with_html_tag.json @@ -0,0 +1,12 @@ +{ + "firstName" : "

bla bla bla

", + "lastName" : "

bla bla bla

", + "id": "PersonId", + "type": "vitamui", + "state": "done", + "task_status": "commit", + "start_date": "2020-08-11T03:06:17.396Z", + "end_date": "2020-08-11T03:06:17.396Z", + "expiration_date": "2020-08-11T03:06:17.396Z", + "result_link": "link to link" +} diff --git a/commons/commons-security/src/test/resources/object_with_xml_tag.json b/commons/commons-security/src/test/resources/object_with_xml_tag.json new file mode 100644 index 00000000000..ebb72f99efb --- /dev/null +++ b/commons/commons-security/src/test/resources/object_with_xml_tag.json @@ -0,0 +1,13 @@ +{ + "firstName" : "John", + "lastName" : "Doe", + "id": "PersonId", + "type": "vitamui", + "state": "done", + "task_status": "commit", + "xml_tag" : "ToveJaniReminderDon't forget me this weekend!", + "start_date": "2020-08-11T03:06:17.396Z", + "end_date": "2020-08-11T03:06:17.396Z", + "expiration_date": "2020-08-11T03:06:17.396Z", + "result_link": "link to link" +} diff --git a/ui/ui-frontend/projects/identity/src/app/user/user.service.ts b/ui/ui-frontend/projects/identity/src/app/user/user.service.ts index cdf28612206..cf2f4f7320f 100644 --- a/ui/ui-frontend/projects/identity/src/app/user/user.service.ts +++ b/ui/ui-frontend/projects/identity/src/app/user/user.service.ts @@ -71,19 +71,16 @@ export class UserService extends SearchService { user.email = user.email; return this.userApi.create(user).pipe( - tap( - (response: User) => { - this.snackBarService.open({ - message: 'SHARED.SNACKBAR.USER_CREATE', - icon: 'vitamui-icon-key', - translateParams: { - param1: response.firstname, - param2: response.lastname, - }, - }); - }, - (error) => this.snackBarService.open({ message: error.error.message, translate: false }) - ) + tap((response: User) => { + this.snackBarService.open({ + message: 'SHARED.SNACKBAR.USER_CREATE', + icon: 'vitamui-icon-key', + translateParams: { + param1: response.firstname, + param2: response.lastname, + }, + }); + }) ); } diff --git a/ui/ui-identity/src/test/java/fr/gouv/vitamui/identity/rest/UserControllerTest.java b/ui/ui-identity/src/test/java/fr/gouv/vitamui/identity/rest/UserControllerTest.java index 5bcc47ebfff..c8288d3a7d9 100644 --- a/ui/ui-identity/src/test/java/fr/gouv/vitamui/identity/rest/UserControllerTest.java +++ b/ui/ui-identity/src/test/java/fr/gouv/vitamui/identity/rest/UserControllerTest.java @@ -28,8 +28,6 @@ public class UserControllerTest extends UiIdentityRestControllerTest { @Value("${ui-identity.prefix}") protected String apiUrl; - private final String PREFIX = "/users"; - @MockBean private UserService service; @@ -90,13 +88,13 @@ public void testCheckExistByEmailNotFound() { } @Test - public void testCheckExistByTotoWithBadCriteraiThenReturnBadRequest() { - LOGGER.debug("testCheckExistByTotoWithBadCriteraiThenReturnBadRequest"); + public void testCheckExistByTotoWithBadCriteraiThenReturnPreconditionFailedException() { + LOGGER.debug("testCheckExistByTotoWithBadCriteraiThenReturnPreconditionFailedException"); Mockito.when(service.checkExist(any(), any())).thenReturn(false); final QueryDto criteria = QueryDto.criteria().addCriterion("toto", "titi", CriterionOperator.EQUALS); super.performHead(CommonConstants.PATH_CHECK, ImmutableMap.of("criteria", criteria.toJson()), - status().isBadRequest()); + status().isPreconditionFailed()); } @Test @@ -113,6 +111,7 @@ public void logbook_when_call_return_ok() { @Override protected String getRessourcePrefix() { + final String PREFIX = "/users"; return "/" + apiUrl + PREFIX; }