SUPPORT-9339: Add sign verify
This commit is contained in:
parent
af52f7df8d
commit
22ffb8a866
11 changed files with 467 additions and 556 deletions
|
|
@ -23,7 +23,7 @@ import org.springframework.kafka.core.ProducerFactory;
|
|||
* @author Alexandr Shalaginov
|
||||
*/
|
||||
@Configuration
|
||||
public class AvKafkaConfig {
|
||||
public class FileKafkaConfig {
|
||||
@Value("${kafka.hosts}")
|
||||
private String kafkaUrl;
|
||||
@Value("${kafka.auth_sec_proto}")
|
||||
|
|
@ -38,7 +38,7 @@ public class AvKafkaConfig {
|
|||
private String saslMechanism;
|
||||
|
||||
@Bean
|
||||
public ProducerFactory<String, String> avProducerFactory() {
|
||||
public ProducerFactory<String, String> fileProducerFactory() {
|
||||
return new DefaultKafkaProducerFactory<>(producerConfigs());
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ public class AvKafkaConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public ConsumerFactory<String, String> avConsumerFactory() {
|
||||
public ConsumerFactory<String, String> fileConsumerFactory() {
|
||||
return new DefaultKafkaConsumerFactory<>(consumerConfigs());
|
||||
}
|
||||
|
||||
|
|
@ -77,16 +77,16 @@ public class AvKafkaConfig {
|
|||
return props;
|
||||
}
|
||||
|
||||
@Bean("avContainerFactory")
|
||||
@Bean("fileContainerFactory")
|
||||
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
|
||||
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
|
||||
factory.setConsumerFactory(avConsumerFactory());
|
||||
factory.setConsumerFactory(fileConsumerFactory());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean("avTemplate")
|
||||
@Bean("fileTemplate")
|
||||
public KafkaTemplate<String, String> kafkaTemplate() {
|
||||
return new KafkaTemplate<>(avProducerFactory());
|
||||
return new KafkaTemplate<>(fileProducerFactory());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7,6 +7,7 @@ public enum FileStatusCode {
|
|||
FILE_UPLOADED("01"),
|
||||
FILE_INFECTED("02"),
|
||||
FILE_CLEAN("03"),
|
||||
FILE_ACCEPTED("04"),
|
||||
FILE_NOT_CHECKED("11");
|
||||
|
||||
private final String code;
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ public class FileInfo {
|
|||
private String departureDateTime;
|
||||
private String timeZone;
|
||||
private FileStatus fileStatus;
|
||||
private String type;
|
||||
|
||||
public FileInfo() {
|
||||
}
|
||||
|
||||
public FileInfo(String fileId, String fileUrl, String fileName, String filePatternCode,
|
||||
String filePatternName, String fileSize, String departureDateTime, String timeZone,
|
||||
FileStatus fileStatus) {
|
||||
FileStatus fileStatus, String type) {
|
||||
this.fileId = fileId;
|
||||
this.fileUrl = fileUrl;
|
||||
this.fileName = fileName;
|
||||
|
|
@ -31,6 +32,7 @@ public class FileInfo {
|
|||
this.departureDateTime = departureDateTime;
|
||||
this.timeZone = timeZone;
|
||||
this.fileStatus = fileStatus;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
|
|
@ -69,6 +71,14 @@ public class FileInfo {
|
|||
return fileStatus;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setFileStatus(FileStatus fileStatus) {
|
||||
this.fileStatus = fileStatus;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,12 @@ import java.time.Duration;
|
|||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.gson.Gson;
|
||||
import ervu.client.fileupload.WebDavClient;
|
||||
import ervu.model.fileupload.*;
|
||||
import org.apache.http.HttpEntity;
|
||||
|
|
@ -34,12 +37,18 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.kafka.annotation.KafkaListener;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.support.Acknowledgment;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import ru.micord.ervu.audit.service.AuditService;
|
||||
import ru.micord.ervu.exception.JsonParsingException;
|
||||
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
||||
import ru.micord.ervu.security.esia.config.EsiaConfig;
|
||||
import ru.micord.ervu.security.esia.exception.EsiaException;
|
||||
import ru.micord.ervu.security.esia.model.EmployeeModel;
|
||||
|
|
@ -53,6 +62,10 @@ import ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil;
|
|||
import ru.micord.ervu.service.InteractionService;
|
||||
import ru.micord.ervu.util.DateUtils;
|
||||
|
||||
import ru.cg.webbpm.modules.core.runtime.api.LocalizedException;
|
||||
import ru.cg.webbpm.modules.core.runtime.api.MessageBundleUtils;
|
||||
|
||||
import static ervu.enums.FileStatusCode.FILE_ACCEPTED;
|
||||
import static ervu.enums.FileStatusCode.FILE_CLEAN;
|
||||
import static ervu.enums.FileStatusCode.FILE_INFECTED;
|
||||
import static ervu.enums.FileStatusCode.FILE_NOT_CHECKED;
|
||||
|
|
@ -65,8 +78,12 @@ import static ru.micord.ervu.util.StringUtils.convertToFio;
|
|||
@Service
|
||||
public class EmployeeInfoFileUploadService {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeInfoFileUploadService.class);
|
||||
private static final String DOCUMENT = "DOCUMENT";
|
||||
private static final MessageSourceAccessor MESSAGE_SOURCE = MessageBundleUtils.createAccessor(
|
||||
"messages/common_errors_messages");
|
||||
private final WebDavClient webDavClient;
|
||||
private final EmployeeInfoKafkaMessageService employeeInfoKafkaMessageService;
|
||||
private final ReplyingKafkaService replyingKafkaService;
|
||||
private final KafkaTemplate<String, String> kafkaTemplate;
|
||||
private final InteractionService interactionService;
|
||||
private final UlDataService ulDataService;
|
||||
|
|
@ -74,31 +91,43 @@ public class EmployeeInfoFileUploadService {
|
|||
private final ObjectMapper objectMapper;
|
||||
private final EsiaConfig esiaConfig;
|
||||
|
||||
@Value("${av.kafka.message.topic.name}")
|
||||
private String kafkaTopicName;
|
||||
@Value("${kafka.clear.s3}")
|
||||
private String kafkaClearS3Topic;
|
||||
|
||||
@Value("${kafka.download.request}")
|
||||
private String kafkaDownloadRequestTopic;
|
||||
|
||||
@Value("${av.kafka.download.request}")
|
||||
private String kafkaRequestTopic;
|
||||
|
||||
@Value("${av.kafka.download.response}")
|
||||
private String kafkaResponseTopic;
|
||||
|
||||
public EmployeeInfoFileUploadService(
|
||||
WebDavClient webDavClient,
|
||||
EmployeeInfoKafkaMessageService employeeInfoKafkaMessageService,
|
||||
@Qualifier("avTemplate") KafkaTemplate<String, String> kafkaTemplate,
|
||||
ReplyingKafkaService replyingKafkaService,
|
||||
InteractionService interactionService,
|
||||
UlDataService ulDataService,
|
||||
AuditService auditService,
|
||||
ObjectMapper objectMapper,
|
||||
EsiaConfig esiaConfig) {
|
||||
EsiaConfig esiaConfig,
|
||||
@Qualifier("fileTemplate") KafkaTemplate<String, String> kafkaTemplate) {
|
||||
this.webDavClient = webDavClient;
|
||||
this.employeeInfoKafkaMessageService = employeeInfoKafkaMessageService;
|
||||
this.kafkaTemplate = kafkaTemplate;
|
||||
this.replyingKafkaService = replyingKafkaService;
|
||||
this.interactionService = interactionService;
|
||||
this.ulDataService = ulDataService;
|
||||
this.auditService = auditService;
|
||||
this.objectMapper = objectMapper;
|
||||
this.esiaConfig = esiaConfig;
|
||||
this.kafkaTemplate = kafkaTemplate;
|
||||
}
|
||||
|
||||
public boolean saveEmployeeInformationFiles(MultipartFile multipartFile,
|
||||
MultipartFile signFile, MultipartFile mchdFile, String formType,
|
||||
String offset) {
|
||||
|
||||
UserIdsPair userIdsPair = SecurityUtil.getUserIdsPair();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String departureDateTime = DateUtils.convertToString(now);
|
||||
|
|
@ -106,182 +135,245 @@ public class EmployeeInfoFileUploadService {
|
|||
if (userIdsPair == null || !isValidCsvWithSig(multipartFile, signFile)) {
|
||||
return false;
|
||||
}
|
||||
String fileId = UUID.randomUUID().toString();
|
||||
String signFileId = UUID.randomUUID().toString();
|
||||
String fileName = multipartFile.getOriginalFilename();
|
||||
long fileSize = multipartFile.getSize();
|
||||
String signFileName = signFile.getOriginalFilename();
|
||||
long signFileSize = signFile.getSize();
|
||||
EmployeeInfoFileFormType employeeInfoFileFormType = EmployeeInfoFileFormType.valueOf(
|
||||
formType);
|
||||
String esiaUserId = userIdsPair.getEsiaUserId();
|
||||
String ervuId = userIdsPair.getErvuId();
|
||||
String accessToken = EsiaAuthInfoStore.getAccessToken(esiaUserId);
|
||||
|
||||
EmployeeModel employeeModel = ulDataService.getEmployeeModel(accessToken);
|
||||
PersonModel personModel = employeeModel.getPerson();
|
||||
EmployeeModel chiefModel = ulDataService.getChiefEmployeeModel(accessToken);
|
||||
VerifyDocumentSignResponse verifyDocumentSignResponse = validateSign(multipartFile, signFile);
|
||||
FileStatus fileStatus = new FileStatus();
|
||||
|
||||
String fio = convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
|
||||
personModel.getLastName()
|
||||
);
|
||||
|
||||
UploadOrgInfo uploadOrgInfo = employeeInfoKafkaMessageService.getOrgInfo(accessToken, ervuId,
|
||||
esiaUserId, personModel
|
||||
);
|
||||
FileInfo fileInfo = employeeInfoKafkaMessageService.getFileInfo(fileId, null, fileName,
|
||||
employeeInfoFileFormType, departureDateTime, offset, null, fileSize
|
||||
|
||||
EmployeeInfoFileFormType employeeInfoFileFormType = EmployeeInfoFileFormType.valueOf(formType);
|
||||
|
||||
FileInfo fileInfo = createFileInfo(multipartFile, employeeInfoFileFormType,
|
||||
departureDateTime, offset, DOCUMENT
|
||||
);
|
||||
FileInfo signFileInfo = employeeInfoKafkaMessageService.getFileInfo(signFileId, null,
|
||||
signFileName, employeeInfoFileFormType, departureDateTime, offset, null, signFileSize
|
||||
FileInfo signFileInfo = createFileInfo(signFile, employeeInfoFileFormType,
|
||||
departureDateTime, offset, "SIGNATURE"
|
||||
);
|
||||
if (verifyDocumentSignResponse.getSignVerifyResult() != null) {
|
||||
fileStatus.setStatus("Некорректная ЭП");
|
||||
fileInfo.setFileStatus(fileStatus);
|
||||
signFileInfo.setFileStatus(fileStatus);
|
||||
interactionService.setStatus(fileId, fileStatus.getStatus(), fileName,
|
||||
employeeInfoFileFormType.getFilePatternCode(), Timestamp.valueOf(now),
|
||||
fio, ervuId
|
||||
);
|
||||
auditService.processUploadEvent(uploadOrgInfo, new FileInfo[] {
|
||||
fileInfo, signFileInfo
|
||||
});
|
||||
//Заменить на свою ошибку
|
||||
throw new RuntimeException(verifyDocumentSignResponse.getSignVerifyResult());
|
||||
FileInfo mchdFileInfo = mchdFile != null ?
|
||||
createFileInfo(mchdFile, employeeInfoFileFormType, departureDateTime,
|
||||
offset, "MCHD"
|
||||
) : null;
|
||||
|
||||
FileStatus fileStatus = new FileStatus();
|
||||
Map<String, String> uploadResults = uploadFiles(multipartFile, signFile, mchdFile);
|
||||
|
||||
String fileUploadUrl = uploadResults.get("fileUrl");
|
||||
String signFileUploadUrl = uploadResults.get("signFile");
|
||||
String mchdFileUploadUrl = uploadResults.get("mchdFile");
|
||||
|
||||
boolean uploadSuccess = checkUploadSuccess(fileUploadUrl, signFileUploadUrl, mchdFileUploadUrl,
|
||||
mchdFile != null
|
||||
);
|
||||
|
||||
fileStatus.setStatus(uploadSuccess ? "Загрузка" : "Невозможно проверить файл ЛК РП");
|
||||
interactionService.setStatus(fileInfo.getFileId(), fileStatus.getStatus(),
|
||||
multipartFile.getOriginalFilename(), employeeInfoFileFormType.getFilePatternCode(),
|
||||
Timestamp.valueOf(now), fio, ervuId
|
||||
);
|
||||
|
||||
fileInfo.setFileStatus(fileStatus);
|
||||
signFileInfo.setFileStatus(fileStatus);
|
||||
if (mchdFileInfo != null) {
|
||||
mchdFileInfo.setFileStatus(fileStatus);
|
||||
}
|
||||
|
||||
if (!uploadSuccess) {
|
||||
handleUploadFailure(fileStatus, uploadOrgInfo, fileInfo, signFileInfo, mchdFileInfo,
|
||||
multipartFile.getOriginalFilename(), signFile.getOriginalFilename(),
|
||||
mchdFile != null ? mchdFile.getOriginalFilename() : null
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
fileInfo.setFileUrl(fileUploadUrl);
|
||||
signFileInfo.setFileUrl(signFileUploadUrl);
|
||||
if (mchdFileInfo != null) {
|
||||
mchdFileInfo.setFileUrl(mchdFileUploadUrl);
|
||||
}
|
||||
|
||||
FileInfo[] fileInfos = mchdFileInfo != null ?
|
||||
new FileInfo[] {fileInfo, signFileInfo, mchdFileInfo} :
|
||||
new FileInfo[] {fileInfo, signFileInfo};
|
||||
|
||||
String response = sendKafkaMessage(uploadOrgInfo, fileInfos, fileStatus);
|
||||
|
||||
DownloadResponse downloadResponse;
|
||||
try {
|
||||
downloadResponse = processMessageFromAv(response);
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
|
||||
fileStatus.setStatus("Невозможно проверить файл ЛК РП");
|
||||
interactionService.updateStatus(fileInfo.getFileId(), fileInfo.getFileStatus().getStatus(),
|
||||
uploadOrgInfo.getOrgId()
|
||||
);
|
||||
auditService.processUploadEvent(uploadOrgInfo, fileInfos);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
VerifyDocumentSignResponse verifyDocumentSignResponse;
|
||||
try {
|
||||
verifyDocumentSignResponse = validateSign(multipartFile, signFile);
|
||||
}
|
||||
catch (Exception e) {
|
||||
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
|
||||
fileStatus.setStatus("Некорректная ЭП");
|
||||
Arrays.stream(downloadResponse.filesInfo())
|
||||
.forEach(fileInfo1 -> fileInfo1.setFileStatus(fileStatus));
|
||||
|
||||
interactionService.updateStatus(fileInfo.getFileId(), fileInfo.getFileStatus().getStatus(),
|
||||
uploadOrgInfo.getOrgId()
|
||||
);
|
||||
|
||||
auditService.processUploadEvent(uploadOrgInfo, new FileInfo[] {fileInfo, signFileInfo});
|
||||
clearS3(response);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return validateSignerAndMchd(verifyDocumentSignResponse, chiefModel, uploadOrgInfo,
|
||||
mchdFile, accessToken, fileStatus, fileInfo, signFileInfo, mchdFileInfo,
|
||||
now, fio, ervuId, employeeInfoFileFormType, response
|
||||
);
|
||||
}
|
||||
|
||||
private FileInfo createFileInfo(MultipartFile file, EmployeeInfoFileFormType formType,
|
||||
String departureDateTime, String offset, String fileType) {
|
||||
|
||||
String fileId = UUID.randomUUID().toString();
|
||||
return employeeInfoKafkaMessageService.getFileInfo(fileId, null, file.getOriginalFilename(),
|
||||
formType, departureDateTime, offset, null, file.getSize(), fileType
|
||||
);
|
||||
}
|
||||
|
||||
private Map<String, String> uploadFiles(MultipartFile multipartFile, MultipartFile signFile,
|
||||
MultipartFile mchdFile) {
|
||||
|
||||
Map<String, MultipartFile> filesToUpload = new HashMap<>();
|
||||
filesToUpload.put("fileUrl", multipartFile);
|
||||
filesToUpload.put("signFile", signFile);
|
||||
|
||||
if (mchdFile != null) {
|
||||
filesToUpload.put("mchdFile", mchdFile);
|
||||
}
|
||||
|
||||
return this.webDavClient.uploadFiles(filesToUpload);
|
||||
}
|
||||
|
||||
private boolean checkUploadSuccess(String fileUploadUrl, String signFileUploadUrl,
|
||||
String mchdFileUploadUrl, boolean hasMchdFile) {
|
||||
|
||||
if (hasMchdFile) {
|
||||
return fileUploadUrl != null && signFileUploadUrl != null && mchdFileUploadUrl != null;
|
||||
}
|
||||
else {
|
||||
return fileUploadUrl != null && signFileUploadUrl != null;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUploadFailure(FileStatus fileStatus, UploadOrgInfo uploadOrgInfo,
|
||||
FileInfo fileInfo, FileInfo signFileInfo, FileInfo mchdFileInfo,
|
||||
String fileName, String signFileName, String mchdFileName) {
|
||||
|
||||
LOGGER.error("Failed to upload files: {}, {}, {}", fileName, signFileName, mchdFileName);
|
||||
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
|
||||
fileStatus.setDescription(
|
||||
"Невозможно проверить файл по причине недоступности или ошибки в работе антивируса");
|
||||
|
||||
FileInfo[] fileInfos = mchdFileInfo != null ?
|
||||
new FileInfo[] {fileInfo, signFileInfo, mchdFileInfo} :
|
||||
new FileInfo[] {fileInfo, signFileInfo};
|
||||
|
||||
auditService.processUploadEvent(uploadOrgInfo, fileInfos);
|
||||
}
|
||||
|
||||
private String sendKafkaMessage(UploadOrgInfo uploadOrgInfo, FileInfo[] fileInfos,
|
||||
FileStatus fileStatus) {
|
||||
|
||||
EmployeeInfoKafkaMessage kafkaMessage = employeeInfoKafkaMessageService.getKafkaMessage(
|
||||
uploadOrgInfo, fileInfos);
|
||||
|
||||
fileStatus.setCode(FILE_UPLOADED.getCode());
|
||||
fileStatus.setDescription("Файл принят до проверки на вирусы");
|
||||
|
||||
String jsonMessage = getJsonKafkaMessage(kafkaMessage);
|
||||
return replyingKafkaService.sendMessageAndGetReply(kafkaRequestTopic,
|
||||
kafkaResponseTopic, jsonMessage
|
||||
);
|
||||
}
|
||||
|
||||
private boolean validateSignerAndMchd(VerifyDocumentSignResponse verifyDocumentSignResponse,
|
||||
EmployeeModel chiefModel, UploadOrgInfo uploadOrgInfo, MultipartFile mchdFile,
|
||||
String accessToken, FileStatus fileStatus, FileInfo fileInfo, FileInfo signFileInfo,
|
||||
FileInfo mchdFileInfo, LocalDateTime now, String fio, String ervuId,
|
||||
EmployeeInfoFileFormType formType, String response) {
|
||||
|
||||
String signerInfo = verifyDocumentSignResponse.getSignerInfo();
|
||||
Map<String, String> signerInfoMap = parseKeyValuePairs(signerInfo);
|
||||
|
||||
String chiefMiddleName = chiefModel.getPerson().getMiddleName();
|
||||
String chiefLastName = chiefModel.getPerson().getLastName();
|
||||
String chiefFirstName = chiefModel.getPerson().getFirstName();
|
||||
if (signerInfoMap.get("SN").equalsIgnoreCase(chiefLastName) && signerInfoMap.get("G")
|
||||
.equalsIgnoreCase(chiefFirstName + " " + chiefMiddleName) && signerInfoMap.get("O")
|
||||
.equalsIgnoreCase(uploadOrgInfo.getOrgName())) {
|
||||
Map<String, String> hashMap = this.webDavClient.uploadFiles(Map.of(
|
||||
"fileUrl", multipartFile,
|
||||
"signUrl", signFile
|
||||
));
|
||||
String fileUploadUrl = hashMap.get("fileUrl");
|
||||
String signFileUploadUrl = hashMap.get("signFile");
|
||||
fileStatus.setStatus(fileUploadUrl == null || signFileUploadUrl == null
|
||||
? "Невозможно проверить файл ЛК РП"
|
||||
: "Загрузка");
|
||||
interactionService.setStatus(fileId, fileStatus.getStatus(), fileName,
|
||||
employeeInfoFileFormType.getFilePatternCode(), Timestamp.valueOf(now),
|
||||
convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
|
||||
personModel.getLastName()
|
||||
),
|
||||
ervuId
|
||||
);
|
||||
fileInfo.setFileStatus(fileStatus);
|
||||
signFileInfo.setFileStatus(fileStatus);
|
||||
if (fileUploadUrl == null || signFileUploadUrl == null) {
|
||||
LOGGER.error("Failed to upload files: {}, {}", fileName, signFileName);
|
||||
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
|
||||
fileStatus.setDescription(
|
||||
"Невозможно проверить файл по причине недоступности или ошибки в работе антивируса");
|
||||
auditService.processUploadEvent(uploadOrgInfo, new FileInfo[] {fileInfo, signFileInfo});
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
fileInfo.setFileUrl(fileUploadUrl);
|
||||
signFileInfo.setFileUrl(signFileUploadUrl);
|
||||
EmployeeInfoKafkaMessage kafkaMessage = employeeInfoKafkaMessageService.getKafkaMessage(
|
||||
uploadOrgInfo, new FileInfo[] {
|
||||
fileInfo, signFileInfo
|
||||
});
|
||||
fileStatus.setCode(FILE_UPLOADED.getCode());
|
||||
fileStatus.setDescription("Файл принят до проверки на вирусы");
|
||||
String jsonMessage = getJsonKafkaMessage(kafkaMessage);
|
||||
return sendMessage(jsonMessage);
|
||||
}
|
||||
|
||||
boolean isSignerValid = signerInfoMap.get("SN").equalsIgnoreCase(chiefLastName) &&
|
||||
signerInfoMap.get("G")
|
||||
.equalsIgnoreCase(chiefFirstName + " " + chiefMiddleName) &&
|
||||
signerInfoMap.get("O").equalsIgnoreCase(uploadOrgInfo.getOrgName());
|
||||
|
||||
if (isSignerValid) {
|
||||
sendMessage(response);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (mchdFile == null) {
|
||||
fileStatus.setStatus("Некорректная МЧД");
|
||||
interactionService.setStatus(fileId, fileStatus.getStatus(), fileName,
|
||||
employeeInfoFileFormType.getFilePatternCode(), Timestamp.valueOf(now),
|
||||
convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
|
||||
personModel.getLastName()
|
||||
),
|
||||
ervuId
|
||||
);
|
||||
auditService.processUploadEvent(uploadOrgInfo, new FileInfo[] {
|
||||
fileInfo, signFileInfo
|
||||
});
|
||||
//Заменить на свою ошибку
|
||||
throw new RuntimeException();
|
||||
}
|
||||
String mchdFileId = UUID.randomUUID().toString();
|
||||
String mchdFileName = mchdFile.getOriginalFilename();
|
||||
long mchdFileSize = mchdFile.getSize();
|
||||
FileInfo mchdFileInfo = employeeInfoKafkaMessageService.getFileInfo(mchdFileId, null,
|
||||
mchdFileName, employeeInfoFileFormType, departureDateTime, offset, fileStatus,
|
||||
mchdFileSize
|
||||
|
||||
if (mchdFile == null) {
|
||||
handleMchdValidationError(fileStatus, uploadOrgInfo, fileInfo, signFileInfo, null,
|
||||
now, fio, ervuId, formType, response
|
||||
);
|
||||
if (validateMchd(mchdFile, accessToken)) {
|
||||
Map<String, String> hashMap = this.webDavClient.uploadFiles(Map.of(
|
||||
"fileUrl", multipartFile,
|
||||
"signUrl", signFile,
|
||||
"mchdFile", mchdFile
|
||||
));
|
||||
String fileUploadUrl = hashMap.get("fileUrl");
|
||||
String signFileUploadUrl = hashMap.get("signFile");
|
||||
String mchdFileUploadUrl = hashMap.get("mchdFile");
|
||||
fileStatus.setStatus(
|
||||
fileUploadUrl == null || signFileUploadUrl == null || mchdFileUploadUrl == null
|
||||
? "Невозможно проверить файл ЛК РП"
|
||||
: "Загрузка");
|
||||
interactionService.setStatus(fileId, fileStatus.getStatus(), fileName,
|
||||
employeeInfoFileFormType.getFilePatternCode(), Timestamp.valueOf(now),
|
||||
convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
|
||||
personModel.getLastName()
|
||||
),
|
||||
ervuId
|
||||
);
|
||||
fileInfo.setFileStatus(fileStatus);
|
||||
signFileInfo.setFileStatus(fileStatus);
|
||||
if (fileUploadUrl == null || signFileUploadUrl == null || mchdFileUploadUrl == null) {
|
||||
LOGGER.error("Failed to upload files: {}, {}, {}", fileName, signFileName,
|
||||
mchdFileName
|
||||
);
|
||||
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
|
||||
fileStatus.setDescription(
|
||||
"Невозможно проверить файл по причине недоступности или ошибки в работе антивируса");
|
||||
auditService.processUploadEvent(uploadOrgInfo,
|
||||
new FileInfo[] {fileInfo, signFileInfo, mchdFileInfo}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
fileInfo.setFileUrl(fileUploadUrl);
|
||||
signFileInfo.setFileUrl(signFileUploadUrl);
|
||||
mchdFileInfo.setFileUrl(mchdFileUploadUrl);
|
||||
EmployeeInfoKafkaMessage kafkaMessage = employeeInfoKafkaMessageService.getKafkaMessage(
|
||||
uploadOrgInfo, new FileInfo[] {
|
||||
fileInfo, signFileInfo, mchdFileInfo
|
||||
});
|
||||
fileStatus.setCode(FILE_UPLOADED.getCode());
|
||||
fileStatus.setDescription("Файл принят до проверки на вирусы");
|
||||
String jsonMessage = getJsonKafkaMessage(kafkaMessage);
|
||||
return sendMessage(jsonMessage);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fileStatus.setStatus("Некорректная МЧД");
|
||||
interactionService.setStatus(fileId, fileStatus.getStatus(), fileName,
|
||||
employeeInfoFileFormType.getFilePatternCode(), Timestamp.valueOf(now),
|
||||
convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
|
||||
personModel.getLastName()
|
||||
),
|
||||
ervuId
|
||||
);
|
||||
auditService.processUploadEvent(uploadOrgInfo, new FileInfo[] {
|
||||
fileInfo, signFileInfo, mchdFileInfo
|
||||
});
|
||||
//Заменить на свою ошибку
|
||||
throw new RuntimeException();
|
||||
}
|
||||
throw new LocalizedException("mchd_null", MESSAGE_SOURCE);
|
||||
}
|
||||
|
||||
try {
|
||||
validateMchd(mchdFile, accessToken, signerInfoMap.get("SN") + " " + signerInfoMap.get("G"),
|
||||
chiefFirstName, chiefLastName, chiefMiddleName
|
||||
);
|
||||
sendMessage(response);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
handleMchdValidationError(fileStatus, uploadOrgInfo, fileInfo, signFileInfo, mchdFileInfo,
|
||||
now, fio, ervuId, formType, response
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMchdValidationError(FileStatus fileStatus, UploadOrgInfo uploadOrgInfo,
|
||||
FileInfo fileInfo, FileInfo signFileInfo, FileInfo mchdFileInfo, LocalDateTime now,
|
||||
String fio, String ervuId, EmployeeInfoFileFormType formType, String response) {
|
||||
|
||||
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
|
||||
fileStatus.setStatus("Некорректная МЧД");
|
||||
|
||||
interactionService.setStatus(fileInfo.getFileId(), fileStatus.getStatus(),
|
||||
fileInfo.getFileName(), formType.getFilePatternCode(), Timestamp.valueOf(now),
|
||||
fio, ervuId
|
||||
);
|
||||
|
||||
FileInfo[] fileInfos = mchdFileInfo != null ?
|
||||
new FileInfo[] {fileInfo, signFileInfo, mchdFileInfo} :
|
||||
new FileInfo[] {fileInfo, signFileInfo};
|
||||
|
||||
auditService.processUploadEvent(uploadOrgInfo, fileInfos);
|
||||
clearS3(response);
|
||||
}
|
||||
|
||||
private boolean isValidCsvWithSig(MultipartFile file, MultipartFile signFile) {
|
||||
|
|
@ -325,22 +417,6 @@ public class EmployeeInfoFileUploadService {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean sendMessage(String message) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(this.kafkaTopicName, message);
|
||||
record.headers()
|
||||
.add("messageId", UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
try {
|
||||
this.kafkaTemplate.send(record).get();
|
||||
LOGGER.debug("Successfully sent record: {}", record);
|
||||
return true;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOGGER.error("Failed to send message", exception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String getJsonKafkaMessage(EmployeeInfoKafkaMessage employeeInfoKafkaMessage) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
|
|
@ -352,25 +428,22 @@ public class EmployeeInfoFileUploadService {
|
|||
}
|
||||
}
|
||||
|
||||
@KafkaListener(id = "${av.kafka.group.id}", topics = "${av.kafka.download.response}",
|
||||
containerFactory = "avContainerFactory")
|
||||
@KafkaListener(id = "${file.kafka.group.id}", topics = "${kafka.download.response}",
|
||||
containerFactory = "fileContainerFactory")
|
||||
public void listenKafka(String kafkaMessage) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
try {
|
||||
DownloadResponse downloadResponse = mapper.readValue(kafkaMessage, DownloadResponse.class);
|
||||
FileInfo fileInfo = downloadResponse.filesInfo()[0];
|
||||
FileInfo fileInfo = Arrays.stream(downloadResponse.filesInfo())
|
||||
.filter(fileInfo1 -> fileInfo1.getType().equals(DOCUMENT))
|
||||
.findFirst()
|
||||
.get();
|
||||
String statusCode = fileInfo.getFileStatus().getCode();
|
||||
|
||||
if (Arrays.asList(FILE_INFECTED.getCode(), FILE_CLEAN.getCode()).contains(statusCode)) {
|
||||
if (FILE_ACCEPTED.getCode().equals(statusCode)) {
|
||||
interactionService.delete(fileInfo.getFileId(), downloadResponse.orgInfo().getOrgId());
|
||||
}
|
||||
else if (statusCode.equals(FILE_NOT_CHECKED.getCode())) {
|
||||
auditService.processUploadEvent(downloadResponse.orgInfo(), downloadResponse.filesInfo());
|
||||
interactionService.updateStatus(fileInfo.getFileId(), fileInfo.getFileStatus().getStatus(),
|
||||
downloadResponse.orgInfo().getOrgId()
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
throw new JsonParsingException(String.format("Fail get json from: %s", kafkaMessage), e);
|
||||
|
|
@ -392,26 +465,61 @@ public class EmployeeInfoFileUploadService {
|
|||
try (CloseableHttpResponse response = httpClient.execute(upload)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
String body = EntityUtils.toString(response.getEntity());
|
||||
if (statusCode == 401) {
|
||||
throw new LocalizedException("file_sign_validate", MESSAGE_SOURCE);
|
||||
}
|
||||
String errorCode = objectMapper.readTree(body)
|
||||
.get("error_code")
|
||||
.asText();
|
||||
if (errorCode.equals("CERT_TRUST_REVOCATION_STATUS_UNKNOWN")) {
|
||||
throw new LocalizedException("crl_certificate_expired", MESSAGE_SOURCE);
|
||||
}
|
||||
if (statusCode != 200) {
|
||||
throw new RuntimeException(statusCode + " " + body);
|
||||
throw new RuntimeException("Unknown error in verify module. Error code " + errorCode);
|
||||
}
|
||||
return objectMapper.readValue(body, VerifyDocumentSignResponse.class);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("Failed to process sign module response ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validateMchd(MultipartFile mchdFile, String accessToken) {
|
||||
private void validateMchd(MultipartFile mchdFile, String accessToken, String agentFio,
|
||||
String chiefFirstName, String chiefLastName, String chiefMiddleName) {
|
||||
String mchdGuid;
|
||||
try {
|
||||
String mchdGuid = getMchdGuid(mchdFile);
|
||||
MchdInfoModel mchdInfoModel = ulDataService.getMchdInfo(mchdGuid, accessToken);
|
||||
mchdInfoModel.
|
||||
|
||||
mchdGuid = getMchdGuid(mchdFile);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new EsiaException(e);
|
||||
throw new LocalizedException("mchd_cant_parse", MESSAGE_SOURCE);
|
||||
}
|
||||
MchdInfoModel mchdInfoModel = ulDataService.getMchdInfoModel(mchdGuid, accessToken);
|
||||
if (!mchdInfoModel.getStatus().equals("A")) {
|
||||
throw new LocalizedException("mchd_expired", MESSAGE_SOURCE);
|
||||
}
|
||||
boolean validAgent = mchdInfoModel.getAgents()
|
||||
.getElements()
|
||||
.stream()
|
||||
.anyMatch(agent1 -> agentFio.equalsIgnoreCase(
|
||||
agent1.getPerson().getLastName() + " " + agent1.getPerson().getFirstName() + " "
|
||||
+ agent1.getPerson().getMiddleName()));
|
||||
if (!validAgent) {
|
||||
throw new LocalizedException("mchd_validate_agent", MESSAGE_SOURCE);
|
||||
}
|
||||
while (mchdInfoModel.getParentGuid() != null) {
|
||||
mchdInfoModel = ulDataService.getMchdInfoModel(mchdInfoModel.getParentGuid(), accessToken);
|
||||
if (!mchdInfoModel.getStatus().equals("A")) {
|
||||
throw new LocalizedException("mchd_tree_expired", MESSAGE_SOURCE);
|
||||
}
|
||||
}
|
||||
MchdInfoModel.Element principal = mchdInfoModel.getPrincipals().getElements().get(0);
|
||||
MchdInfoModel.Person chief = principal.getOrganization().getChief();
|
||||
boolean principalFioEquals = chief.getFirstName().equalsIgnoreCase(chiefFirstName) &&
|
||||
chief.getLastName().equalsIgnoreCase(chiefLastName) &&
|
||||
chief.getMiddleName().equalsIgnoreCase(chiefMiddleName);
|
||||
if (!principalFioEquals) {
|
||||
throw new LocalizedException("mchd_validate_principal", MESSAGE_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -428,14 +536,67 @@ public class EmployeeInfoFileUploadService {
|
|||
return map;
|
||||
}
|
||||
|
||||
private String getMchdGuid(MultipartFile mcnhdFile) {
|
||||
try {
|
||||
return "asdasdasd";
|
||||
|
||||
private String getMchdGuid(MultipartFile mchdFile) throws Exception {
|
||||
Document doc = DocumentBuilderFactory
|
||||
.newInstance()
|
||||
.newDocumentBuilder()
|
||||
.parse(mchdFile.getInputStream());
|
||||
doc.getDocumentElement().normalize();
|
||||
Node node = doc.getElementsByTagNameNS("*", "СвДов").item(0);
|
||||
if (node != null && node.getAttributes().getNamedItem("НомДовер") != null) {
|
||||
return node.getAttributes().getNamedItem("НомДовер").getNodeValue();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new EsiaException(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean sendMessage(String message) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(this.kafkaDownloadRequestTopic, message);
|
||||
record.headers()
|
||||
.add("messageId", UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
try {
|
||||
this.kafkaTemplate.send(record).get();
|
||||
LOGGER.debug("Successfully sent record: {}", record);
|
||||
return true;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOGGER.error("Failed to send message", exception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearS3(String message) {
|
||||
ProducerRecord<String, String> record = new ProducerRecord<>(this.kafkaClearS3Topic, message);
|
||||
record.headers()
|
||||
.add("messageId", UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
|
||||
try {
|
||||
this.kafkaTemplate.send(record).get();
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOGGER.error("Failed to clear s3", exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DownloadResponse processMessageFromAv(String response) throws JsonProcessingException {
|
||||
DownloadResponse downloadResponse = objectMapper.readValue(response, DownloadResponse.class);
|
||||
FileInfo avFile = Arrays.stream(downloadResponse.filesInfo())
|
||||
.filter(fileInfo1 -> fileInfo1.getType().equals(DOCUMENT))
|
||||
.findAny()
|
||||
.get();
|
||||
FileStatus fileStatus1 = avFile.getFileStatus();
|
||||
if (fileStatus1.getCode().equals(FILE_INFECTED.getCode())) {
|
||||
interactionService.updateStatus(avFile.getFileId(), avFile.getFileStatus().getStatus(),
|
||||
downloadResponse.orgInfo().getOrgId());
|
||||
sendMessage(response);
|
||||
throw new LocalizedException("av_file_infected", MESSAGE_SOURCE);
|
||||
}
|
||||
else if (fileStatus1.getCode().equals(FILE_NOT_CHECKED.getCode())) {
|
||||
interactionService.updateStatus(avFile.getFileId(), avFile.getFileStatus().getStatus(),
|
||||
downloadResponse.orgInfo().getOrgId());
|
||||
auditService.processUploadEvent(downloadResponse.orgInfo(), downloadResponse.filesInfo());
|
||||
throw new RuntimeException("File not checked: " + avFile.getFileName());
|
||||
}
|
||||
return downloadResponse;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class EmployeeInfoKafkaMessageService {
|
|||
public EmployeeInfoKafkaMessage getKafkaMessage(String fileId, String fileUrl, String fileName,
|
||||
EmployeeInfoFileFormType formType, String departureDateTime, String accessToken,
|
||||
String offset, FileStatus fileStatus, String ervuId, String prnOid,
|
||||
PersonModel personModel, long fileSize) {
|
||||
PersonModel personModel, long fileSize, String type) {
|
||||
return new EmployeeInfoKafkaMessage(
|
||||
getOrgInfo(accessToken, ervuId, prnOid, personModel),
|
||||
new FileInfo[] {
|
||||
|
|
@ -38,7 +38,8 @@ public class EmployeeInfoKafkaMessageService {
|
|||
departureDateTime,
|
||||
offset,
|
||||
fileStatus,
|
||||
fileSize
|
||||
fileSize,
|
||||
type
|
||||
),
|
||||
}
|
||||
);
|
||||
|
|
@ -50,7 +51,7 @@ public class EmployeeInfoKafkaMessageService {
|
|||
|
||||
public FileInfo getFileInfo(String fileId, String fileUrl, String fileName,
|
||||
EmployeeInfoFileFormType formType, String departureDateTime, String offset,
|
||||
FileStatus fileStatus, long fileSize) {
|
||||
FileStatus fileStatus, long fileSize, String type) {
|
||||
return new FileInfo(
|
||||
fileId,
|
||||
fileUrl,
|
||||
|
|
@ -60,7 +61,8 @@ public class EmployeeInfoKafkaMessageService {
|
|||
String.valueOf(fileSize),
|
||||
departureDateTime,
|
||||
offset,
|
||||
fileStatus
|
||||
fileStatus,
|
||||
type
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.kafka.annotation.EnableKafka;
|
||||
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
|
||||
import org.springframework.kafka.core.ConsumerFactory;
|
||||
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
|
||||
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||
import org.springframework.kafka.core.ProducerFactory;
|
||||
import org.springframework.kafka.core.*;
|
||||
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
|
||||
import org.springframework.kafka.requestreply.CorrelationKey;
|
||||
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
|
||||
|
|
@ -52,6 +49,8 @@ public class ReplyingKafkaConfig {
|
|||
private String password;
|
||||
@Value("${kafka.auth_sasl_mech}")
|
||||
private String saslMechanism;
|
||||
@Value("${av.kafka.download.response}")
|
||||
private String avReplyTopic;
|
||||
|
||||
@Bean("ervuProducerFactory")
|
||||
public ProducerFactory<String, String> producerFactory() {
|
||||
|
|
@ -61,7 +60,7 @@ public class ReplyingKafkaConfig {
|
|||
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||
configProps.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, securityProtocol);
|
||||
configProps.put(SaslConfigs.SASL_JAAS_CONFIG, loginModule + " required username=\""
|
||||
+ username + "\" password=\"" + password + "\";");
|
||||
+ username + "\" password=\"" + password + "\";");
|
||||
configProps.put(SaslConfigs.SASL_MECHANISM, saslMechanism);
|
||||
return new DefaultKafkaProducerFactory<>(configProps);
|
||||
}
|
||||
|
|
@ -91,8 +90,11 @@ public class ReplyingKafkaConfig {
|
|||
|
||||
@Bean
|
||||
public ConcurrentMessageListenerContainer<String, String> replyContainer(
|
||||
@Qualifier("ervuContainerFactory") ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory) {
|
||||
return kafkaListenerContainerFactory.createContainer(orgReplyTopic, excerptReplyTopic, journalReplyTopic);
|
||||
@Qualifier("ervuContainerFactory")
|
||||
ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory) {
|
||||
return kafkaListenerContainerFactory.createContainer(orgReplyTopic, excerptReplyTopic,
|
||||
journalReplyTopic, avReplyTopic
|
||||
);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -12,26 +12,11 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MchdInfoModel implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<String> stateFacts;
|
||||
private String guid;
|
||||
private String number;
|
||||
private String status;
|
||||
private String issuedOn;
|
||||
private String expiredOn;
|
||||
|
||||
private Principals principals;
|
||||
private Agents agents;
|
||||
private Systems systems;
|
||||
private Revocations revocations;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
private String parentGuid;
|
||||
private Member principals;
|
||||
private Member agents;
|
||||
|
||||
public String getGuid() {
|
||||
return guid;
|
||||
|
|
@ -41,14 +26,6 @@ public class MchdInfoModel implements Serializable {
|
|||
this.guid = guid;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
|
@ -57,98 +34,48 @@ public class MchdInfoModel implements Serializable {
|
|||
this.status = status;
|
||||
}
|
||||
|
||||
public String getIssuedOn() {
|
||||
return issuedOn;
|
||||
public String getParentGuid() {
|
||||
return parentGuid;
|
||||
}
|
||||
|
||||
public void setIssuedOn(String issuedOn) {
|
||||
this.issuedOn = issuedOn;
|
||||
public void setParentGuid(String parentGuid) {
|
||||
this.parentGuid = parentGuid;
|
||||
}
|
||||
|
||||
public String getExpiredOn() {
|
||||
return expiredOn;
|
||||
}
|
||||
|
||||
public void setExpiredOn(String expiredOn) {
|
||||
this.expiredOn = expiredOn;
|
||||
}
|
||||
|
||||
public Principals getPrincipals() {
|
||||
public Member getPrincipals() {
|
||||
return principals;
|
||||
}
|
||||
|
||||
public void setPrincipals(Principals principals) {
|
||||
public void setPrincipals(Member principals) {
|
||||
this.principals = principals;
|
||||
}
|
||||
|
||||
public Agents getAgents() {
|
||||
public Member getAgents() {
|
||||
return agents;
|
||||
}
|
||||
|
||||
public void setAgents(Agents agents) {
|
||||
public void setAgents(Member agents) {
|
||||
this.agents = agents;
|
||||
}
|
||||
|
||||
public Systems getSystems() {
|
||||
return systems;
|
||||
}
|
||||
|
||||
public void setSystems(Systems systems) {
|
||||
this.systems = systems;
|
||||
}
|
||||
|
||||
public Revocations getRevocations() {
|
||||
return revocations;
|
||||
}
|
||||
|
||||
public void setRevocations(Revocations revocations) {
|
||||
this.revocations = revocations;
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Principals implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
private int size;
|
||||
private List<PrincipalElement> elements;
|
||||
public static class Member implements Serializable {
|
||||
private List<Element> elements;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public List<PrincipalElement> getElements() {
|
||||
public List<Element> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void setElements(List<PrincipalElement> elements) {
|
||||
public void setElements(List<Element> elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class PrincipalElement implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
public static class Element implements Serializable {
|
||||
private Person person;
|
||||
private Organization organization;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
|
||||
public Organization getOrganization() {
|
||||
return organization;
|
||||
}
|
||||
|
|
@ -156,51 +83,6 @@ public class MchdInfoModel implements Serializable {
|
|||
public void setOrganization(Organization organization) {
|
||||
this.organization = organization;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Agents implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
private int size;
|
||||
private List<AgentElement> elements;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public List<AgentElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void setElements(List<AgentElement> elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class AgentElement implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
private Person person;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
|
||||
public Person getPerson() {
|
||||
return person;
|
||||
|
|
@ -211,171 +93,10 @@ public class MchdInfoModel implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Systems implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
private int size;
|
||||
private List<SystemElement> elements;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public List<SystemElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void setElements(List<SystemElement> elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class SystemElement implements Serializable {
|
||||
private String nsiId;
|
||||
private String name;
|
||||
|
||||
public String getNsiId() {
|
||||
return nsiId;
|
||||
}
|
||||
|
||||
public void setNsiId(String nsiId) {
|
||||
this.nsiId = nsiId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Revocations implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
private int size;
|
||||
private List<RevocationElement> elements;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public List<RevocationElement> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void setElements(List<RevocationElement> elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class RevocationElement implements Serializable {
|
||||
private String number;
|
||||
private String poaGuid;
|
||||
private String revokedOn;
|
||||
private Principals principals;
|
||||
private Agents agents;
|
||||
private Signatory signatory;
|
||||
private Systems systems;
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String getPoaGuid() {
|
||||
return poaGuid;
|
||||
}
|
||||
|
||||
public void setPoaGuid(String poaGuid) {
|
||||
this.poaGuid = poaGuid;
|
||||
}
|
||||
|
||||
public String getRevokedOn() {
|
||||
return revokedOn;
|
||||
}
|
||||
|
||||
public void setRevokedOn(String revokedOn) {
|
||||
this.revokedOn = revokedOn;
|
||||
}
|
||||
|
||||
public Principals getPrincipals() {
|
||||
return principals;
|
||||
}
|
||||
|
||||
public void setPrincipals(Principals principals) {
|
||||
this.principals = principals;
|
||||
}
|
||||
|
||||
public Agents getAgents() {
|
||||
return agents;
|
||||
}
|
||||
|
||||
public void setAgents(Agents agents) {
|
||||
this.agents = agents;
|
||||
}
|
||||
|
||||
public Signatory getSignatory() {
|
||||
return signatory;
|
||||
}
|
||||
|
||||
public void setSignatory(Signatory signatory) {
|
||||
this.signatory = signatory;
|
||||
}
|
||||
|
||||
public Systems getSystems() {
|
||||
return systems;
|
||||
}
|
||||
|
||||
public void setSystems(Systems systems) {
|
||||
this.systems = systems;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Organization implements Serializable {
|
||||
private String ogrn;
|
||||
private String name;
|
||||
private String inn;
|
||||
private String kpp;
|
||||
|
||||
public String getOgrn() {
|
||||
return ogrn;
|
||||
}
|
||||
|
||||
public void setOgrn(String ogrn) {
|
||||
this.ogrn = ogrn;
|
||||
}
|
||||
private Person chief;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -385,55 +106,43 @@ public class MchdInfoModel implements Serializable {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public String getInn() {
|
||||
return inn;
|
||||
public Person getChief() {
|
||||
return chief;
|
||||
}
|
||||
|
||||
public void setInn(String inn) {
|
||||
this.inn = inn;
|
||||
}
|
||||
|
||||
public String getKpp() {
|
||||
return kpp;
|
||||
}
|
||||
|
||||
public void setKpp(String kpp) {
|
||||
this.kpp = kpp;
|
||||
public void setChief(Person chief) {
|
||||
this.chief = chief;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Person implements Serializable {
|
||||
private String snils;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String middleName;
|
||||
|
||||
public String getSnils() {
|
||||
return snils;
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setSnils(String snils) {
|
||||
this.snils = snils;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Signatory implements Serializable {
|
||||
private List<String> stateFacts;
|
||||
private Person person;
|
||||
|
||||
public List<String> getStateFacts() {
|
||||
return stateFacts;
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public void setStateFacts(List<String> stateFacts) {
|
||||
this.stateFacts = stateFacts;
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public Person getPerson() {
|
||||
return person;
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public void setPerson(Person person) {
|
||||
this.person = person;
|
||||
public String getMiddleName() {
|
||||
return middleName;
|
||||
}
|
||||
|
||||
public void setMiddleName(String middleName) {
|
||||
this.middleName = middleName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,6 @@ public interface UlDataService {
|
|||
String getAllUserRoles(String accessToken);
|
||||
|
||||
EsiaHeader readHeader(String accessToken);
|
||||
|
||||
MchdInfoModel getMchdInfoModel(String guid, String accessToken);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.micord.ervu.security.esia.exception.EsiaException;
|
||||
import ru.micord.ervu.security.esia.model.BrhsModel;
|
||||
import ru.micord.ervu.security.esia.model.EmployeeModel;
|
||||
import ru.micord.ervu.security.esia.model.EsiaAccessToken;
|
||||
import ru.micord.ervu.security.esia.model.EsiaHeader;
|
||||
import ru.micord.ervu.security.esia.model.OrganizationModel;
|
||||
import ru.micord.ervu.security.esia.model.PersonModel;
|
||||
import ru.micord.ervu.security.esia.model.*;
|
||||
|
||||
/**
|
||||
* @author Eduard Tihomirov
|
||||
|
|
@ -282,4 +277,25 @@ public class UlDataServiceImpl implements UlDataService {
|
|||
throw new EsiaException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MchdInfoModel getMchdInfoModel(String guid, String accessToken) {
|
||||
try {
|
||||
String url = esiaConfig.getEsiaBaseUri() + "/poa-registry/api/public/v1/poa/" + guid;
|
||||
HttpRequest getReq = HttpRequest.newBuilder(URI.create(url))
|
||||
.header(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||
.header("Authorization", "Bearer ".concat(accessToken))
|
||||
.GET()
|
||||
.timeout(Duration.ofSeconds(esiaConfig.getRequestTimeout()))
|
||||
.build();
|
||||
HttpResponse<String> getResp = HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(esiaConfig.getConnectionTimeout()))
|
||||
.build()
|
||||
.send(getReq, HttpResponse.BodyHandlers.ofString());
|
||||
errorHandler(getResp);
|
||||
return objectMapper.readValue(getResp.body(), MchdInfoModel.class);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new EsiaException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,3 +2,11 @@ kafka_reply_timeout=Превышено время ожидания ответа
|
|||
access_denied=Доступ запрещен. Пользователь должен быть включен в группу "Сотрудник, ответственный за военно-учетную работу" в ЕСИА
|
||||
login_attempts_exceeded=Слишком большое количество попыток авторизоваться в ЕСИА за короткий промежуток времени. Рекомендуем почистить cookie и cash браузера, после повторить авторизацию.
|
||||
crl_certificate_expired=Превышено время ожидания ответа из ЕСИА
|
||||
file_sign_validate=Ошибка проверки файлов. Некорректная электронная подпись
|
||||
mchd_validate_agent=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Представитель не совпадает с подписантом
|
||||
mchd_null=Ошибка проверки файлов. Отсутствует машиночитаемая доверенность. Подписант не является руководителем организации
|
||||
mchd_expired=Ошибка проверки файлов. Недействующая машиночитаемая доверенность.
|
||||
mchd_tree_expired=Ошибка проверки файлов. Одна из родительский доверенностей недействующая.
|
||||
mchd_validate_principal=Ошибка проверки файлов. Некорректная машиночитаемая доверенность. Доверитель не совпадает с руководителем организации
|
||||
av_file_infected=Ошибка проверки файлов. Файлы заражены вирусом
|
||||
mchd_cant_parse=Ошибка проверки файлов. Некорректный формат машиночитаемой доверенности
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@
|
|||
<property name="db.journal.excluded.statuses" value="Направлено в ЕРВУ,Получен ЕРВУ"/>
|
||||
<property name="ervu.kafka.excerpt.reply.topic" value="ervu.lkrp.excerpt.response"/>
|
||||
<property name="ervu.kafka.excerpt.request.topic" value="ervu.lkrp.excerpt.request"/>
|
||||
<property name="av.kafka.group.id" value="1"/>
|
||||
<property name="file.kafka.group.id" value="1"/>
|
||||
<property name="av.kafka.download.response" value="ervu.lkrp.av-fileupload-status"/>
|
||||
<property name="sign.verify.url" value="https://ervu-sign-dev.k8s.micord.ru/verify"/>
|
||||
<property name="esia.auth.info.clear.cron" value="0 0 */1 * * *"/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue