SUPPORT-9339: add sign verify

This commit is contained in:
Eduard Tihomirov 2025-08-28 14:15:18 +03:00
parent 838e1f8358
commit af52f7df8d
18 changed files with 1662 additions and 270 deletions

View file

@ -202,6 +202,10 @@
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.parent.artifactId}</finalName>

View file

@ -13,10 +13,7 @@ import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@ -89,12 +86,22 @@ public class WebDavClient {
}
@Retryable(value = {IOException.class}, backoff = @Backoff(delayExpression = "${webdav.retry.delay:500}"))
public String uploadFile(MultipartFile multipartFile) {
String fileName = getNewFilename(multipartFile.getOriginalFilename());
public Map<String, String> uploadFiles(Map<String, MultipartFile> files) {
String fileCatalog = UUID.randomUUID() + "/";
Sardine sardine = initClient(username, password);
try {
return putAndGetUrl(multipartFile.getBytes(), fileName, sardine);
Map<String, String> result = new HashMap<>();
for (Map.Entry<String, MultipartFile> entry : files.entrySet()) {
String key = entry.getKey();
MultipartFile file = entry.getValue();
if (file != null) {
String fileName = fileCatalog + file.getOriginalFilename();
result.put(key, putAndGetUrl(file.getBytes(), fileName, sardine));
}
}
return result;
}
catch (IOException e) {
throw new WebDavException("Failed to put file into WebDAV", e);
@ -109,12 +116,6 @@ public class WebDavClient {
}
}
private String getNewFilename(String filename) {
int lastIndexOf = filename.lastIndexOf(".");
String fileExtension = lastIndexOf == -1 ? "" : filename.substring(lastIndexOf);
return UUID.randomUUID() + fileExtension;
}
public String putAndGetUrl(byte[] fileBytes, String fileName, Sardine client) throws IOException {
if (badServersCache.size() == urls.length) {
return null;

View file

@ -26,13 +26,15 @@ public class EmployeeInfoFileUploadController {
@RequestMapping(value = "/employee/document", method = RequestMethod.POST)
public ResponseEntity<?> saveEmployeeInformationFile(
@RequestParam("file") MultipartFile multipartFile,
@RequestParam("signFile") MultipartFile signFile,
@RequestParam(value = "mchdFile", required = false) MultipartFile mchdFile,
@RequestHeader("X-Employee-Info-File-Form-Type") String formType,
@RequestHeader("Client-Time-Zone") String clientTimeZone) {
String offset = ZonedDateTime.now(TimeZone.getTimeZone(clientTimeZone).toZoneId())
.getOffset().getId();
if (this.fileUploadService.saveEmployeeInformationFile(multipartFile, formType, offset)) {
if (this.fileUploadService.saveEmployeeInformationFiles(multipartFile, signFile, mchdFile, formType, offset)) {
return ResponseEntity.ok("File successfully uploaded.");
}

View file

@ -3,5 +3,5 @@ package ervu.model.fileupload;
/**
* @author r.latypov
*/
public record DownloadResponse(UploadOrgInfo orgInfo, FileInfo fileInfo) {
public record DownloadResponse(UploadOrgInfo orgInfo, FileInfo[] filesInfo) {
}

View file

@ -1,5 +1,6 @@
package ervu.model.fileupload;
import java.util.Arrays;
import java.util.Objects;
/**
@ -7,19 +8,19 @@ import java.util.Objects;
*/
public class EmployeeInfoKafkaMessage {
private final UploadOrgInfo orgInfo;
private final FileInfo fileInfo;
private final FileInfo[] filesInfo;
public EmployeeInfoKafkaMessage(UploadOrgInfo orgInfo, FileInfo fileInfo) {
public EmployeeInfoKafkaMessage(UploadOrgInfo orgInfo, FileInfo[] filesInfo) {
this.orgInfo = orgInfo;
this.fileInfo = fileInfo;
this.filesInfo = filesInfo;
}
public UploadOrgInfo getOrgInfo() {
return orgInfo;
}
public FileInfo getFileInfo() {
return fileInfo;
public FileInfo[] getFilesInfo() {
return filesInfo;
}
@Override
@ -27,19 +28,21 @@ public class EmployeeInfoKafkaMessage {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmployeeInfoKafkaMessage that = (EmployeeInfoKafkaMessage) o;
return Objects.equals(orgInfo, that.orgInfo) && Objects.equals(fileInfo, that.fileInfo);
return Objects.equals(orgInfo, that.orgInfo) && Arrays.equals(filesInfo, that.filesInfo);
}
@Override
public int hashCode() {
return Objects.hash(orgInfo, fileInfo);
int result = Objects.hash(orgInfo);
result = 31 * result + Arrays.hashCode(filesInfo);
return result;
}
@Override
public String toString() {
return "KafkaMessage{" +
"uploadOrgInfo=" + orgInfo +
", fileInfo=" + fileInfo +
", fileInfo=" + Arrays.toString(filesInfo) +
'}';
}
}

View file

@ -69,6 +69,14 @@ public class FileInfo {
return fileStatus;
}
public void setFileStatus(FileStatus fileStatus) {
this.fileStatus = fileStatus;
}
public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View file

@ -1,21 +1,29 @@
package ervu.service.fileupload;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Locale;
import java.util.UUID;
import java.util.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import ervu.client.fileupload.WebDavClient;
import ervu.model.fileupload.DownloadResponse;
import ervu.model.fileupload.EmployeeInfoFileFormType;
import ervu.model.fileupload.EmployeeInfoKafkaMessage;
import ervu.model.fileupload.FileInfo;
import ervu.model.fileupload.FileStatus;
import ervu.model.fileupload.*;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.tika.Tika;
import org.apache.tika.mime.MediaType;
@ -32,8 +40,12 @@ import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import ru.micord.ervu.audit.service.AuditService;
import ru.micord.ervu.exception.JsonParsingException;
import ru.micord.ervu.security.esia.config.EsiaConfig;
import ru.micord.ervu.security.esia.exception.EsiaException;
import ru.micord.ervu.security.esia.model.EmployeeModel;
import ru.micord.ervu.security.esia.model.MchdInfoModel;
import ru.micord.ervu.security.esia.model.PersonModel;
import ru.micord.ervu.security.esia.model.VerifyDocumentSignResponse;
import ru.micord.ervu.security.esia.service.UlDataService;
import ru.micord.ervu.security.esia.EsiaAuthInfoStore;
import ru.micord.ervu.security.webbpm.jwt.UserIdsPair;
@ -59,6 +71,8 @@ public class EmployeeInfoFileUploadService {
private final InteractionService interactionService;
private final UlDataService ulDataService;
private final AuditService auditService;
private final ObjectMapper objectMapper;
private final EsiaConfig esiaConfig;
@Value("${av.kafka.message.topic.name}")
private String kafkaTopicName;
@ -69,24 +83,35 @@ public class EmployeeInfoFileUploadService {
@Qualifier("avTemplate") KafkaTemplate<String, String> kafkaTemplate,
InteractionService interactionService,
UlDataService ulDataService,
AuditService auditService) {
AuditService auditService,
ObjectMapper objectMapper,
EsiaConfig esiaConfig) {
this.webDavClient = webDavClient;
this.employeeInfoKafkaMessageService = employeeInfoKafkaMessageService;
this.kafkaTemplate = kafkaTemplate;
this.interactionService = interactionService;
this.ulDataService = ulDataService;
this.auditService = auditService;
this.objectMapper = objectMapper;
this.esiaConfig = esiaConfig;
}
public boolean saveEmployeeInformationFile(MultipartFile multipartFile, String formType,
String offset) {
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);
if (userIdsPair == null || !isValid(multipartFile)) {
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();
@ -94,79 +119,207 @@ public class EmployeeInfoFileUploadService {
String accessToken = EsiaAuthInfoStore.getAccessToken(esiaUserId);
EmployeeModel employeeModel = ulDataService.getEmployeeModel(accessToken);
PersonModel personModel = employeeModel.getPerson();
String fileUploadUrl = this.webDavClient.uploadFile(multipartFile);
EmployeeModel chiefModel = ulDataService.getChiefEmployeeModel(accessToken);
VerifyDocumentSignResponse verifyDocumentSignResponse = validateSign(multipartFile, signFile);
FileStatus fileStatus = new FileStatus();
fileStatus.setStatus(fileUploadUrl == null ? "Невозможно проверить файл ЛК РП" : "Загрузка");
LocalDateTime now = LocalDateTime.now();
interactionService.setStatus(fileId, fileStatus.getStatus(), fileName,
employeeInfoFileFormType.getFilePatternCode(), Timestamp.valueOf(now),
convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
personModel.getLastName()
),
ervuId
String fio = convertToFio(personModel.getFirstName(), personModel.getMiddleName(),
personModel.getLastName()
);
long fileSize = multipartFile.getSize();
String departureDateTime = DateUtils.convertToString(now);
EmployeeInfoKafkaMessage kafkaMessage = employeeInfoKafkaMessageService.getKafkaMessage(
fileId,
fileUploadUrl,
fileName,
employeeInfoFileFormType,
departureDateTime,
accessToken,
offset,
fileStatus,
ervuId,
esiaUserId,
personModel,
fileSize
UploadOrgInfo uploadOrgInfo = employeeInfoKafkaMessageService.getOrgInfo(accessToken, ervuId,
esiaUserId, personModel
);
if (fileUploadUrl != null) {
fileStatus.setCode(FILE_UPLOADED.getCode());
fileStatus.setDescription("Файл принят до проверки на вирусы");
String jsonMessage = getJsonKafkaMessage(kafkaMessage);
return sendMessage(jsonMessage);
FileInfo fileInfo = employeeInfoKafkaMessageService.getFileInfo(fileId, null, fileName,
employeeInfoFileFormType, departureDateTime, offset, null, fileSize
);
FileInfo signFileInfo = employeeInfoKafkaMessageService.getFileInfo(signFileId, null,
signFileName, employeeInfoFileFormType, departureDateTime, offset, null, signFileSize
);
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());
}
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);
}
}
else {
LOGGER.error("Failed to upload file: {}", fileName);
fileStatus.setCode(FILE_NOT_CHECKED.getCode());
fileStatus.setDescription("Невозможно проверить файл по причине недоступности или ошибки в работе антивируса");
auditService.processUploadEvent(kafkaMessage.getOrgInfo(), kafkaMessage.getFileInfo());
return false;
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 (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();
}
}
}
private boolean isValid(MultipartFile multipartFile) {
if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
private boolean isValidCsvWithSig(MultipartFile file, MultipartFile signFile) {
if (file == null || signFile == null || file.getOriginalFilename() == null
|| signFile.getOriginalFilename() == null) {
return false;
}
String fileName = multipartFile.getOriginalFilename();
Tika tika = new Tika();
MimeTypes defaultMimeTypes = MimeTypes.getDefaultMimeTypes();
try {
String contentType = new Tika().detect(multipartFile.getBytes());
MimeTypes defaultMimeTypes = MimeTypes.getDefaultMimeTypes();
MimeType mimeType = defaultMimeTypes.forName(contentType);
boolean isCsv = mimeType.getType().equals(MediaType.TEXT_PLAIN)
&& fileName.toLowerCase(Locale.getDefault()).endsWith(".csv");
String fileName = file.getOriginalFilename().toLowerCase(Locale.getDefault());
String signFileName = signFile.getOriginalFilename().toLowerCase(Locale.getDefault());
String fileContentType = tika.detect(file.getBytes());
String signContentType = tika.detect(signFile.getBytes());
MimeType fileMimeType = defaultMimeTypes.forName(fileContentType);
MimeType signMimeType = defaultMimeTypes.forName(signContentType);
boolean isCsv =
MediaType.TEXT_PLAIN.equals(fileMimeType.getType()) && fileName.endsWith(".csv");
boolean isSig =
"application/pkcs7-signature".equals(signMimeType.toString()) && signFileName.endsWith(
".sig");
if (!isCsv) {
LOGGER.info("Trying to upload file={} with wrong mime type={}",
fileName, mimeType
);
LOGGER.info("Invalid main file: name={}, mimeType={}", fileName, fileMimeType);
}
return isCsv;
if (!isSig) {
LOGGER.info("Invalid signature file: name={}, mimeType={}", signFileName, signMimeType);
}
return isCsv && isSig;
}
catch (MimeTypeException e) {
LOGGER.error(
"Couldn't get mime type from bytes for file=" + fileName, e);
return false;
}
catch (IOException e) {
LOGGER.error("Error while checking file type, file=" + fileName,
e
catch (MimeTypeException | IOException e) {
LOGGER.error("Failed to process files: {}, {}", file.getOriginalFilename(),
signFile.getOriginalFilename(), e
);
return false;
}
@ -206,14 +359,14 @@ public class EmployeeInfoFileUploadService {
try {
DownloadResponse downloadResponse = mapper.readValue(kafkaMessage, DownloadResponse.class);
FileInfo fileInfo = downloadResponse.fileInfo();
FileInfo fileInfo = downloadResponse.filesInfo()[0];
String statusCode = fileInfo.getFileStatus().getCode();
if (Arrays.asList(FILE_INFECTED.getCode(), FILE_CLEAN.getCode()).contains(statusCode)) {
interactionService.delete(fileInfo.getFileId(), downloadResponse.orgInfo().getOrgId());
}
else if (statusCode.equals(FILE_NOT_CHECKED.getCode())) {
auditService.processUploadEvent(downloadResponse.orgInfo(), downloadResponse.fileInfo());
auditService.processUploadEvent(downloadResponse.orgInfo(), downloadResponse.filesInfo());
interactionService.updateStatus(fileInfo.getFileId(), fileInfo.getFileStatus().getStatus(),
downloadResponse.orgInfo().getOrgId()
);
@ -223,4 +376,66 @@ public class EmployeeInfoFileUploadService {
throw new JsonParsingException(String.format("Fail get json from: %s", kafkaMessage), e);
}
}
private VerifyDocumentSignResponse validateSign(MultipartFile file, MultipartFile signFile) {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost upload = new HttpPost(esiaConfig.getSignUrl());
HttpEntity multipart = MultipartEntityBuilder.create()
.addBinaryBody("data", file.getBytes(), ContentType.APPLICATION_OCTET_STREAM,
file.getOriginalFilename()
)
.addBinaryBody("sign", signFile.getBytes(), ContentType.APPLICATION_OCTET_STREAM,
signFile.getOriginalFilename()
)
.build();
upload.setEntity(multipart);
try (CloseableHttpResponse response = httpClient.execute(upload)) {
int statusCode = response.getStatusLine().getStatusCode();
String body = EntityUtils.toString(response.getEntity());
if (statusCode != 200) {
throw new RuntimeException(statusCode + " " + body);
}
return objectMapper.readValue(body, VerifyDocumentSignResponse.class);
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private boolean validateMchd(MultipartFile mchdFile, String accessToken) {
try {
String mchdGuid = getMchdGuid(mchdFile);
MchdInfoModel mchdInfoModel = ulDataService.getMchdInfo(mchdGuid, accessToken);
mchdInfoModel.
}
catch (Exception e) {
throw new EsiaException(e);
}
}
private Map<String, String> parseKeyValuePairs(String input) {
Map<String, String> map = new HashMap<>();
String[] pairs = input.split(",");
for (String pair : pairs) {
String[] keyValue = pair.split("=", 2);
if (keyValue.length == 2) {
map.put(keyValue[0].trim(), keyValue[1].trim());
}
}
return map;
}
private String getMchdGuid(MultipartFile mcnhdFile) {
try {
return "asdasdasd";
}
catch (Exception e) {
throw new EsiaException(e);
}
}
}

View file

@ -29,20 +29,26 @@ public class EmployeeInfoKafkaMessageService {
PersonModel personModel, long fileSize) {
return new EmployeeInfoKafkaMessage(
getOrgInfo(accessToken, ervuId, prnOid, personModel),
getFileInfo(
fileId,
fileUrl,
fileName,
formType,
departureDateTime,
offset,
fileStatus,
fileSize
)
new FileInfo[] {
getFileInfo(
fileId,
fileUrl,
fileName,
formType,
departureDateTime,
offset,
fileStatus,
fileSize
),
}
);
}
private FileInfo getFileInfo(String fileId, String fileUrl, String fileName,
public EmployeeInfoKafkaMessage getKafkaMessage(UploadOrgInfo orgInfo, FileInfo[] filesInfo) {
return new EmployeeInfoKafkaMessage(orgInfo, filesInfo);
}
public FileInfo getFileInfo(String fileId, String fileUrl, String fileName,
EmployeeInfoFileFormType formType, String departureDateTime, String offset,
FileStatus fileStatus, long fileSize) {
return new FileInfo(
@ -58,7 +64,7 @@ public class EmployeeInfoKafkaMessageService {
);
}
private UploadOrgInfo getOrgInfo(String accessToken, String ervuId, String prnOid, PersonModel personModel) {
public UploadOrgInfo getOrgInfo(String accessToken, String ervuId, String prnOid, PersonModel personModel) {
OrganizationModel organizationModel = ulDataService.getOrganizationModel(accessToken);
SenderInfo senderInfo = new SenderInfo();
senderInfo.setFirstName(personModel.getFirstName());

View file

@ -10,11 +10,11 @@ import ervu.model.fileupload.UploadOrgInfo;
public class AuditUploadEvent {
private UploadOrgInfo orgInfo;
private FileInfo fileInfo;
private FileInfo[] filesInfo;
public AuditUploadEvent(UploadOrgInfo orgInfo, FileInfo fileInfo) {
public AuditUploadEvent(UploadOrgInfo orgInfo, FileInfo[] filesInfo) {
this.orgInfo = orgInfo;
this.fileInfo = fileInfo;
this.filesInfo = filesInfo;
}
public UploadOrgInfo getOrgInfo() {
@ -25,11 +25,11 @@ public class AuditUploadEvent {
this.orgInfo = orgInfo;
}
public FileInfo getFileInfo() {
return fileInfo;
public FileInfo[] getFilesInfo() {
return filesInfo;
}
public void setFileInfo(FileInfo fileInfo) {
this.fileInfo = fileInfo;
public void setFilesInfo(FileInfo[] filesInfo) {
this.filesInfo = filesInfo;
}
}

View file

@ -16,7 +16,7 @@ public interface AuditService {
void processAuthEvent(HttpServletRequest request, OrgInfo orgInfo, String prnOid, String status,
String eventType);
void processUploadEvent(UploadOrgInfo uploadOrgInfo, FileInfo fileInfo);
void processUploadEvent(UploadOrgInfo uploadOrgInfo, FileInfo[] filesInfo);
void processDownloadEvent(HttpServletRequest request, long fileSize, String fileName,
int formatRegistry, String status, String s3FileUrl);

View file

@ -110,10 +110,10 @@ public class BaseAuditService implements AuditService {
}
@Override
public void processUploadEvent(UploadOrgInfo orgInfo, FileInfo fileInfo) {
public void processUploadEvent(UploadOrgInfo orgInfo, FileInfo[] filesInfo) {
AuditUploadEvent auditUploadEvent = new AuditUploadEvent(
orgInfo,
fileInfo
filesInfo
);
String message = convertToMessage(auditUploadEvent);

View file

@ -0,0 +1,439 @@
package ru.micord.ervu.security.esia.model;
import java.io.Serializable;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* @author Eduard Tihomirov
*/
@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;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getIssuedOn() {
return issuedOn;
}
public void setIssuedOn(String issuedOn) {
this.issuedOn = issuedOn;
}
public String getExpiredOn() {
return expiredOn;
}
public void setExpiredOn(String expiredOn) {
this.expiredOn = expiredOn;
}
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 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 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() {
return elements;
}
public void setElements(List<PrincipalElement> elements) {
this.elements = elements;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class PrincipalElement implements Serializable {
private List<String> stateFacts;
private Organization organization;
public List<String> getStateFacts() {
return stateFacts;
}
public void setStateFacts(List<String> stateFacts) {
this.stateFacts = stateFacts;
}
public Organization getOrganization() {
return organization;
}
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;
}
public void setPerson(Person person) {
this.person = person;
}
}
@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;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInn() {
return inn;
}
public void setInn(String inn) {
this.inn = inn;
}
public String getKpp() {
return kpp;
}
public void setKpp(String kpp) {
this.kpp = kpp;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Person implements Serializable {
private String snils;
public String getSnils() {
return snils;
}
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 setStateFacts(List<String> stateFacts) {
this.stateFacts = stateFacts;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
}

View file

@ -0,0 +1,35 @@
package ru.micord.ervu.security.esia.model;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author Eduard Tihomirov
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class VerifyDocumentSignResponse implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("error_code")
private String errorCode;
@JsonProperty("signer_subject")
private String signerInfo;
public String getSignVerifyResult() {
return errorCode;
}
public void setSignVerifyResult(String signVerifyResult) {
this.errorCode = signVerifyResult;
}
public String getSignerInfo() {
return signerInfo;
}
public void setSignerInfo(String signerInfo) {
this.signerInfo = signerInfo;
}
}