diff --git a/Source/Starfish.Common/Constants.cs b/Source/Starfish.Common/Constants.cs
index 4d7fecf..41cdbc6 100644
--- a/Source/Starfish.Common/Constants.cs
+++ b/Source/Starfish.Common/Constants.cs
@@ -37,5 +37,6 @@ public static class Configuration
public static class RegexPattern
{
public const string Secret = @"^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,32}$";
+ public const string Password = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\x00-\xff]{8,32}$";
}
}
\ No newline at end of file
diff --git a/Source/Starfish.Service/Application/Commands/Identity/ChangePasswordCommand.cs b/Source/Starfish.Service/Application/Commands/Identity/ChangePasswordCommand.cs
index d21d04d..2333a0e 100644
--- a/Source/Starfish.Service/Application/Commands/Identity/ChangePasswordCommand.cs
+++ b/Source/Starfish.Service/Application/Commands/Identity/ChangePasswordCommand.cs
@@ -11,11 +11,12 @@ public ChangePasswordCommand()
{
}
- public ChangePasswordCommand(string userId, string password)
+ public ChangePasswordCommand(string userId, string password, string actionType)
: this()
{
UserId = userId;
Password = password;
+ ActionType = actionType;
}
///
@@ -27,4 +28,10 @@ public ChangePasswordCommand(string userId, string password)
/// 新密码
///
public string Password { get; set; }
+
+ ///
+ /// 操作方式
+ ///
+ /// change-修改;reset-重置
+ public string ActionType { get; set; }
}
\ No newline at end of file
diff --git a/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs b/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs
index 9a35d2d..c28aceb 100644
--- a/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs
+++ b/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs
@@ -10,10 +10,10 @@ namespace Nerosoft.Starfish.Application;
/// 用户命令处理器
///
public sealed class UserCommandHandler : CommandHandlerBase,
- IHandler,
- IHandler,
- IHandler,
- IHandler
+ IHandler,
+ IHandler,
+ IHandler,
+ IHandler
{
///
/// 初始化.
@@ -58,7 +58,7 @@ public Task HandleAsync(UserUpdateCommand message, MessageContext context, Cance
business.IsAdmin = message.Item2.IsAdmin;
business.MarkAsUpdate();
-
+
await business.SaveAsync(true, cancellationToken);
});
}
@@ -68,11 +68,7 @@ public Task HandleAsync(ChangePasswordCommand message, MessageContext context, C
{
return ExecuteAsync(async () =>
{
- var business = await Factory.FetchAsync(message.UserId, cancellationToken);
-
- business.Password = message.Password;
- business.MarkAsUpdate();
- await business.SaveAsync(true, cancellationToken);
+ _ = await Factory.ExecuteAsync(message.UserId, message.Password, message.ActionType, cancellationToken);
});
}
diff --git a/Source/Starfish.Service/Domain/Aggregates/User.cs b/Source/Starfish.Service/Domain/Aggregates/User.cs
index 04141ab..4fb6b9f 100644
--- a/Source/Starfish.Service/Domain/Aggregates/User.cs
+++ b/Source/Starfish.Service/Domain/Aggregates/User.cs
@@ -21,14 +21,13 @@ private User()
/// 初始化用户聚合根
///
///
- ///
- ///
- private User(string userName, string passwordHash, string passwordSalt)
+ ///
+ ///
+ private User(string userName, string password)
: this()
{
UserName = userName;
- PasswordHash = passwordHash;
- PasswordSalt = passwordSalt;
+ SetPassword(password);
}
///
@@ -115,22 +114,25 @@ private User(string userName, string passwordHash, string passwordSalt)
///
internal static User Create(string userName, string password)
{
- var salt = RandomUtility.GenerateUniqueId();
- var hash = Cryptography.DES.Encrypt(password, Encoding.UTF8.GetBytes(salt));
- var entity = new User(userName, hash, salt);
+ var entity = new User(userName, password);
return entity;
}
///
- /// 修改密码
+ /// 设置密码
///
///
- internal void ChangePassword(string password)
+ ///
+ internal void SetPassword(string password, string actionType = null)
{
var salt = RandomUtility.GenerateUniqueId();
var hash = Cryptography.DES.Encrypt(password, Encoding.UTF8.GetBytes(salt));
PasswordHash = hash;
PasswordSalt = salt;
+ if (!string.IsNullOrWhiteSpace(actionType))
+ {
+ RaiseEvent(new UserPasswordChangedEvent { Type = actionType });
+ }
}
///
diff --git a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs
index 44ed584..00e2944 100644
--- a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs
+++ b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs
@@ -160,11 +160,6 @@ protected override Task UpdateAsync(CancellationToken cancellationToken = defaul
Aggregate.SetNickName(NickName);
}
- if (ChangedProperties.Contains(PasswordProperty))
- {
- Aggregate.ChangePassword(Password);
- }
-
if (ChangedProperties.Contains(IsAdminProperty))
{
Aggregate.SetIsAdmin(IsAdmin);
@@ -272,8 +267,6 @@ public override async Task ExecuteAsync(IRuleContext context, CancellationToken
public class PasswordStrengthRule : RuleBase
{
- private const string REGEX_PATTERN = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\x00-\xff]{8,32}$";
-
public override Task ExecuteAsync(IRuleContext context, CancellationToken cancellationToken = default)
{
var target = (UserGeneralBusiness)context.Target;
@@ -284,12 +277,12 @@ public override Task ExecuteAsync(IRuleContext context, CancellationToken cancel
{
context.AddErrorResult(Resources.IDS_ERROR_USER_RULE_PASSWORD_REQUIRED);
}
- else if (!Regex.IsMatch(target.Password, REGEX_PATTERN))
+ else if (!Regex.IsMatch(target.Password, Constants.RegexPattern.Password))
{
context.AddErrorResult(Resources.IDS_ERROR_USER_RULE_PASSWORD_NOT_MARCHED_RULES);
}
}
- else if (target.IsUpdate && target.ChangedProperties.Contains(PasswordProperty) && !Regex.IsMatch(target.Password, REGEX_PATTERN))
+ else if (target.IsUpdate && target.ChangedProperties.Contains(PasswordProperty) && !Regex.IsMatch(target.Password, Constants.RegexPattern.Password))
{
context.AddErrorResult(Resources.IDS_ERROR_USER_RULE_PASSWORD_NOT_MARCHED_RULES);
}
diff --git a/Source/Starfish.Service/Domain/Business/UserPasswordBusiness.cs b/Source/Starfish.Service/Domain/Business/UserPasswordBusiness.cs
new file mode 100644
index 0000000..b21ebf4
--- /dev/null
+++ b/Source/Starfish.Service/Domain/Business/UserPasswordBusiness.cs
@@ -0,0 +1,36 @@
+using System.Text.RegularExpressions;
+using Nerosoft.Euonia.Business;
+using Nerosoft.Euonia.Domain;
+using Nerosoft.Starfish.Service;
+
+namespace Nerosoft.Starfish.Domain;
+
+internal class UserPasswordBusiness : CommandObjectBase, IDomainService
+{
+ [Inject]
+ public IUserRepository Repository { get; set; }
+
+ [FactoryExecute]
+ protected async Task ExecuteAsync(string id, string password, string actionType, CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrWhiteSpace(password))
+ {
+ throw new ValidationException(Resources.IDS_ERROR_USER_RULE_PASSWORD_REQUIRED);
+ }
+ else if (!Regex.IsMatch(password, Constants.RegexPattern.Password))
+ {
+ throw new ValidationException(Resources.IDS_ERROR_USER_RULE_PASSWORD_NOT_MARCHED_RULES);
+ }
+
+ var aggregate = await Repository.GetAsync(id, true, cancellationToken);
+
+ if (aggregate == null)
+ {
+ throw new UserNotFoundException(id);
+ }
+
+ aggregate.SetPassword(password, actionType);
+
+ await Repository.UpdateAsync(aggregate, true, cancellationToken);
+ }
+}
diff --git a/Source/Starfish.Service/Domain/Events/UserPasswordChangedEvent.cs b/Source/Starfish.Service/Domain/Events/UserPasswordChangedEvent.cs
index e18874f..e788d69 100644
--- a/Source/Starfish.Service/Domain/Events/UserPasswordChangedEvent.cs
+++ b/Source/Starfish.Service/Domain/Events/UserPasswordChangedEvent.cs
@@ -7,4 +7,12 @@ namespace Nerosoft.Starfish.Domain;
///
public sealed class UserPasswordChangedEvent : DomainEvent
{
+ ///
+ /// 操作类型
+ ///
+ ///
+ /// - change
+ /// - reset
+ ///
+ public string Type { get; set; }
}
\ No newline at end of file
diff --git a/Source/Starfish.Service/UseCases/Identity/ChangePasswordUseCase.cs b/Source/Starfish.Service/UseCases/Identity/ChangePasswordUseCase.cs
index 8bd518b..11a7215 100644
--- a/Source/Starfish.Service/UseCases/Identity/ChangePasswordUseCase.cs
+++ b/Source/Starfish.Service/UseCases/Identity/ChangePasswordUseCase.cs
@@ -45,7 +45,7 @@ public async Task ExecuteAsync(ChangePasswordInput input, CancellationToken canc
throw new BadRequestException(Resources.IDS_ERROR_PASSWORD_INCORRECT);
}
- var command = new ChangePasswordCommand(user.Id, input.NewPassword);
+ var command = new ChangePasswordCommand(user.Id, input.NewPassword, "change");
await _bus.SendAsync(command, cancellationToken);
}
}
\ No newline at end of file
diff --git a/Source/Starfish.Service/UseCases/Identity/ResetPasswordUseCase.cs b/Source/Starfish.Service/UseCases/Identity/ResetPasswordUseCase.cs
index 1240a2f..77ab0db 100644
--- a/Source/Starfish.Service/UseCases/Identity/ResetPasswordUseCase.cs
+++ b/Source/Starfish.Service/UseCases/Identity/ResetPasswordUseCase.cs
@@ -19,7 +19,7 @@ public ResetPasswordUseCase(IBus bus)
public Task ExecuteAsync(ResetPasswordInput input, CancellationToken cancellationToken = default)
{
- var command = new ChangePasswordCommand(input.Id, input.Password);
+ var command = new ChangePasswordCommand(input.Id, input.Password, "reset");
return _bus.SendAsync(command, cancellationToken);
}
}
\ No newline at end of file
diff --git a/Source/Starfish.Webapi/Controllers/UserController.cs b/Source/Starfish.Webapi/Controllers/UserController.cs
index b43c90e..8b8810e 100644
--- a/Source/Starfish.Webapi/Controllers/UserController.cs
+++ b/Source/Starfish.Webapi/Controllers/UserController.cs
@@ -102,7 +102,7 @@ public async Task DeleteAsync(string id)
await _service.DeleteAsync(id, HttpContext.RequestAborted);
return Ok();
}
-
+
///
/// 重置指定用户密码
///