Skip to content

Commit

Permalink
增加密码修改领域服务。记录密码修改/重置日志。
Browse files Browse the repository at this point in the history
  • Loading branch information
Codespilot committed May 9, 2024
1 parent e25d9f4 commit 399ca28
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 33 deletions.
1 change: 1 addition & 0 deletions Source/Starfish.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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}$";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/// <summary>
Expand All @@ -27,4 +28,10 @@ public ChangePasswordCommand(string userId, string password)
/// 新密码
/// </summary>
public string Password { get; set; }

/// <summary>
/// 操作方式
/// </summary>
/// <value>change-修改;reset-重置</value>
public string ActionType { get; set; }
}
16 changes: 6 additions & 10 deletions Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ namespace Nerosoft.Starfish.Application;
/// 用户命令处理器
/// </summary>
public sealed class UserCommandHandler : CommandHandlerBase,
IHandler<UserCreateCommand>,
IHandler<UserUpdateCommand>,
IHandler<ChangePasswordCommand>,
IHandler<UserDeleteCommand>
IHandler<UserCreateCommand>,
IHandler<UserUpdateCommand>,
IHandler<ChangePasswordCommand>,
IHandler<UserDeleteCommand>
{
/// <summary>
/// 初始化<see cref="UserCommandHandler"/>.
Expand Down Expand Up @@ -58,7 +58,7 @@ public Task HandleAsync(UserUpdateCommand message, MessageContext context, Cance
business.IsAdmin = message.Item2.IsAdmin;

business.MarkAsUpdate();

await business.SaveAsync(true, cancellationToken);
});
}
Expand All @@ -68,11 +68,7 @@ public Task HandleAsync(ChangePasswordCommand message, MessageContext context, C
{
return ExecuteAsync(async () =>
{
var business = await Factory.FetchAsync<UserGeneralBusiness>(message.UserId, cancellationToken);

business.Password = message.Password;
business.MarkAsUpdate();
await business.SaveAsync(true, cancellationToken);
_ = await Factory.ExecuteAsync<UserPasswordBusiness>(message.UserId, message.Password, message.ActionType, cancellationToken);
});
}

Expand Down
22 changes: 12 additions & 10 deletions Source/Starfish.Service/Domain/Aggregates/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ private User()
/// 初始化用户聚合根
/// </summary>
/// <param name="userName"></param>
/// <param name="passwordHash"></param>
/// <param name="passwordSalt"></param>
private User(string userName, string passwordHash, string passwordSalt)
/// <param name="password"></param>
///
private User(string userName, string password)
: this()
{
UserName = userName;
PasswordHash = passwordHash;
PasswordSalt = passwordSalt;
SetPassword(password);
}

/// <summary>
Expand Down Expand Up @@ -115,22 +114,25 @@ private User(string userName, string passwordHash, string passwordSalt)
/// <returns></returns>
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;
}

/// <summary>
/// 修改密码
/// 设置密码
/// </summary>
/// <param name="password"></param>
internal void ChangePassword(string password)
/// <param name="actionType"></param>
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 });
}
}

/// <summary>
Expand Down
11 changes: 2 additions & 9 deletions Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
36 changes: 36 additions & 0 deletions Source/Starfish.Service/Domain/Business/UserPasswordBusiness.cs
Original file line number Diff line number Diff line change
@@ -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<UserPasswordBusiness>, 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ namespace Nerosoft.Starfish.Domain;
/// </summary>
public sealed class UserPasswordChangedEvent : DomainEvent
{
/// <summary>
/// 操作类型
/// </summary>
/// <remarks>
/// - change
/// - reset
/// </remarks>
public string Type { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
2 changes: 1 addition & 1 deletion Source/Starfish.Webapi/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public async Task<IActionResult> DeleteAsync(string id)
await _service.DeleteAsync(id, HttpContext.RequestAborted);
return Ok();
}

/// <summary>
/// 重置指定用户密码
/// </summary>
Expand Down

0 comments on commit 399ca28

Please sign in to comment.