From 512a4591af7591bb41dc2086b1014f1f9eca18fe Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 6 Apr 2022 15:29:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BF=E5=90=8D=E9=82=AE=E7=AE=B1=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=AF=86=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 43 +- .../Service/Common/MailService.cs | 62 ++- .../Service/Management/DTO/UserModel.cs | 11 + .../Management/Interface/IUserService.cs | 6 +- .../Service/Management/UserService.cs | 394 +++++------------- IRaCIS.Core.Domain/Common/VerificationCode.cs | 12 +- 6 files changed, 187 insertions(+), 341 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 3a190841f..466f53f7a 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -2042,28 +2042,23 @@ - + - 修改密码,当前支持旧密码修改密码 - - - - - - - 重置密码发邮件 (未登陆修改) + 重置密码发邮件 (未登陆修改) 发送成功,返回用户账户Id - - - - 接受验证码 设置新密码 (未登陆修改) - - - + + + 验证验证码,没问题就返回用户所有的账户 + + + + + + 获取用户列表 @@ -2115,22 +2110,6 @@ - - - 发送验证码 邮箱或者手机号 - - - - - - - - - 验证设置新密码 - - - - Dashboard统计、全局工作量统计、入组两个维度统计(按照项目、按照人) diff --git a/IRaCIS.Core.Application/Service/Common/MailService.cs b/IRaCIS.Core.Application/Service/Common/MailService.cs index 8fda810b0..02c1b14e5 100644 --- a/IRaCIS.Core.Application/Service/Common/MailService.cs +++ b/IRaCIS.Core.Application/Service/Common/MailService.cs @@ -12,6 +12,8 @@ namespace IRaCIS.Application.Services Task AnolymousSendEmail(string emailAddress, int verificationCode); Task SendMailEditEmail(Guid userId, string userName, string emailAddress, int verificationCode); + + Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode); } public class MailVerificationService : IMailVerificationService @@ -100,19 +102,68 @@ namespace IRaCIS.Application.Services }; using (var smtp = new MailKit.Net.Smtp.SmtpClient()) { - smtp.MessageSent += (sender, args) => + smtp.MessageSent += (sender, args) => + { + // args.Response + var code = verificationCode.ToString(); + _ = _verificationCodeRepository.AddAsync(new VerificationCode() + { + CodeType = 0, + HasSend = true, + Code = code, + UserId = userId, + ExpirationTime = DateTime.Now.AddMinutes(3) + }).Result; + _ = _verificationCodeRepository.SaveChangesAsync().Result; + + }; + + smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; + + await smtp.ConnectAsync("smtp.163.com", 25, SecureSocketOptions.StartTls); + + await smtp.AuthenticateAsync("iracis_grr@163.com", "XLWVQKZAEKLDWOAH"); + + await smtp.SendAsync(messageToSend); + + await smtp.DisconnectAsync(true); + + } + } + + + public async Task AnolymousSendEmailForResetAccount(string emailAddress, int verificationCode) + { + var messageToSend = new MimeMessage(); + //发件地址 + messageToSend.From.Add(new MailboxAddress("GRR", "iracis_grr@163.com")); + //收件地址 + messageToSend.To.Add(new MailboxAddress(String.Empty, emailAddress)); + //主题 + messageToSend.Subject = "Reset Password (Verification Code)"; + + messageToSend.Body = new TextPart("plain") + { + Text = $@"Hey ,you are reset passwoed. The verification code is: {verificationCode}, If it is not your own operation, please ignore it! + + -- GRR" + }; + using (var smtp = new MailKit.Net.Smtp.SmtpClient()) + { + smtp.MessageSent += (sender, args) => { // args.Response var code = verificationCode.ToString(); - _= _verificationCodeRepository.AddAsync(new VerificationCode() + _ = _verificationCodeRepository.AddAsync(new VerificationCode() { - CodeType = 0, + CodeType = Core.Domain.Share.VerifyType.Email, HasSend = true, Code = code, - UserId = userId, + UserId = Guid.Empty,//此时不知道用户 + EmailOrPhone = emailAddress, ExpirationTime = DateTime.Now.AddMinutes(3) }).Result; - _= _verificationCodeRepository.SaveChangesAsync().Result; + _ = _verificationCodeRepository.SaveChangesAsync().Result; }; @@ -125,7 +176,6 @@ namespace IRaCIS.Application.Services await smtp.SendAsync(messageToSend); await smtp.DisconnectAsync(true); - } } diff --git a/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs b/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs index 7a61a909b..e80d2cc50 100644 --- a/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs +++ b/IRaCIS.Core.Application/Service/Management/DTO/UserModel.cs @@ -173,6 +173,17 @@ namespace IRaCIS.Application.Contracts public string OldPassWord { get; set; } = string.Empty; } + + + public class UserAccountDto + { + public Guid UserId { get; set; } + + public string UserName { get; set; } = string.Empty; + + public string UserRealName { get; set; } = string.Empty; + } + public class UserListQueryDTO : PageInput { public string UserName { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs b/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs index 1cce7f516..cc44a25ed 100644 --- a/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs +++ b/IRaCIS.Core.Application/Service/Management/Interface/IUserService.cs @@ -12,9 +12,11 @@ namespace IRaCIS.Application.Services Task> Login(string userName, string password); Task ModifyPassword(EditPasswordCommand editPwModel); Task ResetPassword(Guid userId); - Task SendVerificationCode(string emailOrPhone, VerifyType verificationType, bool isReviewer = false); - Task SetNewPassword(ResetPasswordCommand resetPwdModel); + Task UpdateUser(UserCommand model); Task UpdateUserState(Guid userId, UserStateEnum state); + + //Task SendVerificationCode(string emailOrPhone, VerifyType verificationType, bool isReviewer = false); + //Task SetNewPassword(ResetPasswordCommand resetPwdModel); } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 723f11561..e7d43d42e 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -161,21 +161,110 @@ namespace IRaCIS.Application.Services /// [HttpGet("{userId:guid}")] - public async Task ResetPassword(Guid userId) + public async Task ResetPassword(Guid userId + + + + + /// + /// 重置密码发邮件 (未登陆修改) 发送成功,返回用户账户Id + /// + /// + /// + [AllowAnonymous] + [HttpGet("{email}")] + public async Task AnonymousSendVerificationCode(string email) + { + + //检查手机或者邮箱是否有效 + if (!Regex.IsMatch(email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")) + { + + return ResponseOutput.NotOk("Please input a legal email"); + + } + + ////查找改邮箱或者手机的用户 + var exist = await _userRepository.AnyAsync(t => t.EMail == email); + + if (!exist) + { + return ResponseOutput.NotOk("Email not correct"); + + } + + + //验证码 6位 + int verificationCode = new Random().Next(100000, 1000000); + + await _mailVerificationService.AnolymousSendEmailForResetAccount(email, verificationCode); + + return ResponseOutput.Ok(); + + } + + /// + /// 验证验证码,没问题就返回用户所有的账户 + /// + /// + /// + /// + /// + [AllowAnonymous] + [HttpGet("{email}/{verifyCode}")] + public async Task> VerifyAnonymousVerifyCode(string email, string verifyCode) + { + var verificationRecord = await _verificationCodeRepository + .Where(t => t.UserId == Guid.Empty && t.Code == verifyCode && t.CodeType == VerifyType.Email && t.EmailOrPhone == email).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync(); + + //检查数据库是否存在该验证码 + if (verificationRecord == null) + { + + throw new BusinessValidationFailedException("Verification code error"); + } + else + { + //检查验证码是否失效 + if (verificationRecord.ExpirationTime < DateTime.Now) + { + + throw new BusinessValidationFailedException("The verification code has expired"); + } + else //验证码正确 并且 没有超时 + { + + //删除验证码历史记录 + await _verificationCodeRepository.DeleteFromQueryAsync(t => t.Id == verificationRecord.Id); + } + } + + var list = await _userRepository.Where(t => t.EMail == email).Select(t => new UserAccountDto() { UserId = t.Id, UserName = t.UserName, UserRealName = t.LastName + " / " + t.FirstName }).ToListAsync(); + + + + return list; + } + + + + [AllowAnonymous] + [HttpGet("{userId:guid}/{newPwd}")] + public async Task AnonymousSetPassword(Guid userId, string newPwd) { var success = await _userRepository.UpdateFromQueryAsync(t => t.Id == userId, u => new User() { - Password = MD5Helper.Md5(StaticData.DefaultPassword), - PasswordChanged = false + Password = newPwd, + PasswordChanged = true }); - return ResponseOutput.Result(success); + return ResponseOutput.Ok(success); } /// /// 修改密码,当前支持旧密码修改密码 /// - /// < + /// /// [HttpPost] public async Task ModifyPassword(EditPasswordCommand editPwModel) @@ -225,109 +314,6 @@ namespace IRaCIS.Application.Services } - /// - /// 重置密码发邮件 (未登陆修改) - /// - /// - /// - /// - [AllowAnonymous] - [HttpGet("{email}/{userName}")] - public async Task SendVerificationCode(string email,string userName) - { - - //检查手机或者邮箱是否有效 - if (!Regex.IsMatch(email, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")) - { - - return ResponseOutput.NotOk("Please input a legal email"); - - } - - ////查找改邮箱或者手机的用户 - var exist = await _userRepository.AnyAsync(t => t.EMail == email&& t.UserName == userName); - - if (!exist) - { - return ResponseOutput.NotOk("User Id or Email not correct"); - - } - var user = await _userRepository.FirstOrDefaultAsync(t => t.EMail == email); - - - //验证码 6位 - int verificationCode = new Random().Next(100000, 1000000); - - await _mailVerificationService.SendMail(user.Id, _userInfo.RealName, email, verificationCode); - - return ResponseOutput.Ok(); - - } - - - - /// - ///接受验证码 设置新密码 (未登陆修改) - /// - /// - /// - [HttpPost] - [AllowAnonymous] - public async Task SetNewPassword(AllowAnonymousResetPasswordCommand resetPwdModel) - { - - var user = await _userRepository.FirstOrDefaultAsync(t => t.EMail == resetPwdModel.Email && t.UserName == resetPwdModel.UserName); - - if (user == null) - { - return ResponseOutput.NotOk("User Id or Email not correct"); - } - - - var verificationRecord = await _verificationCodeRepository - .FirstOrDefaultAsync(t => t.UserId == user.Id && t.Code == resetPwdModel.VerificationCode && t.CodeType == VerifyType.Email); - - //检查数据库是否存在该验证码 - if (verificationRecord == null) - { - - return ResponseOutput.NotOk("Verification code error"); - - } - else - { - //检查验证码是否失效 - if (verificationRecord.ExpirationTime < DateTime.Now) - { - return ResponseOutput.NotOk("The verification code has expired"); - - } - else //验证码正确 并且 没有超时 - { - //更新密码 - //var pwd = MD5Helper.Md5(newPwd); - //var count = _doctorRepository.Update().Where(t => t.Id == doctor.Id).Set(d => d.Password == pwd).ExecuteAffrows(); - - var success = await _userRepository.UpdateFromQueryAsync(t => t.Id == user.Id, u => new User() - { - Password = resetPwdModel.NewPwd, - PasswordChanged = true - }); - - //删除验证码历史记录 - await _verificationCodeRepository.DeleteFromQueryAsync(t => t.UserId == user.Id && t.CodeType == VerifyType.Email); - - return ResponseOutput.Result(success); - - } - } - - - } - - - - /// /// 获取用户列表 @@ -511,197 +497,5 @@ namespace IRaCIS.Application.Services } - - /// - /// 发送验证码 邮箱或者手机号 - /// - /// - /// - /// - /// - [HttpGet("{emailOrPhone}/{verificationType:int}")] - [Obsolete] - public async Task SendVerificationCode(string emailOrPhone, VerifyType verificationType, bool isReviewer = false) - { - if (string.IsNullOrEmpty(emailOrPhone)) - { - return ResponseOutput.NotOk(verificationType == VerifyType.Email ? "Please input email" : "Please input phone"); - - } - //防止输入前后有空格 - var emailOrPhoneStr = emailOrPhone.Trim(); - - //检查手机或者邮箱是否有效 - if (!Regex.IsMatch(emailOrPhoneStr, @"/^1[34578]\d{9}$/") && !Regex.IsMatch(emailOrPhoneStr, @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")) - { - - return ResponseOutput.NotOk(verificationType == VerifyType.Email - ? "Please input a legal email" - : "Please input a legal phone"); - - } - - //医生登录 - if (isReviewer) - { - var exist = await _doctorRepository.AnyAsync(t => t.EMail == emailOrPhoneStr || t.Phone == emailOrPhoneStr); - - if (!exist) - { - return ResponseOutput.NotOk(verificationType == VerifyType.Email - ? "No user with this email exists." - : "No user with this phone exists."); - - } - - var user = await _doctorRepository.FirstOrDefaultAsync(t => t.EMail == emailOrPhoneStr || t.Phone == emailOrPhoneStr); - //邮箱 - if (verificationType == VerifyType.Email) - { - //验证码 6位 - int verificationCode = new Random().Next(100000, 1000000); - - await _mailVerificationService.SendMail(user.Id, user.ChineseName, emailOrPhoneStr, - verificationCode); - } - //手机短信 - else - { - - } - - } - else//管理用户登录 - { - //查找改邮箱或者手机的用户 - var exist = await _userRepository.AnyAsync(t => t.EMail == emailOrPhoneStr || t.Phone == emailOrPhoneStr); - - if (!exist) - { - return ResponseOutput.NotOk(verificationType == VerifyType.Email - ? "No user with this email exists." - : "No user with this phone exists."); - - } - var user = await _userRepository.FirstOrDefaultAsync(t => t.EMail == emailOrPhoneStr || t.Phone == emailOrPhoneStr); - //邮箱 - if (verificationType == VerifyType.Email) - { - //验证码 6位 - int verificationCode = new Random().Next(100000, 1000000); - - await _mailVerificationService.SendMail(user.Id, user.LastName + ' ' + user.FirstName, emailOrPhoneStr, - verificationCode); - } - //手机短信 - else - { - - } - } - - return ResponseOutput.Ok(); - } - - - - /// - /// 验证设置新密码 - /// - /// - /// - [HttpPost] - [Obsolete] - public async Task SetNewPassword(ResetPasswordCommand resetPwdModel) - { - if (resetPwdModel.IsReviewer) - { - var emailOrPhoneStr = resetPwdModel.EmailOrPhone.Trim(); - var verificationCodeStr = resetPwdModel.VerificationCode.Trim(); - var user = await _doctorRepository.FirstOrDefaultAsync(t => t.EMail == emailOrPhoneStr || t.Phone == emailOrPhoneStr); - - var verificationRecord = await _verificationCodeRepository - .FirstOrDefaultAsync(t => t.UserId == user.Id && t.Code == verificationCodeStr && t.CodeType == resetPwdModel.VerificationType); - - //检查数据库是否存在该验证码 - if (verificationRecord == null) - { - - return ResponseOutput.NotOk("Verification code error"); - - } - else - { - //检查验证码是否失效 - if (verificationRecord.ExpirationTime < DateTime.Now) - { - return ResponseOutput.NotOk("The verification code has expired"); - - } - else //验证码正确 并且 没有超时 - { - //更新密码 - var success = await _doctorRepository.UpdateFromQueryAsync(t => t.Id == user.Id, u => new Doctor() - { - Password = resetPwdModel.NewPwd - }); - - //删除验证码历史记录 - await _verificationCodeRepository.DeleteFromQueryAsync(t => t.UserId == user.Id && t.CodeType == resetPwdModel.VerificationType); - - return ResponseOutput.Result(success); - - } - } - } - else - { - var emailOrPhoneStr = resetPwdModel.EmailOrPhone.Trim(); - var verificationCodeStr = resetPwdModel.VerificationCode.Trim(); - - var user = await _userRepository.FirstOrDefaultAsync(t => t.EMail == emailOrPhoneStr || t.Phone == emailOrPhoneStr); - - - var verificationRecord = await _verificationCodeRepository - .FirstOrDefaultAsync(t => t.UserId == user.Id && t.Code == verificationCodeStr && t.CodeType == resetPwdModel.VerificationType); - - //检查数据库是否存在该验证码 - if (verificationRecord == null) - { - - return ResponseOutput.NotOk("Verification code error"); - - } - else - { - //检查验证码是否失效 - if (verificationRecord.ExpirationTime < DateTime.Now) - { - return ResponseOutput.NotOk("The verification code has expired"); - - } - else //验证码正确 并且 没有超时 - { - //更新密码 - //var pwd = MD5Helper.Md5(newPwd); - //var count = _doctorRepository.Update().Where(t => t.Id == doctor.Id).Set(d => d.Password == pwd).ExecuteAffrows(); - - var success = await _userRepository.UpdateFromQueryAsync(t => t.Id == user.Id, u => new User() - { - Password = resetPwdModel.NewPwd, - PasswordChanged = true - }); - - //删除验证码历史记录 - await _verificationCodeRepository.DeleteFromQueryAsync(t => t.UserId == user.Id && t.CodeType == resetPwdModel.VerificationType); - - return ResponseOutput.Result(success); - - } - } - } - - } - } } diff --git a/IRaCIS.Core.Domain/Common/VerificationCode.cs b/IRaCIS.Core.Domain/Common/VerificationCode.cs index d5aefbd56..ad1daf877 100644 --- a/IRaCIS.Core.Domain/Common/VerificationCode.cs +++ b/IRaCIS.Core.Domain/Common/VerificationCode.cs @@ -5,20 +5,30 @@ using System.ComponentModel.DataAnnotations.Schema; namespace IRaCIS.Core.Domain.Models { [Table("VerificationCode")] - public class VerificationCode:Entity + public class VerificationCode:Entity, IAuditAdd { //public Guid Id { get; set; } public Guid UserId { get; set; } = Guid.Empty; + //验证码 public string Code { get; set; } + //什么类型的验证码 邮箱|手机 + public VerifyType CodeType { get; set; } public bool HasSend { get; set; } + + //发送的邮箱或者手机 public string EmailOrPhone { get; set; } + + //过期时间 public DateTime ExpirationTime { get; set; } + + public Guid CreateUserId { get; set; } + public DateTime CreateTime { get; set; } } } \ No newline at end of file