Browse Source

Add two-factor setup interface

pull/131/head
cKey 5 years ago
parent
commit
53fdec93a8
  1. 76
      aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln
  2. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs
  3. 2
      aspnet-core/modules/common/LINGYUN.Abp.Settings/Volo/Abp/Settings/ISettingProviderExtensions.cs
  4. 10
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN.Abp.Identity.Application.Contracts.csproj
  5. 18
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/AbpIdentityApplicationContractsModule.cs
  6. 24
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/ChangeEmailAddressInput.cs
  7. 24
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/ChangePhoneNumberInput.cs
  8. 7
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/IdentityUserTwoFactorEnabledDto.cs
  9. 15
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IIdentityUserAppService.cs
  10. 15
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IMyProfileAppService.cs
  11. 8
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityErrorCodes.cs
  12. 2
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN.Abp.Identity.Application.csproj
  13. 3
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModule.cs
  14. 30
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/IdentityUserAppService.cs
  15. 32
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/MyProfileAppService.cs
  16. 24
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN.Abp.Identity.Domain.Shared.csproj
  17. 26
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/AbpIdentityDomainSharedModule.cs
  18. 18
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/IdentityErrorCodes.cs
  19. 38
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/IdentityException.cs
  20. 3
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/en.json
  21. 3
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/zh-Hans.json
  22. 18
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Settings/IdentitySettingDefinitionProvider.cs
  23. 6
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Settings/IdentitySettingNames.cs
  24. 6
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN.Abp.Identity.Domain.csproj
  25. 4
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs
  26. 39
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/IdentityUserManagerExtensions.cs
  27. 14
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/IdentityUserController.cs
  28. 30
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/MyProfileController.cs

76
aspnet-core/LINGYUN.MicroService.IdentityServerAdmin.sln

@ -55,6 +55,30 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{7EE965
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.Authorization", "modules\wechat\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj", "{F61FA8AA-4248-4F2B-87E0-73CD2C027783}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{FD2DDD48-8F84-4924-BBAF-52080AB32267}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Settings", "modules\common\LINGYUN.Abp.Settings\LINGYUN.Abp.Settings.csproj", "{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.Domain.Shared", "modules\identity\LINGYUN.Abp.Identity.Domain.Shared\LINGYUN.Abp.Identity.Domain.Shared.csproj", "{23536755-4F00-4929-9C5E-D4CABD1CC513}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.ExceptionHandling", "modules\common\LINGYUN.Abp.ExceptionHandling\LINGYUN.Abp.ExceptionHandling.csproj", "{80A418EB-6149-4684-80EF-D8574B91FE2B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.ExceptionHandling.Emailing", "modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj", "{986B0610-4AC3-499A-AB81-DF15EA06F4D1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{53E90646-2933-4381-9386-6BC6ED16E71A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Aliyun.Authorization", "modules\common\LINGYUN.Abp.Aliyun.Authorization\LINGYUN.Abp.Aliyun.Authorization.csproj", "{720120B4-76F6-4701-9426-611BB8F84515}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Sms.Aliyun", "modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj", "{D89ECB96-3349-4E77-B884-C18B30289D0D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EventBus.CAP", "modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj", "{39B77454-52AB-43BE-AB33-7680719415A6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenants", "tenants", "{89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy", "modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj", "{99B60A42-29DA-4D91-9255-B90F53BC6D6E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.DbFinder", "modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj", "{70C4FA43-0526-48E3-B852-A21395502604}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -141,6 +165,46 @@ Global
{F61FA8AA-4248-4F2B-87E0-73CD2C027783}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61FA8AA-4248-4F2B-87E0-73CD2C027783}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61FA8AA-4248-4F2B-87E0-73CD2C027783}.Release|Any CPU.Build.0 = Release|Any CPU
{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC}.Release|Any CPU.Build.0 = Release|Any CPU
{23536755-4F00-4929-9C5E-D4CABD1CC513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23536755-4F00-4929-9C5E-D4CABD1CC513}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23536755-4F00-4929-9C5E-D4CABD1CC513}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23536755-4F00-4929-9C5E-D4CABD1CC513}.Release|Any CPU.Build.0 = Release|Any CPU
{80A418EB-6149-4684-80EF-D8574B91FE2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80A418EB-6149-4684-80EF-D8574B91FE2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80A418EB-6149-4684-80EF-D8574B91FE2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80A418EB-6149-4684-80EF-D8574B91FE2B}.Release|Any CPU.Build.0 = Release|Any CPU
{986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{986B0610-4AC3-499A-AB81-DF15EA06F4D1}.Release|Any CPU.Build.0 = Release|Any CPU
{53E90646-2933-4381-9386-6BC6ED16E71A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53E90646-2933-4381-9386-6BC6ED16E71A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53E90646-2933-4381-9386-6BC6ED16E71A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{53E90646-2933-4381-9386-6BC6ED16E71A}.Release|Any CPU.Build.0 = Release|Any CPU
{720120B4-76F6-4701-9426-611BB8F84515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{720120B4-76F6-4701-9426-611BB8F84515}.Debug|Any CPU.Build.0 = Debug|Any CPU
{720120B4-76F6-4701-9426-611BB8F84515}.Release|Any CPU.ActiveCfg = Release|Any CPU
{720120B4-76F6-4701-9426-611BB8F84515}.Release|Any CPU.Build.0 = Release|Any CPU
{D89ECB96-3349-4E77-B884-C18B30289D0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D89ECB96-3349-4E77-B884-C18B30289D0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D89ECB96-3349-4E77-B884-C18B30289D0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D89ECB96-3349-4E77-B884-C18B30289D0D}.Release|Any CPU.Build.0 = Release|Any CPU
{39B77454-52AB-43BE-AB33-7680719415A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39B77454-52AB-43BE-AB33-7680719415A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39B77454-52AB-43BE-AB33-7680719415A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39B77454-52AB-43BE-AB33-7680719415A6}.Release|Any CPU.Build.0 = Release|Any CPU
{99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99B60A42-29DA-4D91-9255-B90F53BC6D6E}.Release|Any CPU.Build.0 = Release|Any CPU
{70C4FA43-0526-48E3-B852-A21395502604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70C4FA43-0526-48E3-B852-A21395502604}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70C4FA43-0526-48E3-B852-A21395502604}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70C4FA43-0526-48E3-B852-A21395502604}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -170,6 +234,18 @@ Global
{177B6CD3-1690-416D-9B37-A821093DEFBD} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
{7EE9651C-17B0-4343-A2ED-92439F8C9019} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
{F61FA8AA-4248-4F2B-87E0-73CD2C027783} = {7EE9651C-17B0-4343-A2ED-92439F8C9019}
{FD2DDD48-8F84-4924-BBAF-52080AB32267} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
{A8C83B9C-C9BF-48EF-80FF-D4FE2C936EFC} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
{23536755-4F00-4929-9C5E-D4CABD1CC513} = {BD964040-90B2-4179-A5EB-5830F5C7E073}
{80A418EB-6149-4684-80EF-D8574B91FE2B} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
{986B0610-4AC3-499A-AB81-DF15EA06F4D1} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
{53E90646-2933-4381-9386-6BC6ED16E71A} = {7EE9651C-17B0-4343-A2ED-92439F8C9019}
{720120B4-76F6-4701-9426-611BB8F84515} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
{D89ECB96-3349-4E77-B884-C18B30289D0D} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
{39B77454-52AB-43BE-AB33-7680719415A6} = {FD2DDD48-8F84-4924-BBAF-52080AB32267}
{89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE} = {14B8F528-C649-4FAD-9BBB-6C979ED403E1}
{99B60A42-29DA-4D91-9255-B90F53BC6D6E} = {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}
{70C4FA43-0526-48E3-B852-A21395502604} = {89BA9708-62E5-4FD6-A28A-CF9E1C26DCAE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {785FFF4D-BC59-499E-88A3-7CB7A7667228}

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs

@ -48,14 +48,14 @@ namespace LINGYUN.Abp.Account
var wehchatOpenId = await WeChatOpenIdFinder.FindAsync(input.Code);
var user = await UserManager.FindByLoginAsync("WeChat", wehchatOpenId.OpenId);
var user = await UserManager.FindByLoginAsync(AbpWeChatAuthorizationConsts.ProviderKey, wehchatOpenId.OpenId);
if (user != null)
{
// 应该要抛出微信号已注册异常,而不是直接返回注册用户数据,否则造成用户信息泄露
throw new UserFriendlyException(L["DuplicateWeChat"]);
}
var userName = input.UserName ?? wehchatOpenId.OpenId;
var userEmail = input.EmailAddress ?? $"{userName}@default.io";//如果邮件地址不验证,随意写入一个
var userName = input.UserName ?? "wx-" + wehchatOpenId.OpenId;
var userEmail = input.EmailAddress ?? $"{userName}@{CurrentTenant.Name ?? "default"}.io";//如果邮件地址不验证,随意写入一个
user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id)
{
@ -65,7 +65,7 @@ namespace LINGYUN.Abp.Account
(await UserManager.AddDefaultRolesAsync(user)).CheckErrors();
var userLogin = new UserLoginInfo("WeChat", wehchatOpenId.OpenId, "微信认证登录");
var userLogin = new UserLoginInfo(AbpWeChatAuthorizationConsts.ProviderKey, wehchatOpenId.OpenId, AbpWeChatAuthorizationConsts.DisplayName);
(await UserManager.AddLoginAsync(user, userLogin)).CheckErrors();
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user);
@ -101,7 +101,7 @@ namespace LINGYUN.Abp.Account
// }
//}
var userEmail = input.EmailAddress ?? $"{input.PhoneNumber}@default.io";//如果邮件地址不验证,随意写入一个
var userEmail = input.EmailAddress ?? $"{input.PhoneNumber}@{CurrentTenant.Name ?? "default"}.io";//如果邮件地址不验证,随意写入一个
var userName = input.UserName ?? input.PhoneNumber;
var user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id)
{
@ -173,6 +173,8 @@ namespace LINGYUN.Abp.Account
/// </remarks>
public virtual async Task VerifyPhoneNumberAsync(VerifyDto input)
{
// TODO: 借用TOTP算法生成6位动态验证码
var verifyCodeExpiration = await SettingProvider.GetAsync<int>(AccountSettingNames.PhoneVerifyCodeExpiration);
var phoneVerifyCacheKey = NormalizeCacheKey(input.PhoneNumber);
var verifyCacheItem = await Cache.GetAsync(phoneVerifyCacheKey);

2
aspnet-core/modules/common/LINGYUN.Abp.Settings/Volo/Abp/Settings/ISettingProviderExtensions.cs

@ -24,5 +24,7 @@ namespace Volo.Abp.Settings
}
return value;
}
}
}

10
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN.Abp.Identity.Application.Contracts.csproj

@ -8,17 +8,11 @@
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Identity\Localization\en.json" />
<None Remove="LINGYUN\Abp\Identity\Localization\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\Identity\Localization\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\Identity\Localization\zh-Hans.json" />
<PackageReference Include="Volo.Abp.Identity.Application.Contracts" Version="3.3.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Identity.Application.Contracts" Version="3.3.0" />
<ProjectReference Include="..\LINGYUN.Abp.Identity.Domain.Shared\LINGYUN.Abp.Identity.Domain.Shared.csproj" />
</ItemGroup>
</Project>

18
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/AbpIdentityApplicationContractsModule.cs

@ -1,32 +1,16 @@
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.Identity.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Identity
{
[DependsOn(
typeof(Volo.Abp.Identity.AbpIdentityApplicationContractsModule),
typeof(AbpIdentityDomainSharedModule),
typeof(AbpAuthorizationModule),
typeof(AbpDddApplicationModule)
)]
public class AbpIdentityApplicationContractsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityApplicationContractsModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<IdentityResource>()
.AddVirtualJson("/LINGYUN/Abp/Identity/Localization");
});
}
}
}

24
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/ChangeEmailAddressInput.cs

@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace LINGYUN.Abp.Identity
{
public class ChangeEmailAddressInput
{
/// <summary>
/// 新邮件地址
/// </summary>
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string NewEmailAddress { get; set; }
/// <summary>
/// 安全验证码
/// </summary>
[DisableAuditing]
[StringLength(6)]
public string Code { get; set; }
}
}

24
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/ChangePhoneNumberInput.cs

@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace LINGYUN.Abp.Identity
{
public class ChangePhoneNumberInput
{
/// <summary>
/// 新手机号
/// </summary>
[Required]
[Phone]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
public string NewPhoneNumber { get; set; }
/// <summary>
/// 安全验证码
/// </summary>
[DisableAuditing]
[StringLength(6)]
public string Code { get; set; }
}
}

7
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/IdentityUserTwoFactorEnabledDto.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.Identity
{
public class IdentityUserTwoFactorEnabledDto
{
public bool Enabled { get; set; }
}
}

15
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IIdentityUserAppService.cs

@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Identity;
namespace LINGYUN.Abp.Identity
{
@ -30,5 +31,19 @@ namespace LINGYUN.Abp.Identity
#endregion
/// <summary>
/// 变更用户双因素验证选项
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
Task ChangeTwoFactorEnabledAsync(Guid id, IdentityUserTwoFactorEnabledDto input);
/// <summary>
/// 变更用户密码
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
Task ChangePasswordAsync(Guid id, ChangePasswordInput input);
}
}

15
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IMyProfileAppService.cs

@ -0,0 +1,15 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.Identity
{
public interface IMyProfileAppService : IApplicationService
{
/// <summary>
/// 变更双因素验证
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task ChangeTwoFactorEnabledAsync(IdentityUserTwoFactorEnabledDto input);
}
}

8
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityErrorCodes.cs

@ -1,8 +0,0 @@
namespace LINGYUN.Abp.Identity
{
public class IdentityErrorCodes
{
public const string StaticClaimTypeChange = "Volo.Abp.Identity:020005";
public const string StaticClaimTypeDeletion = "Volo.Abp.Identity:020006";
}
}

2
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN.Abp.Identity.Application.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />

3
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModule.cs

@ -6,7 +6,8 @@ namespace LINGYUN.Abp.Identity
{
[DependsOn(
typeof(Volo.Abp.Identity.AbpIdentityApplicationModule),
typeof(AbpIdentityApplicationContractsModule))]
typeof(AbpIdentityApplicationContractsModule),
typeof(AbpIdentityDomainModule))]
public class AbpIdentityApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)

30
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/IdentityUserAppService.cs

@ -102,5 +102,35 @@ namespace LINGYUN.Abp.Identity
}
#endregion
[Authorize(Volo.Abp.Identity.IdentityPermissions.Users.Update)]
public virtual async Task ChangePasswordAsync(Guid id, ChangePasswordInput input)
{
var user = await UserManager.GetByIdAsync(id);
if (user.IsExternal)
{
throw new BusinessException(code: Volo.Abp.Identity.IdentityErrorCodes.ExternalUserPasswordChange);
}
if (user.PasswordHash == null)
{
(await UserManager.AddPasswordAsync(user, input.NewPassword)).CheckErrors();
return;
}
(await UserManager.ChangePasswordAsync(user, input.CurrentPassword, input.NewPassword)).CheckErrors();
}
[Authorize(Volo.Abp.Identity.IdentityPermissions.Users.Update)]
public virtual async Task ChangeTwoFactorEnabledAsync(Guid id, IdentityUserTwoFactorEnabledDto input)
{
var user = await UserManager.GetByIdAsync(id);
(await UserManager.SetTwoFactorEnabledWithAccountConfirmedAsync(user, input.Enabled)).CheckErrors();
await CurrentUnitOfWork.SaveChangesAsync();
}
}
}

32
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/MyProfileAppService.cs

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using System.Threading.Tasks;
using Volo.Abp.Identity;
using Volo.Abp.Users;
namespace LINGYUN.Abp.Identity
{
[Authorize]
public class MyProfileAppService : IdentityAppServiceBase, IMyProfileAppService
{
protected IdentityUserManager UserManager { get; }
protected IIdentityUserRepository UserRepository { get; }
public MyProfileAppService(
IdentityUserManager userManager,
IIdentityUserRepository userRepository)
{
UserManager = userManager;
UserRepository = userRepository;
}
public virtual async Task ChangeTwoFactorEnabledAsync(IdentityUserTwoFactorEnabledDto input)
{
var user = await UserManager.GetByIdAsync(CurrentUser.GetId());
(await UserManager.SetTwoFactorEnabledWithAccountConfirmedAsync(user, input.Enabled)).CheckErrors();
await CurrentUnitOfWork.SaveChangesAsync();
}
}
}

24
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN.Abp.Identity.Domain.Shared.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Identity\Localization\en.json" />
<None Remove="LINGYUN\Abp\Identity\Localization\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\Identity\Localization\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\Identity\Localization\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Identity.Domain.Shared" Version="3.3.0" />
</ItemGroup>
</Project>

26
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/AbpIdentityDomainSharedModule.cs

@ -0,0 +1,26 @@
using Volo.Abp.Identity.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Identity
{
[DependsOn(typeof(Volo.Abp.Identity.AbpIdentityDomainSharedModule))]
public class AbpIdentityDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<IdentityResource>()
.AddVirtualJson("/LINGYUN/Abp/Identity/Localization");
});
}
}
}

18
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/IdentityErrorCodes.cs

@ -0,0 +1,18 @@
namespace LINGYUN.Abp.Identity
{
public class IdentityErrorCodes
{
/// <summary>
/// 无法变更静态声明类型
/// </summary>
public const string StaticClaimTypeChange = "Volo.Abp.Identity:020005";
/// <summary>
/// 无法删除静态声明类型
/// </summary>
public const string StaticClaimTypeDeletion = "Volo.Abp.Identity:020006";
/// <summary>
/// 手机号码已被使用
/// </summary>
public const string DuplicatePhoneNumber = "Volo.Abp.Identity:020007";
}
}

38
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/IdentityException.cs

@ -0,0 +1,38 @@
using Microsoft.Extensions.Logging;
using System;
using System.Runtime.Serialization;
using Volo.Abp;
using Volo.Abp.Logging;
namespace LINGYUN.Abp.Identity
{
public class IdentityException : BusinessException, IExceptionWithSelfLogging
{
public IdentityException(
SerializationInfo serializationInfo,
StreamingContext context)
: base(serializationInfo, context)
{
}
public IdentityException(
string code = null,
string message = null,
string details = null,
Exception innerException = null,
LogLevel logLevel = LogLevel.Warning)
: base(code, message, details, innerException, logLevel)
{
}
public virtual void Log(ILogger logger)
{
logger.Log(
LogLevel,
"An id error occurred,code: {0}, Message: {1}, Details: {2}",
Code,
Message,
Details);
}
}
}

3
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/en.json → aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/en.json

@ -40,6 +40,7 @@
"IdentityClaim:Description": "Description",
"IdentityClaim:ValueType": "Value type",
"Volo.Abp.Identity:020005": "The static claim type cannot be changed!",
"Volo.Abp.Identity:020006": "Unable to delete static claim type!"
"Volo.Abp.Identity:020006": "Unable to delete static claim type!",
"Volo.Abp.Identity:020007": "The phone number is already tied to another user!"
}
}

3
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/zh-Hans.json → aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/zh-Hans.json

@ -41,6 +41,7 @@
"IdentityClaim:Description": "描述",
"IdentityClaim:ValueType": "值类型",
"Volo.Abp.Identity:020005": "无法变更静态声明类型!",
"Volo.Abp.Identity:020006": "无法删除静态声明类型!"
"Volo.Abp.Identity:020006": "无法删除静态声明类型!",
"Volo.Abp.Identity:020007": "手机号码已被其他用户绑定!"
}
}

18
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Settings/IdentitySettingDefinitionProvider.cs

@ -0,0 +1,18 @@
using Volo.Abp.Identity.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.Identity.Settings
{
public class IdentitySettingDefinitionProvider : SettingDefinitionProvider
{
public override void Define(ISettingDefinitionContext context)
{
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<IdentityResource>(name);
}
}
}

6
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Settings/IdentitySettingNames.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Abp.Identity.Settings
{
public static class IdentitySettingNames
{
}
}

6
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN.Abp.Identity.Domain.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -11,4 +11,8 @@
<PackageReference Include="Volo.Abp.Identity.Domain" Version="3.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Identity.Domain.Shared\LINGYUN.Abp.Identity.Domain.Shared.csproj" />
</ItemGroup>
</Project>

4
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs

@ -2,7 +2,9 @@
namespace LINGYUN.Abp.Identity
{
[DependsOn(typeof(Volo.Abp.Identity.AbpIdentityDomainModule))]
[DependsOn(
typeof(AbpIdentityDomainSharedModule),
typeof(Volo.Abp.Identity.AbpIdentityDomainModule))]
public class AbpIdentityDomainModule : AbpModule
{
}

39
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/IdentityUserManagerExtensions.cs

@ -0,0 +1,39 @@
using JetBrains.Annotations;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Identity;
namespace Microsoft.AspNetCore.Identity
{
public static class IdentityUserManagerExtensions
{
public static async Task<IdentityResult> SetTwoFactorEnabledWithAccountConfirmedAsync<TUser>(
[NotNull] this UserManager<TUser> userManager,
[NotNull] TUser user,
bool enabled)
where TUser : class
{
Check.NotNull(userManager, nameof(userManager));
Check.NotNull(user, nameof(user));
if (enabled)
{
var phoneNumberConfirmed = await userManager.IsPhoneNumberConfirmedAsync(user);
var emailAddressConfirmed = await userManager.IsEmailConfirmedAsync(user);
// 如果其中一个安全选项未确认,无法启用双因素验证
if (!phoneNumberConfirmed && !emailAddressConfirmed)
{
// TODO: 返回标准的 IdentityResult
//var error = new IdentityError();
//return IdentityResult.Failed(error);
throw new LINGYUN.Abp.Identity.IdentityException(
IdentityErrorCodes.CanNotChangeTwoFactor,
details: phoneNumberConfirmed ? "phone number not confirmed" : "email address not confirmed");
}
}
return await userManager.SetTwoFactorEnabledAsync(user, enabled);
}
}
}

14
aspnet-core/modules/identity/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/IdentityUserController.cs

@ -77,5 +77,19 @@ namespace LINGYUN.Abp.Identity
}
#endregion
[HttpPut] //TODO: Post?
[Route("change-password")]
public virtual async Task ChangePasswordAsync(Guid id, ChangePasswordInput input)
{
await UserAppService.ChangePasswordAsync(id, input);
}
[HttpPut]
[Route("change-two-factor")]
public virtual async Task ChangeTwoFactorEnabledAsync(Guid id, IdentityUserTwoFactorEnabledDto input)
{
await UserAppService.ChangeTwoFactorEnabledAsync(id, input);
}
}
}

30
aspnet-core/modules/identity/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/MyProfileController.cs

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Identity;
namespace LINGYUN.Abp.Identity
{
[RemoteService(Name = IdentityRemoteServiceConsts.RemoteServiceName)]
[Area("identity")]
[ControllerName("Profile")]
[Route("/api/identity/my-profile")]
public class MyProfileController : AbpController, IMyProfileAppService
{
protected IMyProfileAppService MyProfileAppService { get; }
public MyProfileController(
IMyProfileAppService myProfileAppService)
{
MyProfileAppService = myProfileAppService;
}
[HttpPut]
[Route("change-two-factor")]
public virtual async Task ChangeTwoFactorEnabledAsync(IdentityUserTwoFactorEnabledDto input)
{
await MyProfileAppService.ChangeTwoFactorEnabledAsync(input);
}
}
}
Loading…
Cancel
Save