SUPPORT-8706: add audit
This commit is contained in:
parent
4d1d83336f
commit
9bcc2d8586
30 changed files with 1046 additions and 69 deletions
|
|
@ -0,0 +1,88 @@
|
||||||
|
package ru.micord.ervu.audit.config;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.CommonClientConfigs;
|
||||||
|
import org.apache.kafka.clients.admin.AdminClientConfig;
|
||||||
|
import org.apache.kafka.clients.admin.NewTopic;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||||
|
import org.apache.kafka.common.config.SaslConfigs;
|
||||||
|
import org.apache.kafka.common.serialization.StringSerializer;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.kafka.config.TopicBuilder;
|
||||||
|
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||||
|
import org.springframework.kafka.core.KafkaAdmin;
|
||||||
|
import org.springframework.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.kafka.core.ProducerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class AuditKafkaConfig {
|
||||||
|
@Value("${audit.kafka.bootstrap.servers}")
|
||||||
|
private String bootstrapServers;
|
||||||
|
@Value("${audit.kafka.security.protocol}")
|
||||||
|
private String securityProtocol;
|
||||||
|
@Value("${audit.kafka.login.module:org.apache.kafka.common.security.scram.ScramLoginModule}")
|
||||||
|
private String loginModule;
|
||||||
|
@Value("${audit.kafka.username}")
|
||||||
|
private String username;
|
||||||
|
@Value("${audit.kafka.password}")
|
||||||
|
private String password;
|
||||||
|
@Value("${audit.kafka.sasl.mechanism}")
|
||||||
|
private String saslMechanism;
|
||||||
|
@Value("${audit.kafka.authorization.topic}")
|
||||||
|
private String authorizationTopic;
|
||||||
|
@Value("${audit.kafka.action.topic}")
|
||||||
|
private String actionTopic;
|
||||||
|
@Value("${audit.kafka.file.download.topic}")
|
||||||
|
private String fileDownloadTopic;
|
||||||
|
|
||||||
|
@Bean("auditProducerFactory")
|
||||||
|
public ProducerFactory<String, String> producerFactory() {
|
||||||
|
Map<String, Object> configProps = new HashMap<>();
|
||||||
|
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
|
||||||
|
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||||
|
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 + "\";");
|
||||||
|
configProps.put(SaslConfigs.SASL_MECHANISM, saslMechanism);
|
||||||
|
return new DefaultKafkaProducerFactory<>(configProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("auditTemplate")
|
||||||
|
public KafkaTemplate<String, String> kafkaTemplate() {
|
||||||
|
return new KafkaTemplate<>(producerFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public KafkaAdmin auditKafkaAdmin() {
|
||||||
|
Map<String, Object> configs = new HashMap<>();
|
||||||
|
configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
|
||||||
|
configs.put(AdminClientConfig.SECURITY_PROTOCOL_CONFIG, securityProtocol);
|
||||||
|
configs.put(SaslConfigs.SASL_JAAS_CONFIG, loginModule + " required username=\""
|
||||||
|
+ username + "\" password=\"" + password + "\";");
|
||||||
|
configs.put(SaslConfigs.SASL_MECHANISM, saslMechanism);
|
||||||
|
return new KafkaAdmin(configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public NewTopic auditAuthTopic() {
|
||||||
|
return TopicBuilder.name(authorizationTopic).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public NewTopic auditActionTopic() {
|
||||||
|
return TopicBuilder.name(actionTopic).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public NewTopic auditDownloadTopic() {
|
||||||
|
return TopicBuilder.name(fileDownloadTopic).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package ru.micord.ervu.audit.constants;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public final class AuditConstants {
|
||||||
|
public static final String SUBSYSTEM_TYPE = "FL";
|
||||||
|
public static final String LOGOUT_EVENT_TYPE = "logout";
|
||||||
|
public static final String LOGIN_EVENT_TYPE = "login";
|
||||||
|
public static final String SUCCESS_STATUS = "success";
|
||||||
|
public static final String FAILURE_STATUS = "failure";
|
||||||
|
|
||||||
|
private static final Map<String, String> routeDescriptions = Map.of(
|
||||||
|
"/", "Главная",
|
||||||
|
"/mydata", "Мои данные",
|
||||||
|
"/subpoena", "Повестки",
|
||||||
|
"/restriction", "Временные меры"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Map<String, String> downloadTypes = Map.of(
|
||||||
|
"1", "Выписка из реестра воинского учета ФЛ",
|
||||||
|
"2", "Выписка из реестра повесток ФЛ"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static String getRouteDescription(String route) {
|
||||||
|
return Optional.ofNullable(routeDescriptions.get(route))
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Invalid route :" + route));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDownloadType(String formatRegistry) {
|
||||||
|
return Optional.ofNullable(downloadTypes.get(formatRegistry))
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new IllegalArgumentException("Invalid formatRegistry :" + formatRegistry));
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuditConstants() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package ru.micord.ervu.audit.controller;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import ru.micord.ervu.audit.model.AuditActionRequest;
|
||||||
|
import ru.micord.ervu.audit.service.AuditService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/audit")
|
||||||
|
public class AuditController {
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
|
public AuditController(AuditService auditService) {
|
||||||
|
this.auditService = auditService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/action")
|
||||||
|
public ResponseEntity<Void> auditAction(HttpServletRequest request,
|
||||||
|
@RequestBody AuditActionRequest actionEvent) {
|
||||||
|
auditService.processActionEvent(request, actionEvent);
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ru.micord.ervu.audit.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public class AuditActionEvent extends AuditEvent {
|
||||||
|
private String eventType;
|
||||||
|
private String description;
|
||||||
|
private String sourceUrl;
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
public AuditActionEvent(
|
||||||
|
String esiaPersonId, String eventTime, String eventType,
|
||||||
|
String description, String sourceUrl, String fileName) {
|
||||||
|
super(esiaPersonId, eventTime);
|
||||||
|
this.eventType = eventType;
|
||||||
|
this.description = description;
|
||||||
|
this.sourceUrl = sourceUrl;
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventType(String eventType) {
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSourceUrl() {
|
||||||
|
return sourceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceUrl(String sourceUrl) {
|
||||||
|
this.sourceUrl = sourceUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package ru.micord.ervu.audit.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public class AuditActionRequest {
|
||||||
|
private String route;
|
||||||
|
private String sourceUrl;
|
||||||
|
private String eventType;
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoute() {
|
||||||
|
return route;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoute(String route) {
|
||||||
|
this.route = route;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSourceUrl() {
|
||||||
|
return sourceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceUrl(String sourceUrl) {
|
||||||
|
this.sourceUrl = sourceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventType(String eventType) {
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
package ru.micord.ervu.audit.model;
|
||||||
|
|
||||||
|
|
||||||
|
public class AuditAuthorizationEvent extends AuditEvent {
|
||||||
|
private String status;
|
||||||
|
private String eventType;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private String middleName;
|
||||||
|
private String snils;
|
||||||
|
|
||||||
|
public AuditAuthorizationEvent(
|
||||||
|
String esiaPersonId, String eventTime, String firstName,
|
||||||
|
String lastName, String middleName, String snils,
|
||||||
|
String status, String eventType) {
|
||||||
|
super(esiaPersonId, eventTime);
|
||||||
|
this.status = status;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.middleName = middleName;
|
||||||
|
this.snils = snils;
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMiddleName() {
|
||||||
|
return middleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiddleName(String middleName) {
|
||||||
|
this.middleName = middleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSnils() {
|
||||||
|
return snils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSnils(String snils) {
|
||||||
|
this.snils = snils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventType(String eventType) {
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package ru.micord.ervu.audit.model;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public class AuditDownloadEvent extends AuditEvent {
|
||||||
|
private String downloadType;
|
||||||
|
private String fileName;
|
||||||
|
private String s3FileUrl;
|
||||||
|
private String fileSize;
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public AuditDownloadEvent(
|
||||||
|
String esiaPersonId, String eventTime, String downloadType,
|
||||||
|
String fileName, String s3FileUrl, String fileSize,
|
||||||
|
String status) {
|
||||||
|
super(esiaPersonId, eventTime);
|
||||||
|
this.downloadType = downloadType;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.s3FileUrl = s3FileUrl;
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getS3FileUrl() {
|
||||||
|
return s3FileUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setS3FileUrl(String s3FileUrl) {
|
||||||
|
this.s3FileUrl = s3FileUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDownloadType() {
|
||||||
|
return downloadType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownloadType(String downloadType) {
|
||||||
|
this.downloadType = downloadType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileSize(String fileSize) {
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package ru.micord.ervu.audit.model;
|
||||||
|
|
||||||
|
import ru.micord.ervu.audit.constants.AuditConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class AuditEvent {
|
||||||
|
protected final String subsystem = AuditConstants.SUBSYSTEM_TYPE;
|
||||||
|
protected String esiaPersonId;
|
||||||
|
protected String eventTime;
|
||||||
|
|
||||||
|
protected AuditEvent(String esiaPersonId, String eventTime) {
|
||||||
|
this.esiaPersonId = esiaPersonId;
|
||||||
|
this.eventTime = eventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEsiaPersonId() {
|
||||||
|
return esiaPersonId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEsiaPersonId(String esiaPersonId) {
|
||||||
|
this.esiaPersonId = esiaPersonId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubsystem() {
|
||||||
|
return subsystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventTime() {
|
||||||
|
return eventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventTime(String eventTime) {
|
||||||
|
this.eventTime = eventTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package ru.micord.ervu.audit.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public interface AuditKafkaPublisher {
|
||||||
|
void publishEvent(String topicName, String message);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.micord.ervu.audit.service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import ru.micord.ervu.audit.model.AuditActionRequest;
|
||||||
|
import ru.micord.ervu.security.esia.model.PersonModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public interface AuditService {
|
||||||
|
void processActionEvent(HttpServletRequest request, AuditActionRequest auditActionRequest);
|
||||||
|
|
||||||
|
void processAuthEvent(HttpServletRequest request, PersonModel personModel, String status,
|
||||||
|
String eventType);
|
||||||
|
|
||||||
|
void processDownloadEvent(HttpServletRequest request, int fileSize, String fileName,
|
||||||
|
String formatRegistry, String status);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package ru.micord.ervu.audit.service.impl;
|
||||||
|
|
||||||
|
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.kafka.core.KafkaTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.micord.ervu.audit.service.AuditKafkaPublisher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class BaseAuditKafkaPublisher implements AuditKafkaPublisher {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(BaseAuditKafkaPublisher.class);
|
||||||
|
private final KafkaTemplate<String, String> kafkaTemplate;
|
||||||
|
@Value("${audit.kafka.enabled}")
|
||||||
|
private boolean auditEnabled;
|
||||||
|
|
||||||
|
public BaseAuditKafkaPublisher(
|
||||||
|
@Qualifier("auditTemplate") KafkaTemplate<String, String> kafkaTemplate) {
|
||||||
|
this.kafkaTemplate = kafkaTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishEvent(String topic, String message) {
|
||||||
|
if (auditEnabled) {
|
||||||
|
kafkaTemplate.send(topic, message)
|
||||||
|
.addCallback(
|
||||||
|
result -> {
|
||||||
|
},
|
||||||
|
ex -> LOGGER.error("Failed to send message to topic {}: {}", topic, ex.getMessage(),
|
||||||
|
ex
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOGGER.info("Audit is disabled. Event not published.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
package ru.micord.ervu.audit.service.impl;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.micord.ervu.audit.constants.AuditConstants;
|
||||||
|
import ru.micord.ervu.audit.model.AuditActionEvent;
|
||||||
|
import ru.micord.ervu.audit.model.AuditActionRequest;
|
||||||
|
import ru.micord.ervu.audit.model.AuditAuthorizationEvent;
|
||||||
|
import ru.micord.ervu.audit.model.AuditDownloadEvent;
|
||||||
|
import ru.micord.ervu.audit.service.AuditKafkaPublisher;
|
||||||
|
import ru.micord.ervu.audit.service.AuditService;
|
||||||
|
import ru.micord.ervu.security.esia.model.PersonModel;
|
||||||
|
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
|
||||||
|
import ru.micord.ervu.util.DateUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class BaseAuditService implements AuditService {
|
||||||
|
private final AuditKafkaPublisher auditPublisher;
|
||||||
|
private final JwtTokenService jwtTokenService;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
@Value("${audit.kafka.authorization.topic}")
|
||||||
|
private String authorizationTopic;
|
||||||
|
@Value("${audit.kafka.action.topic}")
|
||||||
|
private String actionTopic;
|
||||||
|
@Value("${audit.kafka.file.download.topic}")
|
||||||
|
private String fileDownloadTopic;
|
||||||
|
|
||||||
|
public BaseAuditService(AuditKafkaPublisher auditPublisher, JwtTokenService jwtTokenService,
|
||||||
|
ObjectMapper objectMapper) {
|
||||||
|
this.auditPublisher = auditPublisher;
|
||||||
|
this.jwtTokenService = jwtTokenService;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processActionEvent(
|
||||||
|
HttpServletRequest request, AuditActionRequest auditActionRequest) {
|
||||||
|
String userAccountId = jwtTokenService.getUserAccountId(request);
|
||||||
|
String description = AuditConstants.getRouteDescription(auditActionRequest.getRoute());
|
||||||
|
|
||||||
|
AuditActionEvent event = new AuditActionEvent(
|
||||||
|
userAccountId,
|
||||||
|
DateUtils.getClientTimeFromRequest(request),
|
||||||
|
auditActionRequest.getEventType(),
|
||||||
|
description,
|
||||||
|
auditActionRequest.getSourceUrl(),
|
||||||
|
auditActionRequest.getFileName()
|
||||||
|
);
|
||||||
|
String message = convertToMessage(event);
|
||||||
|
auditPublisher.publishEvent(actionTopic, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processAuthEvent(HttpServletRequest request, PersonModel personModel, String status,
|
||||||
|
String eventType) {
|
||||||
|
AuditAuthorizationEvent event = new AuditAuthorizationEvent(
|
||||||
|
personModel.getPrnsId(),
|
||||||
|
DateUtils.getClientTimeFromRequest(request),
|
||||||
|
personModel.getFirstName(),
|
||||||
|
personModel.getLastName(),
|
||||||
|
personModel.getMiddleName(),
|
||||||
|
personModel.getSnils(),
|
||||||
|
status,
|
||||||
|
eventType
|
||||||
|
);
|
||||||
|
String message = convertToMessage(event);
|
||||||
|
auditPublisher.publishEvent(authorizationTopic, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processDownloadEvent(
|
||||||
|
HttpServletRequest request, int fileSize, String fileName, String formatRegistry,
|
||||||
|
String status) {
|
||||||
|
String userAccountId = jwtTokenService.getUserAccountId(request);
|
||||||
|
|
||||||
|
AuditDownloadEvent event = new AuditDownloadEvent(
|
||||||
|
userAccountId,
|
||||||
|
DateUtils.getClientTimeFromRequest(request),
|
||||||
|
AuditConstants.getDownloadType(formatRegistry),
|
||||||
|
fileName,
|
||||||
|
null,
|
||||||
|
String.valueOf(fileSize),
|
||||||
|
status
|
||||||
|
);
|
||||||
|
String message = convertToMessage(event);
|
||||||
|
auditPublisher.publishEvent(fileDownloadTopic, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertToMessage(Object event) {
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(event);
|
||||||
|
}
|
||||||
|
catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package ru.micord.ervu.controller;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import org.apache.kafka.common.utils.Bytes;
|
import org.apache.kafka.common.utils.Bytes;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
@ -16,29 +17,33 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import rtl.pgs.ervu.proto.ExtractRegistry;
|
import rtl.pgs.ervu.proto.ExtractRegistry;
|
||||||
import rtl.pgs.ervu.proto.ResponseData;
|
import rtl.pgs.ervu.proto.ResponseData;
|
||||||
|
import ru.micord.ervu.audit.constants.AuditConstants;
|
||||||
|
import ru.micord.ervu.audit.service.AuditService;
|
||||||
import ru.micord.ervu.dto.ExtractRequestDto;
|
import ru.micord.ervu.dto.ExtractRequestDto;
|
||||||
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil;
|
import ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gulnaz
|
* @author gulnaz
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
public class ExtractController {
|
public class ExtractController {
|
||||||
|
|
||||||
private final ReplyingKafkaService<Object, Bytes> replyingKafkaService;
|
private final ReplyingKafkaService<Object, Bytes> replyingKafkaService;
|
||||||
|
private final AuditService auditService;
|
||||||
@Value("${ervu.kafka.registry.extract.request.topic}")
|
@Value("${ervu.kafka.registry.extract.request.topic}")
|
||||||
private String registryExtractRequestTopic;
|
private String registryExtractRequestTopic;
|
||||||
@Value("${ervu.kafka.registry.extract.reply.topic}")
|
@Value("${ervu.kafka.registry.extract.reply.topic}")
|
||||||
private String registryExtractReplyTopic;
|
private String registryExtractReplyTopic;
|
||||||
|
|
||||||
public ExtractController(ReplyingKafkaService<Object, Bytes> replyingKafkaService) {
|
public ExtractController(ReplyingKafkaService<Object, Bytes> replyingKafkaService, AuditService auditService) {
|
||||||
this.replyingKafkaService = replyingKafkaService;
|
this.replyingKafkaService = replyingKafkaService;
|
||||||
|
this.auditService = auditService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/extract/{formatRegistry}")
|
@GetMapping(value = "/extract/{formatRegistry}")
|
||||||
public ResponseEntity<Resource> getExtract(@PathVariable String formatRegistry) {
|
public ResponseEntity<Resource> getExtract(HttpServletRequest servletRequest, @PathVariable String formatRegistry) {
|
||||||
String ervuId = SecurityUtil.getErvuId();
|
String ervuId = SecurityUtil.getErvuId();
|
||||||
|
|
||||||
if (ervuId == null) {
|
if (ervuId == null) {
|
||||||
|
|
@ -48,18 +53,29 @@ public class ExtractController {
|
||||||
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractRequestTopic,
|
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractRequestTopic,
|
||||||
registryExtractReplyTopic, request).get();
|
registryExtractReplyTopic, request).get();
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
String fileName = null;
|
||||||
try {
|
try {
|
||||||
ResponseData responseData = ResponseData.parseFrom(reply);
|
ResponseData responseData = ResponseData.parseFrom(reply);
|
||||||
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
|
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
|
||||||
.getExtractRegistry();
|
.getExtractRegistry();
|
||||||
String encodedFilename = URLEncoder.encode(extractRegistry.getFileName(), StandardCharsets.UTF_8);
|
ByteString file = extractRegistry.getFile();
|
||||||
InputStreamResource resource = new InputStreamResource(extractRegistry.getFile().newInput());
|
size = file.size();
|
||||||
|
fileName = extractRegistry.getFileName();
|
||||||
|
String encodedFilename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||||
|
InputStreamResource resource = new InputStreamResource(file.newInput());
|
||||||
|
auditService.processDownloadEvent(servletRequest, size, formatRegistry, fileName,
|
||||||
|
AuditConstants.SUCCESS_STATUS
|
||||||
|
);
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename)
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename)
|
||||||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
.body(resource);
|
.body(resource);
|
||||||
}
|
}
|
||||||
catch (InvalidProtocolBufferException e) {
|
catch (InvalidProtocolBufferException e) {
|
||||||
|
auditService.processDownloadEvent(servletRequest, size, formatRegistry, fileName,
|
||||||
|
AuditConstants.FAILURE_STATUS
|
||||||
|
);
|
||||||
throw new RuntimeException("Failed to parse data", e);
|
throw new RuntimeException("Failed to parse data", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,14 @@ import java.util.Optional;
|
||||||
import ru.micord.ervu.dto.Restriction;
|
import ru.micord.ervu.dto.Restriction;
|
||||||
import ru.micord.ervu.dto.SubpoenaResponseDto;
|
import ru.micord.ervu.dto.SubpoenaResponseDto;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import proto.ervu.rp.summons.MeasuresTemporary;
|
|
||||||
import proto.ervu.rp.summons.ResponseDataAddress;
|
import proto.ervu.rp.summons.ResponseDataAddress;
|
||||||
import proto.ervu.rp.summons.SummonsInfo;
|
import proto.ervu.rp.summons.SummonsInfo;
|
||||||
import proto.ervu.rp.summons.SummonsResponseData;
|
import proto.ervu.rp.summons.SummonsResponseData;
|
||||||
|
|
||||||
import static ru.micord.ervu.util.DateUtil.convertToLocalDate;
|
import static ru.micord.ervu.util.DateUtils.convertToLocalDate;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static ru.micord.ervu.util.DateUtil.convertToString;
|
import static ru.micord.ervu.util.DateUtils.convertToString;
|
||||||
import static ru.micord.ervu.util.DateUtil.getDaysTill;
|
import static ru.micord.ervu.util.DateUtils.getDaysTill;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gulnaz
|
* @author gulnaz
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.springframework.util.StringUtils.hasText;
|
import static org.springframework.util.StringUtils.hasText;
|
||||||
import static ru.micord.ervu.util.DateUtil.convertToLocalDate;
|
import static ru.micord.ervu.util.DateUtils.convertToLocalDate;
|
||||||
import static ru.micord.ervu.util.DateUtil.convertToString;
|
import static ru.micord.ervu.util.DateUtils.convertToString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gulnaz
|
* @author gulnaz
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import ru.micord.ervu.audit.constants.AuditConstants;
|
||||||
|
import ru.micord.ervu.audit.service.AuditService;
|
||||||
import ru.micord.ervu.kafka.model.Document;
|
import ru.micord.ervu.kafka.model.Document;
|
||||||
import ru.micord.ervu.kafka.model.Person;
|
import ru.micord.ervu.kafka.model.Person;
|
||||||
import ru.micord.ervu.kafka.model.Response;
|
import ru.micord.ervu.kafka.model.Response;
|
||||||
|
|
@ -73,6 +75,9 @@ public class EsiaAuthService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private PersonalDataService personalDataService;
|
private PersonalDataService personalDataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuditService auditService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SecurityHelper securityHelper;
|
private SecurityHelper securityHelper;
|
||||||
|
|
||||||
|
|
@ -237,21 +242,40 @@ public class EsiaAuthService {
|
||||||
LOGGER.info("Thread {}: SignSecret: {}ms RequestAccessToken: {}ms VerifySecret: {}ms",
|
LOGGER.info("Thread {}: SignSecret: {}ms RequestAccessToken: {}ms VerifySecret: {}ms",
|
||||||
Thread.currentThread().getId(), signSecret, requestAccessToken, verifySecret);
|
Thread.currentThread().getId(), signSecret, requestAccessToken, verifySecret);
|
||||||
}
|
}
|
||||||
|
long requestPersonData = 0, requestIdERVU = 0;
|
||||||
|
PersonModel personModel = null;
|
||||||
try {
|
try {
|
||||||
Response ervuIdResponse = getErvuIdResponse(esiaAccessTokenStr);
|
long startTime = System.currentTimeMillis();
|
||||||
|
personModel = personalDataService.getPersonModel(esiaAccessTokenStr);
|
||||||
|
requestPersonData = System.currentTimeMillis() - startTime;
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
Response ervuIdResponse = getErvuIdResponse(personModel);
|
||||||
|
requestIdERVU = System.currentTimeMillis() - startTime;
|
||||||
createTokenAndAddCookie(response, prnOid, ervuIdResponse.getErvuId(), expiresIn);
|
createTokenAndAddCookie(response, prnOid, ervuIdResponse.getErvuId(), expiresIn);
|
||||||
|
auditService.processAuthEvent(
|
||||||
|
request, personModel, AuditConstants.SUCCESS_STATUS, AuditConstants.LOGIN_EVENT_TYPE
|
||||||
|
);
|
||||||
return ResponseEntity.ok("Authentication successful");
|
return ResponseEntity.ok("Authentication successful");
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
createTokenAndAddCookie(response, prnOid, null, expiresIn);
|
createTokenAndAddCookie(response, prnOid, null, expiresIn);
|
||||||
String messageId = getMessageId(e);
|
String messageId = getMessageId(e);
|
||||||
String messageWithId = String.format("[%s] %s", messageId, e.getMessage());
|
String messageWithId = String.format("[%s] %s", messageId, e.getMessage());
|
||||||
|
if (personModel != null) {
|
||||||
|
auditService.processAuthEvent(
|
||||||
|
request, personModel, AuditConstants.FAILURE_STATUS, AuditConstants.LOGIN_EVENT_TYPE
|
||||||
|
);
|
||||||
|
}
|
||||||
LOGGER.error(messageWithId, e);
|
LOGGER.error(messageWithId, e);
|
||||||
return new ResponseEntity<>(
|
return new ResponseEntity<>(
|
||||||
"Произошла ошибка " + messageId + ". Обратитесь к системному администратору",
|
"Произошла ошибка " + messageId + ". Обратитесь к системному администратору",
|
||||||
HttpStatus.FORBIDDEN
|
HttpStatus.FORBIDDEN
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
LOGGER.info("Thread {}: RequestPersonData: {}ms RequestIdERVU: {}ms",
|
||||||
|
Thread.currentThread().getId(), requestPersonData, requestIdERVU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getEsiaTokensByRefreshToken(HttpServletRequest request, HttpServletResponse response) {
|
public void getEsiaTokensByRefreshToken(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
|
@ -313,7 +337,8 @@ public class EsiaAuthService {
|
||||||
Long expiresIn = tokenResponse.getExpires_in();
|
Long expiresIn = tokenResponse.getExpires_in();
|
||||||
EsiaTokensStore.addAccessToken(prnOid, esiaAccessTokenStr, expiresIn);
|
EsiaTokensStore.addAccessToken(prnOid, esiaAccessTokenStr, expiresIn);
|
||||||
EsiaTokensStore.addRefreshToken(prnOid, esiaNewRefreshTokenStr, expiresIn);
|
EsiaTokensStore.addRefreshToken(prnOid, esiaNewRefreshTokenStr, expiresIn);
|
||||||
Response ervuIdResponse = getErvuIdResponse(esiaAccessTokenStr);
|
PersonModel personModel = personalDataService.getPersonModel(esiaAccessTokenStr);
|
||||||
|
Response ervuIdResponse = getErvuIdResponse(personModel);
|
||||||
createTokenAndAddCookie(response, esiaAccessToken.getSbj_id(), ervuIdResponse.getErvuId(), expiresIn);
|
createTokenAndAddCookie(response, esiaAccessToken.getSbj_id(), ervuIdResponse.getErvuId(), expiresIn);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
|
@ -354,9 +379,12 @@ public class EsiaAuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String logout(HttpServletRequest request, HttpServletResponse response) {
|
public String logout(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
PersonModel personModel = null;
|
||||||
try {
|
try {
|
||||||
securityHelper.clearAccessCookies(response);
|
|
||||||
String userId = jwtTokenService.getUserAccountId(request);
|
String userId = jwtTokenService.getUserAccountId(request);
|
||||||
|
String accessToken = EsiaTokensStore.getAccessToken(userId);
|
||||||
|
personModel = personalDataService.getPersonModel(accessToken);
|
||||||
|
securityHelper.clearAccessCookies(response);
|
||||||
EsiaTokensStore.removeAccessToken(userId);
|
EsiaTokensStore.removeAccessToken(userId);
|
||||||
EsiaTokensStore.removeRefreshToken(userId);
|
EsiaTokensStore.removeRefreshToken(userId);
|
||||||
String logoutUrl = esiaConfig.getEsiaBaseUri() + esiaConfig.getEsiaLogoutUrl();
|
String logoutUrl = esiaConfig.getEsiaBaseUri() + esiaConfig.getEsiaLogoutUrl();
|
||||||
|
|
@ -364,35 +392,34 @@ public class EsiaAuthService {
|
||||||
URL url = new URL(logoutUrl);
|
URL url = new URL(logoutUrl);
|
||||||
Map<String, String> params = mapOf(
|
Map<String, String> params = mapOf(
|
||||||
"client_id", esiaConfig.getClientId(),
|
"client_id", esiaConfig.getClientId(),
|
||||||
"redirect_url", redirectUrl);
|
"redirect_url", redirectUrl
|
||||||
|
);
|
||||||
|
auditService.processAuthEvent(
|
||||||
|
request, personModel, AuditConstants.SUCCESS_STATUS, AuditConstants.LOGOUT_EVENT_TYPE
|
||||||
|
);
|
||||||
return buildUrl(url, params);
|
return buildUrl(url, params);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
if (personModel != null){
|
||||||
|
auditService.processAuthEvent(
|
||||||
|
request, personModel, AuditConstants.FAILURE_STATUS, AuditConstants.LOGOUT_EVENT_TYPE
|
||||||
|
);
|
||||||
|
}
|
||||||
throw new EsiaException(e);
|
throw new EsiaException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response getErvuIdResponse(String accessToken) {
|
public Response getErvuIdResponse(PersonModel personModel) {
|
||||||
long requestPersonData = 0, requestIdERVU = 0;
|
|
||||||
try {
|
try {
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
PersonModel personModel = personalDataService.getPersonModel(accessToken);
|
|
||||||
requestPersonData = System.currentTimeMillis() - startTime;
|
|
||||||
Person person = copyToPerson(personModel);
|
Person person = copyToPerson(personModel);
|
||||||
startTime = System.currentTimeMillis();
|
|
||||||
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
|
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
|
||||||
requestReplyTopic, objectMapper.writeValueAsString(person)
|
requestReplyTopic, objectMapper.writeValueAsString(person)
|
||||||
);
|
);
|
||||||
requestIdERVU = System.currentTimeMillis() - startTime;
|
|
||||||
return objectMapper.readValue(kafkaResponse, Response.class);
|
return objectMapper.readValue(kafkaResponse, Response.class);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new EsiaException(e);
|
throw new EsiaException(e);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
LOGGER.info("Thread {}: RequestPersonData: {}ms RequestIdERVU: {}ms",
|
|
||||||
Thread.currentThread().getId(), requestPersonData, requestIdERVU);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Person copyToPerson(PersonModel personModel) {
|
private Person copyToPerson(PersonModel personModel) {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,39 @@
|
||||||
package ru.micord.ervu.util;
|
package ru.micord.ervu.util;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gulnaz
|
* @author gulnaz
|
||||||
*/
|
*/
|
||||||
public final class DateUtil {
|
public final class DateUtils {
|
||||||
|
|
||||||
public static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
public static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
||||||
|
|
||||||
private DateUtil() {}
|
private static final DateTimeFormatter DATE_TIME_WITH_TIMEZONE_FORMATTER =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
|
||||||
|
|
||||||
|
private DateUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getClientTimeFromRequest(HttpServletRequest request) {
|
||||||
|
String clientTimeZone = request.getHeader("Client-Time-Zone");
|
||||||
|
ZoneId zoneId;
|
||||||
|
try {
|
||||||
|
zoneId = ZoneId.of(clientTimeZone);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
zoneId = ZoneId.systemDefault();
|
||||||
|
}
|
||||||
|
return ZonedDateTime.now(zoneId).format(DATE_TIME_WITH_TIMEZONE_FORMATTER);
|
||||||
|
}
|
||||||
|
|
||||||
public static LocalDate convertToLocalDate(String date) {
|
public static LocalDate convertToLocalDate(String date) {
|
||||||
return StringUtils.hasText(date)
|
return StringUtils.hasText(date)
|
||||||
10
config.md
10
config.md
|
|
@ -787,6 +787,16 @@ JBPM использует 3 корневых категории логирова
|
||||||
- `ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета
|
- `ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета
|
||||||
- `ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC` - топик для получения выписки из Реестра воинского учета
|
- `ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC` - топик для получения выписки из Реестра воинского учета
|
||||||
- `ERVU_KAFKA_EXTRACT_HEADER_CLASS` - класс для идентификации в заголовке запроса на получение выписки из Реестра повесток/Реестра воинского учета
|
- `ERVU_KAFKA_EXTRACT_HEADER_CLASS` - класс для идентификации в заголовке запроса на получение выписки из Реестра повесток/Реестра воинского учета
|
||||||
|
- `AUDIT_KAFKA_AUTHORIZATION_TOPIC` - топик для отправки аудита в журнал авторизации
|
||||||
|
- `AUDIT_KAFKA_ACTION_TOPIC` - топик для отправки аудита в журнал действий пользователя
|
||||||
|
- `AUDIT_KAFKA_FILE_DOWNLOAD_TOPIC` - топик для отправки аудита в журнал загрузки ЮЛ и ФЛ
|
||||||
|
- `AUDIT_KAFKA_BOOTSTRAP_SERVERS` - список пар хост:порт, использующихся для установки первоначального соединения с кластером Kafka
|
||||||
|
- `AUDIT_KAFKA_SECURITY_PROTOCOL` - протокол, используемый для взаимодействия с брокерами
|
||||||
|
- `AUDIT_KAFKA_DOC_LOGIN_MODULE` - имя класса для входа в систему для SASL-соединений в формате, используемом конфигурационными файлами JAAS
|
||||||
|
- `AUDIT_KAFKA_USERNAME` - пользователь для подключения к Kafka
|
||||||
|
- `AUDIT_KAFKA_PASSWORD` - пароль для подключения к Kafka
|
||||||
|
- `AUDIT_KAFKA_SASL_MECHANISM` - механизм SASL, используемый для клиентских подключений
|
||||||
|
- `AUDIT_KAFKA_ENABLED` - флажок для включения записи аудита в кафку
|
||||||
|
|
||||||
# Прочее
|
# Прочее
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,16 @@ ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC=ervu.extract.info.request
|
||||||
ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC=ervu.extract.info.response
|
ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC=ervu.extract.info.response
|
||||||
ERVU_KAFKA_EXTRACT_HEADER_CLASS=request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3
|
ERVU_KAFKA_EXTRACT_HEADER_CLASS=request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3
|
||||||
ERVU_KAFKA_DOC_LOGIN_MODULE=org.apache.kafka.common.security.scram.ScramLoginModule
|
ERVU_KAFKA_DOC_LOGIN_MODULE=org.apache.kafka.common.security.scram.ScramLoginModule
|
||||||
|
AUDIT_KAFKA_AUTHORIZATION_TOPIC=ervu.lkrp.auth.events
|
||||||
|
AUDIT_KAFKA_ACTION_TOPIC=ervu.lkrp.action.events
|
||||||
|
AUDIT_KAFKA_FILE_DOWNLOAD_TOPIC=ervu.lkrp.import.file
|
||||||
|
AUDIT_KAFKA_BOOTSTRAP_SERVERS=
|
||||||
|
AUDIT_KAFKA_SECURITY_PROTOCOL=
|
||||||
|
AUDIT_KAFKA_DOC_LOGIN_MODULE=
|
||||||
|
AUDIT_KAFKA_USERNAME=
|
||||||
|
AUDIT_KAFKA_PASSWORD=
|
||||||
|
AUDIT_KAFKA_SASL_MECHANISM=
|
||||||
|
AUDIT_KAFKA_ENABLED=false
|
||||||
|
|
||||||
ESIA_TOKEN_CLEAR_CRON=0 0 */1 * * *
|
ESIA_TOKEN_CLEAR_CRON=0 0 */1 * * *
|
||||||
COOKIE_PATH=/fl
|
COOKIE_PATH=/fl
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,16 @@
|
||||||
<property name="ervu.kafka.registry.extract.reply.topic" value="ervu.extract.info.response"/>
|
<property name="ervu.kafka.registry.extract.reply.topic" value="ervu.extract.info.response"/>
|
||||||
<property name="ervu.kafka.extract.header.class" value="request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3"/>
|
<property name="ervu.kafka.extract.header.class" value="request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3"/>
|
||||||
<property name="esia.token.clear.cron" value="0 0 */1 * * *"/>
|
<property name="esia.token.clear.cron" value="0 0 */1 * * *"/>
|
||||||
|
<property name="audit.kafka.bootstrap.servers" value="localhost:9092"/>
|
||||||
|
<property name="audit.kafka.authorization.topic" value="ervu.lkrp.auth.events"/>
|
||||||
|
<property name="audit.kafka.file.download.topic" value="ervu.lkrp.import.file"/>
|
||||||
|
<property name="audit.kafka.action.topic" value="ervu.lkrp.action.events"/>
|
||||||
|
<property name="audit.kafka.security.protocol" value="SASL_PLAINTEXT"/>
|
||||||
|
<property name="audit.kafka.doc.login.module" value="org.apache.kafka.common.security.scram.ScramLoginModule"/>
|
||||||
|
<property name="audit.kafka.sasl.mechanism" value="SCRAM-SHA-256"/>
|
||||||
|
<property name="audit.kafka.username" value="user1"/>
|
||||||
|
<property name="audit.kafka.password" value="Blfi9d2OFG"/>
|
||||||
|
<property name="audit.kafka.enabled" value="false"/>
|
||||||
</system-properties>
|
</system-properties>
|
||||||
<management>
|
<management>
|
||||||
<audit-log>
|
<audit-log>
|
||||||
|
|
|
||||||
42
frontend/src/ts/ervu/LinkClickHandler.ts
Normal file
42
frontend/src/ts/ervu/LinkClickHandler.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import {AnalyticalScope, Behavior, Control, NotNull} from "@webbpm/base-package";
|
||||||
|
import {ElementRef} from "@angular/core";
|
||||||
|
import {AuditService} from "./service/AuditService";
|
||||||
|
import {LinkEventTypeEnum} from "./component/enum/LinkEventTypeEnum";
|
||||||
|
|
||||||
|
@AnalyticalScope(Control)
|
||||||
|
export class LinkClickHandler extends Behavior {
|
||||||
|
@NotNull()
|
||||||
|
public eventType: LinkEventTypeEnum;
|
||||||
|
private control: Control;
|
||||||
|
private auditService: AuditService;
|
||||||
|
private el: ElementRef;
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
this.control = this.getScript(Control);
|
||||||
|
this.el = this.control.getEl();
|
||||||
|
super.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
|
super.bindEvents();
|
||||||
|
if (this.el) {
|
||||||
|
this.el.nativeElement.addEventListener('click',
|
||||||
|
(event: MouseEvent) => this.onClickFunction(event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unbindEvents() {
|
||||||
|
super.unbindEvents()
|
||||||
|
if (this.el) {
|
||||||
|
this.el.nativeElement.removeEventListener('click',
|
||||||
|
(event: MouseEvent) => this.onClickFunction(event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onClickFunction(event: MouseEvent) {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (target.tagName === 'A') {
|
||||||
|
this.auditService.logActionAudit(this.eventType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,8 +27,12 @@ export class ExtractLoadService extends Behavior {
|
||||||
this.button = this.getScript(AbstractButton);
|
this.button = this.getScript(AbstractButton);
|
||||||
this.httpClient = this.injector.get(HttpClient);
|
this.httpClient = this.injector.get(HttpClient);
|
||||||
this.onClickFunction = () => {
|
this.onClickFunction = () => {
|
||||||
|
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
this.httpClient.get('extract/' + this.formatRegistry, {
|
this.httpClient.get('extract/' + this.formatRegistry, {
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
|
headers: {
|
||||||
|
"Client-Time-Zone": timeZone,
|
||||||
|
},
|
||||||
observe: 'response'
|
observe: 'response'
|
||||||
}).toPromise()
|
}).toPromise()
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
|
||||||
5
frontend/src/ts/ervu/component/enum/LinkEventTypeEnum.ts
Normal file
5
frontend/src/ts/ervu/component/enum/LinkEventTypeEnum.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export enum LinkEventTypeEnum {
|
||||||
|
NAVIGATION_TO_SOURCE = "Переход на другие источники",
|
||||||
|
DOWNLOAD_TEMPLATE = "Скачивание шаблона",
|
||||||
|
DOWNLOAD_EXAMPLE = "Скачивание примера заполнения формы"
|
||||||
|
}
|
||||||
43
frontend/src/ts/ervu/service/AuditService.ts
Normal file
43
frontend/src/ts/ervu/service/AuditService.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import {Injectable} from "@angular/core";
|
||||||
|
import {HttpClient} from "@angular/common/http";
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuditService {
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient, private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public logActionAudit(eventType: string, fileName?: string): void {
|
||||||
|
const currentRoute = this.router.url;
|
||||||
|
const sourceUrl = window.location.href;
|
||||||
|
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
|
||||||
|
const data: AuditAction = {
|
||||||
|
eventType: eventType,
|
||||||
|
sourceUrl: sourceUrl,
|
||||||
|
route: currentRoute,
|
||||||
|
fileName: fileName
|
||||||
|
};
|
||||||
|
|
||||||
|
this.httpClient.post("audit/action", data, {
|
||||||
|
headers: {
|
||||||
|
"Client-Time-Zone": timeZone,
|
||||||
|
}
|
||||||
|
}).toPromise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuditAction {
|
||||||
|
eventType: string;
|
||||||
|
sourceUrl: string;
|
||||||
|
route: string;
|
||||||
|
fileName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AuditConstants {
|
||||||
|
public static readonly OPEN_PAGE_EVENT = "Открытие страницы";
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,7 @@ import {LogOutComponent} from "./component/logout.component";
|
||||||
import {LoadForm} from "../../ervu/component/container/LoadForm";
|
import {LoadForm} from "../../ervu/component/container/LoadForm";
|
||||||
import {InMemoryStaticGrid} from "../../ervu/component/grid/InMemoryStaticGrid";
|
import {InMemoryStaticGrid} from "../../ervu/component/grid/InMemoryStaticGrid";
|
||||||
import {AuthenticationService} from "../security/authentication.service";
|
import {AuthenticationService} from "../security/authentication.service";
|
||||||
|
import {AuditService} from "../../ervu/service/AuditService";
|
||||||
import {HomeLandingComponent} from "./component/home-landing.component";
|
import {HomeLandingComponent} from "./component/home-landing.component";
|
||||||
|
|
||||||
registerLocaleData(localeRu);
|
registerLocaleData(localeRu);
|
||||||
|
|
@ -64,7 +65,7 @@ export function checkAuthentication(authService: AuthenticationService): () => P
|
||||||
DIRECTIVES
|
DIRECTIVES
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
AuthenticationService,
|
AuthenticationService, AuditService,
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: checkAuthentication,
|
useFactory: checkAuthentication,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
Router
|
Router
|
||||||
} from "@angular/router";
|
} from "@angular/router";
|
||||||
import {ProgressIndicationService} from "@webbpm/base-package";
|
import {ProgressIndicationService} from "@webbpm/base-package";
|
||||||
|
import {AuditConstants, AuditService} from "../../../ervu/service/AuditService";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
moduleId: module.id,
|
moduleId: module.id,
|
||||||
|
|
@ -21,7 +22,8 @@ export class WebbpmComponent {
|
||||||
|
|
||||||
constructor(private router: Router,
|
constructor(private router: Router,
|
||||||
private progressIndicationService: ProgressIndicationService,
|
private progressIndicationService: ProgressIndicationService,
|
||||||
private cd: ChangeDetectorRef) {
|
private cd: ChangeDetectorRef,
|
||||||
|
private auditService: AuditService) {
|
||||||
router.events.subscribe((event: Event) => {
|
router.events.subscribe((event: Event) => {
|
||||||
if (event instanceof NavigationStart) {
|
if (event instanceof NavigationStart) {
|
||||||
progressIndicationService.showProgressBar();
|
progressIndicationService.showProgressBar();
|
||||||
|
|
@ -29,9 +31,15 @@ export class WebbpmComponent {
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
}
|
}
|
||||||
else if (event instanceof NavigationEnd
|
else if (event instanceof NavigationEnd
|
||||||
|| event instanceof NavigationError
|
|| event instanceof NavigationError
|
||||||
|| event instanceof NavigationCancel) {
|
|| event instanceof NavigationCancel) {
|
||||||
progressIndicationService.hideProgressBar();
|
progressIndicationService.hideProgressBar();
|
||||||
|
|
||||||
|
if (event instanceof NavigationEnd
|
||||||
|
&& event.url != '/home'
|
||||||
|
&& event.url != '/access-denied') {
|
||||||
|
this.auditService.logActionAudit(AuditConstants.OPEN_PAGE_EVENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1034,6 +1034,7 @@
|
||||||
<componentRootId>6f1b4ecf-7311-41ea-87f7-56f77ea66251</componentRootId>
|
<componentRootId>6f1b4ecf-7311-41ea-87f7-56f77ea66251</componentRootId>
|
||||||
<name>Гиперссылка - на Госуслугах</name>
|
<name>Гиперссылка - на Госуслугах</name>
|
||||||
<container>false</container>
|
<container>false</container>
|
||||||
|
<expanded>false</expanded>
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="2fe08181-8a1e-4cda-be3a-0b0ddcb21603">
|
<scripts id="2fe08181-8a1e-4cda-be3a-0b0ddcb21603">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -1072,6 +1073,22 @@
|
||||||
</value>
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
</properties>
|
</properties>
|
||||||
|
</scripts>
|
||||||
|
<scripts id="53f844ea-7cd7-4bd3-b9fa-0ba97d517b5f">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
</scripts>
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
</children>
|
</children>
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,6 @@
|
||||||
<componentRootId>a674ce01-eadd-4297-b782-53e45e059310</componentRootId>
|
<componentRootId>a674ce01-eadd-4297-b782-53e45e059310</componentRootId>
|
||||||
<name>HB - (сценарий) в связи с неявкой в военкомат без уважительной причины в течение 20 календарных</name>
|
<name>HB - (сценарий) в связи с неявкой в военкомат без уважительной причины в течение 20 календарных</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -325,7 +324,6 @@
|
||||||
<componentRootId>854640d1-9de8-4d5a-8f00-5d33cdf097f3</componentRootId>
|
<componentRootId>854640d1-9de8-4d5a-8f00-5d33cdf097f3</componentRootId>
|
||||||
<name>HB - (сценарий) в качестве ограничения, направленного на обеспечение явки в военкомат</name>
|
<name>HB - (сценарий) в качестве ограничения, направленного на обеспечение явки в военкомат</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -450,7 +448,6 @@
|
||||||
<componentRootId>0276d338-dbbc-406a-a356-96f7fd02a5a6</componentRootId>
|
<componentRootId>0276d338-dbbc-406a-a356-96f7fd02a5a6</componentRootId>
|
||||||
<name>Таблица - временные меры</name>
|
<name>Таблица - временные меры</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="fe8cfe1c-5381-411e-aee6-cf4b38fcea07">
|
<scripts id="fe8cfe1c-5381-411e-aee6-cf4b38fcea07">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -623,7 +620,6 @@
|
||||||
<componentRootId>040fa808-ccbf-4844-b179-d63f54dc220a</componentRootId>
|
<componentRootId>040fa808-ccbf-4844-b179-d63f54dc220a</componentRootId>
|
||||||
<name>HB - запрет на выезд из России</name>
|
<name>HB - запрет на выезд из России</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -1683,7 +1679,6 @@
|
||||||
<componentRootId>52dc50c2-9c0c-44a8-94fb-ff190bdce295</componentRootId>
|
<componentRootId>52dc50c2-9c0c-44a8-94fb-ff190bdce295</componentRootId>
|
||||||
<name>VB - правый</name>
|
<name>VB - правый</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -1818,7 +1813,6 @@
|
||||||
<componentRootId>ffa21c64-1030-45c8-9901-db59f298fc11</componentRootId>
|
<componentRootId>ffa21c64-1030-45c8-9901-db59f298fc11</componentRootId>
|
||||||
<name>Диалоговые окна (информационные)</name>
|
<name>Диалоговые окна (информационные)</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
||||||
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
|
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
|
||||||
|
|
@ -3002,7 +2996,6 @@
|
||||||
<componentRootId>6a606277-7950-41b1-a59f-7d1deb5cccd2</componentRootId>
|
<componentRootId>6a606277-7950-41b1-a59f-7d1deb5cccd2</componentRootId>
|
||||||
<name>Уважительные причины неявки в военкомат</name>
|
<name>Уважительные причины неявки в военкомат</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -3232,6 +3225,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="9cc0c0c5-77a3-410f-874b-4d3879a36124">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="6dd87957-9a07-4c23-b203-90d8fb8bc181">
|
<children id="6dd87957-9a07-4c23-b203-90d8fb8bc181">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -3344,7 +3353,6 @@
|
||||||
<componentRootId>07d89523-77ea-40f3-96d0-952c74b082b0</componentRootId>
|
<componentRootId>07d89523-77ea-40f3-96d0-952c74b082b0</componentRootId>
|
||||||
<name>AC - для вызова диалогов</name>
|
<name>AC - для вызова диалогов</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
||||||
|
|
@ -513,7 +513,6 @@
|
||||||
<componentRootId>4e247261-22c9-4b75-bc42-1214d6478193</componentRootId>
|
<componentRootId>4e247261-22c9-4b75-bc42-1214d6478193</componentRootId>
|
||||||
<name>HB заголовок - Повестки</name>
|
<name>HB заголовок - Повестки</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -573,7 +572,6 @@
|
||||||
<componentRootId>3962166c-e12b-4866-b6fc-e53c9f233272</componentRootId>
|
<componentRootId>3962166c-e12b-4866-b6fc-e53c9f233272</componentRootId>
|
||||||
<name>VB - 1.1.1.1 (на имя выписана повестка) сценарий</name>
|
<name>VB - 1.1.1.1 (на имя выписана повестка) сценарий</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -640,7 +638,6 @@
|
||||||
<componentRootId>54ec4ded-0f1d-44b1-beea-1d10f2c65d6b</componentRootId>
|
<componentRootId>54ec4ded-0f1d-44b1-beea-1d10f2c65d6b</componentRootId>
|
||||||
<name>HB - явитесь по повестке в военкомат</name>
|
<name>HB - явитесь по повестке в военкомат</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
||||||
<scripts id="b6068710-0f31-48ec-8e03-c0c1480a40c0"/>
|
<scripts id="b6068710-0f31-48ec-8e03-c0c1480a40c0"/>
|
||||||
|
|
@ -783,7 +780,6 @@
|
||||||
<componentRootId>54755bcb-801b-450d-aa2e-046e2a405538</componentRootId>
|
<componentRootId>54755bcb-801b-450d-aa2e-046e2a405538</componentRootId>
|
||||||
<name>VB - 1.1.1.1 (на ? дату нет сформированных повесток) сценарий</name>
|
<name>VB - 1.1.1.1 (на ? дату нет сформированных повесток) сценарий</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -919,7 +915,6 @@
|
||||||
<componentRootId>ae6bbd9c-b3f6-458a-9c19-07e06a4716da</componentRootId>
|
<componentRootId>ae6bbd9c-b3f6-458a-9c19-07e06a4716da</componentRootId>
|
||||||
<name>VB - 1.1.1.1 (в реестре нет информации о сформированных повестках) сценарий</name>
|
<name>VB - 1.1.1.1 (в реестре нет информации о сформированных повестках) сценарий</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -1728,7 +1723,6 @@
|
||||||
<componentRootId>8ed0924a-73dc-4732-8426-0a7217654309</componentRootId>
|
<componentRootId>8ed0924a-73dc-4732-8426-0a7217654309</componentRootId>
|
||||||
<name>HB - данные загружаются</name>
|
<name>HB - данные загружаются</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -2404,7 +2398,6 @@
|
||||||
<componentRootId>935a9f9f-4d12-4813-b313-919627c0e642</componentRootId>
|
<componentRootId>935a9f9f-4d12-4813-b313-919627c0e642</componentRootId>
|
||||||
<name>VB - 1.1.2.2 (применены временные меры) сценарий</name>
|
<name>VB - 1.1.2.2 (применены временные меры) сценарий</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -2961,7 +2954,6 @@
|
||||||
<componentRootId>4b46dfb0-e372-48e7-96cb-6d488cbfbc55</componentRootId>
|
<componentRootId>4b46dfb0-e372-48e7-96cb-6d488cbfbc55</componentRootId>
|
||||||
<name>VB - 1.1.2.2 (на "дата" нет действующих ограничений) сценарий</name>
|
<name>VB - 1.1.2.2 (на "дата" нет действующих ограничений) сценарий</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -3114,7 +3106,6 @@
|
||||||
<componentRootId>751006da-a8d6-45c6-8eee-0895c30f8035</componentRootId>
|
<componentRootId>751006da-a8d6-45c6-8eee-0895c30f8035</componentRootId>
|
||||||
<name>VB - 1.1.2.2 (В реестре нет информации о примененных временных мерах) сценарий</name>
|
<name>VB - 1.1.2.2 (В реестре нет информации о примененных временных мерах) сценарий</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -3177,7 +3168,6 @@
|
||||||
<componentRootId>a4bb1eb3-c05a-4c96-acc4-885a99e4e28d</componentRootId>
|
<componentRootId>a4bb1eb3-c05a-4c96-acc4-885a99e4e28d</componentRootId>
|
||||||
<name>HB - данные загружаются</name>
|
<name>HB - данные загружаются</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -4049,7 +4039,6 @@
|
||||||
<componentRootId>304824d5-9f9f-4af9-9b08-6232f7536774</componentRootId>
|
<componentRootId>304824d5-9f9f-4af9-9b08-6232f7536774</componentRootId>
|
||||||
<name>FS - 1.1.3 (Воинский учёт)</name>
|
<name>FS - 1.1.3 (Воинский учёт)</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="46f20297-81d1-4786-bb17-2a78ca6fda6f">
|
<scripts id="46f20297-81d1-4786-bb17-2a78ca6fda6f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -7511,7 +7500,6 @@
|
||||||
<componentRootId>cc277790-aa36-4798-9a37-97d2a381e5e8</componentRootId>
|
<componentRootId>cc277790-aa36-4798-9a37-97d2a381e5e8</componentRootId>
|
||||||
<name>Реестр воинского учета</name>
|
<name>Реестр воинского учета</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -7709,6 +7697,7 @@
|
||||||
<componentRootId>61e47a39-6f30-4d52-92db-fce8f0df062c</componentRootId>
|
<componentRootId>61e47a39-6f30-4d52-92db-fce8f0df062c</componentRootId>
|
||||||
<name>Текст(гссылка) - Закон о воинской обязанности и военной службе, ст. 8.2.</name>
|
<name>Текст(гссылка) - Закон о воинской обязанности и военной службе, ст. 8.2.</name>
|
||||||
<container>false</container>
|
<container>false</container>
|
||||||
|
<expanded>false</expanded>
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -7726,6 +7715,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="ed835461-d64e-44b3-aa26-63abb48473ad">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="757294ad-d1dd-4a9f-987d-40a666b2ad9d">
|
<children id="757294ad-d1dd-4a9f-987d-40a666b2ad9d">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -7837,7 +7842,6 @@
|
||||||
<componentRootId>018ebef5-5b82-464e-ae64-b8a38c11a244</componentRootId>
|
<componentRootId>018ebef5-5b82-464e-ae64-b8a38c11a244</componentRootId>
|
||||||
<name>Реестр повесток</name>
|
<name>Реестр повесток</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -8155,6 +8159,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="f5574121-d46d-4ce1-a314-515f81571e49">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="7281e53c-3e98-453f-935a-cd5f93420620">
|
<children id="7281e53c-3e98-453f-935a-cd5f93420620">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -8273,7 +8293,6 @@
|
||||||
<componentRootId>e40b27e3-8df0-4e8c-adeb-6e24de6f18d2</componentRootId>
|
<componentRootId>e40b27e3-8df0-4e8c-adeb-6e24de6f18d2</componentRootId>
|
||||||
<name>Временные меры</name>
|
<name>Временные меры</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -8626,6 +8645,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="72fc7c7d-ab13-40f5-a79d-75619e3af934">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="52473ef0-1993-4be5-a86f-7cbc6dc8e75a">
|
<children id="52473ef0-1993-4be5-a86f-7cbc6dc8e75a">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -8751,7 +8786,6 @@
|
||||||
<componentRootId>dce4d66d-4b4f-4883-a54c-e44e96a06a53</componentRootId>
|
<componentRootId>dce4d66d-4b4f-4883-a54c-e44e96a06a53</componentRootId>
|
||||||
<name>Уважительные причины неявки в военкомат</name>
|
<name>Уважительные причины неявки в военкомат</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -8981,6 +9015,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="9b7eead5-b15c-4e63-a6c2-ef164b092268">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="3e33975b-5bde-4d58-a4d5-a7acb9633beb">
|
<children id="3e33975b-5bde-4d58-a4d5-a7acb9633beb">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -9092,7 +9142,6 @@
|
||||||
<componentRootId>5777f90d-5b51-4c1b-b0cc-4ace05faa8f3</componentRootId>
|
<componentRootId>5777f90d-5b51-4c1b-b0cc-4ace05faa8f3</componentRootId>
|
||||||
<name>Диалог - Отрицательное количество дней до явки в военкомат</name>
|
<name>Диалог - Отрицательное количество дней до явки в военкомат</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -9406,7 +9455,6 @@
|
||||||
<componentRootId>2452bb18-95f0-4bfc-a40d-52b59e3c5cd6</componentRootId>
|
<componentRootId>2452bb18-95f0-4bfc-a40d-52b59e3c5cd6</componentRootId>
|
||||||
<name>AC - на вызов диалоговых окон</name>
|
<name>AC - на вызов диалоговых окон</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -10395,7 +10443,6 @@
|
||||||
<componentRootId>5443b358-365f-4bfd-bb4c-f2854dd96da4</componentRootId>
|
<componentRootId>5443b358-365f-4bfd-bb4c-f2854dd96da4</componentRootId>
|
||||||
<name>Диалоговые окна отправки на электронную почту</name>
|
<name>Диалоговые окна отправки на электронную почту</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
||||||
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
|
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
|
||||||
|
|
@ -10558,6 +10605,22 @@
|
||||||
<value>
|
<value>
|
||||||
<simple>"https://www.gosuslugi.ru"</simple>
|
<simple>"https://www.gosuslugi.ru"</simple>
|
||||||
</value>
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
|
<scripts id="a5b10562-a190-4409-bbc9-afc6e9dcf26d">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
</properties>
|
</properties>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
|
@ -10692,7 +10755,6 @@
|
||||||
<componentRootId>f25ca4de-d55b-4a06-bb4c-5eedd65d4095</componentRootId>
|
<componentRootId>f25ca4de-d55b-4a06-bb4c-5eedd65d4095</componentRootId>
|
||||||
<name>Диалог - Отправка выписки на электронную почту - к удалению</name>
|
<name>Диалог - Отправка выписки на электронную почту - к удалению</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -10869,6 +10931,22 @@
|
||||||
<value>
|
<value>
|
||||||
<simple>"https://www.gosuslugi.ru"</simple>
|
<simple>"https://www.gosuslugi.ru"</simple>
|
||||||
</value>
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
|
<scripts id="d727881a-0a95-45a3-ad0d-e9d6d58e816a">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
</properties>
|
</properties>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
|
@ -11088,7 +11166,6 @@
|
||||||
<componentRootId>673d4fd7-0527-41df-abcd-2ab522bb161c</componentRootId>
|
<componentRootId>673d4fd7-0527-41df-abcd-2ab522bb161c</componentRootId>
|
||||||
<name>Диалог - Выписка отправлена - к удалению</name>
|
<name>Диалог - Выписка отправлена - к удалению</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -11268,7 +11345,6 @@
|
||||||
<componentRootId>d9788c7d-ebeb-413a-969a-a33f167a2bd9</componentRootId>
|
<componentRootId>d9788c7d-ebeb-413a-969a-a33f167a2bd9</componentRootId>
|
||||||
<name>Диалог - не удалось отправить выписку</name>
|
<name>Диалог - не удалось отправить выписку</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -11461,7 +11537,6 @@
|
||||||
<componentRootId>8aff628b-a0a4-4296-854d-8a03dbef5937</componentRootId>
|
<componentRootId>8aff628b-a0a4-4296-854d-8a03dbef5937</componentRootId>
|
||||||
<name>AC - на вызов диалоговых окон</name>
|
<name>AC - на вызов диалоговых окон</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f"/>
|
||||||
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
|
<scripts id="72befe90-1915-483f-b88c-d1ec5d4bdc8e"/>
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,6 @@
|
||||||
<componentRootId>2d0083b3-0994-4131-9cfc-de84cab46dab</componentRootId>
|
<componentRootId>2d0083b3-0994-4131-9cfc-de84cab46dab</componentRootId>
|
||||||
<name>HB - явитесь по повестке в военкомат. Ели не придёте в срок, к Вам применят временные меры</name>
|
<name>HB - явитесь по повестке в военкомат. Ели не придёте в срок, к Вам применят временные меры</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -1101,6 +1100,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="bf78cf16-a0a1-41ee-9945-8670cd247a15">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
</children>
|
</children>
|
||||||
<children id="7aabbeed-3e64-4cdd-8fe3-841b134da135">
|
<children id="7aabbeed-3e64-4cdd-8fe3-841b134da135">
|
||||||
|
|
@ -2412,7 +2427,6 @@
|
||||||
<componentRootId>c9c74406-f8f4-4a9a-8a62-57fe026f5fa5</componentRootId>
|
<componentRootId>c9c74406-f8f4-4a9a-8a62-57fe026f5fa5</componentRootId>
|
||||||
<name>FS - (если вы не можете явиться по уважительной причине)</name>
|
<name>FS - (если вы не можете явиться по уважительной причине)</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="46f20297-81d1-4786-bb17-2a78ca6fda6f">
|
<scripts id="46f20297-81d1-4786-bb17-2a78ca6fda6f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -2505,7 +2519,6 @@
|
||||||
<componentRootId>2f73cbfa-c121-49b0-994a-1bc17d654e1a</componentRootId>
|
<componentRootId>2f73cbfa-c121-49b0-994a-1bc17d654e1a</componentRootId>
|
||||||
<name>FS - (дней до применения всех временных мер)</name>
|
<name>FS - (дней до применения всех временных мер)</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="46f20297-81d1-4786-bb17-2a78ca6fda6f">
|
<scripts id="46f20297-81d1-4786-bb17-2a78ca6fda6f">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -2838,6 +2851,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="11e50082-7200-4ad6-bd54-ee10c3c0b5a2">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="b6aa0a33-f198-4846-9105-64aa80094be6">
|
<children id="b6aa0a33-f198-4846-9105-64aa80094be6">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -3249,6 +3278,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="3faadefb-4757-4f48-8b41-ffde6981f883">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="e78fddf7-4f36-45cf-89a7-29c68e3616e8">
|
<children id="e78fddf7-4f36-45cf-89a7-29c68e3616e8">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -3360,7 +3405,6 @@
|
||||||
<componentRootId>43f57db1-0f42-4d3c-8166-45e7691b124a</componentRootId>
|
<componentRootId>43f57db1-0f42-4d3c-8166-45e7691b124a</componentRootId>
|
||||||
<name>Временные меры</name>
|
<name>Временные меры</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -3684,6 +3728,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="ce2084ca-ce7d-4789-9ba2-e78cc8df9bef">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="c90d9a4f-0c35-47a1-a07c-345240c3b7d3">
|
<children id="c90d9a4f-0c35-47a1-a07c-345240c3b7d3">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -3802,7 +3862,6 @@
|
||||||
<componentRootId>76ac701a-62f6-493e-8ab3-9391e956c3f1</componentRootId>
|
<componentRootId>76ac701a-62f6-493e-8ab3-9391e956c3f1</componentRootId>
|
||||||
<name>Уважительные причины неявки в военкомат</name>
|
<name>Уважительные причины неявки в военкомат</name>
|
||||||
<container>true</container>
|
<container>true</container>
|
||||||
<expanded>false</expanded>
|
|
||||||
<childrenReordered>false</childrenReordered>
|
<childrenReordered>false</childrenReordered>
|
||||||
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
<scripts id="cf4526a1-96ab-4820-8aa9-62fb54c2b64c">
|
||||||
<properties>
|
<properties>
|
||||||
|
|
@ -4032,6 +4091,22 @@
|
||||||
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
<scripts id="f203f156-be32-4131-9c86-4d6bac6d5d56">
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</scripts>
|
</scripts>
|
||||||
|
<scripts id="29b36664-c038-438c-b4a4-41eb37d0225f">
|
||||||
|
<classRef type="TS">
|
||||||
|
<className>LinkClickHandler</className>
|
||||||
|
<packageName>ervu</packageName>
|
||||||
|
</classRef>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
<expanded>true</expanded>
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>eventType</key>
|
||||||
|
<value>
|
||||||
|
<simple>"NAVIGATION_TO_SOURCE"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
<children id="72183341-d63b-4e4b-85a5-0187806b8158">
|
<children id="72183341-d63b-4e4b-85a5-0187806b8158">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue