From d7565437459549a530c32cc6d4f8597d3ce48807 Mon Sep 17 00:00:00 2001 From: Eduard Tihomiorv Date: Tue, 28 Oct 2025 10:42:18 +0300 Subject: [PATCH] SUPPORT-9509: Fix --- .../EmployeeInfoFileUploadService.java | 41 ++++++++++++++----- .../security/esia/model/MchdInfoModel.java | 23 +++++++++++ .../esia/service/EsiaAuthService.java | 3 +- .../common_errors_messages.properties | 5 ++- .../common_errors_messages_ru_RU.properties | 4 +- 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/backend/src/main/java/ervu/service/fileupload/EmployeeInfoFileUploadService.java b/backend/src/main/java/ervu/service/fileupload/EmployeeInfoFileUploadService.java index ec294912..c082c050 100644 --- a/backend/src/main/java/ervu/service/fileupload/EmployeeInfoFileUploadService.java +++ b/backend/src/main/java/ervu/service/fileupload/EmployeeInfoFileUploadService.java @@ -3,9 +3,12 @@ package ervu.service.fileupload; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.sql.Timestamp; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.UUID; @@ -53,7 +56,11 @@ import ru.micord.ervu.exception.JsonParsingException; import ru.micord.ervu.journal.SenderInfo; import ru.micord.ervu.kafka.service.ReplyingKafkaService; import ru.micord.ervu.security.esia.config.EsiaConfig; -import ru.micord.ervu.security.esia.model.*; +import ru.micord.ervu.security.esia.model.EmployeeModel; +import ru.micord.ervu.security.esia.model.MchdInfoModel; +import ru.micord.ervu.security.esia.model.OrganizationModel; +import ru.micord.ervu.security.esia.model.PersonModel; +import ru.micord.ervu.security.esia.model.VerifyDocumentSignResponse; import ru.micord.ervu.security.esia.service.MchdService; import ru.micord.ervu.security.esia.service.UlDataService; import ru.micord.ervu.security.esia.EsiaAuthInfoStore; @@ -336,13 +343,12 @@ public class EmployeeInfoFileUploadService { String chiefMiddleName = chiefModel.getPerson().getMiddleName(); String chiefLastName = chiefModel.getPerson().getLastName(); String chiefFirstName = chiefModel.getPerson().getFirstName(); + boolean isSignerLastName = signerInfoMap.get("SN").equalsIgnoreCase(chiefLastName); + boolean isSignerFirstNameAndMiddleName = signerInfoMap.get("G") + .equalsIgnoreCase(chiefFirstName + " " + chiefMiddleName); + boolean isSignerOgrn = signerInfoMap.get("ОГРН").equalsIgnoreCase(ogrn); - boolean isSignerValid = signerInfoMap.get("SN").equalsIgnoreCase(chiefLastName) && - signerInfoMap.get("G") - .equalsIgnoreCase(chiefFirstName + " " + chiefMiddleName) && - signerInfoMap.get("O").equalsIgnoreCase(uploadOrgInfo.getOrgName()); - - if (isSignerValid) { + if (isSignerLastName && isSignerFirstNameAndMiddleName && isSignerOgrn) { FileStatusResponse fileStatusResponse = new FileStatusResponse(uploadOrgInfo, new FileInfo[] {fileInfo, signFileInfo}, fileInfo.getFileStatus() ); @@ -366,7 +372,18 @@ public class EmployeeInfoFileUploadService { if (mchdFile == null) { handleMchdValidationError(uploadOrgInfo, fileInfo, signFileInfo, null, ervuId, response ); - throw new LocalizedException("mchd_null", MESSAGE_SOURCE); + List falseResults = new ArrayList<>(); + if (!isSignerLastName) { + falseResults.add("фамилия"); + } + if (!isSignerFirstNameAndMiddleName) { + falseResults.add("имя или отчество"); + } + if (!isSignerOgrn) { + falseResults.add("организация"); + } + String result = String.join(", ", falseResults); + throw new LocalizedException("mchd_null", MESSAGE_SOURCE, result); } FileStatusResponse fileStatusResponse = new FileStatusResponse(uploadOrgInfo, new FileInfo[] {fileInfo, signFileInfo, mchdFileInfo}, fileInfo.getFileStatus() @@ -549,13 +566,15 @@ public class EmployeeInfoFileUploadService { throw new LocalizedException("mchd_cant_parse", MESSAGE_SOURCE); } MchdInfoModel mchdInfoModel = mchdService.getMchdInfoModel(mchdGuid); - if (!mchdInfoModel.getStatus().equals("A")) { + LocalDate now = LocalDate.now(); + if (!mchdInfoModel.getStatus().equals("A") || now.isAfter(mchdInfoModel.getExpiredOn()) + || mchdInfoModel.getIssuedOn().isAfter(now)) { throw new LocalizedException("mchd_expired", MESSAGE_SOURCE); } boolean validAgent = mchdInfoModel.getAgents() .getElements() .stream() - .anyMatch(agent1 -> agent1.getPerson().getSnils().equals(snils)); + .anyMatch(agent1 -> agent1.getPerson().getSnils().replaceAll("[\\s-]", "").equals(snils)); if (!validAgent) { throw new LocalizedException("mchd_validate_agent", MESSAGE_SOURCE); } @@ -669,4 +688,4 @@ public class EmployeeInfoFileUploadService { auditService.processUploadEvent(uploadOrgInfo, new FileInfo[] {fileInfo, signFileInfo}, packInfo); clearS3(response); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/ru/micord/ervu/security/esia/model/MchdInfoModel.java b/backend/src/main/java/ru/micord/ervu/security/esia/model/MchdInfoModel.java index ab63ee75..b4331b22 100644 --- a/backend/src/main/java/ru/micord/ervu/security/esia/model/MchdInfoModel.java +++ b/backend/src/main/java/ru/micord/ervu/security/esia/model/MchdInfoModel.java @@ -1,9 +1,12 @@ package ru.micord.ervu.security.esia.model; import java.io.Serializable; +import java.time.LocalDate; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; /** @@ -17,6 +20,10 @@ public class MchdInfoModel implements Serializable { private String parentGuid; private Member principals; private Member agents; + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate issuedOn; + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate expiredOn; public String getGuid() { return guid; @@ -58,6 +65,22 @@ public class MchdInfoModel implements Serializable { this.agents = agents; } + public LocalDate getIssuedOn() { + return issuedOn; + } + + public void setIssuedOn(LocalDate issuedOn) { + this.issuedOn = issuedOn; + } + + public LocalDate getExpiredOn() { + return expiredOn; + } + + public void setExpiredOn(LocalDate expiredOn) { + this.expiredOn = expiredOn; + } + @JsonIgnoreProperties(ignoreUnknown = true) public static class Member implements Serializable { private List elements; diff --git a/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java b/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java index 564c9058..d773fa49 100644 --- a/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java +++ b/backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java @@ -676,7 +676,7 @@ public class EsiaAuthService { SignResponse signResponse = signMap(parameters); String newState = signResponse.getState(); String clientSecret = signResponse.getSignature(); - String authUrl = esiaConfig.getEsiaBaseUri() + esiaConfig.getEsiaSystemTokenUrl(); + String authUrl = esiaConfig.getEsiaBaseUri() + esiaConfig.getEsiaTokenUrl(); String postBody = new FormUrlencoded() .setParameter("client_id", clientId) .setParameter("grant_type", "client_credentials") @@ -685,6 +685,7 @@ public class EsiaAuthService { .setParameter("scope", scope) .setParameter("timestamp", timestamp) .setParameter("token_type", "Bearer") + .setParameter("client_certificate_hash", esiaConfig.getClientCertHash()) .setParameter("redirect_uri", esiaConfig.getRedirectUrl()) .toFormUrlencodedString(); HttpRequest postReq = HttpRequest.newBuilder(URI.create(authUrl)) diff --git a/backend/src/main/resources/messages/common_errors_messages.properties b/backend/src/main/resources/messages/common_errors_messages.properties index 7f06599b..5213f5dc 100644 --- a/backend/src/main/resources/messages/common_errors_messages.properties +++ b/backend/src/main/resources/messages/common_errors_messages.properties @@ -7,9 +7,10 @@ cert_untrusted_root=Сертификат или цепочка сертифик cert_is_not_time_valid=Этот сертификат или один из сертификатов в цепочке сертификатов является недопустимым по времени file_sign_validate=Ошибка проверки файлов. Некорректная электронная подпись mchd_validate_agent=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Представитель не совпадает с подписантом -mchd_null=Ошибка проверки файлов. Отсутствует машиночитаемая доверенность. Подписант не является руководителем организации +mchd_null=Ошибка проверки файлов. Отсутствует машиночитаемая доверенность. Подписант не является руководителем организации. Не совпадает {0} +temp_sign_error=Ошибка проверки файлов. Подписант не является руководителем организации. Приложите подпись руководителя mchd_expired=Ошибка проверки файлов. Недействующая машиночитаемая доверенность. mchd_tree_expired=Ошибка проверки файлов. Одна из родительских доверенностей недействующая. -mchd_validate_principal=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Доверитель не совпадает с руководителем организации +mchd_validate_principal=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Доверенность выдана не той организацией, под которой была осуществлена загрузка файлов. av_file_infected=Ошибка проверки файлов. Файлы заражены вирусом mchd_cant_parse=Ошибка проверки файлов. Некорректный формат машиночитаемой доверенности diff --git a/backend/src/main/resources/messages/common_errors_messages_ru_RU.properties b/backend/src/main/resources/messages/common_errors_messages_ru_RU.properties index acca81c5..de63bcb8 100644 --- a/backend/src/main/resources/messages/common_errors_messages_ru_RU.properties +++ b/backend/src/main/resources/messages/common_errors_messages_ru_RU.properties @@ -7,9 +7,9 @@ cert_untrusted_root=Сертификат или цепочка сертифик cert_is_not_time_valid=Этот сертификат или один из сертификатов в цепочке сертификатов является недопустимым по времени file_sign_validate=Ошибка проверки файлов. Некорректная электронная подпись mchd_validate_agent=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Представитель не совпадает с подписантом -mchd_null=Ошибка проверки файлов. Отсутствует машиночитаемая доверенность. Подписант не является руководителем организации +mchd_null=Ошибка проверки файлов. Отсутствует машиночитаемая доверенность. Подписант не является руководителем организации. Не совпадает {0} mchd_expired=Ошибка проверки файлов. Недействующая машиночитаемая доверенность. mchd_tree_expired=Ошибка проверки файлов. Одна из родительских доверенностей недействующая. -mchd_validate_principal=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Доверитель не совпадает с руководителем организации +mchd_validate_principal=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Доверенность выдана не той организацией, под которой была осуществлена загрузка файлов. av_file_infected=Ошибка проверки файлов. Файлы заражены вирусом mchd_cant_parse=Ошибка проверки файлов. Некорректный формат машиночитаемой доверенности \ No newline at end of file