@@ -39,8 +39,11 @@ namespace IRaCIS.Application.Contracts
|
||||
|
||||
public UserTypeEnum UserTypeEnum { get; set; }
|
||||
|
||||
|
||||
public bool IsTestUser { get; set; }
|
||||
/// <summary>
|
||||
/// 上一次修改密码的时间
|
||||
/// </summary>
|
||||
public DateTime? LastChangePassWordTime { get; set; }
|
||||
public bool IsTestUser { get; set; }
|
||||
public bool IsAdmin { get; set; } = false;
|
||||
public string UserTypeShortName { get; set; } = string.Empty;
|
||||
public bool PasswordChanged { get; set; }
|
||||
@@ -55,7 +58,9 @@ namespace IRaCIS.Application.Contracts
|
||||
public bool IsFirstAdd { get; set; }
|
||||
public bool IsReviewer { get; set; } = false;
|
||||
|
||||
}
|
||||
public int LoginState { get; set; } = 0;
|
||||
|
||||
}
|
||||
|
||||
public class MenuFuncTreeNodeView
|
||||
{
|
||||
|
||||
@@ -23,13 +23,14 @@ namespace IRaCIS.Application.Services
|
||||
public class UserService : BaseService, IUserService
|
||||
{
|
||||
private readonly IRepository<User> _userRepository;
|
||||
private readonly IMailVerificationService _mailVerificationService;
|
||||
|
||||
private readonly IMailVerificationService _mailVerificationService;
|
||||
private readonly IRepository<VerificationCode> _verificationCodeRepository;
|
||||
private readonly IRepository<Doctor> _doctorRepository;
|
||||
private readonly IRepository<TrialUser> _userTrialRepository;
|
||||
private readonly IRepository<UserLog> _userLogRepository;
|
||||
|
||||
private readonly IDistributedLockProvider _distributedLockProvider;
|
||||
private readonly IRepository<UserPassWordLog> _userPassWordLogRepository;
|
||||
private readonly IDistributedLockProvider _distributedLockProvider;
|
||||
private readonly IEasyCachingProvider _cache;
|
||||
private readonly IReadingImageTaskService _readingImageTaskService;
|
||||
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
||||
@@ -44,13 +45,14 @@ namespace IRaCIS.Application.Services
|
||||
IReadingImageTaskService readingImageTaskService,
|
||||
IRepository<TrialUser> userTrialRepository,
|
||||
IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig,
|
||||
IRepository<UserLog> userLogRepository
|
||||
IRepository<UserLog> userLogRepository,
|
||||
IRepository<UserPassWordLog> userPassWordLogRepository
|
||||
,
|
||||
IDistributedLockProvider distributedLockProvider)
|
||||
{
|
||||
_userLogRepository = userLogRepository;
|
||||
|
||||
_verifyConfig = verifyConfig;
|
||||
this._userPassWordLogRepository = userPassWordLogRepository;
|
||||
_verifyConfig = verifyConfig;
|
||||
_cache = cache;
|
||||
this._readingImageTaskService = readingImageTaskService;
|
||||
_userRepository = userRepository;
|
||||
@@ -94,36 +96,51 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
private async Task VerifyUserPwdAsync(Guid userId, string newPwd, string? oldPwd = null)
|
||||
{
|
||||
//var dbUser = (await _userRepository.FirstOrDefaultAsync(t => t.Id == userId)).IfNullThrowException();
|
||||
//var dbUser = (await _userRepository.FirstOrDefaultAsync(t => t.Id == userId)).IfNullThrowException();
|
||||
|
||||
if (_verifyConfig.CurrentValue.OpenUserComplexPassword)
|
||||
if (oldPwd != null && oldPwd == newPwd)
|
||||
{
|
||||
//---新密码与旧密码相同。
|
||||
throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]);
|
||||
}
|
||||
|
||||
|
||||
var dbUser = (await _userRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
if (oldPwd != null && dbUser.Password != oldPwd)
|
||||
{
|
||||
//---旧密码验证失败。
|
||||
throw new BusinessValidationFailedException(_localizer["User_OldPwdInvalid"]);
|
||||
}
|
||||
|
||||
if (dbUser.Password == newPwd)
|
||||
{
|
||||
//---新密码与旧密码相同。
|
||||
throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]);
|
||||
}
|
||||
|
||||
var passWordList = await _userPassWordLogRepository.Where(x => x.UserId == userId).OrderByDescending(x => x.CreateTime).Take(2).ToListAsync();
|
||||
if (passWordList.Any(x => x.PassWord == newPwd))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["User_PassWordRepeat"]);
|
||||
}
|
||||
|
||||
await _userPassWordLogRepository.AddAsync(new UserPassWordLog()
|
||||
{
|
||||
|
||||
if (oldPwd != null && oldPwd == newPwd)
|
||||
{
|
||||
//---新密码与旧密码相同。
|
||||
throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]);
|
||||
}
|
||||
CreateTime = DateTime.Now,
|
||||
PassWord = oldPwd,
|
||||
UserId = userId,
|
||||
});
|
||||
|
||||
await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == userId, x => new User()
|
||||
{
|
||||
LastChangePassWordTime = DateTime.Now,
|
||||
});
|
||||
await _userPassWordLogRepository.SaveChangesAsync();
|
||||
|
||||
|
||||
var dbUser = (await _userRepository.Where(t => t.Id == userId).FirstOrDefaultAsync()).IfNullThrowException();
|
||||
|
||||
if (oldPwd != null && dbUser.Password != oldPwd)
|
||||
{
|
||||
//---旧密码验证失败。
|
||||
throw new BusinessValidationFailedException(_localizer["User_OldPwdInvalid"]);
|
||||
}
|
||||
|
||||
if (dbUser.Password == newPwd)
|
||||
{
|
||||
//---新密码与旧密码相同。
|
||||
throw new BusinessValidationFailedException(_localizer["User_NewOldPwdSame"]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
await Task.CompletedTask;
|
||||
|
||||
|
||||
}
|
||||
@@ -650,7 +667,7 @@ namespace IRaCIS.Application.Services
|
||||
|
||||
if (failCount >= maxFailures)
|
||||
{
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName,LoginPassword=password, OptType = UserOptType.AccountLocked }, true);
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountLocked }, true);
|
||||
|
||||
//$"密码连续错误{maxFailures}次,当前账号已被限制登录,请等待 {lockoutMinutes} 分钟后再试。"
|
||||
throw new BusinessValidationFailedException(_localizer["User_ErrorLimit", maxFailures, lockoutMinutes]);
|
||||
@@ -668,7 +685,7 @@ namespace IRaCIS.Application.Services
|
||||
failCount++;
|
||||
_cache.Set(cacheKey, failCount, TimeSpan.FromMinutes(lockoutMinutes));
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId=Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = Guid.Empty, OptUserId = Guid.Empty, LoginFaildName = userName, LoginPassword = password, OptType = UserOptType.AccountOrPasswordError }, true);
|
||||
|
||||
return ResponseOutput.NotOk(_localizer["User_CheckNameOrPw"], new LoginReturnDTO());
|
||||
|
||||
@@ -684,14 +701,44 @@ namespace IRaCIS.Application.Services
|
||||
return ResponseOutput.NotOk(_localizer["User_Disabled"], new LoginReturnDTO());
|
||||
}
|
||||
|
||||
//超过90天没修改密码
|
||||
if (loginUser.LastChangePassWordTime != null && DateTime.Now.AddDays(-90) > loginUser.LastChangePassWordTime.Value)
|
||||
{
|
||||
loginUser.LoginState = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//登录成功 清除缓存
|
||||
_cache.Set(cacheKey, 0, TimeSpan.FromMinutes(lockoutMinutes));
|
||||
|
||||
var lastLoginLog = await _userLogRepository.Where(x => x.LoginUserId == loginUser.Id).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync();
|
||||
if (lastLoginLog!=null)
|
||||
{
|
||||
if (lastLoginLog.IP != _userInfo.IP)
|
||||
{
|
||||
loginUser.LoginState = 2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, LoginUserId = loginUser.Id, OptUserId = loginUser.Id, OptType = UserOptType.Login }, true);
|
||||
|
||||
userLoginReturnModel.BasicInfo = loginUser;
|
||||
|
||||
if (loginUser.LastChangePassWordTime == null)
|
||||
{
|
||||
await _userRepository.BatchUpdateNoTrackingAsync(x => x.Id == loginUser.Id, x => new User()
|
||||
{
|
||||
LastChangePassWordTime = DateTime.Now
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 登录 清除缓存
|
||||
//_cache.Remove(userLoginReturnModel.BasicInfo.Id.ToString());
|
||||
|
||||
Reference in New Issue
Block a user