SUPPORT-9001: reset-pass
This commit is contained in:
parent
2bc376eafa
commit
a1e3797486
18 changed files with 190 additions and 19 deletions
|
|
@ -13,10 +13,7 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
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 org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
|
@ -36,6 +33,10 @@ import ru.micord.ervu.account_applications.dto.deactivate.DeactivateProcessReque
|
|||
import ru.micord.ervu.account_applications.dto.edit.EditData;
|
||||
import ru.micord.ervu.account_applications.dto.edit.EditPersonDto;
|
||||
import ru.micord.ervu.account_applications.dto.edit.EditPersonProcessRequest;
|
||||
import ru.micord.ervu.account_applications.dto.password.ResetPasswordData;
|
||||
import ru.micord.ervu.account_applications.dto.password.ResetPasswordDto;
|
||||
import ru.micord.ervu.account_applications.dto.password.ResetPasswordProcessRequest;
|
||||
import ru.micord.ervu.account_applications.dto.password.UserIdInfo;
|
||||
import ru.micord.ervu.account_applications.enums.ProcessKey;
|
||||
import ru.micord.ervu.account_applications.security.context.SecurityContext;
|
||||
import ru.micord.ervu.account_applications.service.UserApplicationListService;
|
||||
|
|
@ -100,6 +101,30 @@ public class AdminController {
|
|||
return doRequest(request);
|
||||
}
|
||||
|
||||
@GetMapping("/exists")
|
||||
public ResponseEntity<Boolean> userExists(@RequestParam(name = "login") String login) {
|
||||
boolean result = applicationListService.userExists(login);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/password/reset")
|
||||
public ResponseEntity<?> resetPassword(@RequestBody ResetPasswordDto dto){
|
||||
ResetPasswordProcessRequest request = new ResetPasswordProcessRequest(ProcessKey.RESET_PASSWORD.getValue(),
|
||||
getUserId(), new ResetPasswordData(new UserIdInfo(dto.accountId())));
|
||||
ResponseEntity<?> responseEntity = doRequest(request);
|
||||
if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
|
||||
String traceId = ((ProcessResponse) Objects.requireNonNull(responseEntity.getBody())).traceId();
|
||||
applicationListService.saveTraceId(traceId, dto.appNumber());
|
||||
}
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
@GetMapping("/password/check")
|
||||
public ResponseEntity<Boolean> passwordCheck(@RequestParam(name = "login") String login) {
|
||||
boolean result = applicationListService.isPasswordExpired(login);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
private <R> ResponseEntity<?> doRequest(ProcessRequest<R> request) {
|
||||
HttpEntity<ProcessRequest<R>> entity = setEntity(getToken(), request);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
package ru.micord.ervu.account_applications.dao;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jooq.DSLContext;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import ru.micord.ervu.account_applications.enums.ApplicationStatus;
|
||||
|
|
@ -29,6 +33,7 @@ public class UserApplicationListDao {
|
|||
dslContext.update(USER_APPLICATION_LIST)
|
||||
.set(USER_APPLICATION_LIST.APPLICATION_STATUS, ApplicationStatus.ACCEPTED.name())
|
||||
.set(USER_APPLICATION_LIST.USER_PASSWORD, encodedPass)
|
||||
.set(USER_APPLICATION_LIST.PASSWORD_LAST_UPDATED, Timestamp.valueOf(LocalDateTime.now()))
|
||||
.where(USER_APPLICATION_LIST.TRACE_ID.eq(traceId))
|
||||
.execute();
|
||||
}
|
||||
|
|
@ -47,4 +52,18 @@ public class UserApplicationListDao {
|
|||
.where(USER_APPLICATION_LIST.TRACE_ID.eq(traceId))
|
||||
.execute();
|
||||
}
|
||||
|
||||
public boolean userExists(String login) {
|
||||
return dslContext.fetchExists(
|
||||
dslContext.selectOne()
|
||||
.from(USER_APPLICATION_LIST)
|
||||
.where(USER_APPLICATION_LIST.USER_LOGIN.eq(login)));
|
||||
}
|
||||
|
||||
public Optional<LocalDateTime> getPasswordLastUpdated(String login) {
|
||||
return dslContext.select(USER_APPLICATION_LIST.PASSWORD_LAST_UPDATED)
|
||||
.from(USER_APPLICATION_LIST)
|
||||
.where(USER_APPLICATION_LIST.USER_LOGIN.eq(login))
|
||||
.fetchOptionalInto(LocalDateTime.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,6 +242,13 @@ public class UserApplicationList extends TableImpl<UserApplicationListRecord> {
|
|||
*/
|
||||
public final TableField<UserApplicationListRecord, String> TRACE_ID = createField(DSL.name("trace_id"), SQLDataType.VARCHAR(36), this, "Идентификатор процесса");
|
||||
|
||||
/**
|
||||
* The column
|
||||
* <code>public.user_application_list.password_last_updated</code>. Дата
|
||||
* последнего обновления пароля
|
||||
*/
|
||||
public final TableField<UserApplicationListRecord, Timestamp> PASSWORD_LAST_UPDATED = createField(DSL.name("password_last_updated"), SQLDataType.TIMESTAMP(0), this, "Дата последнего обновления пароля");
|
||||
|
||||
private UserApplicationList(Name alias, Table<UserApplicationListRecord> aliased) {
|
||||
this(alias, aliased, (Field<?>[]) null, null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -506,6 +506,24 @@ public class UserApplicationListRecord extends UpdatableRecordImpl<UserApplicati
|
|||
return (String) get(30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for
|
||||
* <code>public.user_application_list.password_last_updated</code>. Дата
|
||||
* последнего обновления пароля
|
||||
*/
|
||||
public void setPasswordLastUpdated(Timestamp value) {
|
||||
set(31, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for
|
||||
* <code>public.user_application_list.password_last_updated</code>. Дата
|
||||
* последнего обновления пароля
|
||||
*/
|
||||
public Timestamp getPasswordLastUpdated() {
|
||||
return (Timestamp) get(31);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Primary key information
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
@ -529,7 +547,7 @@ public class UserApplicationListRecord extends UpdatableRecordImpl<UserApplicati
|
|||
/**
|
||||
* Create a detached, initialised UserApplicationListRecord
|
||||
*/
|
||||
public UserApplicationListRecord(Long userApplicationListId, String applicationKind, String userLogin, String userPassword, String secondname, String firstname, String middlename, String phone, Timestamp startDate, Timestamp closeDate, String userStatus, String applicationStatus, String comment, Long jobPositionId, Long userRoleId, UUID recruitmentId, String userAccountId, String sex, Date birthDate, String snils, String jobPosition, Long numberApp, String editComment, String personId, String updateSecondname, String updateFirstname, String updateMiddlename, String updateSex, Date updateBirthDate, String updateJobPosition, String traceId) {
|
||||
public UserApplicationListRecord(Long userApplicationListId, String applicationKind, String userLogin, String userPassword, String secondname, String firstname, String middlename, String phone, Timestamp startDate, Timestamp closeDate, String userStatus, String applicationStatus, String comment, Long jobPositionId, Long userRoleId, UUID recruitmentId, String userAccountId, String sex, Date birthDate, String snils, String jobPosition, Long numberApp, String editComment, String personId, String updateSecondname, String updateFirstname, String updateMiddlename, String updateSex, Date updateBirthDate, String updateJobPosition, String traceId, Timestamp passwordLastUpdated) {
|
||||
super(UserApplicationList.USER_APPLICATION_LIST);
|
||||
|
||||
setUserApplicationListId(userApplicationListId);
|
||||
|
|
@ -563,6 +581,7 @@ public class UserApplicationListRecord extends UpdatableRecordImpl<UserApplicati
|
|||
setUpdateBirthDate(updateBirthDate);
|
||||
setUpdateJobPosition(updateJobPosition);
|
||||
setTraceId(traceId);
|
||||
setPasswordLastUpdated(passwordLastUpdated);
|
||||
resetChangedOnNotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package ru.micord.ervu.account_applications.dto.password;
|
||||
|
||||
|
||||
/**
|
||||
* @author Adel Kalimullin
|
||||
*/
|
||||
public record ResetPasswordData(UserIdInfo account) {
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package ru.micord.ervu.account_applications.dto.password;
|
||||
|
||||
/**
|
||||
* @author Adel Kalimullin
|
||||
*/
|
||||
public record ResetPasswordDto(long appNumber, String accountId) {
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package ru.micord.ervu.account_applications.dto.password;
|
||||
|
||||
import ru.micord.ervu.account_applications.dto.ProcessRequest;
|
||||
|
||||
/**
|
||||
* @author Adel Kalimullin
|
||||
*/
|
||||
public class ResetPasswordProcessRequest extends ProcessRequest {
|
||||
|
||||
public ResetPasswordProcessRequest(String processKey, String userId, Object data) {
|
||||
super(processKey, userId, data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package ru.micord.ervu.account_applications.dto.password;
|
||||
|
||||
/**
|
||||
* @author Adel Kalimullin
|
||||
*/
|
||||
public record UserIdInfo(String id){
|
||||
}
|
||||
|
|
@ -8,7 +8,8 @@ public enum ProcessKey {
|
|||
EDIT_PERSON("milBaseEditAccountPersonIDMProcess"),
|
||||
EDIT_ACCOUNT("milBaseEditAccountIDMProcess"),
|
||||
EDIT_ROLES("milBaseEditAccountRolesIDMSubProcess"),
|
||||
DEACTIVATE("milBaseMassDeActivateAccountIDMProcess");
|
||||
DEACTIVATE("milBaseMassDeActivateAccountIDMProcess"),
|
||||
RESET_PASSWORD("milBaseResetPasswordProcess");
|
||||
|
||||
private final String value;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class AccountServiceImpl extends AbstractUserDataService {
|
|||
|
||||
private Account fetchAccountById(Object id) throws IOException, InterruptedException {
|
||||
String url = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||
.pathSegment(PathConstant.ACCOUNTS_PATH)
|
||||
.path(PathConstant.ACCOUNTS_PATH)
|
||||
.pathSegment(id.toString())
|
||||
.queryParam("expand", "person,user-domain,region")
|
||||
.toUriString();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class RoleServiceImpl extends AbstractUserDataService {
|
|||
|
||||
private List<Role> fetchRolesByAccountId(Object accountId) throws IOException, InterruptedException {
|
||||
String url = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||
.pathSegment(PathConstant.ACCOUNTS_PATH)
|
||||
.path(PathConstant.ACCOUNTS_PATH)
|
||||
.pathSegment(accountId.toString())
|
||||
.pathSegment(ROLES)
|
||||
.toUriString();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package ru.micord.ervu.account_applications.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.micord.ervu.account_applications.dao.UserApplicationListDao;
|
||||
|
||||
|
|
@ -23,6 +26,16 @@ public class UserApplicationListService {
|
|||
dao.savePassword(traceId, encodedPass);
|
||||
}
|
||||
|
||||
public boolean userExists(String login){
|
||||
return dao.userExists(login);
|
||||
}
|
||||
|
||||
public boolean isPasswordExpired(String login) {
|
||||
return dao.getPasswordLastUpdated(login)
|
||||
.map(date -> ChronoUnit.DAYS.between(date, LocalDateTime.now()) > 20)
|
||||
.orElse(true);
|
||||
}
|
||||
|
||||
public void saveAcceptedStatus(String traceId) {
|
||||
dao.saveAcceptedStatus(traceId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,12 @@ package ru.micord.ervu.account_applications.service;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import model.grid.GridRow;
|
||||
import model.grid.GridRows;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import ru.micord.ervu.account_applications.component.model.Credential;
|
||||
|
|
@ -36,7 +33,7 @@ public class UserCredentialsServiceIpml extends AbstractUserDataService {
|
|||
|
||||
private List<Credential> fetchCredentialsByPersonId(Object personId) throws IOException, InterruptedException {
|
||||
String url = UriComponentsBuilder.fromHttpUrl(ervuUrl)
|
||||
.pathSegment(PathConstant.PERSONS_PATH)
|
||||
.path(PathConstant.PERSONS_PATH)
|
||||
.pathSegment(personId.toString())
|
||||
.pathSegment(CREDENTIALS)
|
||||
.toUriString();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
|
||||
|
||||
<changeSet id="0001" author="a.kalimullin">
|
||||
<comment>add password_last_updated column to user_application_list table</comment>
|
||||
<sql>
|
||||
ALTER TABLE user_application_list ADD COLUMN IF NOT EXISTS password_last_updated TIMESTAMP;
|
||||
COMMENT ON COLUMN user_application_list.password_last_updated IS 'Дата последнего обновления пароля';
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
<include file="20250304_SUPPORT-8956_drop_security.xml" relativeToChangelogFile="true"/>
|
||||
<include file="20250307_ERVU-308_create_table_update.xml" relativeToChangelogFile="true"/>
|
||||
<include file="20250312-SUPPORT-8696_add_column_role.xml" relativeToChangelogFile="true"/>
|
||||
<include file="20250314_add_password_last_update.xml" relativeToChangelogFile="true"/>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
AnalyticalScope,
|
||||
Behavior,
|
||||
NotNull,
|
||||
SaveButton
|
||||
} from "@webbpm/base-package";
|
||||
import {AnalyticalScope, Behavior, NotNull, SaveButton} from "@webbpm/base-package";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {FormField} from "../field/FormField";
|
||||
import {AccountAction} from "../enum/AccountAction";
|
||||
|
|
@ -40,6 +35,8 @@ export class UserManagementService extends Behavior {
|
|||
case AccountAction.DEACTIVATE:
|
||||
this.doRequest("user/deactivate", jsonObj);
|
||||
break;
|
||||
case AccountAction.RESET_PASSWORD:
|
||||
this.doRequest("user/password-reset",jsonObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export enum AccountAction {
|
||||
CREATE = "CREATE",
|
||||
EDIT = "EDIT",
|
||||
DEACTIVATE = "DEACTIVATE"
|
||||
DEACTIVATE = "DEACTIVATE",
|
||||
RESET_PASSWORD="RESET_PASSWORD"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import {AnalyticalScope, Behavior, Control, ControlWithValue, Visible,} from "@webbpm/base-package";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
|
||||
|
||||
@AnalyticalScope(Control)
|
||||
export class FieldChecker extends Behavior {
|
||||
private client: HttpClient;
|
||||
private control: ControlWithValue;
|
||||
|
||||
initialize() {
|
||||
this.client = this.injector.get(HttpClient);
|
||||
this.control = this.getScript('component.ControlWithValue');
|
||||
}
|
||||
|
||||
@Visible()
|
||||
passwordCheck(login: string) {
|
||||
return this.client.get<boolean>(`user/password/check?login=${encodeURIComponent(login)}`)
|
||||
.toPromise()
|
||||
.then((isExpired: boolean) => {
|
||||
this.control.setValue(isExpired);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Ошибка при проверке пароля:", error);
|
||||
this.control.setValue(null);
|
||||
});
|
||||
}
|
||||
|
||||
@Visible()
|
||||
userExists(login: string) {
|
||||
return this.client.get<boolean>(`user/exists?login=${encodeURIComponent(login)}`)
|
||||
.toPromise()
|
||||
.then((exists: boolean) => {
|
||||
this.control.setValue(exists);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Ошибка при проверке пользователя:", error);
|
||||
this.control.setValue(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue