diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/exception/IdmValidatorException.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/exception/IdmValidatorException.java new file mode 100644 index 00000000..2b599f3a --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/exception/IdmValidatorException.java @@ -0,0 +1,14 @@ +package ru.micord.ervu.account_applications.component.exception; + +/** + * @author Emir Suleimanov + */ +public class IdmValidatorException extends RuntimeException { + public IdmValidatorException(String message) { + super(message); + } + + public IdmValidatorException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/model/dto/IdmPersonsResponse.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/dto/IdmPersonsResponse.java new file mode 100644 index 00000000..a9ceb60c --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/model/dto/IdmPersonsResponse.java @@ -0,0 +1,22 @@ +package ru.micord.ervu.account_applications.component.model.dto; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * @author Emir Suleimanov + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class IdmPersonsResponse { + private List> records; + + public List> getRecords() { + return records; + } + + public void setRecords(List> records) { + this.records = records; + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/rpc/IdmValidatorRpcService.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/rpc/IdmValidatorRpcService.java new file mode 100644 index 00000000..a31cc65a --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/rpc/IdmValidatorRpcService.java @@ -0,0 +1,22 @@ +package ru.micord.ervu.account_applications.component.rpc; + +import ru.micord.ervu.account_applications.component.service.IdmValidatorService; + +import ru.cg.webbpm.modules.standard_annotations.validation.NotNull; +import ru.cg.webbpm.modules.webkit.annotations.RpcCall; +import ru.cg.webbpm.modules.webkit.annotations.RpcService; +import ru.cg.webbpm.modules.webkit.beans.Behavior; + +/** + * @author Emir Suleimanov + */ +@RpcService +public class IdmValidatorRpcService extends Behavior { + @NotNull + public IdmValidatorService validatorService; + + @RpcCall + public boolean valueExists(String login) { + return validatorService.valueExists(login); + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmLoginValidatorService.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmLoginValidatorService.java new file mode 100644 index 00000000..2b3d84f6 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmLoginValidatorService.java @@ -0,0 +1,41 @@ +package ru.micord.ervu.account_applications.component.service; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import ru.micord.ervu.account_applications.component.exception.IdmValidatorException; + +/** + * @author Emir Suleimanov + */ +@Service +public class IdmLoginValidatorService implements IdmValidatorService{ + private final RestTemplate restTemplate; + + @Value("${ervu.url}") + private String ervuUrl; + + public IdmLoginValidatorService(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public boolean valueExists(String login) { + String url = String.format("%s/service/idm/credentials/login/%s", ervuUrl, login); + try { + ResponseEntity>> response = restTemplate.exchange( + url, HttpMethod.GET, null, new ParameterizedTypeReference<>() {} + ); + return response.getBody() != null && + response.getBody().stream() + .anyMatch(user -> login.equals(user.get("userName"))); + } catch (Exception e) { + throw new IdmValidatorException("Ошибка при проверке логина: " + login, e); + } + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmSnilsValidatorService.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmSnilsValidatorService.java new file mode 100644 index 00000000..8d6fcda0 --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmSnilsValidatorService.java @@ -0,0 +1,46 @@ +package ru.micord.ervu.account_applications.component.service; + +import java.util.Objects; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import ru.micord.ervu.account_applications.component.exception.IdmValidatorException; +import ru.micord.ervu.account_applications.component.model.dto.IdmPersonsResponse; + +/** + * @author Emir Suleimanov + */ +@Service +public class IdmSnilsValidatorService implements IdmValidatorService { + private final RestTemplate restTemplate; + + @Value("${ervu.url}") + private String ervuUrl; + + public IdmSnilsValidatorService(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public boolean valueExists(String snils) { + String url = String.format("%s/service/idm/persons?query=snils==\"%s\"", ervuUrl, snils); + try { + ResponseEntity response = restTemplate.exchange( + url, HttpMethod.GET, null, new ParameterizedTypeReference<>() {} + ); + IdmPersonsResponse records = response.getBody(); + if (Objects.nonNull(records)) { + return Optional.ofNullable(records.getRecords()) + .map(record -> record.stream().anyMatch(value -> snils.equals(value.get("snils")))) + .orElse(false); + } + return false; + } catch (Exception e) { + throw new IdmValidatorException("Ошибка при проверке СНИЛС: " + snils, e); + } + } +} diff --git a/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmValidatorService.java b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmValidatorService.java new file mode 100644 index 00000000..ead4d62e --- /dev/null +++ b/backend/src/main/java/ru/micord/ervu/account_applications/component/service/IdmValidatorService.java @@ -0,0 +1,8 @@ +package ru.micord.ervu.account_applications.component.service; + +/** + * @author Emir Suleimanov + */ +public interface IdmValidatorService { + boolean valueExists(String value); +} \ No newline at end of file diff --git a/frontend/src/resources/app-config.json b/frontend/src/resources/app-config.json index e82e7d15..b96610ca 100644 --- a/frontend/src/resources/app-config.json +++ b/frontend/src/resources/app-config.json @@ -16,6 +16,5 @@ "password_pattern": "^((?=(.*\\d){1,})(?=.*[a-zа-яё])(?=.*[A-ZА-ЯЁ]).{8,})$", "password_pattern_error": "Пароль должен содержать заглавные или прописные буквы и как минимум 1 цифру", "show.client.errors": false, - "available_task.single_fetch": true, - "ervu_url": "https://ervu-dev.pgs.rtlabs.ru/service" + "available_task.single_fetch": true } diff --git a/frontend/src/ts/account_applications/component/IdmService.ts b/frontend/src/ts/account_applications/component/IdmService.ts deleted file mode 100644 index e6111210..00000000 --- a/frontend/src/ts/account_applications/component/IdmService.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import {Observable, throwError} from 'rxjs'; -import {catchError, map} from "rxjs/operators"; -import {AppConfigService} from "@webbpm/base-package"; - -@Injectable({ - providedIn: 'root' - }) -export class IdmService { - private ervuUrl: string; - - constructor(private http: HttpClient, appConfigService: AppConfigService) { - this.ervuUrl = appConfigService.getParamValue("ervu_url"); - } - - checkLoginExists(login: string): Observable { - const url = `${this.ervuUrl}/idm/credentials/login/${login}`; - return this.http.get(url).pipe( - map(response => - response.length > 0 && response.some(user => user.userName === login) - ), - catchError(error => throwError(error)) - ); - } - - checkSnilsExists(snils: string): Observable { - const url = `${this.ervuUrl}/idm/persons?query=snils%3D%3D%22${snils}%22`; - return this.http.get<{ records: any[] }>(url).pipe( - map(response => - response.records.length > 0 && response.records.some(person => person.snils === snils) - ), - catchError(error => throwError(error)) - ); - } -} diff --git a/frontend/src/ts/account_applications/component/field/AbstractIdmValidator.ts b/frontend/src/ts/account_applications/component/field/AbstractIdmValidator.ts index 630170cc..123f9863 100644 --- a/frontend/src/ts/account_applications/component/field/AbstractIdmValidator.ts +++ b/frontend/src/ts/account_applications/component/field/AbstractIdmValidator.ts @@ -1,19 +1,22 @@ import {SimpleValidator, TextField} from "@webbpm/base-package"; import {Observable} from "rxjs"; -import {IdmService} from "../IdmService"; +import { + IdmValidatorRpcService +} from "../../../generated/ru/micord/ervu/account_applications/component/rpc/IdmValidatorRpcService"; +import {first} from "rxjs/operators"; export abstract class AbstractIdmValidator extends SimpleValidator { protected abstract ERROR_MESSAGE: string; protected abstract checkValueExists(value: string): Observable; protected textField: TextField; - protected idmService: IdmService; + protected rpcService: IdmValidatorRpcService; protected textInput: HTMLInputElement; initialize(): void { super.initialize(); this.textField = this.getScript(TextField); - this.idmService = this.injector.get(IdmService); + this.rpcService = this.getScript(IdmValidatorRpcService); this.textInput = this.textField.getEl().nativeElement.querySelector('input'); this.textInput.addEventListener('blur', this.onBlurHandler.bind(this)); } @@ -25,17 +28,16 @@ export abstract class AbstractIdmValidator extends SimpleValidator { const cleanedValue = this.cleanValue(inputValue); if (!this.isPatternValid(cleanedValue)) return Promise.resolve(false); - return this.checkValueExists(cleanedValue).toPromise().then( - (exists) => { + return this.checkValueExists(cleanedValue).pipe(first()).toPromise() + .then(exists => { this.pushError(!exists, this.ERROR_MESSAGE); return !exists; - }, - (err) => { + }) + .catch(err => { const fieldName = this.textField.getObjectName(); console.error(`Ошибка проверки ${fieldName}: ${err.message}`); return false; - } - ); + }); } private async onBlurHandler(event: FocusEvent): Promise { diff --git a/frontend/src/ts/account_applications/component/field/IdmLoginValidator.ts b/frontend/src/ts/account_applications/component/field/IdmLoginValidator.ts index 65e34b61..61bb0370 100644 --- a/frontend/src/ts/account_applications/component/field/IdmLoginValidator.ts +++ b/frontend/src/ts/account_applications/component/field/IdmLoginValidator.ts @@ -1,11 +1,11 @@ -import {Observable} from "rxjs"; +import {from, Observable} from "rxjs"; import {AbstractIdmValidator} from "./AbstractIdmValidator"; export class IdmLoginValidator extends AbstractIdmValidator { protected ERROR_MESSAGE = "Пользователь с указанным логином уже существует"; protected checkValueExists(value: string): Observable { - return this.idmService.checkLoginExists(value); + return from(this.rpcService.valueExists(value)); } protected isPatternValid(value: string): boolean { diff --git a/frontend/src/ts/account_applications/component/field/IdmSnilsValidator.ts b/frontend/src/ts/account_applications/component/field/IdmSnilsValidator.ts index 05144990..9d26d633 100644 --- a/frontend/src/ts/account_applications/component/field/IdmSnilsValidator.ts +++ b/frontend/src/ts/account_applications/component/field/IdmSnilsValidator.ts @@ -1,11 +1,11 @@ -import {Observable} from "rxjs"; +import {from, Observable} from "rxjs"; import {AbstractIdmValidator} from "./AbstractIdmValidator"; export class IdmSnilsValidator extends AbstractIdmValidator { protected ERROR_MESSAGE = "Пользователь с указанным СНИЛС уже существует"; protected checkValueExists(value: string): Observable { - return this.idmService.checkSnilsExists(value); + return from(this.rpcService.valueExists(value)); } protected cleanValue(value: string): string { diff --git a/resources/src/main/resources/business-model/Список заявок на пользователя/Создание заявки на добавление пользователя.page b/resources/src/main/resources/business-model/Список заявок на пользователя/Создание заявки на добавление пользователя.page index 7d4c8a6a..5f4f2b30 100644 --- a/resources/src/main/resources/business-model/Список заявок на пользователя/Создание заявки на добавление пользователя.page +++ b/resources/src/main/resources/business-model/Список заявок на пользователя/Создание заявки на добавление пользователя.page @@ -2033,6 +2033,25 @@ true true + + + IdmValidatorRpcService + ru.micord.ervu.account_applications.component.rpc + +true +true + + + validatorService + + + IdmLoginValidatorService + ru.micord.ervu.account_applications.component.service + + + + + b310f98a-69c6-4e7b-8cdb-f1ab9f9c0d94 @@ -2185,6 +2204,25 @@ true true + + + IdmValidatorRpcService + ru.micord.ervu.account_applications.component.rpc + +true +true + + + validatorService + + + IdmSnilsValidatorService + ru.micord.ervu.account_applications.component.service + + + + + d7d54cfb-26b5-4dba-b56f-b6247183c24d