From f9e1c07d3428ad9b50577f954be69201f1f00afb Mon Sep 17 00:00:00 2001 From: damon Date: Mon, 4 Mar 2024 22:51:54 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E7=A7=BB=E9=99=A4Administrator=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Identity/AdministratorAssignCommand.cs | 10 -- .../Identity/AdministratorDeleteCommand.cs | 13 -- .../Commands/Identity/UserCreateCommand.cs | 40 +++++- .../IAdministratorApplicationService.cs | 15 --- .../Handlers/AdministratorCommandHandler.cs | 49 ------- .../Handlers/UserCommandHandler.cs | 12 +- .../AdministratorApplicationService.cs | 46 ------- .../Mappings/IdentityMappingProfile.cs | 3 - .../Domain/Aggregates/Administrator.cs | 12 -- .../Domain/Aggregates/User.cs | 22 ++- .../Business/AdministratorGeneralBusiness.cs | 125 ------------------ .../Domain/Business/UserGeneralBusiness.cs | 31 ++++- .../Repositories/IAdministratorRepository.cs | 9 -- .../Contexts/AbstractDatabaseModelBuilder.cs | 5 +- .../RelationalDatabaseModelBuilder.cs | 23 +--- .../Repositories/AdministratorRepository.cs | 19 --- .../AdministratorSpecification.cs | 51 ------- .../Admins/AdministratorAssignUseCase.cs | 37 ------ .../Admins/AdministratorCountUseCase.cs | 49 ------- .../Admins/AdministratorDeleteUseCase.cs | 36 ----- .../Admins/AdministratorQueryUseCase.cs | 49 ------- .../Identity/GrantWithPasswordUseCase.cs | 8 +- .../Identity/GrantWithRefreshTokenUseCase.cs | 10 +- .../UseCases/Identity/UserCreateUseCase.cs | 3 +- .../Identity/AdministratorCriteria.cs | 15 --- .../Identity/AdministratorItemDto.cs | 37 ------ .../Identity/UserCreateDto.cs | 7 +- .../Controllers/AdministratorController.cs | 78 ----------- .../Rest/Defines/IAdministratorApi.cs | 19 --- .../Rest/ServiceCollectionExtensions.cs | 1 - 30 files changed, 102 insertions(+), 732 deletions(-) delete mode 100644 Source/Starfish.Service/Application/Commands/Identity/AdministratorAssignCommand.cs delete mode 100644 Source/Starfish.Service/Application/Commands/Identity/AdministratorDeleteCommand.cs delete mode 100644 Source/Starfish.Service/Application/Contracts/IAdministratorApplicationService.cs delete mode 100644 Source/Starfish.Service/Application/Handlers/AdministratorCommandHandler.cs delete mode 100644 Source/Starfish.Service/Application/Implements/AdministratorApplicationService.cs delete mode 100644 Source/Starfish.Service/Domain/Aggregates/Administrator.cs delete mode 100644 Source/Starfish.Service/Domain/Business/AdministratorGeneralBusiness.cs delete mode 100644 Source/Starfish.Service/Domain/Repositories/IAdministratorRepository.cs delete mode 100644 Source/Starfish.Service/Repository/Repositories/AdministratorRepository.cs delete mode 100644 Source/Starfish.Service/Repository/Specifications/AdministratorSpecification.cs delete mode 100644 Source/Starfish.Service/UseCases/Admins/AdministratorAssignUseCase.cs delete mode 100644 Source/Starfish.Service/UseCases/Admins/AdministratorCountUseCase.cs delete mode 100644 Source/Starfish.Service/UseCases/Admins/AdministratorDeleteUseCase.cs delete mode 100644 Source/Starfish.Service/UseCases/Admins/AdministratorQueryUseCase.cs delete mode 100644 Source/Starfish.Transit/Identity/AdministratorCriteria.cs delete mode 100644 Source/Starfish.Transit/Identity/AdministratorItemDto.cs delete mode 100644 Source/Starfish.Webapi/Controllers/AdministratorController.cs delete mode 100644 Source/Starfish.Webapp/Rest/Defines/IAdministratorApi.cs diff --git a/Source/Starfish.Service/Application/Commands/Identity/AdministratorAssignCommand.cs b/Source/Starfish.Service/Application/Commands/Identity/AdministratorAssignCommand.cs deleted file mode 100644 index 07d704a..0000000 --- a/Source/Starfish.Service/Application/Commands/Identity/AdministratorAssignCommand.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Nerosoft.Euonia.Domain; - -namespace Nerosoft.Starfish.Application; - -public class AdministratorAssignCommand : Command -{ - public string UserId { get; set; } - - public List Roles { get; set; } -} \ No newline at end of file diff --git a/Source/Starfish.Service/Application/Commands/Identity/AdministratorDeleteCommand.cs b/Source/Starfish.Service/Application/Commands/Identity/AdministratorDeleteCommand.cs deleted file mode 100644 index 2a30718..0000000 --- a/Source/Starfish.Service/Application/Commands/Identity/AdministratorDeleteCommand.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Nerosoft.Euonia.Domain; - -namespace Nerosoft.Starfish.Application; - -public class AdministratorDeleteCommand : Command -{ - public AdministratorDeleteCommand(string userId) - { - UserId = userId; - } - - public string UserId { get; set; } -} \ No newline at end of file diff --git a/Source/Starfish.Service/Application/Commands/Identity/UserCreateCommand.cs b/Source/Starfish.Service/Application/Commands/Identity/UserCreateCommand.cs index 4d20d3b..fc88a7e 100644 --- a/Source/Starfish.Service/Application/Commands/Identity/UserCreateCommand.cs +++ b/Source/Starfish.Service/Application/Commands/Identity/UserCreateCommand.cs @@ -6,14 +6,40 @@ namespace Nerosoft.Starfish.Application; /// /// 创建用户命令 /// -public sealed class UserCreateCommand : Command +public sealed class UserCreateCommand : Command { /// - /// 构造函数 + /// 用户名 /// - /// 用户创建数据传输对象 - public UserCreateCommand(UserCreateDto data) - : base(data) - { - } + public string UserName { get; set; } + + /// + /// 密码 + /// + public string Password { get; set; } + + /// + /// 邮箱 + /// + public string Email { get; set; } + + /// + /// 电话 + /// + public string Phone { get; set; } + + /// + /// 昵称 + /// + public string NickName { get; set; } + + /// + /// 是否是管理员 + /// + public bool IsAdmin { get; set; } = false; + + /// + /// 是否是预留账号 + /// + public bool Reserved { get; set; } = false; } \ No newline at end of file diff --git a/Source/Starfish.Service/Application/Contracts/IAdministratorApplicationService.cs b/Source/Starfish.Service/Application/Contracts/IAdministratorApplicationService.cs deleted file mode 100644 index f0fd3df..0000000 --- a/Source/Starfish.Service/Application/Contracts/IAdministratorApplicationService.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Nerosoft.Euonia.Application; -using Nerosoft.Starfish.Transit; - -namespace Nerosoft.Starfish.Application; - -public interface IAdministratorApplicationService : IApplicationService -{ - Task> QueryAsync(AdministratorCriteria criteria, int skip, int count, CancellationToken cancellationToken = default); - - Task CountAsync(AdministratorCriteria criteria, CancellationToken cancellationToken = default); - - Task AssignAsync(AdministratorAssignDto data, CancellationToken cancellationToken = default); - - Task DeleteAsync(string userId, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/Source/Starfish.Service/Application/Handlers/AdministratorCommandHandler.cs b/Source/Starfish.Service/Application/Handlers/AdministratorCommandHandler.cs deleted file mode 100644 index b390baa..0000000 --- a/Source/Starfish.Service/Application/Handlers/AdministratorCommandHandler.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Nerosoft.Euonia.Bus; -using Nerosoft.Euonia.Business; -using Nerosoft.Euonia.Repository; -using Nerosoft.Starfish.Domain; -using Nerosoft.Starfish.Service; - -namespace Nerosoft.Starfish.Application; - -public class AdministratorCommandHandler : CommandHandlerBase, - IHandler, - IHandler -{ - public AdministratorCommandHandler(IUnitOfWorkManager unitOfWork, IObjectFactory factory) - : base(unitOfWork, factory) - { - } - - public Task HandleAsync(AdministratorAssignCommand message, MessageContext context, CancellationToken cancellationToken = default) - { - return ExecuteAsync(async () => - { - var business = await Factory.FetchAsync(message.UserId, cancellationToken); - business.UserId = message.UserId; - business.SetRoles(message.Roles); - if (business.Aggregate == null) - { - business.MarkAsInsert(); - } - else - { - business.MarkAsUpdate(); - } - - _ = await business.SaveAsync(false, cancellationToken); - }); - } - - public Task HandleAsync(AdministratorDeleteCommand message, MessageContext context, CancellationToken cancellationToken = default) - { - return ExecuteAsync(async () => - { - var business = await Factory.FetchAsync(message.UserId, cancellationToken); - - business.MarkAsDelete(); - - _ = await business.SaveAsync(false, cancellationToken); - }); - } -} \ 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 7755a3b..5b57a24 100644 --- a/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs +++ b/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs @@ -31,11 +31,13 @@ public Task HandleAsync(UserCreateCommand message, MessageContext context, Cance return ExecuteAsync(async () => { var business = await Factory.CreateAsync(cancellationToken); - business.UserName = message.Item1.UserName; - business.Password = message.Item1.Password; - business.NickName = message.Item1.NickName; - business.Email = message.Item1.Email; - business.Phone = message.Item1.Phone; + business.UserName = message.UserName; + business.Password = message.Password; + business.NickName = message.NickName; + business.Email = message.Email; + business.Phone = message.Phone; + business.IsAdmin = message.IsAdmin; + business.Reserved = message.Reserved; business.MarkAsInsert(); await business.SaveAsync(false, cancellationToken); diff --git a/Source/Starfish.Service/Application/Implements/AdministratorApplicationService.cs b/Source/Starfish.Service/Application/Implements/AdministratorApplicationService.cs deleted file mode 100644 index 44afdc4..0000000 --- a/Source/Starfish.Service/Application/Implements/AdministratorApplicationService.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Nerosoft.Euonia.Application; -using Nerosoft.Starfish.Transit; -using Nerosoft.Starfish.UseCases; - -namespace Nerosoft.Starfish.Application; - -internal class AdministratorApplicationService : BaseApplicationService, IAdministratorApplicationService -{ - public Task> QueryAsync(AdministratorCriteria criteria, int skip, int count, CancellationToken cancellationToken = default) - { - var input = new GenericQueryInput(criteria, skip, count); - var useCase = LazyServiceProvider.GetRequiredService(); - return useCase.ExecuteAsync(input, cancellationToken).ContinueWith(task => - { - task.WaitAndUnwrapException(cancellationToken); - return task.Result.Result; - }, cancellationToken); - } - - public Task CountAsync(AdministratorCriteria criteria, CancellationToken cancellationToken = default) - { - var input = new AdministratorCountInput(criteria); - var useCase = LazyServiceProvider.GetRequiredService(); - return useCase.ExecuteAsync(input, cancellationToken).ContinueWith(task => - { - task.WaitAndUnwrapException(cancellationToken); - return task.Result.Result; - }, cancellationToken); - } - - public Task AssignAsync(AdministratorAssignDto data, CancellationToken cancellationToken = default) - { - var input = new AdministratorAssignInput(data); - var useCase = LazyServiceProvider.GetRequiredService(); - return useCase.ExecuteAsync(input, cancellationToken) - .ContinueWith(task => task.WaitAndUnwrapException(cancellationToken), cancellationToken); - } - - public Task DeleteAsync(string userId, CancellationToken cancellationToken = default) - { - var input = new AdministratorDeleteInput(userId); - var useCase = LazyServiceProvider.GetRequiredService(); - return useCase.ExecuteAsync(input, cancellationToken) - .ContinueWith(task => task.WaitAndUnwrapException(cancellationToken), cancellationToken); - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/Application/Mappings/IdentityMappingProfile.cs b/Source/Starfish.Service/Application/Mappings/IdentityMappingProfile.cs index e5a9b76..cc9fb35 100644 --- a/Source/Starfish.Service/Application/Mappings/IdentityMappingProfile.cs +++ b/Source/Starfish.Service/Application/Mappings/IdentityMappingProfile.cs @@ -27,9 +27,6 @@ public IdentityMappingProfile() .ForMember(dest => dest.NickName, options => options.MapFrom(src => src.User.NickName)) .ForMember(dest => dest.Email, options => options.MapFrom(src => src.User.Email)) .ForMember(dest => dest.Phone, options => options.MapFrom(src => src.User.Phone)); - - CreateMap(); - CreateMap(); } private static string Mask(string source) diff --git a/Source/Starfish.Service/Domain/Aggregates/Administrator.cs b/Source/Starfish.Service/Domain/Aggregates/Administrator.cs deleted file mode 100644 index 8bcf181..0000000 --- a/Source/Starfish.Service/Domain/Aggregates/Administrator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Nerosoft.Euonia.Domain; - -namespace Nerosoft.Starfish.Domain; - -public class Administrator : Aggregate -{ - public string UserId { get; set; } - - public User User { get; set; } - - public string Roles { get; set; } -} \ No newline at end of file diff --git a/Source/Starfish.Service/Domain/Aggregates/User.cs b/Source/Starfish.Service/Domain/Aggregates/User.cs index cac5abe..04141ab 100644 --- a/Source/Starfish.Service/Domain/Aggregates/User.cs +++ b/Source/Starfish.Service/Domain/Aggregates/User.cs @@ -16,7 +16,7 @@ public sealed class User : Aggregate, IHasCreateTime, IHasUpdateTime, IT private User() { } - + /// /// 初始化用户聚合根 /// @@ -77,6 +77,11 @@ private User(string userName, string passwordHash, string passwordSalt) /// 预留账号不允许删除、设置角色等 public bool Reserved { get; set; } + /// + /// 是否是管理员 + /// + public bool IsAdmin { get; set; } + /// /// 来源 /// @@ -155,6 +160,21 @@ internal void SetNickName(string nickName) NickName = nickName; } + internal void SetIsAdmin(bool isAdmin) + { + if (Reserved) + { + return; + } + + if (isAdmin == IsAdmin) + { + return; + } + + IsAdmin = isAdmin; + } + /// /// 增加授权失败次数 /// diff --git a/Source/Starfish.Service/Domain/Business/AdministratorGeneralBusiness.cs b/Source/Starfish.Service/Domain/Business/AdministratorGeneralBusiness.cs deleted file mode 100644 index 8b8909f..0000000 --- a/Source/Starfish.Service/Domain/Business/AdministratorGeneralBusiness.cs +++ /dev/null @@ -1,125 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nerosoft.Euonia.Business; -using Nerosoft.Starfish.Service; - -// ReSharper disable MemberCanBePrivate.Global - -namespace Nerosoft.Starfish.Domain; - -internal sealed class AdministratorGeneralBusiness : EditableObjectBase -{ - [Inject] - public IUserRepository UserRepository { get; set; } - - [Inject] - public IAdministratorRepository AdministratorRepository { get; set; } - - public Administrator Aggregate { get; private set; } - - public static readonly PropertyInfo UserIdProperty = RegisterProperty(p => p.UserId); - - public string UserId - { - get => GetProperty(UserIdProperty); - set => SetProperty(UserIdProperty, value); - } - - public static readonly PropertyInfo> RolesProperty = RegisterProperty>(p => p.Roles, []); - - public HashSet Roles - { - get => GetProperty(RolesProperty); - set => SetProperty(RolesProperty, value); - } - - protected override void AddRules() - { - Rules.AddRule(new UserCheckRule()); - } - - public void SetRoles(IEnumerable roles) - { - if (Roles.SetEquals(roles)) - { - return; - } - - Roles.Clear(); - if (roles.Any()) - { - foreach (var role in roles) - { - Roles.Add(role); - } - } - - ChangedProperties.Add(RolesProperty); - } - - [FactoryFetch] - internal async Task FetchAsync(string userId, CancellationToken cancellationToken = default) - { - var aggregate = await AdministratorRepository.GetAsync(t => t.UserId == userId, query => query.AsTracking(), cancellationToken); - - if (aggregate != null) - { - using (BypassRuleChecks) - { - UserId = aggregate.UserId; - Roles = [..aggregate.Roles.Split(",")]; - } - - Aggregate = aggregate; - } - } - - [FactoryInsert] - protected override async Task InsertAsync(CancellationToken cancellationToken = default) - { - Aggregate = new Administrator - { - UserId = UserId, - Roles = Roles.JoinAsString(",") - }; - - await AdministratorRepository.InsertAsync(Aggregate, true, cancellationToken); - } - - [FactoryUpdate] - protected override async Task UpdateAsync(CancellationToken cancellationToken = default) - { - if (ChangedProperties.Contains(RolesProperty)) - { - Aggregate.Roles = Roles.JoinAsString(","); - } - - await AdministratorRepository.UpdateAsync(Aggregate, true, cancellationToken); - } - - [FactoryDelete] - protected override async Task DeleteAsync(CancellationToken cancellationToken = default) - { - if (Aggregate == null) - { - throw new NotFoundException(); - } - - await AdministratorRepository.DeleteAsync(Aggregate, true, cancellationToken); - } - - public class UserCheckRule : RuleBase - { - public override async Task ExecuteAsync(IRuleContext context, CancellationToken cancellationToken = default) - { - var target = (AdministratorGeneralBusiness)context.Target; - if (target.ChangedProperties.Contains(UserIdProperty)) - { - var exists = await target.UserRepository.AnyAsync(t => t.Id == target.UserId, query => query.AsNoTracking(), cancellationToken); - if (exists) - { - context.AddErrorResult(string.Format(Resources.IDS_ERROR_USER_NOT_EXISTS, target.UserId)); - } - } - } - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs index f9264e6..7f128f1 100644 --- a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs +++ b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs @@ -28,6 +28,8 @@ public UserGeneralBusiness(IServiceProvider provider) public static readonly PropertyInfo NickNameProperty = RegisterProperty(p => p.NickName); public static readonly PropertyInfo EmailProperty = RegisterProperty(p => p.Email); public static readonly PropertyInfo PhoneProperty = RegisterProperty(p => p.Phone); + public static readonly PropertyInfo IsAdminProperty = RegisterProperty(p => p.IsAdmin); + public static readonly PropertyInfo ReservedProperty = RegisterProperty(p => p.Reserved); public string Id { @@ -65,6 +67,18 @@ public string Phone set => SetProperty(PhoneProperty, value); } + public bool IsAdmin + { + get => GetProperty(IsAdminProperty); + set => SetProperty(IsAdminProperty, value); + } + + public bool Reserved + { + get => GetProperty(ReservedProperty); + set => SetProperty(ReservedProperty, value); + } + protected override void AddRules() { Rules.AddRule(new DuplicateUserNameCheckRule()); @@ -111,13 +125,15 @@ protected override Task InsertAsync(CancellationToken cancellationToken = defaul } user.SetNickName(NickName ?? UserName); + user.SetIsAdmin(IsAdmin); + user.Reserved = Reserved; return Repository.InsertAsync(user, true, cancellationToken) - .ContinueWith(task => - { - task.WaitAndUnwrapException(cancellationToken); - Id = task.Result.Id; - }, cancellationToken); + .ContinueWith(task => + { + task.WaitAndUnwrapException(cancellationToken); + Id = task.Result.Id; + }, cancellationToken); } [FactoryUpdate] @@ -143,6 +159,11 @@ protected override Task UpdateAsync(CancellationToken cancellationToken = defaul Aggregate.ChangePassword(Password); } + if (ChangedProperties.Contains(IsAdminProperty)) + { + Aggregate.SetIsAdmin(IsAdmin); + } + return _repository.UpdateAsync(Aggregate, true, cancellationToken); } diff --git a/Source/Starfish.Service/Domain/Repositories/IAdministratorRepository.cs b/Source/Starfish.Service/Domain/Repositories/IAdministratorRepository.cs deleted file mode 100644 index 791776b..0000000 --- a/Source/Starfish.Service/Domain/Repositories/IAdministratorRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Nerosoft.Starfish.Repository; -using Nerosoft.Starfish.Service; - -namespace Nerosoft.Starfish.Domain; - -internal interface IAdministratorRepository : IBaseRepository -{ - Task GetByUserIdAsync(string userId, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/Source/Starfish.Service/Repository/Contexts/AbstractDatabaseModelBuilder.cs b/Source/Starfish.Service/Repository/Contexts/AbstractDatabaseModelBuilder.cs index 3e8c7dd..4f1b827 100644 --- a/Source/Starfish.Service/Repository/Contexts/AbstractDatabaseModelBuilder.cs +++ b/Source/Starfish.Service/Repository/Contexts/AbstractDatabaseModelBuilder.cs @@ -8,7 +8,6 @@ internal abstract class AbstractDatabaseModelBuilder : IModelBuilder public virtual void Configure(ModelBuilder modelBuilder) { ConfigureUser(modelBuilder); - ConfigureAdministrator(modelBuilder); ConfigureTeam(modelBuilder); ConfigureTeamMember(modelBuilder); ConfigureConfiguration(modelBuilder); @@ -20,9 +19,7 @@ public virtual void Configure(ModelBuilder modelBuilder) } protected abstract ModelBuilder ConfigureUser(ModelBuilder modelBuilder); - - protected abstract ModelBuilder ConfigureAdministrator(ModelBuilder modelBuilder); - + protected abstract ModelBuilder ConfigureTeam(ModelBuilder modelBuilder); protected abstract ModelBuilder ConfigureTeamMember(ModelBuilder modelBuilder); diff --git a/Source/Starfish.Service/Repository/Contexts/RelationalDatabaseModelBuilder.cs b/Source/Starfish.Service/Repository/Contexts/RelationalDatabaseModelBuilder.cs index c81a44d..7b7a124 100644 --- a/Source/Starfish.Service/Repository/Contexts/RelationalDatabaseModelBuilder.cs +++ b/Source/Starfish.Service/Repository/Contexts/RelationalDatabaseModelBuilder.cs @@ -31,28 +31,7 @@ protected override ModelBuilder ConfigureUser(ModelBuilder modelBuilder) .HasValueGenerator(); }); } - - protected override ModelBuilder ConfigureAdministrator(ModelBuilder modelBuilder) - { - return modelBuilder.Entity(entity => - { - entity.ToTable("administrator"); - - entity.HasKey(t => t.Id); - - entity.HasIndex(t => t.UserId).HasDatabaseName("IDX_ADMIN_USER_ID") - .IsUnique(); - - entity.Property(t => t.Id) - .IsRequired() - .HasValueGenerator(); - - entity.HasOne(t => t.User) - .WithMany() - .HasForeignKey(t => t.UserId); - }); - } - + protected override ModelBuilder ConfigureTeam(ModelBuilder modelBuilder) { return modelBuilder.Entity(entity => diff --git a/Source/Starfish.Service/Repository/Repositories/AdministratorRepository.cs b/Source/Starfish.Service/Repository/Repositories/AdministratorRepository.cs deleted file mode 100644 index acb15ef..0000000 --- a/Source/Starfish.Service/Repository/Repositories/AdministratorRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nerosoft.Euonia.Repository; -using Nerosoft.Starfish.Domain; -using Nerosoft.Starfish.Service; - -namespace Nerosoft.Starfish.Repository; - -internal sealed class AdministratorRepository : BaseRepository, IAdministratorRepository -{ - public AdministratorRepository(IContextProvider provider) - : base(provider) - { - } - - public Task GetByUserIdAsync(string userId, CancellationToken cancellationToken = default) - { - return Context.Set().FirstOrDefaultAsync(t => t.UserId == userId, cancellationToken); - } -} diff --git a/Source/Starfish.Service/Repository/Specifications/AdministratorSpecification.cs b/Source/Starfish.Service/Repository/Specifications/AdministratorSpecification.cs deleted file mode 100644 index 43e49ae..0000000 --- a/Source/Starfish.Service/Repository/Specifications/AdministratorSpecification.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Nerosoft.Euonia.Linq; -using Nerosoft.Starfish.Domain; - -namespace Nerosoft.Starfish.Repository; - -internal static class AdministratorSpecification -{ - public static Specification UserNameContains(string userName) - { - userName = userName.Normalize(TextCaseType.Lower); - return new DirectSpecification(t => t.User.UserName.Contains(userName)); - } - - public static Specification NickNameContains(string nickName) - { - nickName = nickName.Normalize(TextCaseType.Lower); - return new DirectSpecification(t => t.User.NickName.ToLower().Contains(nickName)); - } - - public static Specification EmailContains(string email) - { - email = email.Normalize(TextCaseType.Lower); - return new DirectSpecification(t => t.User.Email.Contains(email)); - } - - public static Specification PhoneContains(string email) - { - email = email.Normalize(TextCaseType.Lower); - return new DirectSpecification(t => t.User.Phone.Contains(email)); - } - - public static Specification Matches(string keyword) - { - if (string.IsNullOrEmpty(keyword)) - { - return new TrueSpecification(); - } - - keyword = keyword.Normalize(TextCaseType.Lower); - - ISpecification[] specifications = - [ - UserNameContains(keyword), - NickNameContains(keyword), - EmailContains(keyword), - PhoneContains(keyword) - ]; - - return new CompositeSpecification(PredicateOperator.OrElse, specifications); - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/UseCases/Admins/AdministratorAssignUseCase.cs b/Source/Starfish.Service/UseCases/Admins/AdministratorAssignUseCase.cs deleted file mode 100644 index ed6efc1..0000000 --- a/Source/Starfish.Service/UseCases/Admins/AdministratorAssignUseCase.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Nerosoft.Euonia.Application; -using Nerosoft.Euonia.Bus; -using Nerosoft.Euonia.Claims; -using Nerosoft.Euonia.Mapping; -using Nerosoft.Starfish.Application; -using Nerosoft.Starfish.Transit; - -namespace Nerosoft.Starfish.UseCases; - -internal interface IAdministratorAssignUseCase : INonOutputUseCase; - -internal record AdministratorAssignInput(AdministratorAssignDto Data); - -internal class AdministratorAssignUseCase : IAdministratorAssignUseCase -{ - private readonly IBus _bus; - private readonly UserPrincipal _user; - - public AdministratorAssignUseCase(IBus bus, UserPrincipal user) - { - _bus = bus; - _user = user; - } - - public Task ExecuteAsync(AdministratorAssignInput input, CancellationToken cancellationToken = default) - { - _user.EnsureInRoles(["SA"]); - - if (string.Equals(_user.UserId, input.Data.UserId)) - { - throw new InvalidOperationException(); - } - - var command = TypeAdapter.ProjectedAs(input.Data); - return _bus.SendAsync(command, cancellationToken); - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/UseCases/Admins/AdministratorCountUseCase.cs b/Source/Starfish.Service/UseCases/Admins/AdministratorCountUseCase.cs deleted file mode 100644 index 4cb8b2c..0000000 --- a/Source/Starfish.Service/UseCases/Admins/AdministratorCountUseCase.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Security.Authentication; -using Microsoft.EntityFrameworkCore; -using Nerosoft.Euonia.Application; -using Nerosoft.Euonia.Claims; -using Nerosoft.Starfish.Domain; -using Nerosoft.Starfish.Repository; -using Nerosoft.Starfish.Transit; - -namespace Nerosoft.Starfish.UseCases; - -internal interface IAdministratorCountUseCase : IUseCase; - -internal record AdministratorCountInput(AdministratorCriteria Criteria); - -internal record AdministratorCountOutput(int Result); - -internal class AdministratorCountUseCase : IAdministratorCountUseCase -{ - private readonly IAdministratorRepository _repository; - private readonly UserPrincipal _user; - - public AdministratorCountUseCase(IAdministratorRepository repository, UserPrincipal user) - { - _repository = repository; - _user = user; - } - - public Task ExecuteAsync(AdministratorCountInput input, CancellationToken cancellationToken = default) - { - if (_user.IsAuthenticated) - { - throw new AuthenticationException(Resources.IDS_MESSAGE_LOGS_AUTH_FAILED); - } - - if (!_user.IsInRoles(["SA"])) - { - throw new UnauthorizedAccessException(Resources.IDS_ERROR_COMMON_UNAUTHORIZED_ACCESS); - } - - var predicate = AdministratorSpecification.Matches(input.Criteria.Keyword).Satisfy(); - - return _repository.CountAsync(predicate, query => query.AsNoTracking().Include(t => t.User), cancellationToken) - .ContinueWith(task => - { - task.WaitAndUnwrapException(cancellationToken); - return new AdministratorCountOutput(task.Result); - }, cancellationToken); - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/UseCases/Admins/AdministratorDeleteUseCase.cs b/Source/Starfish.Service/UseCases/Admins/AdministratorDeleteUseCase.cs deleted file mode 100644 index c278b4c..0000000 --- a/Source/Starfish.Service/UseCases/Admins/AdministratorDeleteUseCase.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Nerosoft.Euonia.Application; -using Nerosoft.Euonia.Bus; -using Nerosoft.Euonia.Claims; -using Nerosoft.Starfish.Application; - -namespace Nerosoft.Starfish.UseCases; - -internal interface IAdministratorDeleteUseCase : INonOutputUseCase; - -internal record AdministratorDeleteInput(string UserId) : IUseCaseInput; - -internal class AdministratorDeleteUseCase : IAdministratorDeleteUseCase -{ - private readonly IBus _bus; - private readonly UserPrincipal _user; - - public AdministratorDeleteUseCase(IBus bus, UserPrincipal user) - { - _bus = bus; - _user = user; - } - - public Task ExecuteAsync(AdministratorDeleteInput input, CancellationToken cancellationToken = default) - { - _user.EnsureInRoles(["SA"]); - - if (string.Equals(_user.UserId, input.UserId)) - { - throw new InvalidOperationException(); - } - - var command = new AdministratorDeleteCommand(input.UserId); - - return _bus.SendAsync(command, cancellationToken); - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/UseCases/Admins/AdministratorQueryUseCase.cs b/Source/Starfish.Service/UseCases/Admins/AdministratorQueryUseCase.cs deleted file mode 100644 index 4167d73..0000000 --- a/Source/Starfish.Service/UseCases/Admins/AdministratorQueryUseCase.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Security.Authentication; -using Microsoft.EntityFrameworkCore; -using Nerosoft.Euonia.Application; -using Nerosoft.Euonia.Claims; -using Nerosoft.Euonia.Mapping; -using Nerosoft.Starfish.Domain; -using Nerosoft.Starfish.Repository; -using Nerosoft.Starfish.Transit; - -namespace Nerosoft.Starfish.UseCases; - -internal interface IAdministratorQueryUseCase : IUseCase, AdministratorQueryOutput>; - -internal record AdministratorQueryOutput(List Result); - -internal class AdministratorQueryUseCase : IAdministratorQueryUseCase -{ - private readonly IAdministratorRepository _repository; - private readonly UserPrincipal _user; - - public AdministratorQueryUseCase(IAdministratorRepository repository, UserPrincipal user) - { - _repository = repository; - _user = user; - } - - public Task ExecuteAsync(GenericQueryInput input, CancellationToken cancellationToken = default) - { - if (_user.IsAuthenticated) - { - throw new AuthenticationException(Resources.IDS_MESSAGE_LOGS_AUTH_FAILED); - } - - if (!_user.IsInRoles(["SA"])) - { - throw new UnauthorizedAccessException(Resources.IDS_ERROR_COMMON_UNAUTHORIZED_ACCESS); - } - - var predicate = AdministratorSpecification.Matches(input.Criteria.Keyword).Satisfy(); - - return _repository.FindAsync(predicate, query => query.AsNoTracking().Include(t => t.User), input.Skip, input.Count, cancellationToken) - .ContinueWith(task => - { - task.WaitAndUnwrapException(cancellationToken); - var result = TypeAdapter.ProjectedAs>(task.Result); - return new AdministratorQueryOutput(result); - }, cancellationToken); - } -} \ No newline at end of file diff --git a/Source/Starfish.Service/UseCases/Identity/GrantWithPasswordUseCase.cs b/Source/Starfish.Service/UseCases/Identity/GrantWithPasswordUseCase.cs index 4abf7ba..ae383bb 100644 --- a/Source/Starfish.Service/UseCases/Identity/GrantWithPasswordUseCase.cs +++ b/Source/Starfish.Service/UseCases/Identity/GrantWithPasswordUseCase.cs @@ -41,9 +41,6 @@ public GrantWithPasswordUseCase(IServiceProvider provider) private IUserRepository _userRepository; private IUserRepository UserRepository => _userRepository ??= _provider.GetService(); - private IAdministratorRepository _adminRespository; - private IAdministratorRepository AdminRepository => _adminRespository ??= _provider.GetService(); - private IdentityCommonComponent _component; private IdentityCommonComponent Component => _component ??= _provider.GetService(); @@ -79,9 +76,8 @@ public async Task ExecuteAsync(GrantWithPassword throw new AuthenticationException(Resources.IDS_ERROR_USER_LOCKOUT); } - var administrator = await AdminRepository.GetByUserIdAsync(user.Id, cancellationToken); - var roles = administrator?.Roles?.Split(","); - + string[] roles = user.IsAdmin ? ["SA"] : []; + var (accessToken, refreshToken, issuesAt, expiresAt) = Component.GenerateAccessToken(user.Id, user.UserName, roles); @events.Add(new UserAuthSucceedEvent { diff --git a/Source/Starfish.Service/UseCases/Identity/GrantWithRefreshTokenUseCase.cs b/Source/Starfish.Service/UseCases/Identity/GrantWithRefreshTokenUseCase.cs index c415c38..18448e0 100644 --- a/Source/Starfish.Service/UseCases/Identity/GrantWithRefreshTokenUseCase.cs +++ b/Source/Starfish.Service/UseCases/Identity/GrantWithRefreshTokenUseCase.cs @@ -43,9 +43,6 @@ public GrantWithRefreshTokenUseCase(IServiceProvider provider) private IUserRepository UserRepository => _provider.GetService(); private ITokenRepository TokenRepository => _provider.GetService(); - private IAdministratorRepository _adminRespository; - private IAdministratorRepository AdminRepository => _adminRespository ??= _provider.GetService(); - private IdentityCommonComponent _component; private IdentityCommonComponent Component => _component ??= _provider.GetService(); @@ -88,10 +85,9 @@ public async Task ExecuteAsync(GrantWithRefr { throw new AuthenticationException(Resources.IDS_ERROR_USER_LOCKOUT); } - - var administrator = await AdminRepository.GetByUserIdAsync(user.Id, cancellationToken); - var roles = administrator?.Roles?.Split(","); - + + string[] roles = user.IsAdmin ? ["SA"] : []; + var (accessToken, refreshToken, issuesAt, expiresAt) = Component.GenerateAccessToken(user.Id, user.UserName, roles); @events.Add(new UserAuthSucceedEvent { diff --git a/Source/Starfish.Service/UseCases/Identity/UserCreateUseCase.cs b/Source/Starfish.Service/UseCases/Identity/UserCreateUseCase.cs index 07657dd..7b1772c 100644 --- a/Source/Starfish.Service/UseCases/Identity/UserCreateUseCase.cs +++ b/Source/Starfish.Service/UseCases/Identity/UserCreateUseCase.cs @@ -1,5 +1,6 @@ using Nerosoft.Euonia.Application; using Nerosoft.Euonia.Bus; +using Nerosoft.Euonia.Mapping; using Nerosoft.Starfish.Application; using Nerosoft.Starfish.Transit; @@ -22,7 +23,7 @@ public UserCreateUseCase(IBus bus) public Task ExecuteAsync(UserCreateInput input, CancellationToken cancellationToken = default) { - var command = new UserCreateCommand(input.Data); + var command = TypeAdapter.ProjectedAs(input.Data); return _bus.SendAsync(command, cancellationToken) .ContinueWith(task => new UserCreateOutput(task.Result), cancellationToken); } diff --git a/Source/Starfish.Transit/Identity/AdministratorCriteria.cs b/Source/Starfish.Transit/Identity/AdministratorCriteria.cs deleted file mode 100644 index 917e576..0000000 --- a/Source/Starfish.Transit/Identity/AdministratorCriteria.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Nerosoft.Starfish.Transit; - -/// -/// 管理员搜索条件 -/// -public class AdministratorCriteria -{ - /// - /// 关键字 - /// - /// - /// 搜索用户名、昵称、邮箱、电话号码 - /// - public string Keyword { get; set; } -} \ No newline at end of file diff --git a/Source/Starfish.Transit/Identity/AdministratorItemDto.cs b/Source/Starfish.Transit/Identity/AdministratorItemDto.cs deleted file mode 100644 index b7b52f1..0000000 --- a/Source/Starfish.Transit/Identity/AdministratorItemDto.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Nerosoft.Starfish.Transit; - -/// -/// 管理员列表项数据传输对象 -/// -public sealed class AdministratorItemDto -{ - /// - /// 用户Id - /// - public string UserId { get; set; } - - /// - /// 用户名 - /// - public string UserName { get; set; } - - /// - /// 昵称 - /// - public string NickName { get; set; } - - /// - /// 邮箱 - /// - public string Email { get; set; } - - /// - /// 电话号码 - /// - public string Phone { get; set; } - - /// - /// 角色 - /// - public List Roles { get; set; } -} \ No newline at end of file diff --git a/Source/Starfish.Transit/Identity/UserCreateDto.cs b/Source/Starfish.Transit/Identity/UserCreateDto.cs index d998735..561c9bc 100644 --- a/Source/Starfish.Transit/Identity/UserCreateDto.cs +++ b/Source/Starfish.Transit/Identity/UserCreateDto.cs @@ -24,9 +24,14 @@ public class UserCreateDto /// 电话 /// public string Phone { get; set; } - + /// /// 昵称 /// public string NickName { get; set; } + + /// + /// 是否是管理员 + /// + public bool IsAdmin { get; set; } } \ No newline at end of file diff --git a/Source/Starfish.Webapi/Controllers/AdministratorController.cs b/Source/Starfish.Webapi/Controllers/AdministratorController.cs deleted file mode 100644 index d7aa7a9..0000000 --- a/Source/Starfish.Webapi/Controllers/AdministratorController.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Nerosoft.Starfish.Application; -using Nerosoft.Starfish.Transit; - -namespace Nerosoft.Starfish.Webapi.Controllers; - -/// -/// 管理员管理Controller -/// -[Route("api/[controller]")] -[ApiController, ApiExplorerSettings(GroupName = "identity")] -[Authorize] -public class AdministratorController : ControllerBase -{ - private readonly IAdministratorApplicationService _service; - - /// - /// 构造函数 - /// - /// - public AdministratorController(IAdministratorApplicationService service) - { - _service = service; - } - - /// - /// 查询管理员列表 - /// - /// - /// - /// - /// - [HttpGet] - [Produces(typeof(List))] - public async Task QueryAsync([FromQuery] AdministratorCriteria criteria, int skip = Constants.Query.Skip, int count = Constants.Query.Count) - { - var result = await _service.QueryAsync(criteria, skip, count, HttpContext.RequestAborted); - return Ok(result); - } - - /// - /// 查询管理员数量 - /// - /// - /// - [HttpGet("count")] - [Produces(typeof(int))] - public async Task CountAsync([FromQuery] AdministratorCriteria criteria) - { - var result = await _service.CountAsync(criteria, HttpContext.RequestAborted); - return Ok(result); - } - - /// - /// 创建管理员 - /// - /// - /// - [HttpPost] - public async Task AssignAsync([FromBody] AdministratorAssignDto data) - { - await _service.AssignAsync(data, HttpContext.RequestAborted); - return Ok(); - } - - /// - /// 删除管理员 - /// - /// - /// - [HttpDelete("{userId}")] - public async Task DeleteAsync(string userId) - { - await _service.DeleteAsync(userId, HttpContext.RequestAborted); - return Ok(); - } -} \ No newline at end of file diff --git a/Source/Starfish.Webapp/Rest/Defines/IAdministratorApi.cs b/Source/Starfish.Webapp/Rest/Defines/IAdministratorApi.cs deleted file mode 100644 index 5efa708..0000000 --- a/Source/Starfish.Webapp/Rest/Defines/IAdministratorApi.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Nerosoft.Starfish.Transit; -using Refit; - -namespace Nerosoft.Starfish.Webapp.Rest; - -internal interface IAdministratorApi -{ - [Get("/api/administrator")] - Task>> QueryAsync([Query] AdministratorCriteria criteria, int skip = Constants.Query.Skip, int count = Constants.Query.Count, CancellationToken cancellationToken = default); - - [Post("/api/administrator")] - Task AssignAsync([Body] AdministratorAssignDto data, CancellationToken cancellationToken = default); - - [Get("/api/administrator/count")] - Task> CountAsync([Query] AdministratorCriteria criteria, CancellationToken cancellationToken = default); - - [Delete("/api/administrator/{userId}")] - Task DeleteAsync(string userId, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/Source/Starfish.Webapp/Rest/ServiceCollectionExtensions.cs b/Source/Starfish.Webapp/Rest/ServiceCollectionExtensions.cs index a519c44..e4dfbd9 100644 --- a/Source/Starfish.Webapp/Rest/ServiceCollectionExtensions.cs +++ b/Source/Starfish.Webapp/Rest/ServiceCollectionExtensions.cs @@ -39,7 +39,6 @@ public static IServiceCollection AddHttpClientApi(this IServiceCollection servic .AddTransient(provider => provider.GetRestService(HTTP_CLIENT_NAME)) .AddTransient(provider => provider.GetRestService(HTTP_CLIENT_NAME)) .AddTransient(provider => provider.GetRestService(HTTP_CLIENT_NAME)) - .AddTransient(provider => provider.GetRestService(HTTP_CLIENT_NAME)) .AddTransient(provider => provider.GetRestService(HTTP_CLIENT_NAME)) .AddTransient(provider => provider.GetRestService(HTTP_CLIENT_NAME)); From ba8e2c7b1f6c5c9796f65fef7b544f6c95186600 Mon Sep 17 00:00:00 2001 From: damon Date: Mon, 4 Mar 2024 22:52:34 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=95=B0=E6=8D=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Contracts/IUserApplicationService.cs | 7 ++++ .../Implements/UserApplicationService.cs | 7 ++++ .../Identity/UserInitializeUseCase.cs | 33 +++++++++++++++++++ .../Controllers/UserController.cs | 12 +++++++ 4 files changed, 59 insertions(+) create mode 100644 Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs diff --git a/Source/Starfish.Service/Application/Contracts/IUserApplicationService.cs b/Source/Starfish.Service/Application/Contracts/IUserApplicationService.cs index aeb787e..d366678 100644 --- a/Source/Starfish.Service/Application/Contracts/IUserApplicationService.cs +++ b/Source/Starfish.Service/Application/Contracts/IUserApplicationService.cs @@ -76,4 +76,11 @@ public interface IUserApplicationService : IApplicationService /// /// Task ResetPasswordAsync(string id, string password, CancellationToken cancellationToken = default); + + /// + /// 初始化用户 + /// + /// + /// + Task InitializeAsync(CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/Source/Starfish.Service/Application/Implements/UserApplicationService.cs b/Source/Starfish.Service/Application/Implements/UserApplicationService.cs index 6ccf283..0f2afc7 100644 --- a/Source/Starfish.Service/Application/Implements/UserApplicationService.cs +++ b/Source/Starfish.Service/Application/Implements/UserApplicationService.cs @@ -72,4 +72,11 @@ public Task ResetPasswordAsync(string id, string password, CancellationToken can var input = new ResetPasswordInput(id, password); return useCase.ExecuteAsync(input, cancellationToken); } + + public Task InitializeAsync(CancellationToken cancellationToken = default) + { + var useCase = LazyServiceProvider.GetService(); + return useCase.ExecuteAsync(cancellationToken); + } + } \ No newline at end of file diff --git a/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs b/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs new file mode 100644 index 0000000..d8543f8 --- /dev/null +++ b/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs @@ -0,0 +1,33 @@ +using Nerosoft.Euonia.Application; +using Nerosoft.Euonia.Bus; +using Nerosoft.Euonia.Mapping; +using Nerosoft.Starfish.Application; +using Nerosoft.Starfish.Transit; + +namespace Nerosoft.Starfish.UseCases; + +internal interface IUserInitializeUseCase : IParameterlessUseCase; + +internal class UserInitializeUseCase : IUserInitializeUseCase +{ + private readonly IBus _bus; + + public UserInitializeUseCase(IBus bus) + { + _bus = bus; + } + + public async Task ExecuteAsync(CancellationToken cancellationToken = default) + { + var userCreateDto = new UserCreateDto + { + UserName = "starfish", + Password = "starfish.888", + NickName = "admin", + IsAdmin = true + }; + var command = TypeAdapter.ProjectedAs(userCreateDto); + command.Reserved = true; + await _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..bb92aa6 100644 --- a/Source/Starfish.Webapi/Controllers/UserController.cs +++ b/Source/Starfish.Webapi/Controllers/UserController.cs @@ -128,4 +128,16 @@ public async Task ChangePasswordAsync([FromBody] ChangePasswordRe await _service.ChangePasswordAsync(data.OldPassword, data.NewPassword, HttpContext.RequestAborted); return Ok(); } + + /// + /// 初始化用户数据 + /// + /// + [HttpPost("init")] + [AllowAnonymous] + public async Task InitializeAsync() + { + await _service.InitializeAsync(HttpContext.RequestAborted); + return Ok(); + } } \ No newline at end of file From 31bf85d771d4ef9c2eece6359e12dcf2edfa6258 Mon Sep 17 00:00:00 2001 From: damon Date: Tue, 5 Mar 2024 15:13:31 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E5=88=A0=E9=99=A4AdministratorAssignDto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Identity/AdministratorAssignDto.cs | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 Source/Starfish.Transit/Identity/AdministratorAssignDto.cs diff --git a/Source/Starfish.Transit/Identity/AdministratorAssignDto.cs b/Source/Starfish.Transit/Identity/AdministratorAssignDto.cs deleted file mode 100644 index c8ef616..0000000 --- a/Source/Starfish.Transit/Identity/AdministratorAssignDto.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Nerosoft.Starfish.Transit; - -/// -/// 管理员编辑数据传输对象 -/// -public class AdministratorAssignDto -{ - /// - /// 用户Id - /// - public string UserId { get; set; } - - /// - /// 角色 - /// - public List Roles { get; set; } -} From a9e5b68a545e5fabfdc30876bc186a7f0447dd4a Mon Sep 17 00:00:00 2001 From: damon Date: Tue, 5 Mar 2024 15:14:23 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=90=8D=E6=A0=A1=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Domain/Business/UserGeneralBusiness.cs | 32 +++++++++++++++---- .../Seedwork/ServiceProviderExtensions.cs | 9 ++++++ Source/Starfish.Webapi/appsettings.json | 7 ++++ 3 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 Source/Starfish.Service/Seedwork/ServiceProviderExtensions.cs diff --git a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs index 7f128f1..2c7dd20 100644 --- a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs +++ b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using Nerosoft.Euonia.Business; using Nerosoft.Euonia.Domain; using Nerosoft.Starfish.Service; @@ -81,7 +82,7 @@ public bool Reserved protected override void AddRules() { - Rules.AddRule(new DuplicateUserNameCheckRule()); + Rules.AddRule(_provider.GetServiceOrCreateInstance()); Rules.AddRule(new DuplicateEmailCheckRule()); Rules.AddRule(new DuplicatePhoneCheckRule()); Rules.AddRule(new PasswordStrengthRule()); @@ -129,11 +130,11 @@ protected override Task InsertAsync(CancellationToken cancellationToken = defaul user.Reserved = Reserved; return Repository.InsertAsync(user, true, cancellationToken) - .ContinueWith(task => - { - task.WaitAndUnwrapException(cancellationToken); - Id = task.Result.Id; - }, cancellationToken); + .ContinueWith(task => + { + task.WaitAndUnwrapException(cancellationToken); + Id = task.Result.Id; + }, cancellationToken); } [FactoryUpdate] @@ -178,8 +179,15 @@ protected override Task DeleteAsync(CancellationToken cancellationToken = defaul return _repository.DeleteAsync(Aggregate, true, cancellationToken); } - public class DuplicateUserNameCheckRule : RuleBase + public class UserNameAvailabilityCheckRule : RuleBase { + private readonly IConfiguration _configuration; + + public UserNameAvailabilityCheckRule(IConfiguration configuration) + { + _configuration = configuration; + } + public override async Task ExecuteAsync(IRuleContext context, CancellationToken cancellationToken = default) { var target = (UserGeneralBusiness)context.Target; @@ -188,6 +196,16 @@ public override async Task ExecuteAsync(IRuleContext context, CancellationToken return; } + if (!target.Reserved) + { + var reserved = _configuration.GetValue>("ReservedUsernames"); + if (reserved.Contains(target.UserName, StringComparison.OrdinalIgnoreCase)) + { + context.AddErrorResult(string.Format(Resources.IDS_ERROR_USER_USERNAME_UNAVAILABLE, target.UserName)); + return; + } + } + var repository = target.Repository; var exists = await repository.CheckUserNameExistsAsync(target.UserName, cancellationToken); if (exists) diff --git a/Source/Starfish.Service/Seedwork/ServiceProviderExtensions.cs b/Source/Starfish.Service/Seedwork/ServiceProviderExtensions.cs new file mode 100644 index 0000000..d95b199 --- /dev/null +++ b/Source/Starfish.Service/Seedwork/ServiceProviderExtensions.cs @@ -0,0 +1,9 @@ +namespace Nerosoft.Starfish.Service; + +internal static class ServiceProviderExtensions +{ + public static T GetServiceOrCreateInstance(this IServiceProvider provider) + { + return ActivatorUtilities.GetServiceOrCreateInstance(provider); + } +} diff --git a/Source/Starfish.Webapi/appsettings.json b/Source/Starfish.Webapi/appsettings.json index 71e5de8..1a11702 100644 --- a/Source/Starfish.Webapi/appsettings.json +++ b/Source/Starfish.Webapi/appsettings.json @@ -27,6 +27,13 @@ "TopicName": "nerosoft.starfish.topic" } }, + "InitializeUsername": "starfish", + "ReservedUsernames": [ + "starfish", + "admin", + "administrator", + "root" + ], "FeatureManagement": { "UserRegistration": true }, From d8ea3a2b847a19b9e77f68f0e2d9441254e02514 Mon Sep 17 00:00:00 2001 From: damon Date: Tue, 5 Mar 2024 23:08:02 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E7=94=A8=E6=88=B7=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Application/ApplicationServiceModule.cs | 2 + .../Handlers/UserCommandHandler.cs | 4 ++ .../Services/UserInitializeService.cs | 28 ++++++++++++++ .../Domain/Business/UserGeneralBusiness.cs | 5 +++ .../Identity/UserInitializeUseCase.cs | 37 +++++++++++++------ .../Controllers/UserController.cs | 12 ------ Source/Starfish.Webapi/appsettings.json | 5 ++- 7 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 Source/Starfish.Service/Application/Services/UserInitializeService.cs diff --git a/Source/Starfish.Service/Application/ApplicationServiceModule.cs b/Source/Starfish.Service/Application/ApplicationServiceModule.cs index 26e53bc..842d90a 100644 --- a/Source/Starfish.Service/Application/ApplicationServiceModule.cs +++ b/Source/Starfish.Service/Application/ApplicationServiceModule.cs @@ -49,6 +49,8 @@ public override void ConfigureServices(ServiceConfigurationContext context) ConfigureCachingServices(context.Services); ConfigureBusServices(context.Services); + + context.Services.AddHostedService(); } private void ConfigureCachingServices(IServiceCollection services) diff --git a/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs b/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs index 5b57a24..9a35d2d 100644 --- a/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs +++ b/Source/Starfish.Service/Application/Handlers/UserCommandHandler.cs @@ -54,7 +54,11 @@ public Task HandleAsync(UserUpdateCommand message, MessageContext context, Cance business.Email = message.Item2.Email; business.NickName = message.Item2.NickName; + business.Phone = message.Item2.Phone; + business.IsAdmin = message.Item2.IsAdmin; + business.MarkAsUpdate(); + await business.SaveAsync(true, cancellationToken); }); } diff --git a/Source/Starfish.Service/Application/Services/UserInitializeService.cs b/Source/Starfish.Service/Application/Services/UserInitializeService.cs new file mode 100644 index 0000000..4fff946 --- /dev/null +++ b/Source/Starfish.Service/Application/Services/UserInitializeService.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Nerosoft.Starfish.Application; + +internal class UserInitializeService : BackgroundService +{ + private readonly IUserApplicationService _service; + private readonly ILogger _logger; + + public UserInitializeService(IUserApplicationService service, ILoggerFactory logger) + { + _service = service; + _logger = logger.CreateLogger(); + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + await _service.InitializeAsync(stoppingToken); + } + catch (Exception exception) + { + _logger.LogError(exception, exception.Message); + } + } +} diff --git a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs index 2c7dd20..44ed584 100644 --- a/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs +++ b/Source/Starfish.Service/Domain/Business/UserGeneralBusiness.cs @@ -140,6 +140,11 @@ protected override Task InsertAsync(CancellationToken cancellationToken = defaul [FactoryUpdate] protected override Task UpdateAsync(CancellationToken cancellationToken = default) { + if (!HasChangedProperties) + { + return Task.CompletedTask; + } + if (ChangedProperties.Contains(EmailProperty)) { Aggregate.SetEmail(Email); diff --git a/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs b/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs index d8543f8..bf41a8f 100644 --- a/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs +++ b/Source/Starfish.Service/UseCases/Identity/UserInitializeUseCase.cs @@ -1,8 +1,8 @@ +using Microsoft.Extensions.Configuration; using Nerosoft.Euonia.Application; using Nerosoft.Euonia.Bus; -using Nerosoft.Euonia.Mapping; using Nerosoft.Starfish.Application; -using Nerosoft.Starfish.Transit; +using Nerosoft.Starfish.Domain; namespace Nerosoft.Starfish.UseCases; @@ -11,23 +11,38 @@ internal interface IUserInitializeUseCase : IParameterlessUseCase; internal class UserInitializeUseCase : IUserInitializeUseCase { private readonly IBus _bus; + private readonly IUserRepository _repository; + private readonly IConfiguration _configuration; - public UserInitializeUseCase(IBus bus) + public UserInitializeUseCase(IBus bus, IUserRepository repository, IConfiguration configuration) { _bus = bus; + _repository = repository; + _configuration = configuration; } public async Task ExecuteAsync(CancellationToken cancellationToken = default) { - var userCreateDto = new UserCreateDto + var username = _configuration["InitializeUser:UserName"]; + + if (string.IsNullOrWhiteSpace(username)) + { + return; + } + + var exists = await _repository.CheckUserNameExistsAsync(username, cancellationToken); + if (exists) + { + return; + } + + var command = new UserCreateCommand { - UserName = "starfish", - Password = "starfish.888", - NickName = "admin", - IsAdmin = true + UserName = _configuration["InitializeUser:UserName"], + Password = _configuration["InitializeUser:Password"], + IsAdmin = true, + Reserved = true }; - var command = TypeAdapter.ProjectedAs(userCreateDto); - command.Reserved = true; - await _bus.SendAsync(command, cancellationToken); + await _bus.SendAsync(command, cancellationToken).ContinueWith(task => task.WaitAndUnwrapException()); } } \ No newline at end of file diff --git a/Source/Starfish.Webapi/Controllers/UserController.cs b/Source/Starfish.Webapi/Controllers/UserController.cs index bb92aa6..b43c90e 100644 --- a/Source/Starfish.Webapi/Controllers/UserController.cs +++ b/Source/Starfish.Webapi/Controllers/UserController.cs @@ -128,16 +128,4 @@ public async Task ChangePasswordAsync([FromBody] ChangePasswordRe await _service.ChangePasswordAsync(data.OldPassword, data.NewPassword, HttpContext.RequestAborted); return Ok(); } - - /// - /// 初始化用户数据 - /// - /// - [HttpPost("init")] - [AllowAnonymous] - public async Task InitializeAsync() - { - await _service.InitializeAsync(HttpContext.RequestAborted); - return Ok(); - } } \ No newline at end of file diff --git a/Source/Starfish.Webapi/appsettings.json b/Source/Starfish.Webapi/appsettings.json index 1a11702..85142d8 100644 --- a/Source/Starfish.Webapi/appsettings.json +++ b/Source/Starfish.Webapi/appsettings.json @@ -27,7 +27,10 @@ "TopicName": "nerosoft.starfish.topic" } }, - "InitializeUsername": "starfish", + "InitializeUser": { + "UserName": "admin", + "Password": "Starfish.8888" + }, "ReservedUsernames": [ "starfish", "admin", From c9537062e80da6acd61eae4940571fe867e5bf5a Mon Sep 17 00:00:00 2001 From: damon Date: Tue, 5 Mar 2024 23:09:29 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Identity/UserDetailDto.cs | 5 ++ .../Starfish.Transit/Identity/UserItemDto.cs | 5 ++ .../Identity/UserUpdateDto.cs | 10 ++++ .../Misc/ConnectionInfoDto.cs | 32 ++++++++++++ .../Team/TeamMemberAppendDto.cs | 17 +++++++ Source/Starfish.Webapp/Pages/User/Edit.razor | 49 +++++++++++++------ Source/Starfish.Webapp/Pages/User/Index.razor | 23 ++++----- .../Starfish.Webapp/Properties/Resources.resx | 9 ++++ .../Properties/Resources.zh-Hans.resx | 9 ++++ .../Properties/Resources.zh-Hant.resx | 15 +++--- 10 files changed, 141 insertions(+), 33 deletions(-) create mode 100644 Source/Starfish.Transit/Misc/ConnectionInfoDto.cs create mode 100644 Source/Starfish.Transit/Team/TeamMemberAppendDto.cs diff --git a/Source/Starfish.Transit/Identity/UserDetailDto.cs b/Source/Starfish.Transit/Identity/UserDetailDto.cs index 6cf9728..556e676 100644 --- a/Source/Starfish.Transit/Identity/UserDetailDto.cs +++ b/Source/Starfish.Transit/Identity/UserDetailDto.cs @@ -30,6 +30,11 @@ public class UserDetailDto /// public string NickName { get; set; } + /// + /// 是否管理员 + /// + public bool IsAdmin { get; set; } + /// /// 创建时间 /// diff --git a/Source/Starfish.Transit/Identity/UserItemDto.cs b/Source/Starfish.Transit/Identity/UserItemDto.cs index 90019a3..031947c 100644 --- a/Source/Starfish.Transit/Identity/UserItemDto.cs +++ b/Source/Starfish.Transit/Identity/UserItemDto.cs @@ -29,4 +29,9 @@ public class UserItemDto /// 昵称 /// public string NickName { get; set; } + + /// + /// 是否管理员 + /// + public bool IsAdmin { get; set; } } \ No newline at end of file diff --git a/Source/Starfish.Transit/Identity/UserUpdateDto.cs b/Source/Starfish.Transit/Identity/UserUpdateDto.cs index c6e2c9e..34fa3ac 100644 --- a/Source/Starfish.Transit/Identity/UserUpdateDto.cs +++ b/Source/Starfish.Transit/Identity/UserUpdateDto.cs @@ -10,8 +10,18 @@ public class UserUpdateDto /// public string Email { get; set; } + /// + /// 电话号码 + /// + public string Phone { get; set; } + /// /// 昵称 /// public string NickName { get; set; } + + /// + /// 是否是管理员 + /// + public bool IsAdmin { get; set; } } diff --git a/Source/Starfish.Transit/Misc/ConnectionInfoDto.cs b/Source/Starfish.Transit/Misc/ConnectionInfoDto.cs new file mode 100644 index 0000000..799eb27 --- /dev/null +++ b/Source/Starfish.Transit/Misc/ConnectionInfoDto.cs @@ -0,0 +1,32 @@ +namespace Nerosoft.Starfish.Transit; + +/// +/// 连接信息传输对象 +/// +public class ConnectionInfoDto +{ + /// + /// 配置Id + /// + public string ConfigurationId { get; set; } + + /// + /// 配置名称 + /// + public string ConfigurationName { get; set; } + + /// + /// 连接Id + /// + public string ConnectionId { get; set; } + + /// + /// 连接类型 + /// + public string ConnectionType { get; set; } + + /// + /// 连接时间 + /// + public DateTime ConnectedTime { get; set; } +} \ No newline at end of file diff --git a/Source/Starfish.Transit/Team/TeamMemberAppendDto.cs b/Source/Starfish.Transit/Team/TeamMemberAppendDto.cs new file mode 100644 index 0000000..76301b8 --- /dev/null +++ b/Source/Starfish.Transit/Team/TeamMemberAppendDto.cs @@ -0,0 +1,17 @@ +namespace Nerosoft.Starfish.Transit; + +/// +/// 添加团队成员请求Dto +/// +public class TeamMemberAppendDto +{ + /// + /// 用户Id + /// + public string UserId { get; set; } + + /// + /// 角色 + /// + public string Role { get; set; } +} \ No newline at end of file diff --git a/Source/Starfish.Webapp/Pages/User/Edit.razor b/Source/Starfish.Webapp/Pages/User/Edit.razor index d85d55d..d659621 100644 --- a/Source/Starfish.Webapp/Pages/User/Edit.razor +++ b/Source/Starfish.Webapp/Pages/User/Edit.razor @@ -4,7 +4,7 @@ - + @Dialog.Instance.Parameters.Title @@ -16,25 +16,32 @@ + ReadOnly="@(!string.IsNullOrEmpty(Content))" /> @if (string.IsNullOrEmpty(Content)) { + TextFieldType="TextFieldType.Password" /> + TextFieldType="TextFieldType.Password" /> } + @bind-Value="NickName" /> + TextFieldType="TextFieldType.Email" /> + + + + @@ -63,6 +70,10 @@ private string Email { get; set; } + private string Phone { get; set; } + + private bool IsAdmin { get; set; } + protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -77,10 +88,12 @@ if (!string.IsNullOrEmpty(Content)) { var request = new UserUpdateDto - { - NickName = NickName, - Email = Email - }; + { + NickName = NickName, + Email = Email, + Phone = Phone, + IsAdmin = IsAdmin + }; await Api.UpdateAsync(Content, request) .EnsureSuccess(); @@ -93,12 +106,14 @@ } var request = new UserCreateDto - { - UserName = UserName, - Password = Password, - NickName = NickName, - Email = Email - }; + { + UserName = UserName, + Password = Password, + NickName = NickName, + Email = Email, + Phone = Phone, + IsAdmin = IsAdmin + }; await Api.CreateAsync(request) .EnsureSuccess(); @@ -140,6 +155,8 @@ UserName = result.UserName; NickName = result.NickName; Email = result.Email; + Phone = result.Phone; + IsAdmin = result.IsAdmin; }); } diff --git a/Source/Starfish.Webapp/Pages/User/Index.razor b/Source/Starfish.Webapp/Pages/User/Index.razor index 882e060..86ba9d9 100644 --- a/Source/Starfish.Webapp/Pages/User/Index.razor +++ b/Source/Starfish.Webapp/Pages/User/Index.razor @@ -15,31 +15,32 @@ + GridTemplateColumns="0.5fr 0.5fr 1fr 1fr 0.4fr 0.2fr"> @(context.UserName) - - - + + + + - - + + - + @@ -59,10 +60,10 @@ { List items = null; var tasks = new List - { + { Api.SearchAsync(Criteria, request.StartIndex, Pagination.ItemsPerPage, request.CancellationToken) .EnsureSuccess(result => items = result, request.CancellationToken) - }; + }; if (request.StartIndex == 0) { diff --git a/Source/Starfish.Webapp/Properties/Resources.resx b/Source/Starfish.Webapp/Properties/Resources.resx index 249e0c5..9e01898 100644 --- a/Source/Starfish.Webapp/Properties/Resources.resx +++ b/Source/Starfish.Webapp/Properties/Resources.resx @@ -570,6 +570,9 @@ Email + + Administrator + Nick name @@ -588,12 +591,18 @@ Email + + Administrator + Nick name Password + + Phone number + User name diff --git a/Source/Starfish.Webapp/Properties/Resources.zh-Hans.resx b/Source/Starfish.Webapp/Properties/Resources.zh-Hans.resx index 67f30c1..299150b 100644 --- a/Source/Starfish.Webapp/Properties/Resources.zh-Hans.resx +++ b/Source/Starfish.Webapp/Properties/Resources.zh-Hans.resx @@ -570,6 +570,9 @@ 邮箱 + + 管理员 + 昵称 @@ -588,12 +591,18 @@ 邮箱 + + 管理员 + 昵称 密码 + + 手机号 + 用户名 diff --git a/Source/Starfish.Webapp/Properties/Resources.zh-Hant.resx b/Source/Starfish.Webapp/Properties/Resources.zh-Hant.resx index 34cd414..734f742 100644 --- a/Source/Starfish.Webapp/Properties/Resources.zh-Hant.resx +++ b/Source/Starfish.Webapp/Properties/Resources.zh-Hant.resx @@ -345,12 +345,6 @@ 配置 - - 配置Id - - - 配置名稱 - 連接時間 @@ -576,6 +570,9 @@ 電子郵件 + + 管理員 + 昵稱 @@ -594,12 +591,18 @@ 電子郵件 + + 管理員 + 昵稱 密碼 + + 手機號 + 用戶名