Merge remote-tracking branch 'origin/hotfix/1.9.8' into feature/SUPPORT-8897_fix_handler
This commit is contained in:
commit
cb6b472268
49 changed files with 1425 additions and 121 deletions
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ru.micord.ervu.lkrp</groupId>
|
<groupId>ru.micord.ervu.lkrp</groupId>
|
||||||
<artifactId>fl</artifactId>
|
<artifactId>fl</artifactId>
|
||||||
<version>1.9.5-SNAPSHOT</version>
|
<version>1.9.8-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
||||||
<artifactId>backend</artifactId>
|
<artifactId>backend</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -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,113 @@
|
||||||
|
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;
|
||||||
|
private String serverIp;
|
||||||
|
private String serverHostName;
|
||||||
|
private String clientIp;
|
||||||
|
private String clientHostName;
|
||||||
|
|
||||||
|
public AuditAuthorizationEvent(
|
||||||
|
String esiaPersonId, String eventTime, String firstName,
|
||||||
|
String lastName, String middleName, String snils,
|
||||||
|
String status, String eventType, String serverIp,
|
||||||
|
String serverHostName, String clientIp, String clientHostName) {
|
||||||
|
super(esiaPersonId, eventTime);
|
||||||
|
this.status = status;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.middleName = middleName;
|
||||||
|
this.snils = snils;
|
||||||
|
this.eventType = eventType;
|
||||||
|
this.serverIp = serverIp;
|
||||||
|
this.serverHostName = serverHostName;
|
||||||
|
this.clientIp = clientIp;
|
||||||
|
this.clientHostName = clientHostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerIp() {
|
||||||
|
return serverIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerIp(String serverIp) {
|
||||||
|
this.serverIp = serverIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerHostName() {
|
||||||
|
return serverHostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerHostName(String serverHostName) {
|
||||||
|
this.serverHostName = serverHostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientIp() {
|
||||||
|
return clientIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientIp(String clientIp) {
|
||||||
|
this.clientIp = clientIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientHostName() {
|
||||||
|
return clientHostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientHostName(String clientHostName) {
|
||||||
|
this.clientHostName = clientHostName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,114 @@
|
||||||
|
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;
|
||||||
|
import ru.micord.ervu.util.NetworkUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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) {
|
||||||
|
String serverIp = NetworkUtils.getServerIp();
|
||||||
|
String clientIp = NetworkUtils.getClientIp(request);
|
||||||
|
String serverHostName = NetworkUtils.getHostName(serverIp);
|
||||||
|
String clientHostName = NetworkUtils.getHostName(clientIp);
|
||||||
|
|
||||||
|
AuditAuthorizationEvent event = new AuditAuthorizationEvent(
|
||||||
|
personModel.getPrnsId(),
|
||||||
|
DateUtils.getClientTimeFromRequest(request),
|
||||||
|
personModel.getFirstName(),
|
||||||
|
personModel.getLastName(),
|
||||||
|
personModel.getMiddleName(),
|
||||||
|
personModel.getSnils(),
|
||||||
|
status,
|
||||||
|
eventType,
|
||||||
|
serverIp,
|
||||||
|
serverHostName,
|
||||||
|
clientIp,
|
||||||
|
clientHostName
|
||||||
|
);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,11 @@ package ru.micord.ervu.controller;
|
||||||
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
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;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
|
@ -15,10 +17,13 @@ import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
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 ru.micord.ervu.audit.constants.AuditConstants;
|
||||||
import rtl.pgs.ervu.proto.ResponseData;
|
import ru.micord.ervu.audit.service.AuditService;
|
||||||
import ru.micord.ervu.dto.ExtractEmptyRequestDto;
|
import ru.micord.ervu.dto.ExtractEmptyRequestDto;
|
||||||
import ru.micord.ervu.dto.ExtractRequestDto;
|
import ru.micord.ervu.dto.ExtractRequestDto;
|
||||||
|
import ru.micord.ervu.kafka.dto.EmptyExtract;
|
||||||
|
import ru.micord.ervu.kafka.dto.Extract;
|
||||||
|
import ru.micord.ervu.kafka.dto.FullExtract;
|
||||||
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
||||||
import ru.micord.ervu.security.esia.model.PersonModel;
|
import ru.micord.ervu.security.esia.model.PersonModel;
|
||||||
import ru.micord.ervu.security.esia.service.PersonalDataService;
|
import ru.micord.ervu.security.esia.service.PersonalDataService;
|
||||||
|
|
@ -26,6 +31,8 @@ import ru.micord.ervu.security.esia.token.EsiaTokensStore;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.UserIdsPair;
|
import ru.micord.ervu.security.webbpm.jwt.UserIdsPair;
|
||||||
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
|
||||||
*/
|
*/
|
||||||
|
|
@ -33,6 +40,7 @@ import ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil;
|
||||||
public class ExtractController {
|
public class ExtractController {
|
||||||
private final PersonalDataService personalDataService;
|
private final PersonalDataService personalDataService;
|
||||||
private final ReplyingKafkaService<Object, Bytes> replyingKafkaService;
|
private final ReplyingKafkaService<Object, Bytes> replyingKafkaService;
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
@Value("${ervu.kafka.registry.extract.empty.request.topic}")
|
@Value("${ervu.kafka.registry.extract.empty.request.topic}")
|
||||||
private String registryExtractEmptyRequestTopic;
|
private String registryExtractEmptyRequestTopic;
|
||||||
|
|
@ -40,59 +48,72 @@ public class ExtractController {
|
||||||
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;
|
||||||
|
@Value("${ervu.kafka.registry.extract.type.header:empty}")
|
||||||
|
private String registryExtractTypeHeader;
|
||||||
|
|
||||||
public ExtractController(PersonalDataService personalDataService, ReplyingKafkaService<Object, Bytes> replyingKafkaService) {
|
public ExtractController(
|
||||||
|
PersonalDataService personalDataService,
|
||||||
|
ReplyingKafkaService<Object, Bytes> replyingKafkaService,
|
||||||
|
AuditService auditService
|
||||||
|
) {
|
||||||
this.personalDataService = personalDataService;
|
this.personalDataService = personalDataService;
|
||||||
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) {
|
||||||
UserIdsPair userIdsPair = SecurityUtil.getUserIdsPair();
|
UserIdsPair userIdsPair = SecurityUtil.getUserIdsPair();
|
||||||
String ervuId = userIdsPair.getErvuId();
|
String ervuId = userIdsPair.getErvuId();
|
||||||
String fileName;
|
ConsumerRecord<String, Bytes> record;
|
||||||
ByteString file;
|
boolean isEmpty = true;
|
||||||
|
|
||||||
|
if (ervuId != null) {
|
||||||
|
ExtractRequestDto request = new ExtractRequestDto(ervuId, formatRegistry);
|
||||||
|
record = replyingKafkaService.sendMessageAndGetReply(
|
||||||
|
registryExtractRequestTopic, registryExtractReplyTopic, request);
|
||||||
|
isEmpty = Arrays.stream(record.headers().toArray())
|
||||||
|
.filter(header -> header.key().equals(registryExtractTypeHeader))
|
||||||
|
.findFirst()
|
||||||
|
.map(header -> Boolean.parseBoolean(new String(header.value(), StandardCharsets.UTF_8)))
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String esiaUserId = userIdsPair.getEsiaUserId(); // esiaUserId is not null here
|
||||||
|
String esiaAccessToken = EsiaTokensStore.getAccessToken(esiaUserId);
|
||||||
|
PersonModel personModel = personalDataService.getPersonModel(esiaAccessToken);
|
||||||
|
|
||||||
|
ExtractEmptyRequestDto emptyRequest = new ExtractEmptyRequestDto(
|
||||||
|
personModel.getLastName(),
|
||||||
|
personModel.getFirstName(), personModel.getMiddleName(), personModel.getBirthDate(),
|
||||||
|
personModel.getSnils(), formatRegistry
|
||||||
|
);
|
||||||
|
record = replyingKafkaService.sendMessageAndGetReply(registryExtractEmptyRequestTopic,
|
||||||
|
registryExtractReplyTopic, emptyRequest);
|
||||||
|
}
|
||||||
|
byte[] bytes = record.value().get();
|
||||||
|
String fileName = null;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (ervuId != null) {
|
Extract extract = ervuId == null || isEmpty ? new EmptyExtract(bytes) : new FullExtract(bytes);
|
||||||
ExtractRequestDto request = new ExtractRequestDto(ervuId, formatRegistry);
|
fileName = extract.getFileName();
|
||||||
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractRequestTopic,
|
|
||||||
registryExtractReplyTopic, request).get();
|
|
||||||
ResponseData responseData = ResponseData.parseFrom(reply);
|
|
||||||
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
|
|
||||||
.getExtractRegistry();
|
|
||||||
fileName = extractRegistry.getFileName();
|
|
||||||
file = extractRegistry.getFile();
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String esiaUserId = userIdsPair.getEsiaUserId(); // esiaUserid is not null here
|
|
||||||
String esiaAccessToken = EsiaTokensStore.getAccessToken(esiaUserId);
|
|
||||||
PersonModel personModel = personalDataService.getPersonModel(esiaAccessToken);
|
|
||||||
|
|
||||||
ExtractEmptyRequestDto emptyRequest = new ExtractEmptyRequestDto(
|
|
||||||
personModel.getLastName(),
|
|
||||||
personModel.getFirstName(), personModel.getMiddleName(), personModel.getBirthDate(),
|
|
||||||
personModel.getSnils(), formatRegistry
|
|
||||||
);
|
|
||||||
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractEmptyRequestTopic,
|
|
||||||
registryExtractReplyTopic, emptyRequest).get();
|
|
||||||
rtl.pgs.ervu.proto.emptyrequest.ResponseData responseData = rtl.pgs.ervu.proto.emptyrequest.ResponseData
|
|
||||||
.parseFrom(reply);
|
|
||||||
rtl.pgs.ervu.proto.emptyrequest.ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
|
|
||||||
.getExtractRegistry();
|
|
||||||
fileName = extractRegistry.getFileName();
|
|
||||||
file = extractRegistry.getFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
String encodedFilename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
String encodedFilename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||||
|
ByteString file = extract.getFile();
|
||||||
InputStreamResource resource = new InputStreamResource(file.newInput());
|
InputStreamResource resource = new InputStreamResource(file.newInput());
|
||||||
|
size = file.size();
|
||||||
|
auditService.processDownloadEvent(servletRequest, size, fileName, formatRegistry,
|
||||||
|
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, fileName, formatRegistry,
|
||||||
|
AuditConstants.FAILURE_STATUS
|
||||||
|
);
|
||||||
throw new RuntimeException("Failed to parse data", e);
|
throw new RuntimeException("Failed to parse data", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,14 @@ import proto.ervu.rp.summons.RecruitmentInfo;
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.micord.ervu.kafka.dto;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import rtl.pgs.ervu.proto.emptyrequest.ExtractRegistry;
|
||||||
|
import rtl.pgs.ervu.proto.emptyrequest.ResponseData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gulnaz
|
||||||
|
*/
|
||||||
|
public class EmptyExtract extends Extract {
|
||||||
|
|
||||||
|
public EmptyExtract(byte[] bytes) throws InvalidProtocolBufferException {
|
||||||
|
ResponseData responseData = ResponseData.parseFrom(bytes);
|
||||||
|
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
|
||||||
|
.getExtractRegistry();
|
||||||
|
fileName = extractRegistry.getFileName();
|
||||||
|
file = extractRegistry.getFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
20
backend/src/main/java/ru/micord/ervu/kafka/dto/Extract.java
Normal file
20
backend/src/main/java/ru/micord/ervu/kafka/dto/Extract.java
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.micord.ervu.kafka.dto;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gulnaz
|
||||||
|
*/
|
||||||
|
public abstract class Extract {
|
||||||
|
|
||||||
|
protected String fileName;
|
||||||
|
protected ByteString file;
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteString getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.micord.ervu.kafka.dto;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import rtl.pgs.ervu.proto.ExtractRegistry;
|
||||||
|
import rtl.pgs.ervu.proto.ResponseData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gulnaz
|
||||||
|
*/
|
||||||
|
public class FullExtract extends Extract {
|
||||||
|
|
||||||
|
public FullExtract(byte[] bytes) throws InvalidProtocolBufferException {
|
||||||
|
ResponseData responseData = ResponseData.parseFrom(bytes);
|
||||||
|
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
|
||||||
|
.getExtractRegistry();
|
||||||
|
fileName = extractRegistry.getFileName();
|
||||||
|
file = extractRegistry.getFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ru.micord.ervu.kafka.exception;
|
||||||
|
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
|
import ru.cg.webbpm.modules.core.runtime.api.LocalizedException;
|
||||||
|
import ru.cg.webbpm.modules.core.runtime.api.MessageBundleUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emir Suleimanov
|
||||||
|
*/
|
||||||
|
public class KafkaMessageReplyTimeoutException extends LocalizedException {
|
||||||
|
private static final MessageSourceAccessor MESSAGE_SOURCE = MessageBundleUtils.createAccessor("messages/common_errors_messages");
|
||||||
|
private static final String KAFKA_REPLY_TIMEOUT = "kafka_reply_timeout";
|
||||||
|
|
||||||
|
public KafkaMessageReplyTimeoutException(Throwable cause) {
|
||||||
|
super(KAFKA_REPLY_TIMEOUT, MESSAGE_SOURCE, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package ru.micord.ervu.kafka.service;
|
package ru.micord.ervu.kafka.service;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
|
||||||
public interface ReplyingKafkaService<T, V> {
|
public interface ReplyingKafkaService<T, V> {
|
||||||
|
|
||||||
V sendMessageAndGetReply(String requestTopic,
|
ConsumerRecord<String, V> sendMessageAndGetReply(String requestTopic,
|
||||||
String replyTopic,
|
String replyTopic,
|
||||||
T requestMessage);
|
T requestMessage);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
|
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
|
||||||
import org.springframework.kafka.requestreply.RequestReplyFuture;
|
import org.springframework.kafka.requestreply.RequestReplyFuture;
|
||||||
|
import ru.micord.ervu.kafka.exception.KafkaMessageReplyTimeoutException;
|
||||||
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -19,14 +20,13 @@ public abstract class BaseReplyingKafkaService<T, V> implements ReplyingKafkaSer
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V sendMessageAndGetReply(String requestTopic, String replyTopic, T requestMessage) {
|
public ConsumerRecord<String, V> sendMessageAndGetReply(String requestTopic, String replyTopic, T requestMessage) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
RequestReplyFuture<String, T, V> replyFuture = getTemplate().sendAndReceive(
|
RequestReplyFuture<String, T, V> replyFuture = getTemplate().sendAndReceive(
|
||||||
getProducerRecord(requestTopic, replyTopic, requestMessage));
|
getProducerRecord(requestTopic, replyTopic, requestMessage));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
V result = Optional.ofNullable(replyFuture.get())
|
ConsumerRecord<String, V> result = Optional.ofNullable(replyFuture.get())
|
||||||
.map(ConsumerRecord::value)
|
|
||||||
.orElseThrow(() -> new RuntimeException("Kafka return result is null"));
|
.orElseThrow(() -> new RuntimeException("Kafka return result is null"));
|
||||||
LOGGER.info("Thread {} - KafkaSendMessageAndGetReply: {} ms",
|
LOGGER.info("Thread {} - KafkaSendMessageAndGetReply: {} ms",
|
||||||
Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
|
Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
|
||||||
|
|
@ -35,7 +35,7 @@ public abstract class BaseReplyingKafkaService<T, V> implements ReplyingKafkaSer
|
||||||
catch (InterruptedException | ExecutionException e) {
|
catch (InterruptedException | ExecutionException e) {
|
||||||
LOGGER.error("Thread {} - KafkaSendMessageAndGetReply: {} ms",
|
LOGGER.error("Thread {} - KafkaSendMessageAndGetReply: {} ms",
|
||||||
Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
|
Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
|
||||||
throw new RuntimeException("Failed to get kafka response", e);
|
throw new KafkaMessageReplyTimeoutException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected abstract ReplyingKafkaTemplate<String, T, V> getTemplate();
|
protected abstract ReplyingKafkaTemplate<String, T, V> getTemplate();
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,10 @@ public class EsiaController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/esia/auth")
|
@GetMapping(value = "/esia/auth")
|
||||||
public ResponseEntity<?> esiaAuth(@RequestParam(value = "code", required = false) String code,
|
public void esiaAuth(@RequestParam(value = "code", required = false) String code,
|
||||||
@RequestParam(value = "error", required = false) String error, HttpServletRequest request,
|
@RequestParam(value = "error", required = false) String error, HttpServletRequest request,
|
||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
return esiaAuthService.getEsiaTokensByCode(code, error, request, response);
|
esiaAuthService.authEsiaTokensByCode(code, error, request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/esia/refresh")
|
@RequestMapping(value = "/esia/refresh")
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,10 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
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;
|
||||||
|
|
@ -50,6 +51,7 @@ import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
|
||||||
import ru.micord.ervu.security.webbpm.jwt.model.Token;
|
import ru.micord.ervu.security.webbpm.jwt.model.Token;
|
||||||
|
|
||||||
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.getCurrentUserEsiaId;
|
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.getCurrentUserEsiaId;
|
||||||
|
import ru.cg.webbpm.modules.core.runtime.api.MessageBundleUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Eduard Tihomirov
|
* @author Eduard Tihomirov
|
||||||
|
|
@ -57,7 +59,8 @@ import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.getCurrentUse
|
||||||
@Service
|
@Service
|
||||||
public class EsiaAuthService {
|
public class EsiaAuthService {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||||
|
private static final MessageSourceAccessor MESSAGE_SOURCE = MessageBundleUtils.createAccessor(
|
||||||
|
"messages/common_errors_messages");
|
||||||
@Autowired
|
@Autowired
|
||||||
private ObjectMapper objectMapper;
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
|
@ -74,6 +77,9 @@ public class EsiaAuthService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private PersonalDataService personalDataService;
|
private PersonalDataService personalDataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuditService auditService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SecurityHelper securityHelper;
|
private SecurityHelper securityHelper;
|
||||||
|
|
||||||
|
|
@ -151,13 +157,10 @@ public class EsiaAuthService {
|
||||||
return uriBuilder.toString();
|
return uriBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<?> getEsiaTokensByCode(String esiaAuthCode, String error,
|
public void authEsiaTokensByCode(String esiaAuthCode, String error,
|
||||||
HttpServletRequest request, HttpServletResponse response) {
|
HttpServletRequest request, HttpServletResponse response) {
|
||||||
if (error != null && !error.equals("null")) {
|
if (error != null && !error.equals("null")) {
|
||||||
return new ResponseEntity<>(
|
throw new EsiaException(error);
|
||||||
"Произошла неизвестная ошибка. Обратитесь к системному администратору",
|
|
||||||
HttpStatus.FORBIDDEN
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
String esiaAccessTokenStr = null;
|
String esiaAccessTokenStr = null;
|
||||||
String prnOid = null;
|
String prnOid = null;
|
||||||
|
|
@ -239,21 +242,26 @@ public class EsiaAuthService {
|
||||||
Thread.currentThread().getId(), signSecret, requestAccessToken, verifySecret);
|
Thread.currentThread().getId(), signSecret, requestAccessToken, verifySecret);
|
||||||
}
|
}
|
||||||
PersonModel personModel = null;
|
PersonModel personModel = null;
|
||||||
|
String ervuId = null, status = null;
|
||||||
try {
|
try {
|
||||||
personModel = personalDataService.getPersonModel(esiaAccessTokenStr);
|
personModel = personalDataService.getPersonModel(esiaAccessTokenStr);
|
||||||
Response ervuIdResponse = getErvuIdResponse(personModel);
|
Response ervuIdResponse = getErvuIdResponse(personModel);
|
||||||
createTokenAndAddCookie(response, prnOid, ervuIdResponse.getErvuId(), expiresIn);
|
ervuId = ervuIdResponse.getErvuId();
|
||||||
return ResponseEntity.ok("Authentication successful");
|
status = AuditConstants.SUCCESS_STATUS;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
createTokenAndAddCookie(response, prnOid, null, expiresIn);
|
status = AuditConstants.FAILURE_STATUS;
|
||||||
String messageId = getMessageId(e);
|
if (e instanceof EsiaException || e instanceof JsonProcessingException) {
|
||||||
String messageWithId = String.format("[%s] %s", messageId, e.getMessage());
|
throw new EsiaException(e);
|
||||||
LOGGER.error(messageWithId, e);
|
}
|
||||||
return new ResponseEntity<>(
|
}
|
||||||
"Произошла ошибка " + messageId + ". Обратитесь к системному администратору",
|
finally {
|
||||||
HttpStatus.FORBIDDEN
|
if (personModel != null) {
|
||||||
);
|
auditService.processAuthEvent(
|
||||||
|
request, personModel, status, AuditConstants.LOGIN_EVENT_TYPE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
createTokenAndAddCookie(response, prnOid, ervuId, expiresIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,9 +367,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();
|
||||||
|
|
@ -369,10 +380,19 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -381,7 +401,7 @@ public class EsiaAuthService {
|
||||||
Person person = copyToPerson(personModel);
|
Person person = copyToPerson(personModel);
|
||||||
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
|
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
|
||||||
requestReplyTopic, objectMapper.writeValueAsString(person)
|
requestReplyTopic, objectMapper.writeValueAsString(person)
|
||||||
);
|
).value();
|
||||||
return objectMapper.readValue(kafkaResponse, Response.class);
|
return objectMapper.readValue(kafkaResponse, Response.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public class SubpoenaService {
|
||||||
}
|
}
|
||||||
SubpoenaRequestDto subpoenaRequestDto = new SubpoenaRequestDto(ervuId);
|
SubpoenaRequestDto subpoenaRequestDto = new SubpoenaRequestDto(ervuId);
|
||||||
byte[] reply = replyingKafkaService.sendMessageAndGetReply(recruitRequestTopic,
|
byte[] reply = replyingKafkaService.sendMessageAndGetReply(recruitRequestTopic,
|
||||||
recruitReplyTopic, subpoenaRequestDto).get();
|
recruitReplyTopic, subpoenaRequestDto).value().get();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SummonsResponseData responseData = SummonsResponseData.parseFrom(reply);
|
SummonsResponseData responseData = SummonsResponseData.parseFrom(reply);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
53
backend/src/main/java/ru/micord/ervu/util/NetworkUtils.java
Normal file
53
backend/src/main/java/ru/micord/ervu/util/NetworkUtils.java
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ru.micord.ervu.util;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adel Kalimullin
|
||||||
|
*/
|
||||||
|
public final class NetworkUtils {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(NetworkUtils.class);
|
||||||
|
private static final String IP_HEADER = "X-Forwarded-For";
|
||||||
|
private static final String UNKNOWN = "unknown";
|
||||||
|
|
||||||
|
private NetworkUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getServerIp() {
|
||||||
|
try {
|
||||||
|
InetAddress inetAddress = InetAddress.getLocalHost();
|
||||||
|
return inetAddress.getHostAddress();
|
||||||
|
}
|
||||||
|
catch (UnknownHostException e) {
|
||||||
|
LOGGER.error("Failed to get local IP address", e);
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getClientIp(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader(IP_HEADER);
|
||||||
|
if (StringUtils.hasText(ip) && !ip.equalsIgnoreCase(UNKNOWN)) {
|
||||||
|
return ip.split(",")[0].trim();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHostName(String ip) {
|
||||||
|
try {
|
||||||
|
InetAddress inetAddress = InetAddress.getByName(ip);
|
||||||
|
return inetAddress.getHostName();
|
||||||
|
}
|
||||||
|
catch (UnknownHostException e) {
|
||||||
|
LOGGER.error("Unknown host for IP {}", ip, e);
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
error.unknown=Система временно недоступна. Пожалуйста, повторите попытку позже.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
error.unknown=The system is temporarily unavailable. Please try again later.
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
kafka_reply_timeout=Превышено время ожидания ответа от сервера. Попробуйте повторить запрос позже или обратитесь к системному администратору
|
||||||
|
access_denied=Доступ запрещен. Пользователь должен быть включен в группу "Сотрудник, ответственный за военно-учетную работу" в ЕСИА
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
kafka_reply_timeout=Превышено время ожидания ответа от сервера. Попробуйте повторить запрос позже или обратитесь к системному администратору
|
||||||
|
access_denied=Доступ запрещен. Пользователь должен быть включен в группу "Сотрудник, ответственный за военно-учетную работу" в ЕСИА
|
||||||
10
config.md
10
config.md
|
|
@ -788,6 +788,16 @@ JBPM использует 3 корневых категории логирова
|
||||||
- `ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета при наличии ErvuId
|
- `ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета при наличии ErvuId
|
||||||
- `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` - флажок для включения записи аудита в кафку
|
||||||
|
|
||||||
# Прочее
|
# Прочее
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,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
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,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>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ru.micord.ervu.lkrp</groupId>
|
<groupId>ru.micord.ervu.lkrp</groupId>
|
||||||
<artifactId>fl</artifactId>
|
<artifactId>fl</artifactId>
|
||||||
<version>1.9.5-SNAPSHOT</version>
|
<version>1.9.8-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ru.micord.ervu.lkrp</groupId>
|
<groupId>ru.micord.ervu.lkrp</groupId>
|
||||||
<artifactId>fl</artifactId>
|
<artifactId>fl</artifactId>
|
||||||
<version>1.9.5-SNAPSHOT</version>
|
<version>1.9.8-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
||||||
|
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,8 +29,12 @@ export class ExtractLoadService extends Behavior {
|
||||||
this.errorEvent.subscribe(() => console.log("error event occurred", this.errorEvent));
|
this.errorEvent.subscribe(() => console.log("error event occurred", this.errorEvent));
|
||||||
this.onClickFunction = () => {
|
this.onClickFunction = () => {
|
||||||
console.log("click event occurred");
|
console.log("click event occurred");
|
||||||
|
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 = "Скачивание примера заполнения формы"
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,9 @@ export class InMemoryStaticGrid extends GridV2 {
|
||||||
super.initGrid();
|
super.initGrid();
|
||||||
this.subscription = this.injector.get(ErvuDataService).message.subscribe(value => {
|
this.subscription = this.injector.get(ErvuDataService).message.subscribe(value => {
|
||||||
this.rowData = value ? value[this.dataList] : null;
|
this.rowData = value ? value[this.dataList] : null;
|
||||||
|
this.initDeferred.promise.then(() => {
|
||||||
|
this.refreshData();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
pom.xml
2
pom.xml
|
|
@ -4,7 +4,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>ru.micord.ervu.lkrp</groupId>
|
<groupId>ru.micord.ervu.lkrp</groupId>
|
||||||
<artifactId>fl</artifactId>
|
<artifactId>fl</artifactId>
|
||||||
<version>1.9.5-SNAPSHOT</version>
|
<version>1.9.8-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<modules>
|
<modules>
|
||||||
<module>backend</module>
|
<module>backend</module>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ru.micord.ervu.lkrp</groupId>
|
<groupId>ru.micord.ervu.lkrp</groupId>
|
||||||
<artifactId>fl</artifactId>
|
<artifactId>fl</artifactId>
|
||||||
<version>1.9.5-SNAPSHOT</version>
|
<version>1.9.8-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
<groupId>ru.micord.ervu.lkrp.fl</groupId>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -869,7 +865,6 @@
|
||||||
<componentRootId>573a720b-91f7-4e25-a441-7fd3133fdf31</componentRootId>
|
<componentRootId>573a720b-91f7-4e25-a441-7fd3133fdf31</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 +1678,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 +1812,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"/>
|
||||||
|
|
@ -2045,6 +2038,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="a1579d08-139a-429e-8601-2bf95aa91147">
|
||||||
|
<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="56f58b69-0324-4823-bb69-98682542e514">
|
<children id="56f58b69-0324-4823-bb69-98682542e514">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -2456,6 +2465,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="f2041b5d-0cd4-4b7f-a790-98edc48e9d86">
|
||||||
|
<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="8ae2b128-9044-428e-b88e-7095f1207c97">
|
<children id="8ae2b128-9044-428e-b88e-7095f1207c97">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -2891,6 +2916,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="9d29fb9f-020d-46eb-a8c4-efd831aae46a">
|
||||||
|
<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="67caa536-dc5e-49c6-a8b9-c3c4cf9d0459">
|
<children id="67caa536-dc5e-49c6-a8b9-c3c4cf9d0459">
|
||||||
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
<prototypeId>fd7e47b9-dce1-4d14-9f3a-580c79f59579</prototypeId>
|
||||||
|
|
@ -3002,7 +3043,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>
|
||||||
|
|
@ -3174,6 +3214,7 @@
|
||||||
<componentRootId>613a502f-2276-454e-bb91-4596be5e94cf</componentRootId>
|
<componentRootId>613a502f-2276-454e-bb91-4596be5e94cf</componentRootId>
|
||||||
<name>Гиперссылка - Закон о воинской обязанности и военной службе, ст. 7.</name>
|
<name>Гиперссылка - Закон о воинской обязанности и военной службе, ст. 7.</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>
|
||||||
|
|
@ -3215,6 +3256,7 @@
|
||||||
<componentRootId>81c3d5d2-0f2e-401d-b107-4ad7467f7b30</componentRootId>
|
<componentRootId>81c3d5d2-0f2e-401d-b107-4ad7467f7b30</componentRootId>
|
||||||
<name>Текст(гссылка) - Закон о воинской обязанности и военной службе, ст. 7.</name>
|
<name>Текст(гссылка) - Закон о воинской обязанности и военной службе, ст. 7.</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>
|
||||||
|
|
@ -3232,6 +3274,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 +3402,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>
|
||||||
|
|
@ -1773,7 +1768,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>
|
||||||
|
|
@ -2443,7 +2437,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>
|
||||||
|
|
@ -3000,7 +2993,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>
|
||||||
|
|
@ -3153,7 +3145,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>
|
||||||
|
|
@ -3216,7 +3207,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>
|
||||||
|
|
@ -7326,7 +7316,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>
|
||||||
|
|
@ -7524,6 +7513,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>
|
||||||
|
|
@ -7541,6 +7531,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>
|
||||||
|
|
@ -7652,7 +7658,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>
|
||||||
|
|
@ -7970,6 +7975,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>
|
||||||
|
|
@ -8088,7 +8109,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>
|
||||||
|
|
@ -8441,6 +8461,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>
|
||||||
|
|
@ -8566,7 +8602,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>
|
||||||
|
|
@ -8796,6 +8831,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>
|
||||||
|
|
@ -8907,7 +8958,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>
|
||||||
|
|
@ -9221,7 +9271,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>
|
||||||
|
|
@ -10210,7 +10259,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"/>
|
||||||
|
|
@ -10373,6 +10421,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>
|
||||||
|
|
@ -10507,7 +10571,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>
|
||||||
|
|
@ -10684,6 +10747,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>
|
||||||
|
|
@ -10903,7 +10982,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>
|
||||||
|
|
@ -11083,7 +11161,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>
|
||||||
|
|
@ -11276,7 +11353,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>
|
||||||
|
|
@ -338,6 +337,7 @@
|
||||||
<componentRootId>fc2ddccc-d84c-4b0b-a9fc-5aa1391d590b</componentRootId>
|
<componentRootId>fc2ddccc-d84c-4b0b-a9fc-5aa1391d590b</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>
|
||||||
|
|
@ -1101,6 +1101,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">
|
||||||
|
|
@ -1133,6 +1149,12 @@
|
||||||
</item>
|
</item>
|
||||||
</value>
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>visible</key>
|
||||||
|
<value>
|
||||||
|
<simple>false</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
</properties>
|
</properties>
|
||||||
</scripts>
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
|
|
@ -2099,6 +2121,7 @@
|
||||||
<componentRootId>713e58f9-9106-4e75-bf08-23761e541e51</componentRootId>
|
<componentRootId>713e58f9-9106-4e75-bf08-23761e541e51</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>
|
||||||
|
|
@ -2412,7 +2435,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 +2527,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>
|
||||||
|
|
@ -2611,7 +2632,6 @@
|
||||||
<componentRootId>d63ff6bf-f971-4a5e-8b36-e4c5a2e48771</componentRootId>
|
<componentRootId>d63ff6bf-f971-4a5e-8b36-e4c5a2e48771</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"/>
|
||||||
|
|
@ -2838,6 +2858,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 +3285,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 +3412,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 +3735,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 +3869,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 +4098,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>
|
||||||
|
|
@ -4448,5 +4530,87 @@
|
||||||
</properties>
|
</properties>
|
||||||
</scripts>
|
</scripts>
|
||||||
</children>
|
</children>
|
||||||
|
<children id="66d254b2-bf2b-40eb-b175-ccc50b9dceed">
|
||||||
|
<prototypeId>98594cec-0a9b-4cef-af09-e1b71cb2ad9e</prototypeId>
|
||||||
|
<componentRootId>66d254b2-bf2b-40eb-b175-ccc50b9dceed</componentRootId>
|
||||||
|
<name>AC - временная мера</name>
|
||||||
|
<container>false</container>
|
||||||
|
<childrenReordered>false</childrenReordered>
|
||||||
|
<scripts id="37dff5c8-1599-4984-b107-c44a87b6da2e">
|
||||||
|
<properties>
|
||||||
|
<entry>
|
||||||
|
<key>elseActions</key>
|
||||||
|
<value>
|
||||||
|
<item id="8d3cc8e0-b29f-465f-bfd5-5b04403944b8" removed="true"/>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>eventRefs</key>
|
||||||
|
<value>
|
||||||
|
<item id="8bf6b67c-543f-4637-abc9-abc82dab3401" removed="false">
|
||||||
|
<value>
|
||||||
|
<complex>
|
||||||
|
<entry>
|
||||||
|
<key>behavior</key>
|
||||||
|
<value>
|
||||||
|
<simple>{"objectId":"05e0b1a0-7d08-4480-8532-b19692e8812a","packageName":"component.button","className":"Button","type":"TS"}</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>propertyName</key>
|
||||||
|
<value>
|
||||||
|
<simple>"clickEvent"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</complex>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>ifCondition</key>
|
||||||
|
<value>
|
||||||
|
<complex>
|
||||||
|
<entry>
|
||||||
|
<key>logicalOperation</key>
|
||||||
|
<value>
|
||||||
|
<simple>null</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</complex>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>thenActions</key>
|
||||||
|
<value>
|
||||||
|
<item id="d67b987f-e771-4551-808b-28c56b13febc" removed="false">
|
||||||
|
<value>
|
||||||
|
<complex>
|
||||||
|
<entry>
|
||||||
|
<key>behavior</key>
|
||||||
|
<value>
|
||||||
|
<simple>{"objectId":"43f57db1-0f42-4d3c-8166-45e7691b124a","packageName":"component","className":"Dialog","type":"TS"}</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>method</key>
|
||||||
|
<value>
|
||||||
|
<simple>"show"</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<key>value</key>
|
||||||
|
<value>
|
||||||
|
<simple>null</simple>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</complex>
|
||||||
|
</value>
|
||||||
|
</item>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</properties>
|
||||||
|
</scripts>
|
||||||
|
</children>
|
||||||
</rootObjects>
|
</rootObjects>
|
||||||
</xmlPage>
|
</xmlPage>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue