Browse Source

use file-scoped namespacing for account module

pull/10696/head
Ahmet Çotur 4 years ago
parent
commit
1b86375ab0
  1. 45
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/AbpAccountApplicationContractsModule.cs
  2. 11
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/AccountRemoteServiceConsts.cs
  3. 21
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/ChangePasswordInput.cs
  4. 13
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/IAccountAppService.cs
  5. 13
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/IProfileAppService.cs
  6. 11
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/AccountResource.cs
  7. 23
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/ProfileDto.cs
  8. 35
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/RegisterDto.cs
  9. 19
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/ResetPasswordDto.cs
  10. 23
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/SendPasswordResetCodeDto.cs
  11. 11
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Settings/AccountSettingNames.cs
  12. 29
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/UpdateProfileDto.cs
  13. 43
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModule.cs
  14. 17
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModuleAutoMapperProfile.cs
  15. 125
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs
  16. 9
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountUrlNames.cs
  17. 135
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs
  18. 11
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AppUrlProviderAccountExtensions.cs
  19. 21
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/IAccountEmailer.cs
  20. 25
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs
  21. 9
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/Templates/AccountEmailTemplates.cs
  22. 117
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/ProfileAppService.cs
  23. 47
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Settings/AccountSettingDefinitionProvider.cs
  24. 21
      modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorAutoMapperProfile.cs
  25. 45
      modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorModule.cs
  26. 25
      modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs
  27. 13
      modules/account/src/Volo.Abp.Account.Blazor/AbpAccountComponentBase.cs
  28. 129
      modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor.cs
  29. 7
      modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.cs
  30. 7
      modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.cs
  31. 27
      modules/account/src/Volo.Abp.Account.HttpApi.Client/Volo/Abp/Account/AbpAccountHttpApiClientModule.cs
  32. 41
      modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AbpAccountHttpApiModule.cs
  33. 57
      modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs
  34. 55
      modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/ProfileController.cs
  35. 23
      modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AbpAccountInstallerModule.cs
  36. 15
      modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AccountInstallerPipelineBuilder.cs
  37. 69
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/AbpAccountWebIdentityServerModule.cs
  38. 75
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Areas/Account/Controllers/ErrorController.cs
  39. 285
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs
  40. 91
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLogoutModel.cs
  41. 365
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Consent.cshtml.cs
  42. 23
      modules/account/src/Volo.Abp.Account.Web/AbpAccountOptions.cs
  43. 25
      modules/account/src/Volo.Abp.Account.Web/AbpAccountUserMenuContributor.cs
  44. 11
      modules/account/src/Volo.Abp.Account.Web/AbpAccountWebAutomapperProfile.cs
  45. 127
      modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs
  46. 25
      modules/account/src/Volo.Abp.Account.Web/AccountModuleToolbarContributor.cs
  47. 273
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
  48. 19
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/AbpLoginResult.cs
  49. 19
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/LoginResultType.cs
  50. 25
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/UserLoginInfo.cs
  51. 11
      modules/account/src/Volo.Abp.Account.Web/Modules/Account/Components/Toolbar/UserLoginLink/UserLoginLinkViewComponent.cs
  52. 29
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccessDenied.cshtml.cs
  53. 65
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs
  54. 83
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/AccountProfilePasswordManagementGroupViewComponent.cs
  55. 85
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/AccountProfilePersonalInfoManagementGroupViewComponent.cs
  56. 86
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/ForgotPassword.cshtml.cs
  57. 39
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/LoggedOut.cshtml.cs
  58. 464
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
  59. 51
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs
  60. 49
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml.cs
  61. 29
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/PasswordResetLinkSent.cshtml.cs
  62. 239
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs
  63. 138
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPassword.cshtml.cs
  64. 25
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPasswordConfirmation.cshtml.cs
  65. 51
      modules/account/src/Volo.Abp.Account.Web/ProfileManagement/AccountProfileManagementPageContributor.cs
  66. 9
      modules/account/src/Volo.Abp.Account.Web/ProfileManagement/IProfileManagementPageContributor.cs
  67. 19
      modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageCreationContext.cs
  68. 54
      modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageGroup.cs
  69. 15
      modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageOptions.cs
  70. 37
      modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AbpAccountApplicationTestBase.cs
  71. 97
      modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AbpAccountApplicationTestModule.cs
  72. 69
      modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AccountAppService_Tests.cs
  73. 133
      modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/ProfileAppService_Tests.cs

45
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/AbpAccountApplicationContractsModule.cs

@ -6,32 +6,31 @@ using Volo.Abp.Modularity;
using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[DependsOn(
typeof(AbpIdentityApplicationContractsModule)
)]
public class AbpAccountApplicationContractsModule : AbpModule
{
[DependsOn(
typeof(AbpIdentityApplicationContractsModule)
)]
public class AbpAccountApplicationContractsModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountApplicationContractsModule>();
});
options.FileSets.AddEmbedded<AbpAccountApplicationContractsModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AccountResource>("en")
.AddBaseTypes(typeof(AbpValidationResource))
.AddVirtualJson("/Volo/Abp/Account/Localization/Resources");
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AccountResource>("en")
.AddBaseTypes(typeof(AbpValidationResource))
.AddVirtualJson("/Volo/Abp/Account/Localization/Resources");
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("Volo.Account", typeof(AccountResource));
});
}
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("Volo.Account", typeof(AccountResource));
});
}
}
}

11
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/AccountRemoteServiceConsts.cs

@ -1,9 +1,8 @@
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public static class AccountRemoteServiceConsts
{
public static class AccountRemoteServiceConsts
{
public const string RemoteServiceName = "AbpAccount";
public const string RemoteServiceName = "AbpAccount";
public const string ModuleName = "account";
}
public const string ModuleName = "account";
}

21
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/ChangePasswordInput.cs

@ -3,17 +3,16 @@ using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class ChangePasswordInput
{
public class ChangePasswordInput
{
[DisableAuditing]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
public string CurrentPassword { get; set; }
[DisableAuditing]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
public string CurrentPassword { get; set; }
[Required]
[DisableAuditing]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
public string NewPassword { get; set; }
}
[Required]
[DisableAuditing]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
public string NewPassword { get; set; }
}

13
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/IAccountAppService.cs

@ -2,14 +2,13 @@
using Volo.Abp.Application.Services;
using Volo.Abp.Identity;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public interface IAccountAppService : IApplicationService
{
public interface IAccountAppService : IApplicationService
{
Task<IdentityUserDto> RegisterAsync(RegisterDto input);
Task<IdentityUserDto> RegisterAsync(RegisterDto input);
Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input);
Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input);
Task ResetPasswordAsync(ResetPasswordDto input);
}
Task ResetPasswordAsync(ResetPasswordDto input);
}

13
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/IProfileAppService.cs

@ -2,14 +2,13 @@
using Volo.Abp.Application.Services;
using Volo.Abp.Identity;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public interface IProfileAppService : IApplicationService
{
public interface IProfileAppService : IApplicationService
{
Task<ProfileDto> GetAsync();
Task<ProfileDto> GetAsync();
Task<ProfileDto> UpdateAsync(UpdateProfileDto input);
Task<ProfileDto> UpdateAsync(UpdateProfileDto input);
Task ChangePasswordAsync(ChangePasswordInput input);
}
Task ChangePasswordAsync(ChangePasswordInput input);
}

11
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/AccountResource.cs

@ -1,10 +1,9 @@
using Volo.Abp.Localization;
namespace Volo.Abp.Account.Localization
namespace Volo.Abp.Account.Localization;
[LocalizationResourceName("AbpAccount")]
public class AccountResource
{
[LocalizationResourceName("AbpAccount")]
public class AccountResource
{
}
}
}

23
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/ProfileDto.cs

@ -1,24 +1,23 @@
using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class ProfileDto : ExtensibleObject, IHasConcurrencyStamp
{
public class ProfileDto : ExtensibleObject, IHasConcurrencyStamp
{
public string UserName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Surname { get; set; }
public string PhoneNumber { get; set; }
public string PhoneNumber { get; set; }
public bool IsExternal { get; set; }
public bool IsExternal { get; set; }
public bool HasPassword { get; set; }
public bool HasPassword { get; set; }
public string ConcurrencyStamp { get; set; }
}
public string ConcurrencyStamp { get; set; }
}

35
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/RegisterDto.cs

@ -4,26 +4,25 @@ using Volo.Abp.Identity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class RegisterDto : ExtensibleObject
{
public class RegisterDto : ExtensibleObject
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
public string UserName { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
public string UserName { get; set; }
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string EmailAddress { get; set; }
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string EmailAddress { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
[Required]
public string AppName { get; set; }
}
[Required]
public string AppName { get; set; }
}

19
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/ResetPasswordDto.cs

@ -2,17 +2,16 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class ResetPasswordDto
{
public class ResetPasswordDto
{
public Guid UserId { get; set; }
public Guid UserId { get; set; }
[Required]
public string ResetToken { get; set; }
[Required]
public string ResetToken { get; set; }
[Required]
[DisableAuditing]
public string Password { get; set; }
}
[Required]
[DisableAuditing]
public string Password { get; set; }
}

23
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/SendPasswordResetCodeDto.cs

@ -2,20 +2,19 @@
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class SendPasswordResetCodeDto
{
public class SendPasswordResetCodeDto
{
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string Email { get; set; }
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string Email { get; set; }
[Required]
public string AppName { get; set; }
[Required]
public string AppName { get; set; }
public string ReturnUrl { get; set; }
public string ReturnUrl { get; set; }
public string ReturnUrlHash { get; set; }
}
public string ReturnUrlHash { get; set; }
}

11
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Settings/AccountSettingNames.cs

@ -1,9 +1,8 @@
namespace Volo.Abp.Account.Settings
namespace Volo.Abp.Account.Settings;
public class AccountSettingNames
{
public class AccountSettingNames
{
public const string IsSelfRegistrationEnabled = "Abp.Account.IsSelfRegistrationEnabled";
public const string IsSelfRegistrationEnabled = "Abp.Account.IsSelfRegistrationEnabled";
public const string EnableLocalLogin = "Abp.Account.EnableLocalLogin";
}
public const string EnableLocalLogin = "Abp.Account.EnableLocalLogin";
}

29
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/UpdateProfileDto.cs

@ -2,25 +2,24 @@
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class UpdateProfileDto : ExtensibleObject
{
public class UpdateProfileDto : ExtensibleObject
{
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
public string UserName { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
public string UserName { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string Email { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string Email { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxNameLength))]
public string Name { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxNameLength))]
public string Name { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxSurnameLength))]
public string Surname { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxSurnameLength))]
public string Surname { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
public string PhoneNumber { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
public string PhoneNumber { get; set; }
public string ConcurrencyStamp { get; set; }
}
public string ConcurrencyStamp { get; set; }
}

43
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModule.cs

@ -6,32 +6,31 @@ using Volo.Abp.UI.Navigation;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpUiNavigationModule),
typeof(AbpEmailingModule)
)]
public class AbpAccountApplicationModule : AbpModule
{
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpUiNavigationModule),
typeof(AbpEmailingModule)
)]
public class AbpAccountApplicationModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountApplicationModule>();
});
options.FileSets.AddEmbedded<AbpAccountApplicationModule>();
});
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAccountApplicationModuleAutoMapperProfile>(validate: true);
});
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAccountApplicationModuleAutoMapperProfile>(validate: true);
});
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].Urls[AccountUrlNames.PasswordReset] = "Account/ResetPassword";
});
}
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].Urls[AccountUrlNames.PasswordReset] = "Account/ResetPassword";
});
}
}

17
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AbpAccountApplicationModuleAutoMapperProfile.cs

@ -1,16 +1,15 @@
using AutoMapper;
using Volo.Abp.Identity;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class AbpAccountApplicationModuleAutoMapperProfile : Profile
{
public class AbpAccountApplicationModuleAutoMapperProfile : Profile
public AbpAccountApplicationModuleAutoMapperProfile()
{
public AbpAccountApplicationModuleAutoMapperProfile()
{
CreateMap<IdentityUser, ProfileDto>()
.ForMember(dest => dest.HasPassword,
op => op.MapFrom(src => src.PasswordHash != null))
.MapExtraProperties();
}
CreateMap<IdentityUser, ProfileDto>()
.ForMember(dest => dest.HasPassword,
op => op.MapFrom(src => src.PasswordHash != null))
.MapExtraProperties();
}
}

125
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs

@ -9,88 +9,87 @@ using Volo.Abp.Identity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Settings;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class AccountAppService : ApplicationService, IAccountAppService
{
public class AccountAppService : ApplicationService, IAccountAppService
protected IIdentityRoleRepository RoleRepository { get; }
protected IdentityUserManager UserManager { get; }
protected IAccountEmailer AccountEmailer { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AccountAppService(
IdentityUserManager userManager,
IIdentityRoleRepository roleRepository,
IAccountEmailer accountEmailer,
IdentitySecurityLogManager identitySecurityLogManager,
IOptions<IdentityOptions> identityOptions)
{
protected IIdentityRoleRepository RoleRepository { get; }
protected IdentityUserManager UserManager { get; }
protected IAccountEmailer AccountEmailer { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AccountAppService(
IdentityUserManager userManager,
IIdentityRoleRepository roleRepository,
IAccountEmailer accountEmailer,
IdentitySecurityLogManager identitySecurityLogManager,
IOptions<IdentityOptions> identityOptions)
{
RoleRepository = roleRepository;
AccountEmailer = accountEmailer;
IdentitySecurityLogManager = identitySecurityLogManager;
UserManager = userManager;
IdentityOptions = identityOptions;
LocalizationResource = typeof(AccountResource);
}
RoleRepository = roleRepository;
AccountEmailer = accountEmailer;
IdentitySecurityLogManager = identitySecurityLogManager;
UserManager = userManager;
IdentityOptions = identityOptions;
public virtual async Task<IdentityUserDto> RegisterAsync(RegisterDto input)
{
await CheckSelfRegistrationAsync();
LocalizationResource = typeof(AccountResource);
}
await IdentityOptions.SetAsync();
public virtual async Task<IdentityUserDto> RegisterAsync(RegisterDto input)
{
await CheckSelfRegistrationAsync();
var user = new IdentityUser(GuidGenerator.Create(), input.UserName, input.EmailAddress, CurrentTenant.Id);
await IdentityOptions.SetAsync();
input.MapExtraPropertiesTo(user);
var user = new IdentityUser(GuidGenerator.Create(), input.UserName, input.EmailAddress, CurrentTenant.Id);
(await UserManager.CreateAsync(user, input.Password)).CheckErrors();
input.MapExtraPropertiesTo(user);
await UserManager.SetEmailAsync(user,input.EmailAddress);
await UserManager.AddDefaultRolesAsync(user);
(await UserManager.CreateAsync(user, input.Password)).CheckErrors();
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user);
}
await UserManager.SetEmailAsync(user, input.EmailAddress);
await UserManager.AddDefaultRolesAsync(user);
public virtual async Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input)
{
var user = await GetUserByEmailAsync(input.Email);
var resetToken = await UserManager.GeneratePasswordResetTokenAsync(user);
await AccountEmailer.SendPasswordResetLinkAsync(user, resetToken, input.AppName, input.ReturnUrl, input.ReturnUrlHash);
}
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user);
}
public virtual async Task ResetPasswordAsync(ResetPasswordDto input)
{
await IdentityOptions.SetAsync();
public virtual async Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input)
{
var user = await GetUserByEmailAsync(input.Email);
var resetToken = await UserManager.GeneratePasswordResetTokenAsync(user);
await AccountEmailer.SendPasswordResetLinkAsync(user, resetToken, input.AppName, input.ReturnUrl, input.ReturnUrlHash);
}
var user = await UserManager.GetByIdAsync(input.UserId);
(await UserManager.ResetPasswordAsync(user, input.ResetToken, input.Password)).CheckErrors();
public virtual async Task ResetPasswordAsync(ResetPasswordDto input)
{
await IdentityOptions.SetAsync();
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.ChangePassword
});
}
var user = await UserManager.GetByIdAsync(input.UserId);
(await UserManager.ResetPasswordAsync(user, input.ResetToken, input.Password)).CheckErrors();
protected virtual async Task<IdentityUser> GetUserByEmailAsync(string email)
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
throw new UserFriendlyException(L["Volo.Account:InvalidEmailAddress", email]);
}
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.ChangePassword
});
}
return user;
protected virtual async Task<IdentityUser> GetUserByEmailAsync(string email)
{
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
throw new UserFriendlyException(L["Volo.Account:InvalidEmailAddress", email]);
}
protected virtual async Task CheckSelfRegistrationAsync()
return user;
}
protected virtual async Task CheckSelfRegistrationAsync()
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled))
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled))
{
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
}
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
}
}
}

9
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountUrlNames.cs

@ -1,7 +1,6 @@
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public static class AccountUrlNames
{
public static class AccountUrlNames
{
public const string PasswordReset = "Abp.Account.PasswordReset";
}
public const string PasswordReset = "Abp.Account.PasswordReset";
}

135
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AccountEmailer.cs

@ -13,95 +13,94 @@ using Volo.Abp.MultiTenancy;
using Volo.Abp.TextTemplating;
using Volo.Abp.UI.Navigation.Urls;
namespace Volo.Abp.Account.Emailing
namespace Volo.Abp.Account.Emailing;
public class AccountEmailer : IAccountEmailer, ITransientDependency
{
public class AccountEmailer : IAccountEmailer, ITransientDependency
protected ITemplateRenderer TemplateRenderer { get; }
protected IEmailSender EmailSender { get; }
protected IStringLocalizer<AccountResource> StringLocalizer { get; }
protected IAppUrlProvider AppUrlProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
public AccountEmailer(
IEmailSender emailSender,
ITemplateRenderer templateRenderer,
IStringLocalizer<AccountResource> stringLocalizer,
IAppUrlProvider appUrlProvider,
ICurrentTenant currentTenant)
{
protected ITemplateRenderer TemplateRenderer { get; }
protected IEmailSender EmailSender { get; }
protected IStringLocalizer<AccountResource> StringLocalizer { get; }
protected IAppUrlProvider AppUrlProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
EmailSender = emailSender;
StringLocalizer = stringLocalizer;
AppUrlProvider = appUrlProvider;
CurrentTenant = currentTenant;
TemplateRenderer = templateRenderer;
}
public virtual async Task SendPasswordResetLinkAsync(
IdentityUser user,
string resetToken,
string appName,
string returnUrl = null,
string returnUrlHash = null)
{
Debug.Assert(CurrentTenant.Id == user.TenantId, "This method can only work for current tenant!");
var url = await AppUrlProvider.GetResetPasswordUrlAsync(appName);
//TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key
var link = $"{url}?userId={user.Id}&{TenantResolverConsts.DefaultTenantKey}={user.TenantId}&resetToken={UrlEncoder.Default.Encode(resetToken)}";
public AccountEmailer(
IEmailSender emailSender,
ITemplateRenderer templateRenderer,
IStringLocalizer<AccountResource> stringLocalizer,
IAppUrlProvider appUrlProvider,
ICurrentTenant currentTenant)
if (!returnUrl.IsNullOrEmpty())
{
EmailSender = emailSender;
StringLocalizer = stringLocalizer;
AppUrlProvider = appUrlProvider;
CurrentTenant = currentTenant;
TemplateRenderer = templateRenderer;
link += "&returnUrl=" + NormalizeReturnUrl(returnUrl);
}
public virtual async Task SendPasswordResetLinkAsync(
IdentityUser user,
string resetToken,
string appName,
string returnUrl = null,
string returnUrlHash = null)
if (!returnUrlHash.IsNullOrEmpty())
{
Debug.Assert(CurrentTenant.Id == user.TenantId, "This method can only work for current tenant!");
var url = await AppUrlProvider.GetResetPasswordUrlAsync(appName);
//TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key
var link = $"{url}?userId={user.Id}&{TenantResolverConsts.DefaultTenantKey}={user.TenantId}&resetToken={UrlEncoder.Default.Encode(resetToken)}";
link += "&returnUrlHash=" + returnUrlHash;
}
if (!returnUrl.IsNullOrEmpty())
{
link += "&returnUrl=" + NormalizeReturnUrl(returnUrl);
}
var emailContent = await TemplateRenderer.RenderAsync(
AccountEmailTemplates.PasswordResetLink,
new { link = link }
);
if (!returnUrlHash.IsNullOrEmpty())
{
link += "&returnUrlHash=" + returnUrlHash;
}
var emailContent = await TemplateRenderer.RenderAsync(
AccountEmailTemplates.PasswordResetLink,
new { link = link }
);
await EmailSender.SendAsync(
user.Email,
StringLocalizer["PasswordReset"],
emailContent
);
}
await EmailSender.SendAsync(
user.Email,
StringLocalizer["PasswordReset"],
emailContent
);
protected virtual string NormalizeReturnUrl(string returnUrl)
{
if (returnUrl.IsNullOrEmpty())
{
return returnUrl;
}
protected virtual string NormalizeReturnUrl(string returnUrl)
//Handling openid connect login
if (returnUrl.StartsWith("/connect/authorize/callback", StringComparison.OrdinalIgnoreCase))
{
if (returnUrl.IsNullOrEmpty())
if (returnUrl.Contains("?"))
{
return returnUrl;
}
//Handling openid connect login
if (returnUrl.StartsWith("/connect/authorize/callback", StringComparison.OrdinalIgnoreCase))
{
if (returnUrl.Contains("?"))
var queryPart = returnUrl.Split('?')[1];
var queryParameters = queryPart.Split('&');
foreach (var queryParameter in queryParameters)
{
var queryPart = returnUrl.Split('?')[1];
var queryParameters = queryPart.Split('&');
foreach (var queryParameter in queryParameters)
if (queryParameter.Contains("="))
{
if (queryParameter.Contains("="))
var queryParam = queryParameter.Split('=');
if (queryParam[0] == "redirect_uri")
{
var queryParam = queryParameter.Split('=');
if (queryParam[0] == "redirect_uri")
{
return HttpUtility.UrlDecode(queryParam[1]);
}
return HttpUtility.UrlDecode(queryParam[1]);
}
}
}
}
return returnUrl;
}
return returnUrl;
}
}

11
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/AppUrlProviderAccountExtensions.cs

@ -1,13 +1,12 @@
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation.Urls;
namespace Volo.Abp.Account.Emailing
namespace Volo.Abp.Account.Emailing;
public static class AppUrlProviderAccountExtensions
{
public static class AppUrlProviderAccountExtensions
public static Task<string> GetResetPasswordUrlAsync(this IAppUrlProvider appUrlProvider, string appName)
{
public static Task<string> GetResetPasswordUrlAsync(this IAppUrlProvider appUrlProvider, string appName)
{
return appUrlProvider.GetUrlAsync(appName, AccountUrlNames.PasswordReset);
}
return appUrlProvider.GetUrlAsync(appName, AccountUrlNames.PasswordReset);
}
}

21
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/IAccountEmailer.cs

@ -1,16 +1,15 @@
using System.Threading.Tasks;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Emailing
namespace Volo.Abp.Account.Emailing;
public interface IAccountEmailer
{
public interface IAccountEmailer
{
Task SendPasswordResetLinkAsync(
IdentityUser user,
string resetToken,
string appName,
string returnUrl = null,
string returnUrlHash = null
);
}
Task SendPasswordResetLinkAsync(
IdentityUser user,
string resetToken,
string appName,
string returnUrl = null,
string returnUrlHash = null
);
}

25
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/Templates/AccountEmailTemplateDefinitionProvider.cs

@ -3,20 +3,19 @@ using Volo.Abp.Emailing.Templates;
using Volo.Abp.Localization;
using Volo.Abp.TextTemplating;
namespace Volo.Abp.Account.Emailing.Templates
namespace Volo.Abp.Account.Emailing.Templates;
public class AccountEmailTemplateDefinitionProvider : TemplateDefinitionProvider
{
public class AccountEmailTemplateDefinitionProvider : TemplateDefinitionProvider
public override void Define(ITemplateDefinitionContext context)
{
public override void Define(ITemplateDefinitionContext context)
{
context.Add(
new TemplateDefinition(
AccountEmailTemplates.PasswordResetLink,
displayName: LocalizableString.Create<AccountResource>($"TextTemplate:{AccountEmailTemplates.PasswordResetLink}"),
layout: StandardEmailTemplates.Layout,
localizationResource: typeof(AccountResource)
).WithVirtualFilePath("/Volo/Abp/Account/Emailing/Templates/PasswordResetLink.tpl", true)
);
}
context.Add(
new TemplateDefinition(
AccountEmailTemplates.PasswordResetLink,
displayName: LocalizableString.Create<AccountResource>($"TextTemplate:{AccountEmailTemplates.PasswordResetLink}"),
layout: StandardEmailTemplates.Layout,
localizationResource: typeof(AccountResource)
).WithVirtualFilePath("/Volo/Abp/Account/Emailing/Templates/PasswordResetLink.tpl", true)
);
}
}

9
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Emailing/Templates/AccountEmailTemplates.cs

@ -1,7 +1,6 @@
namespace Volo.Abp.Account.Emailing.Templates
namespace Volo.Abp.Account.Emailing.Templates;
public static class AccountEmailTemplates
{
public static class AccountEmailTemplates
{
public const string PasswordResetLink = "Abp.Account.PasswordResetLink";
}
public const string PasswordResetLink = "Abp.Account.PasswordResetLink";
}

117
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/ProfileAppService.cs

@ -11,89 +11,88 @@ using Volo.Abp.ObjectExtending;
using Volo.Abp.Settings;
using Volo.Abp.Users;
namespace Volo.Abp.Account
{
[Authorize]
public class ProfileAppService : IdentityAppServiceBase, IProfileAppService
{
protected IdentityUserManager UserManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
namespace Volo.Abp.Account;
public ProfileAppService(
IdentityUserManager userManager,
IOptions<IdentityOptions> identityOptions)
{
UserManager = userManager;
IdentityOptions = identityOptions;
}
[Authorize]
public class ProfileAppService : IdentityAppServiceBase, IProfileAppService
{
protected IdentityUserManager UserManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public virtual async Task<ProfileDto> GetAsync()
{
var currentUser = await UserManager.GetByIdAsync(CurrentUser.GetId());
public ProfileAppService(
IdentityUserManager userManager,
IOptions<IdentityOptions> identityOptions)
{
UserManager = userManager;
IdentityOptions = identityOptions;
}
return ObjectMapper.Map<IdentityUser, ProfileDto>(currentUser);
}
public virtual async Task<ProfileDto> GetAsync()
{
var currentUser = await UserManager.GetByIdAsync(CurrentUser.GetId());
public virtual async Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{
await IdentityOptions.SetAsync();
return ObjectMapper.Map<IdentityUser, ProfileDto>(currentUser);
}
var user = await UserManager.GetByIdAsync(CurrentUser.GetId());
public virtual async Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{
await IdentityOptions.SetAsync();
user.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
var user = await UserManager.GetByIdAsync(CurrentUser.GetId());
if (!string.Equals(user.UserName, input.UserName, StringComparison.InvariantCultureIgnoreCase))
{
if (await SettingProvider.IsTrueAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled))
{
(await UserManager.SetUserNameAsync(user, input.UserName)).CheckErrors();
}
}
user.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
if (!string.Equals(user.Email, input.Email, StringComparison.InvariantCultureIgnoreCase))
if (!string.Equals(user.UserName, input.UserName, StringComparison.InvariantCultureIgnoreCase))
{
if (await SettingProvider.IsTrueAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled))
{
if (await SettingProvider.IsTrueAsync(IdentitySettingNames.User.IsEmailUpdateEnabled))
{
(await UserManager.SetEmailAsync(user, input.Email)).CheckErrors();
}
(await UserManager.SetUserNameAsync(user, input.UserName)).CheckErrors();
}
}
if (!string.Equals(user.PhoneNumber, input.PhoneNumber, StringComparison.InvariantCultureIgnoreCase))
if (!string.Equals(user.Email, input.Email, StringComparison.InvariantCultureIgnoreCase))
{
if (await SettingProvider.IsTrueAsync(IdentitySettingNames.User.IsEmailUpdateEnabled))
{
(await UserManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
(await UserManager.SetEmailAsync(user, input.Email)).CheckErrors();
}
}
user.Name = input.Name;
user.Surname = input.Surname;
if (!string.Equals(user.PhoneNumber, input.PhoneNumber, StringComparison.InvariantCultureIgnoreCase))
{
(await UserManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
}
input.MapExtraPropertiesTo(user);
user.Name = input.Name;
user.Surname = input.Surname;
(await UserManager.UpdateAsync(user)).CheckErrors();
input.MapExtraPropertiesTo(user);
await CurrentUnitOfWork.SaveChangesAsync();
(await UserManager.UpdateAsync(user)).CheckErrors();
return ObjectMapper.Map<IdentityUser, ProfileDto>(user);
}
await CurrentUnitOfWork.SaveChangesAsync();
public virtual async Task ChangePasswordAsync(ChangePasswordInput input)
{
await IdentityOptions.SetAsync();
return ObjectMapper.Map<IdentityUser, ProfileDto>(user);
}
var currentUser = await UserManager.GetByIdAsync(CurrentUser.GetId());
public virtual async Task ChangePasswordAsync(ChangePasswordInput input)
{
await IdentityOptions.SetAsync();
if (currentUser.IsExternal)
{
throw new BusinessException(code: IdentityErrorCodes.ExternalUserPasswordChange);
}
var currentUser = await UserManager.GetByIdAsync(CurrentUser.GetId());
if (currentUser.PasswordHash == null)
{
(await UserManager.AddPasswordAsync(currentUser, input.NewPassword)).CheckErrors();
if (currentUser.IsExternal)
{
throw new BusinessException(code: IdentityErrorCodes.ExternalUserPasswordChange);
}
return;
}
if (currentUser.PasswordHash == null)
{
(await UserManager.AddPasswordAsync(currentUser, input.NewPassword)).CheckErrors();
(await UserManager.ChangePasswordAsync(currentUser, input.CurrentPassword, input.NewPassword)).CheckErrors();
return;
}
(await UserManager.ChangePasswordAsync(currentUser, input.CurrentPassword, input.NewPassword)).CheckErrors();
}
}

47
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/Settings/AccountSettingDefinitionProvider.cs

@ -2,32 +2,31 @@
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace Volo.Abp.Account.Settings
namespace Volo.Abp.Account.Settings;
public class AccountSettingDefinitionProvider : SettingDefinitionProvider
{
public class AccountSettingDefinitionProvider : SettingDefinitionProvider
public override void Define(ISettingDefinitionContext context)
{
public override void Define(ISettingDefinitionContext context)
{
context.Add(
new SettingDefinition(
AccountSettingNames.IsSelfRegistrationEnabled,
"true",
L("DisplayName:Abp.Account.IsSelfRegistrationEnabled"),
L("Description:Abp.Account.IsSelfRegistrationEnabled"), isVisibleToClients : true)
);
context.Add(
new SettingDefinition(
AccountSettingNames.IsSelfRegistrationEnabled,
"true",
L("DisplayName:Abp.Account.IsSelfRegistrationEnabled"),
L("Description:Abp.Account.IsSelfRegistrationEnabled"), isVisibleToClients: true)
);
context.Add(
new SettingDefinition(
AccountSettingNames.EnableLocalLogin,
"true",
L("DisplayName:Abp.Account.EnableLocalLogin"),
L("Description:Abp.Account.EnableLocalLogin"), isVisibleToClients : true)
);
}
context.Add(
new SettingDefinition(
AccountSettingNames.EnableLocalLogin,
"true",
L("DisplayName:Abp.Account.EnableLocalLogin"),
L("Description:Abp.Account.EnableLocalLogin"), isVisibleToClients: true)
);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<AccountResource>(name);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<AccountResource>(name);
}
}
}

21
modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorAutoMapperProfile.cs

@ -3,18 +3,17 @@ using Volo.Abp.Account.Blazor.Pages.Account;
using Volo.Abp.AutoMapper;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Blazor
namespace Volo.Abp.Account.Blazor;
public class AbpAccountBlazorAutoMapperProfile : Profile
{
public class AbpAccountBlazorAutoMapperProfile : Profile
public AbpAccountBlazorAutoMapperProfile()
{
public AbpAccountBlazorAutoMapperProfile()
{
CreateMap<ProfileDto, PersonalInfoModel>()
.Ignore(x => x.PhoneNumberConfirmed)
.Ignore(x => x.EmailConfirmed);
CreateMap<ProfileDto, PersonalInfoModel>()
.Ignore(x => x.PhoneNumberConfirmed)
.Ignore(x => x.EmailConfirmed);
CreateMap<PersonalInfoModel, UpdateProfileDto>()
.Ignore(x => x.ExtraProperties);
}
CreateMap<PersonalInfoModel, UpdateProfileDto>()
.Ignore(x => x.ExtraProperties);
}
}
}

45
modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorModule.cs

@ -5,33 +5,32 @@ using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Account.Blazor
namespace Volo.Abp.Account.Blazor;
[DependsOn(
typeof(AbpAspNetCoreComponentsWebThemingModule),
typeof(AbpAutoMapperModule),
typeof(AbpAccountApplicationContractsModule)
)]
public class AbpAccountBlazorModule : AbpModule
{
[DependsOn(
typeof(AbpAspNetCoreComponentsWebThemingModule),
typeof(AbpAutoMapperModule),
typeof(AbpAccountApplicationContractsModule)
)]
public class AbpAccountBlazorModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpAccountBlazorModule>();
context.Services.AddAutoMapperObjectMapper<AbpAccountBlazorModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAccountBlazorAutoMapperProfile>(validate: true);
});
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAccountBlazorAutoMapperProfile>(validate: true);
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new AbpAccountBlazorUserMenuContributor());
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new AbpAccountBlazorUserMenuContributor());
});
Configure<AbpRouterOptions>(options =>
{
options.AdditionalAssemblies.Add(typeof(AbpAccountBlazorModule).Assembly);
});
}
Configure<AbpRouterOptions>(options =>
{
options.AdditionalAssemblies.Add(typeof(AbpAccountBlazorModule).Assembly);
});
}
}

25
modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs

@ -2,22 +2,21 @@
using Volo.Abp.Account.Localization;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Account.Blazor
namespace Volo.Abp.Account.Blazor;
public class AbpAccountBlazorUserMenuContributor : IMenuContributor
{
public class AbpAccountBlazorUserMenuContributor : IMenuContributor
public Task ConfigureMenuAsync(MenuConfigurationContext context)
{
public Task ConfigureMenuAsync(MenuConfigurationContext context)
if (context.Menu.Name != StandardMenus.User)
{
if (context.Menu.Name != StandardMenus.User)
{
return Task.CompletedTask;
}
var accountResource = context.GetLocalizer<AccountResource>();
context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["MyAccount"], url: "account/manage-profile", icon: "fa fa-cog"));
return Task.CompletedTask;
}
var accountResource = context.GetLocalizer<AccountResource>();
context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["MyAccount"], url: "account/manage-profile", icon: "fa fa-cog"));
return Task.CompletedTask;
}
}
}

13
modules/account/src/Volo.Abp.Account.Blazor/AbpAccountComponentBase.cs

@ -1,14 +1,13 @@
using Volo.Abp.Account.Localization;
using Volo.Abp.AspNetCore.Components;
namespace Volo.Abp.Account.Blazor
namespace Volo.Abp.Account.Blazor;
public abstract class AbpAccountComponentBase : AbpComponentBase
{
public abstract class AbpAccountComponentBase : AbpComponentBase
protected AbpAccountComponentBase()
{
protected AbpAccountComponentBase()
{
LocalizationResource = typeof(AccountResource);
ObjectMapperContext = typeof(AbpAccountBlazorModule);
}
LocalizationResource = typeof(AccountResource);
ObjectMapperContext = typeof(AbpAccountBlazorModule);
}
}

129
modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor.cs

@ -3,94 +3,93 @@ using Microsoft.AspNetCore.Components;
using Volo.Abp.AspNetCore.Components.Messages;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Blazor.Pages.Account
namespace Volo.Abp.Account.Blazor.Pages.Account;
public partial class AccountManage
{
public partial class AccountManage
[Inject] protected IProfileAppService ProfileAppService { get; set; }
[Inject] protected IUiMessageService UiMessageService { get; set; }
protected string SelectedTab = "Password";
protected ChangePasswordModel ChangePasswordModel;
protected PersonalInfoModel PersonalInfoModel;
protected override async Task OnInitializedAsync()
{
[Inject] protected IProfileAppService ProfileAppService { get; set; }
[Inject] protected IUiMessageService UiMessageService { get; set; }
await GetUserInformations();
}
protected string SelectedTab = "Password";
protected async Task GetUserInformations()
{
var user = await ProfileAppService.GetAsync();
protected ChangePasswordModel ChangePasswordModel;
ChangePasswordModel = new ChangePasswordModel
{
HideOldPasswordInput = !user.HasPassword
};
protected PersonalInfoModel PersonalInfoModel;
PersonalInfoModel = ObjectMapper.Map<ProfileDto, PersonalInfoModel>(user);
}
protected override async Task OnInitializedAsync()
protected async Task ChangePasswordAsync()
{
if (string.IsNullOrWhiteSpace(ChangePasswordModel.CurrentPassword))
{
await GetUserInformations();
return;
}
protected async Task GetUserInformations()
if (ChangePasswordModel.NewPassword != ChangePasswordModel.NewPasswordConfirm)
{
var user = await ProfileAppService.GetAsync();
ChangePasswordModel = new ChangePasswordModel
{
HideOldPasswordInput = !user.HasPassword
};
PersonalInfoModel = ObjectMapper.Map<ProfileDto, PersonalInfoModel>(user);
await UiMessageService.Warn(L["NewPasswordConfirmFailed"]);
return;
}
protected async Task ChangePasswordAsync()
await ProfileAppService.ChangePasswordAsync(new ChangePasswordInput
{
if (string.IsNullOrWhiteSpace(ChangePasswordModel.CurrentPassword))
{
return;
}
if (ChangePasswordModel.NewPassword != ChangePasswordModel.NewPasswordConfirm)
{
await UiMessageService.Warn(L["NewPasswordConfirmFailed"]);
return;
}
await ProfileAppService.ChangePasswordAsync(new ChangePasswordInput
{
CurrentPassword = ChangePasswordModel.CurrentPassword,
NewPassword = ChangePasswordModel.NewPassword
});
await UiMessageService.Success(L["PasswordChanged"]);
}
CurrentPassword = ChangePasswordModel.CurrentPassword,
NewPassword = ChangePasswordModel.NewPassword
});
protected async Task UpdatePersonalInfoAsync()
{
await ProfileAppService.UpdateAsync(
ObjectMapper.Map<PersonalInfoModel, UpdateProfileDto>(PersonalInfoModel)
);
await UiMessageService.Success(L["PersonalSettingsSaved"]);
}
await UiMessageService.Success(L["PasswordChanged"]);
}
public class ChangePasswordModel
protected async Task UpdatePersonalInfoAsync()
{
public string CurrentPassword { get; set; }
await ProfileAppService.UpdateAsync(
ObjectMapper.Map<PersonalInfoModel, UpdateProfileDto>(PersonalInfoModel)
);
public string NewPassword { get; set; }
await UiMessageService.Success(L["PersonalSettingsSaved"]);
}
}
public string NewPasswordConfirm { get; set; }
public class ChangePasswordModel
{
public string CurrentPassword { get; set; }
public bool HideOldPasswordInput { get; set; }
}
public class PersonalInfoModel
{
public string UserName { get; set; }
public string NewPassword { get; set; }
public string Email { get; set; }
public string NewPasswordConfirm { get; set; }
public string Name { get; set; }
public bool HideOldPasswordInput { get; set; }
}
public string Surname { get; set; }
public class PersonalInfoModel
{
public string UserName { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public string Name { get; set; }
public bool EmailConfirmed { get; set; }
}
}
public string Surname { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool EmailConfirmed { get; set; }
}

7
modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.cs

@ -1,8 +1,7 @@
// This file is part of AccountClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Volo.Abp.Account.ClientProxies
namespace Volo.Abp.Account.ClientProxies;
public partial class AccountClientProxy
{
public partial class AccountClientProxy
{
}
}

7
modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.cs

@ -1,8 +1,7 @@
// This file is part of ProfileClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Volo.Abp.Account.ClientProxies
namespace Volo.Abp.Account.ClientProxies;
public partial class ProfileClientProxy
{
public partial class ProfileClientProxy
{
}
}

27
modules/account/src/Volo.Abp.Account.HttpApi.Client/Volo/Abp/Account/AbpAccountHttpApiClientModule.cs

@ -3,22 +3,21 @@ using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpHttpClientModule))]
public class AbpAccountHttpApiClientModule : AbpModule
{
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpHttpClientModule))]
public class AbpAccountHttpApiClientModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddStaticHttpClientProxies(typeof(AbpAccountApplicationContractsModule).Assembly,
AccountRemoteServiceConsts.RemoteServiceName);
context.Services.AddStaticHttpClientProxies(typeof(AbpAccountApplicationContractsModule).Assembly,
AccountRemoteServiceConsts.RemoteServiceName);
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountHttpApiClientModule>();
});
}
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountHttpApiClientModule>();
});
}
}

41
modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AbpAccountHttpApiModule.cs

@ -6,30 +6,29 @@ using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpIdentityHttpApiModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpAccountHttpApiModule : AbpModule
{
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpIdentityHttpApiModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpAccountHttpApiModule : AbpModule
public override void PreConfigureServices(ServiceConfigurationContext context)
{
public override void PreConfigureServices(ServiceConfigurationContext context)
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountHttpApiModule).Assembly);
});
}
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountHttpApiModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpLocalizationOptions>(options =>
{
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AccountResource>()
.AddBaseTypes(typeof(AbpUiResource));
});
}
options.Resources
.Get<AccountResource>()
.AddBaseTypes(typeof(AbpUiResource));
});
}
}
}

57
modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs

@ -3,39 +3,38 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Identity;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Area(AccountRemoteServiceConsts.ModuleName)]
[Route("api/account")]
public class AccountController : AbpControllerBase, IAccountAppService
{
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Area(AccountRemoteServiceConsts.ModuleName)]
[Route("api/account")]
public class AccountController : AbpControllerBase, IAccountAppService
{
protected IAccountAppService AccountAppService { get; }
protected IAccountAppService AccountAppService { get; }
public AccountController(IAccountAppService accountAppService)
{
AccountAppService = accountAppService;
}
public AccountController(IAccountAppService accountAppService)
{
AccountAppService = accountAppService;
}
[HttpPost]
[Route("register")]
public virtual Task<IdentityUserDto> RegisterAsync(RegisterDto input)
{
return AccountAppService.RegisterAsync(input);
}
[HttpPost]
[Route("register")]
public virtual Task<IdentityUserDto> RegisterAsync(RegisterDto input)
{
return AccountAppService.RegisterAsync(input);
}
[HttpPost]
[Route("send-password-reset-code")]
public virtual Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input)
{
return AccountAppService.SendPasswordResetCodeAsync(input);
}
[HttpPost]
[Route("send-password-reset-code")]
public virtual Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input)
{
return AccountAppService.SendPasswordResetCodeAsync(input);
}
[HttpPost]
[Route("reset-password")]
public virtual Task ResetPasswordAsync(ResetPasswordDto input)
{
return AccountAppService.ResetPasswordAsync(input);
}
[HttpPost]
[Route("reset-password")]
public virtual Task ResetPasswordAsync(ResetPasswordDto input)
{
return AccountAppService.ResetPasswordAsync(input);
}
}

55
modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/ProfileController.cs

@ -2,38 +2,37 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Area(AccountRemoteServiceConsts.ModuleName)]
[ControllerName("Profile")]
[Route("/api/account/my-profile")]
public class ProfileController : AbpControllerBase, IProfileAppService
{
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Area(AccountRemoteServiceConsts.ModuleName)]
[ControllerName("Profile")]
[Route("/api/account/my-profile")]
public class ProfileController : AbpControllerBase, IProfileAppService
{
protected IProfileAppService ProfileAppService { get; }
protected IProfileAppService ProfileAppService { get; }
public ProfileController(IProfileAppService profileAppService)
{
ProfileAppService = profileAppService;
}
public ProfileController(IProfileAppService profileAppService)
{
ProfileAppService = profileAppService;
}
[HttpGet]
public virtual Task<ProfileDto> GetAsync()
{
return ProfileAppService.GetAsync();
}
[HttpGet]
public virtual Task<ProfileDto> GetAsync()
{
return ProfileAppService.GetAsync();
}
[HttpPut]
public virtual Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{
return ProfileAppService.UpdateAsync(input);
}
[HttpPut]
public virtual Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{
return ProfileAppService.UpdateAsync(input);
}
[HttpPost]
[Route("change-password")]
public virtual Task ChangePasswordAsync(ChangePasswordInput input)
{
return ProfileAppService.ChangePasswordAsync(input);
}
[HttpPost]
[Route("change-password")]
public virtual Task ChangePasswordAsync(ChangePasswordInput input)
{
return ProfileAppService.ChangePasswordAsync(input);
}
}

23
modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AbpAccountInstallerModule.cs

@ -2,20 +2,19 @@
using Volo.Abp.Studio;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[DependsOn(
typeof(AbpStudioModuleInstallerModule),
typeof(AbpVirtualFileSystemModule)
)]
public class AbpAccountInstallerModule : AbpModule
{
[DependsOn(
typeof(AbpStudioModuleInstallerModule),
typeof(AbpVirtualFileSystemModule)
)]
public class AbpAccountInstallerModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountInstallerModule>();
});
}
options.FileSets.AddEmbedded<AbpAccountInstallerModule>();
});
}
}

15
modules/account/src/Volo.Abp.Account.Installer/Volo/Abp/Account/AccountInstallerPipelineBuilder.cs

@ -3,15 +3,14 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Studio.ModuleInstalling;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IModuleInstallingPipelineBuilder))]
public class AccountInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IModuleInstallingPipelineBuilder))]
public class AccountInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency
public async Task<ModuleInstallingPipeline> BuildAsync(ModuleInstallingContext context)
{
public async Task<ModuleInstallingPipeline> BuildAsync(ModuleInstallingContext context)
{
return GetBasePipeline(context);
}
return GetBasePipeline(context);
}
}

69
modules/account/src/Volo.Abp.Account.Web.IdentityServer/AbpAccountWebIdentityServerModule.cs

@ -6,48 +6,47 @@ using Volo.Abp.IdentityServer;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Account.Web
namespace Volo.Abp.Account.Web;
[DependsOn(
typeof(AbpAccountWebModule),
typeof(AbpIdentityServerDomainModule)
)]
public class AbpAccountWebIdentityServerModule : AbpModule
{
[DependsOn(
typeof(AbpAccountWebModule),
typeof(AbpIdentityServerDomainModule)
)]
public class AbpAccountWebIdentityServerModule : AbpModule
public override void PreConfigureServices(ServiceConfigurationContext context)
{
public override void PreConfigureServices(ServiceConfigurationContext context)
context.Services.PreConfigure<AbpIdentityAspNetCoreOptions>(options =>
{
context.Services.PreConfigure<AbpIdentityAspNetCoreOptions>(options =>
{
options.ConfigureAuthentication = false;
});
options.ConfigureAuthentication = false;
});
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebIdentityServerModule).Assembly);
});
}
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebIdentityServerModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountWebIdentityServerModule>();
});
options.FileSets.AddEmbedded<AbpAccountWebIdentityServerModule>();
});
Configure<IdentityServerOptions>(options =>
{
options.UserInteraction.ConsentUrl = "/Consent";
options.UserInteraction.ErrorUrl = "/Account/Error";
});
Configure<IdentityServerOptions>(options =>
{
options.UserInteraction.ConsentUrl = "/Consent";
options.UserInteraction.ErrorUrl = "/Account/Error";
});
//TODO: Try to reuse from AbpIdentityAspNetCoreModule
context.Services
.AddAuthentication(o =>
{
o.DefaultScheme = IdentityConstants.ApplicationScheme;
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();
}
//TODO: Try to reuse from AbpIdentityAspNetCoreModule
context.Services
.AddAuthentication(o =>
{
o.DefaultScheme = IdentityConstants.ApplicationScheme;
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies();
}
}

75
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Areas/Account/Controllers/ErrorController.cs

@ -12,52 +12,51 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Views.Error;
using Volo.Abp.Http;
namespace Volo.Abp.Account.Web.Areas.Account.Controllers
namespace Volo.Abp.Account.Web.Areas.Account.Controllers;
[Area("account")]
public class ErrorController : AbpController
{
[Area("account")]
public class ErrorController : AbpController
private readonly IIdentityServerInteractionService _interaction;
private readonly IWebHostEnvironment _environment;
private readonly AbpErrorPageOptions _abpErrorPageOptions;
public ErrorController(
IIdentityServerInteractionService interaction,
IWebHostEnvironment environment,
IOptions<AbpErrorPageOptions> abpErrorPageOptions)
{
private readonly IIdentityServerInteractionService _interaction;
private readonly IWebHostEnvironment _environment;
private readonly AbpErrorPageOptions _abpErrorPageOptions;
public ErrorController(
IIdentityServerInteractionService interaction,
IWebHostEnvironment environment,
IOptions<AbpErrorPageOptions> abpErrorPageOptions)
_interaction = interaction;
_environment = environment;
_abpErrorPageOptions = abpErrorPageOptions.Value;
}
public virtual async Task<IActionResult> Index(string errorId)
{
var errorMessage = await _interaction.GetErrorContextAsync(errorId) ?? new ErrorMessage
{
_interaction = interaction;
_environment = environment;
_abpErrorPageOptions = abpErrorPageOptions.Value;
}
Error = L["Error"]
};
public virtual async Task<IActionResult> Index(string errorId)
if (!_environment.IsDevelopment())
{
var errorMessage = await _interaction.GetErrorContextAsync(errorId) ?? new ErrorMessage
{
Error = L["Error"]
};
if (!_environment.IsDevelopment())
{
// Only show in development
errorMessage.ErrorDescription = null;
}
const int statusCode = (int)HttpStatusCode.InternalServerError;
return View(GetErrorPageUrl(statusCode), new AbpErrorViewModel
{
ErrorInfo = new RemoteServiceErrorInfo(errorMessage.Error, errorMessage.ErrorDescription),
HttpStatusCode = statusCode
});
// Only show in development
errorMessage.ErrorDescription = null;
}
protected virtual string GetErrorPageUrl(int statusCode)
const int statusCode = (int)HttpStatusCode.InternalServerError;
return View(GetErrorPageUrl(statusCode), new AbpErrorViewModel
{
var page = _abpErrorPageOptions.ErrorViewUrls.GetOrDefault(statusCode.ToString());
ErrorInfo = new RemoteServiceErrorInfo(errorMessage.Error, errorMessage.ErrorDescription),
HttpStatusCode = statusCode
});
}
return string.IsNullOrWhiteSpace(page) ? "~/Views/Error/Default.cshtml" : page;
}
protected virtual string GetErrorPageUrl(int statusCode)
{
var page = _abpErrorPageOptions.ErrorViewUrls.GetOrDefault(statusCode.ToString());
return string.IsNullOrWhiteSpace(page) ? "~/Views/Error/Default.cshtml" : page;
}
}

285
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs

@ -20,201 +20,200 @@ using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Settings;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
[ExposeServices(typeof(LoginModel))]
public class IdentityServerSupportedLoginModel : LoginModel
{
[ExposeServices(typeof(LoginModel))]
public class IdentityServerSupportedLoginModel : LoginModel
protected IIdentityServerInteractionService Interaction { get; }
protected IClientStore ClientStore { get; }
protected IEventService IdentityServerEvents { get; }
public IdentityServerSupportedLoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IEventService identityServerEvents,
IOptions<IdentityOptions> identityOptions)
: base(
schemeProvider,
accountOptions,
identityOptions)
{
protected IIdentityServerInteractionService Interaction { get; }
protected IClientStore ClientStore { get; }
protected IEventService IdentityServerEvents { get; }
public IdentityServerSupportedLoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IEventService identityServerEvents,
IOptions<IdentityOptions> identityOptions)
:base(
schemeProvider,
accountOptions,
identityOptions)
{
Interaction = interaction;
ClientStore = clientStore;
IdentityServerEvents = identityServerEvents;
}
Interaction = interaction;
ClientStore = clientStore;
IdentityServerEvents = identityServerEvents;
}
public override async Task<IActionResult> OnGetAsync()
{
LoginInput = new LoginInputModel();
public override async Task<IActionResult> OnGetAsync()
{
LoginInput = new LoginInputModel();
var context = await Interaction.GetAuthorizationContextAsync(ReturnUrl);
var context = await Interaction.GetAuthorizationContextAsync(ReturnUrl);
if (context != null)
{
ShowCancelButton = true;
if (context != null)
{
ShowCancelButton = true;
LoginInput.UserNameOrEmailAddress = context.LoginHint;
LoginInput.UserNameOrEmailAddress = context.LoginHint;
//TODO: Reference AspNetCore MultiTenancy module and use options to get the tenant key!
var tenant = context.Parameters[TenantResolverConsts.DefaultTenantKey];
if (!string.IsNullOrEmpty(tenant))
{
CurrentTenant.Change(Guid.Parse(tenant));
Response.Cookies.Append(TenantResolverConsts.DefaultTenantKey, tenant);
}
}
if (context?.IdP != null)
//TODO: Reference AspNetCore MultiTenancy module and use options to get the tenant key!
var tenant = context.Parameters[TenantResolverConsts.DefaultTenantKey];
if (!string.IsNullOrEmpty(tenant))
{
LoginInput.UserNameOrEmailAddress = context.LoginHint;
ExternalProviders = new[] { new ExternalProviderModel { AuthenticationScheme = context.IdP } };
return Page();
CurrentTenant.Change(Guid.Parse(tenant));
Response.Cookies.Append(TenantResolverConsts.DefaultTenantKey, tenant);
}
}
var providers = await GetExternalProviders();
ExternalProviders = providers.ToList();
if (context?.IdP != null)
{
LoginInput.UserNameOrEmailAddress = context.LoginHint;
ExternalProviders = new[] { new ExternalProviderModel { AuthenticationScheme = context.IdP } };
return Page();
}
var providers = await GetExternalProviders();
ExternalProviders = providers.ToList();
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
if (context?.Client?.ClientId != null)
if (context?.Client?.ClientId != null)
{
var client = await ClientStore.FindEnabledClientByIdAsync(context?.Client?.ClientId);
if (client != null)
{
var client = await ClientStore.FindEnabledClientByIdAsync(context?.Client?.ClientId);
if (client != null)
{
EnableLocalLogin = client.EnableLocalLogin;
EnableLocalLogin = client.EnableLocalLogin;
if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())
{
providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();
}
if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())
{
providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();
}
}
}
if (IsExternalLoginOnly)
{
return await base.OnPostExternalLogin(providers.First().AuthenticationScheme);
}
return Page();
if (IsExternalLoginOnly)
{
return await base.OnPostExternalLogin(providers.First().AuthenticationScheme);
}
public override async Task<IActionResult> OnPostAsync(string action)
return Page();
}
public override async Task<IActionResult> OnPostAsync(string action)
{
var context = await Interaction.GetAuthorizationContextAsync(ReturnUrl);
if (action == "Cancel")
{
var context = await Interaction.GetAuthorizationContextAsync(ReturnUrl);
if (action == "Cancel")
if (context == null)
{
if (context == null)
{
return Redirect("~/");
}
return Redirect("~/");
}
await Interaction.GrantConsentAsync(context, new ConsentResponse()
{
Error = AuthorizationError.AccessDenied
});
await Interaction.GrantConsentAsync(context, new ConsentResponse()
{
Error = AuthorizationError.AccessDenied
});
return Redirect(ReturnUrl);
}
return Redirect(ReturnUrl);
}
await CheckLocalLoginAsync();
await CheckLocalLoginAsync();
ValidateModel();
ValidateModel();
await IdentityOptions.SetAsync();
await IdentityOptions.SetAsync();
ExternalProviders = await GetExternalProviders();
ExternalProviders = await GetExternalProviders();
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
await ReplaceEmailToUsernameOfInputIfNeeds();
await ReplaceEmailToUsernameOfInputIfNeeds();
var result = await SignInManager.PasswordSignInAsync(
LoginInput.UserNameOrEmailAddress,
LoginInput.Password,
LoginInput.RememberMe,
true
);
var result = await SignInManager.PasswordSignInAsync(
LoginInput.UserNameOrEmailAddress,
LoginInput.Password,
LoginInput.RememberMe,
true
);
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress,
ClientId = context?.Client?.ClientId
});
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress,
ClientId = context?.Client?.ClientId
});
if (result.RequiresTwoFactor)
{
return await TwoFactorLoginResultAsync();
}
if (result.RequiresTwoFactor)
{
return await TwoFactorLoginResultAsync();
}
if (result.IsLockedOut)
{
Alerts.Warning(L["UserLockedOutMessage"]);
return Page();
}
if (result.IsLockedOut)
{
Alerts.Warning(L["UserLockedOutMessage"]);
return Page();
}
if (result.IsNotAllowed)
{
Alerts.Warning(L["LoginIsNotAllowed"]);
return Page();
}
if (result.IsNotAllowed)
{
Alerts.Warning(L["LoginIsNotAllowed"]);
return Page();
}
if (!result.Succeeded)
{
Alerts.Danger(L["InvalidUserNameOrPassword"]);
return Page();
}
if (!result.Succeeded)
{
Alerts.Danger(L["InvalidUserNameOrPassword"]);
return Page();
}
//TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
//TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
Debug.Assert(user != null, nameof(user) + " != null");
await IdentityServerEvents.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName)); //TODO: Use user's name once implemented
Debug.Assert(user != null, nameof(user) + " != null");
await IdentityServerEvents.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id.ToString(), user.UserName)); //TODO: Use user's name once implemented
return RedirectSafely(ReturnUrl, ReturnUrlHash);
}
return RedirectSafely(ReturnUrl, ReturnUrlHash);
}
public override async Task<IActionResult> OnPostExternalLogin(string provider)
public override async Task<IActionResult> OnPostExternalLogin(string provider)
{
if (AccountOptions.WindowsAuthenticationSchemeName == provider)
{
if (AccountOptions.WindowsAuthenticationSchemeName == provider)
{
return await ProcessWindowsLoginAsync();
}
return await base.OnPostExternalLogin(provider);
return await ProcessWindowsLoginAsync();
}
protected virtual async Task<IActionResult> ProcessWindowsLoginAsync()
return await base.OnPostExternalLogin(provider);
}
protected virtual async Task<IActionResult> ProcessWindowsLoginAsync()
{
var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);
if (result.Succeeded)
{
var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);
if (result.Succeeded)
var props = new AuthenticationProperties()
{
var props = new AuthenticationProperties()
{
RedirectUri = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new {ReturnUrl, ReturnUrlHash}),
Items =
RedirectUri = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash }),
Items =
{
{
"LoginProvider", AccountOptions.WindowsAuthenticationSchemeName
},
}
};
var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, result.Principal.FindFirstValue(ClaimTypes.PrimarySid)));
id.AddClaim(new Claim(ClaimTypes.Name, result.Principal.FindFirstValue(ClaimTypes.Name)));
};
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props);
var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, result.Principal.FindFirstValue(ClaimTypes.PrimarySid)));
id.AddClaim(new Claim(ClaimTypes.Name, result.Principal.FindFirstValue(ClaimTypes.Name)));
return Redirect(props.RedirectUri);
}
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props);
return Challenge(AccountOptions.WindowsAuthenticationSchemeName);
return Redirect(props.RedirectUri);
}
return Challenge(AccountOptions.WindowsAuthenticationSchemeName);
}
}

91
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLogoutModel.cs

@ -6,69 +6,68 @@ using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Web.Pages.Account
{
[ExposeServices(typeof(LogoutModel))]
public class IdentityServerSupportedLogoutModel : LogoutModel
{
protected IIdentityServerInteractionService Interaction { get; }
namespace Volo.Abp.Account.Web.Pages.Account;
public IdentityServerSupportedLogoutModel(IIdentityServerInteractionService interaction)
{
Interaction = interaction;
}
[ExposeServices(typeof(LogoutModel))]
public class IdentityServerSupportedLogoutModel : LogoutModel
{
protected IIdentityServerInteractionService Interaction { get; }
public async override Task<IActionResult> OnGetAsync()
{
await SignInManager.SignOutAsync();
public IdentityServerSupportedLogoutModel(IIdentityServerInteractionService interaction)
{
Interaction = interaction;
}
var logoutId = Request.Query["logoutId"].ToString();
public async override Task<IActionResult> OnGetAsync()
{
await SignInManager.SignOutAsync();
if (!string.IsNullOrEmpty(logoutId))
{
var logoutContext = await Interaction.GetLogoutContextAsync(logoutId);
var logoutId = Request.Query["logoutId"].ToString();
await SaveSecurityLogAsync(logoutContext?.ClientId);
if (!string.IsNullOrEmpty(logoutId))
{
var logoutContext = await Interaction.GetLogoutContextAsync(logoutId);
await SignInManager.SignOutAsync();
await SaveSecurityLogAsync(logoutContext?.ClientId);
HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
await SignInManager.SignOutAsync();
var vm = new LoggedOutModel()
{
PostLogoutRedirectUri = logoutContext?.PostLogoutRedirectUri,
ClientName = logoutContext?.ClientName,
SignOutIframeUrl = logoutContext?.SignOutIFrameUrl
};
HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
Logger.LogInformation($"Redirecting to LoggedOut Page...");
var vm = new LoggedOutModel()
{
PostLogoutRedirectUri = logoutContext?.PostLogoutRedirectUri,
ClientName = logoutContext?.ClientName,
SignOutIframeUrl = logoutContext?.SignOutIFrameUrl
};
return RedirectToPage("./LoggedOut", vm);
}
Logger.LogInformation($"Redirecting to LoggedOut Page...");
await SaveSecurityLogAsync();
return RedirectToPage("./LoggedOut", vm);
}
if (ReturnUrl != null)
{
return LocalRedirect(ReturnUrl);
}
await SaveSecurityLogAsync();
Logger.LogInformation(
$"IdentityServerSupportedLogoutModel couldn't find postLogoutUri... Redirecting to:/Account/Login..");
return RedirectToPage("/Account/Login");
if (ReturnUrl != null)
{
return LocalRedirect(ReturnUrl);
}
protected virtual async Task SaveSecurityLogAsync(string clientId = null)
Logger.LogInformation(
$"IdentityServerSupportedLogoutModel couldn't find postLogoutUri... Redirecting to:/Account/Login..");
return RedirectToPage("/Account/Login");
}
protected virtual async Task SaveSecurityLogAsync(string clientId = null)
{
if (CurrentUser.IsAuthenticated)
{
if (CurrentUser.IsAuthenticated)
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout,
ClientId = clientId
});
}
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout,
ClientId = clientId
});
}
}
}

365
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Consent.cshtml.cs

@ -11,256 +11,255 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.UI;
namespace Volo.Abp.Account.Web.Pages
namespace Volo.Abp.Account.Web.Pages;
//TODO: Move this into the Account folder!!!
public class ConsentModel : AbpPageModel
{
//TODO: Move this into the Account folder!!!
public class ConsentModel : AbpPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty]
public ConsentModel.ConsentInputModel ConsentInput { get; set; }
[BindProperty]
public ConsentModel.ConsentInputModel ConsentInput { get; set; }
public ClientInfoModel ClientInfo { get; set; }
public ClientInfoModel ClientInfo { get; set; }
private readonly IIdentityServerInteractionService _interaction;
private readonly IClientStore _clientStore;
private readonly IResourceStore _resourceStore;
private readonly IIdentityServerInteractionService _interaction;
private readonly IClientStore _clientStore;
private readonly IResourceStore _resourceStore;
public ConsentModel(
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IResourceStore resourceStore)
{
_interaction = interaction;
_clientStore = clientStore;
_resourceStore = resourceStore;
}
public ConsentModel(
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IResourceStore resourceStore)
public virtual async Task<IActionResult> OnGet()
{
var request = await _interaction.GetAuthorizationContextAsync(ReturnUrl);
if (request == null)
{
_interaction = interaction;
_clientStore = clientStore;
_resourceStore = resourceStore;
throw new ApplicationException($"No consent request matching request: {ReturnUrl}");
}
public virtual async Task<IActionResult> OnGet()
var client = await _clientStore.FindEnabledClientByIdAsync(request.Client.ClientId);
if (client == null)
{
var request = await _interaction.GetAuthorizationContextAsync(ReturnUrl);
if (request == null)
{
throw new ApplicationException($"No consent request matching request: {ReturnUrl}");
}
throw new ApplicationException($"Invalid client id: {request.Client.ClientId}");
}
var client = await _clientStore.FindEnabledClientByIdAsync(request.Client.ClientId);
if (client == null)
{
throw new ApplicationException($"Invalid client id: {request.Client.ClientId}");
}
var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ValidatedResources.RawScopeValues);
if (resources == null || (!resources.IdentityResources.Any() && !resources.ApiResources.Any()))
{
throw new ApplicationException($"No scopes matching: {request.ValidatedResources.RawScopeValues.Aggregate((x, y) => x + ", " + y)}");
}
ClientInfo = new ClientInfoModel(client);
ConsentInput = new ConsentInputModel
{
RememberConsent = true,
IdentityScopes = resources.IdentityResources.Select(x => CreateScopeViewModel(x, true)).ToList(),
};
var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ValidatedResources.RawScopeValues);
if (resources == null || (!resources.IdentityResources.Any() && !resources.ApiResources.Any()))
var apiScopes = new List<ScopeViewModel>();
foreach (var parsedScope in request.ValidatedResources.ParsedScopes)
{
var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);
if (apiScope != null)
{
throw new ApplicationException($"No scopes matching: {request.ValidatedResources.RawScopeValues.Aggregate((x, y) => x + ", " + y)}");
var scopeVm = CreateScopeViewModel(parsedScope, apiScope, true);
apiScopes.Add(scopeVm);
}
}
ClientInfo = new ClientInfoModel(client);
ConsentInput = new ConsentInputModel
{
RememberConsent = true,
IdentityScopes = resources.IdentityResources.Select(x => CreateScopeViewModel(x, true)).ToList(),
};
if (resources.OfflineAccess)
{
apiScopes.Add(GetOfflineAccessScope(true));
}
var apiScopes = new List<ScopeViewModel>();
foreach(var parsedScope in request.ValidatedResources.ParsedScopes)
{
var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);
if (apiScope != null)
{
var scopeVm = CreateScopeViewModel(parsedScope, apiScope, true);
apiScopes.Add(scopeVm);
}
}
ConsentInput.ApiScopes = apiScopes;
if (resources.OfflineAccess)
{
apiScopes.Add(GetOfflineAccessScope(true));
}
return Page();
}
ConsentInput.ApiScopes = apiScopes;
public virtual async Task<IActionResult> OnPost(string userDecision)
{
var result = await ProcessConsentAsync();
return Page();
if (result.IsRedirect)
{
return Redirect(result.RedirectUri);
}
public virtual async Task<IActionResult> OnPost(string userDecision)
if (result.HasValidationError)
{
var result = await ProcessConsentAsync();
//ModelState.AddModelError("", result.ValidationError);
throw new ApplicationException("Error: " + result.ValidationError);
}
if (result.IsRedirect)
{
return Redirect(result.RedirectUri);
}
throw new ApplicationException("Unknown Error!");
}
if (result.HasValidationError)
{
//ModelState.AddModelError("", result.ValidationError);
throw new ApplicationException("Error: " + result.ValidationError);
}
protected virtual async Task<ConsentModel.ProcessConsentResult> ProcessConsentAsync()
{
var result = new ConsentModel.ProcessConsentResult();
throw new ApplicationException("Unknown Error!");
}
ConsentResponse grantedConsent;
protected virtual async Task<ConsentModel.ProcessConsentResult> ProcessConsentAsync()
if (ConsentInput.UserDecision == "no")
{
var result = new ConsentModel.ProcessConsentResult();
ConsentResponse grantedConsent;
if (ConsentInput.UserDecision == "no")
grantedConsent = new ConsentResponse
{
Error = AuthorizationError.AccessDenied
};
}
else
{
if (!ConsentInput.IdentityScopes.IsNullOrEmpty() || !ConsentInput.ApiScopes.IsNullOrEmpty())
{
grantedConsent = new ConsentResponse
{
Error = AuthorizationError.AccessDenied
RememberConsent = ConsentInput.RememberConsent,
ScopesValuesConsented = ConsentInput.GetAllowedScopeNames()
};
}
else
{
if (!ConsentInput.IdentityScopes.IsNullOrEmpty() || !ConsentInput.ApiScopes.IsNullOrEmpty())
{
grantedConsent = new ConsentResponse
{
RememberConsent = ConsentInput.RememberConsent,
ScopesValuesConsented = ConsentInput.GetAllowedScopeNames()
};
}
else
{
throw new UserFriendlyException("You must pick at least one permission"); //TODO: How to handle this
}
throw new UserFriendlyException("You must pick at least one permission"); //TODO: How to handle this
}
}
if (grantedConsent != null)
if (grantedConsent != null)
{
var request = await _interaction.GetAuthorizationContextAsync(ReturnUrl);
if (request == null)
{
var request = await _interaction.GetAuthorizationContextAsync(ReturnUrl);
if (request == null)
{
return result;
}
await _interaction.GrantConsentAsync(request, grantedConsent);
result.RedirectUri = ReturnUrl; //TODO: ReturnUrlHash?
return result;
}
return result;
}
await _interaction.GrantConsentAsync(request, grantedConsent);
protected virtual ConsentModel.ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)
{
return new ConsentModel.ScopeViewModel
{
Name = identity.Name,
DisplayName = identity.DisplayName,
Description = identity.Description,
Emphasize = identity.Emphasize,
Required = identity.Required,
Checked = check || identity.Required
};
result.RedirectUri = ReturnUrl; //TODO: ReturnUrlHash?
}
protected virtual ConsentModel.ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)
return result;
}
protected virtual ConsentModel.ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)
{
return new ConsentModel.ScopeViewModel
{
var displayName = apiScope.DisplayName ?? apiScope.Name;
if (!string.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))
{
displayName += ":" + parsedScopeValue.ParsedParameter;
}
Name = identity.Name,
DisplayName = identity.DisplayName,
Description = identity.Description,
Emphasize = identity.Emphasize,
Required = identity.Required,
Checked = check || identity.Required
};
}
return new ScopeViewModel
{
Name = parsedScopeValue.RawValue,
DisplayName = displayName,
Description = apiScope.Description,
Emphasize = apiScope.Emphasize,
Required = apiScope.Required,
Checked = check || apiScope.Required
};
protected virtual ConsentModel.ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)
{
var displayName = apiScope.DisplayName ?? apiScope.Name;
if (!string.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))
{
displayName += ":" + parsedScopeValue.ParsedParameter;
}
protected virtual ConsentModel.ScopeViewModel GetOfflineAccessScope(bool check)
return new ScopeViewModel
{
return new ConsentModel.ScopeViewModel
{
Name = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess,
DisplayName = "Offline Access", //TODO: Localize
Description = "Access to your applications and resources, even when you are offline",
Emphasize = true,
Checked = check
};
}
Name = parsedScopeValue.RawValue,
DisplayName = displayName,
Description = apiScope.Description,
Emphasize = apiScope.Emphasize,
Required = apiScope.Required,
Checked = check || apiScope.Required
};
}
public class ConsentInputModel
protected virtual ConsentModel.ScopeViewModel GetOfflineAccessScope(bool check)
{
return new ConsentModel.ScopeViewModel
{
public List<ConsentModel.ScopeViewModel> IdentityScopes { get; set; }
Name = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess,
DisplayName = "Offline Access", //TODO: Localize
Description = "Access to your applications and resources, even when you are offline",
Emphasize = true,
Checked = check
};
}
public List<ConsentModel.ScopeViewModel> ApiScopes { get; set; }
public class ConsentInputModel
{
public List<ConsentModel.ScopeViewModel> IdentityScopes { get; set; }
[Required]
public string UserDecision { get; set; }
public List<ConsentModel.ScopeViewModel> ApiScopes { get; set; }
public bool RememberConsent { get; set; }
[Required]
public string UserDecision { get; set; }
public List<string> GetAllowedScopeNames()
{
var identityScopes = IdentityScopes ?? new List<ConsentModel.ScopeViewModel>();
var apiScopes = ApiScopes ?? new List<ConsentModel.ScopeViewModel>();
return identityScopes.Union(apiScopes).Where(s => s.Checked).Select(s => s.Name).ToList();
}
}
public bool RememberConsent { get; set; }
public class ScopeViewModel
public List<string> GetAllowedScopeNames()
{
[Required]
[HiddenInput]
public string Name { get; set; }
var identityScopes = IdentityScopes ?? new List<ConsentModel.ScopeViewModel>();
var apiScopes = ApiScopes ?? new List<ConsentModel.ScopeViewModel>();
return identityScopes.Union(apiScopes).Where(s => s.Checked).Select(s => s.Name).ToList();
}
}
public class ScopeViewModel
{
[Required]
[HiddenInput]
public string Name { get; set; }
public bool Checked { get; set; }
public bool Checked { get; set; }
public string DisplayName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string Description { get; set; }
public bool Emphasize { get; set; }
public bool Emphasize { get; set; }
public bool Required { get; set; }
}
public bool Required { get; set; }
}
public class ProcessConsentResult
{
public bool IsRedirect => RedirectUri != null;
public string RedirectUri { get; set; }
public class ProcessConsentResult
{
public bool IsRedirect => RedirectUri != null;
public string RedirectUri { get; set; }
public bool HasValidationError => ValidationError != null;
public string ValidationError { get; set; }
}
public bool HasValidationError => ValidationError != null;
public string ValidationError { get; set; }
}
public class ClientInfoModel
{
public string ClientName { get; set; }
public class ClientInfoModel
{
public string ClientName { get; set; }
public string ClientUrl { get; set; }
public string ClientUrl { get; set; }
public string ClientLogoUrl { get; set; }
public string ClientLogoUrl { get; set; }
public bool AllowRememberConsent { get; set; }
public bool AllowRememberConsent { get; set; }
public ClientInfoModel(Client client)
{
//TODO: Automap
ClientName = client.ClientId;
ClientUrl = client.ClientUri;
ClientLogoUrl = client.LogoUri;
AllowRememberConsent = client.AllowRememberConsent;
}
public ClientInfoModel(Client client)
{
//TODO: Automap
ClientName = client.ClientId;
ClientUrl = client.ClientUri;
ClientLogoUrl = client.LogoUri;
AllowRememberConsent = client.AllowRememberConsent;
}
}
}

23
modules/account/src/Volo.Abp.Account.Web/AbpAccountOptions.cs

@ -1,16 +1,15 @@
namespace Volo.Abp.Account.Web
namespace Volo.Abp.Account.Web;
public class AbpAccountOptions
{
public class AbpAccountOptions
{
/// <summary>
/// Default value: "Windows".
/// </summary>
public string WindowsAuthenticationSchemeName { get; set; }
/// <summary>
/// Default value: "Windows".
/// </summary>
public string WindowsAuthenticationSchemeName { get; set; }
public AbpAccountOptions()
{
//TODO: This makes us depend on the Microsoft.AspNetCore.Server.IISIntegration package.
WindowsAuthenticationSchemeName = "Windows"; //Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme;
}
public AbpAccountOptions()
{
//TODO: This makes us depend on the Microsoft.AspNetCore.Server.IISIntegration package.
WindowsAuthenticationSchemeName = "Windows"; //Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme;
}
}

25
modules/account/src/Volo.Abp.Account.Web/AbpAccountUserMenuContributor.cs

@ -5,24 +5,23 @@ using Microsoft.Extensions.Localization;
using Volo.Abp.Account.Localization;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Account.Web
namespace Volo.Abp.Account.Web;
public class AbpAccountUserMenuContributor : IMenuContributor
{
public class AbpAccountUserMenuContributor : IMenuContributor
public virtual Task ConfigureMenuAsync(MenuConfigurationContext context)
{
public virtual Task ConfigureMenuAsync(MenuConfigurationContext context)
if (context.Menu.Name != StandardMenus.User)
{
if (context.Menu.Name != StandardMenus.User)
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}
var uiResource = context.GetLocalizer<AbpUiResource>();
var accountResource = context.GetLocalizer<AccountResource>();
var uiResource = context.GetLocalizer<AbpUiResource>();
var accountResource = context.GetLocalizer<AccountResource>();
context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["MyAccount"], url: "~/Account/Manage", icon: "fa fa-cog", order: 1000, null));
context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", uiResource["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000));
context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["MyAccount"], url: "~/Account/Manage", icon: "fa fa-cog", order: 1000, null));
context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", uiResource["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000));
return Task.CompletedTask;
}
return Task.CompletedTask;
}
}

11
modules/account/src/Volo.Abp.Account.Web/AbpAccountWebAutomapperProfile.cs

@ -3,13 +3,12 @@ using Volo.Abp.Identity;
using AutoMapper;
using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo;
namespace Volo.Abp.Account.Web
namespace Volo.Abp.Account.Web;
public class AbpAccountWebAutoMapperProfile : Profile
{
public class AbpAccountWebAutoMapperProfile : Profile
public AbpAccountWebAutoMapperProfile()
{
public AbpAccountWebAutoMapperProfile()
{
CreateMap<ProfileDto, AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel>();
}
CreateMap<ProfileDto, AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel>();
}
}

127
modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs

@ -15,85 +15,84 @@ using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Account.Web
namespace Volo.Abp.Account.Web;
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpIdentityAspNetCoreModule),
typeof(AbpAutoMapperModule),
typeof(AbpAspNetCoreMvcUiThemeSharedModule),
typeof(AbpExceptionHandlingModule)
)]
public class AbpAccountWebModule : AbpModule
{
[DependsOn(
typeof(AbpAccountApplicationContractsModule),
typeof(AbpIdentityAspNetCoreModule),
typeof(AbpAutoMapperModule),
typeof(AbpAspNetCoreMvcUiThemeSharedModule),
typeof(AbpExceptionHandlingModule)
)]
public class AbpAccountWebModule : AbpModule
public override void PreConfigureServices(ServiceConfigurationContext context)
{
public override void PreConfigureServices(ServiceConfigurationContext context)
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(typeof(AccountResource), typeof(AbpAccountWebModule).Assembly);
});
options.AddAssemblyResource(typeof(AccountResource), typeof(AbpAccountWebModule).Assembly);
});
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebModule).Assembly);
});
}
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAccountWebModule>();
});
options.FileSets.AddEmbedded<AbpAccountWebModule>();
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new AbpAccountUserMenuContributor());
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new AbpAccountUserMenuContributor());
});
Configure<AbpToolbarOptions>(options =>
{
options.Contributors.Add(new AccountModuleToolbarContributor());
});
Configure<AbpToolbarOptions>(options =>
{
options.Contributors.Add(new AccountModuleToolbarContributor());
});
ConfigureProfileManagementPage();
ConfigureProfileManagementPage();
context.Services.AddAutoMapperObjectMapper<AbpAccountWebModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAccountWebAutoMapperProfile>(validate: true);
});
context.Services.AddAutoMapperObjectMapper<AbpAccountWebModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAccountWebAutoMapperProfile>(validate: true);
});
Configure<DynamicJavaScriptProxyOptions>(options =>
{
options.DisableModule(AccountRemoteServiceConsts.ModuleName);
});
}
Configure<DynamicJavaScriptProxyOptions>(options =>
{
options.DisableModule(AccountRemoteServiceConsts.ModuleName);
});
}
private void ConfigureProfileManagementPage()
private void ConfigureProfileManagementPage()
{
Configure<RazorPagesOptions>(options =>
{
Configure<RazorPagesOptions>(options =>
{
options.Conventions.AuthorizePage("/Account/Manage");
});
options.Conventions.AuthorizePage("/Account/Manage");
});
Configure<ProfileManagementPageOptions>(options =>
{
options.Contributors.Add(new AccountProfileManagementPageContributor());
});
Configure<ProfileManagementPageOptions>(options =>
{
options.Contributors.Add(new AccountProfileManagementPageContributor());
});
Configure<AbpBundlingOptions>(options =>
{
options.ScriptBundles
.Configure(typeof(ManageModel).FullName,
configuration =>
{
configuration.AddFiles("/client-proxies/account-proxy.js");
configuration.AddFiles("/Pages/Account/Components/ProfileManagementGroup/Password/Default.js");
configuration.AddFiles("/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js");
});
});
Configure<AbpBundlingOptions>(options =>
{
options.ScriptBundles
.Configure(typeof(ManageModel).FullName,
configuration =>
{
configuration.AddFiles("/client-proxies/account-proxy.js");
configuration.AddFiles("/Pages/Account/Components/ProfileManagementGroup/Password/Default.js");
configuration.AddFiles("/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js");
});
});
}
}
}

25
modules/account/src/Volo.Abp.Account.Web/AccountModuleToolbarContributor.cs

@ -4,23 +4,22 @@ using Volo.Abp.Account.Web.Modules.Account.Components.Toolbar.UserLoginLink;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars;
using Volo.Abp.Users;
namespace Volo.Abp.Account.Web
namespace Volo.Abp.Account.Web;
public class AccountModuleToolbarContributor : IToolbarContributor
{
public class AccountModuleToolbarContributor : IToolbarContributor
public virtual Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
{
public virtual Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
if (context.Toolbar.Name != StandardToolbars.Main)
{
if (context.Toolbar.Name != StandardToolbars.Main)
{
return Task.CompletedTask;
}
if (!context.ServiceProvider.GetRequiredService<ICurrentUser>().IsAuthenticated)
{
context.Toolbar.Items.Add(new ToolbarItem(typeof(UserLoginLinkViewComponent)));
}
return Task.CompletedTask;
}
if (!context.ServiceProvider.GetRequiredService<ICurrentUser>().IsAuthenticated)
{
context.Toolbar.Items.Add(new ToolbarItem(typeof(UserLoginLinkViewComponent)));
}
return Task.CompletedTask;
}
}

273
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs

@ -15,174 +15,173 @@ using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
using UserLoginInfo = Volo.Abp.Account.Web.Areas.Account.Controllers.Models.UserLoginInfo;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace Volo.Abp.Account.Web.Areas.Account.Controllers
namespace Volo.Abp.Account.Web.Areas.Account.Controllers;
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Controller]
[ControllerName("Login")]
[Area("account")]
[Route("api/account")]
public class AccountController : AbpControllerBase
{
[RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
[Controller]
[ControllerName("Login")]
[Area("account")]
[Route("api/account")]
public class AccountController : AbpControllerBase
protected SignInManager<IdentityUser> SignInManager { get; }
protected IdentityUserManager UserManager { get; }
protected ISettingProvider SettingProvider { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AccountController(
SignInManager<IdentityUser> signInManager,
IdentityUserManager userManager,
ISettingProvider settingProvider,
IdentitySecurityLogManager identitySecurityLogManager,
IOptions<IdentityOptions> identityOptions)
{
protected SignInManager<IdentityUser> SignInManager { get; }
protected IdentityUserManager UserManager { get; }
protected ISettingProvider SettingProvider { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AccountController(
SignInManager<IdentityUser> signInManager,
IdentityUserManager userManager,
ISettingProvider settingProvider,
IdentitySecurityLogManager identitySecurityLogManager,
IOptions<IdentityOptions> identityOptions)
LocalizationResource = typeof(AccountResource);
SignInManager = signInManager;
UserManager = userManager;
SettingProvider = settingProvider;
IdentitySecurityLogManager = identitySecurityLogManager;
IdentityOptions = identityOptions;
}
[HttpPost]
[Route("login")]
public virtual async Task<AbpLoginResult> Login(UserLoginInfo login)
{
await CheckLocalLoginAsync();
ValidateLoginInfo(login);
await ReplaceEmailToUsernameOfInputIfNeeds(login);
var signInResult = await SignInManager.PasswordSignInAsync(
login.UserNameOrEmailAddress,
login.Password,
login.RememberMe,
true
);
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
LocalizationResource = typeof(AccountResource);
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = signInResult.ToIdentitySecurityLogAction(),
UserName = login.UserNameOrEmailAddress
});
SignInManager = signInManager;
UserManager = userManager;
SettingProvider = settingProvider;
IdentitySecurityLogManager = identitySecurityLogManager;
IdentityOptions = identityOptions;
}
return GetAbpLoginResult(signInResult);
}
[HttpPost]
[Route("login")]
public virtual async Task<AbpLoginResult> Login(UserLoginInfo login)
[HttpGet]
[Route("logout")]
public virtual async Task Logout()
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
await CheckLocalLoginAsync();
ValidateLoginInfo(login);
await ReplaceEmailToUsernameOfInputIfNeeds(login);
var signInResult = await SignInManager.PasswordSignInAsync(
login.UserNameOrEmailAddress,
login.Password,
login.RememberMe,
true
);
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = signInResult.ToIdentitySecurityLogAction(),
UserName = login.UserNameOrEmailAddress
});
return GetAbpLoginResult(signInResult);
}
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
[HttpGet]
[Route("logout")]
public virtual async Task Logout()
await SignInManager.SignOutAsync();
}
[HttpPost]
[Route("checkPassword")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual Task<AbpLoginResult> CheckPasswordCompatible(UserLoginInfo login)
{
return CheckPassword(login);
}
[HttpPost]
[Route("check-password")]
public virtual async Task<AbpLoginResult> CheckPassword(UserLoginInfo login)
{
ValidateLoginInfo(login);
await ReplaceEmailToUsernameOfInputIfNeeds(login);
var identityUser = await UserManager.FindByNameAsync(login.UserNameOrEmailAddress);
if (identityUser == null)
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
}
await SignInManager.SignOutAsync();
await IdentityOptions.SetAsync();
return GetAbpLoginResult(await SignInManager.CheckPasswordSignInAsync(identityUser, login.Password, true));
}
protected virtual async Task ReplaceEmailToUsernameOfInputIfNeeds(UserLoginInfo login)
{
if (!ValidationHelper.IsValidEmailAddress(login.UserNameOrEmailAddress))
{
return;
}
[HttpPost]
[Route("checkPassword")]
[ApiExplorerSettings(IgnoreApi = true)]
public virtual Task<AbpLoginResult> CheckPasswordCompatible(UserLoginInfo login)
var userByUsername = await UserManager.FindByNameAsync(login.UserNameOrEmailAddress);
if (userByUsername != null)
{
return CheckPassword(login);
return;
}
[HttpPost]
[Route("check-password")]
public virtual async Task<AbpLoginResult> CheckPassword(UserLoginInfo login)
var userByEmail = await UserManager.FindByEmailAsync(login.UserNameOrEmailAddress);
if (userByEmail == null)
{
ValidateLoginInfo(login);
return;
}
await ReplaceEmailToUsernameOfInputIfNeeds(login);
login.UserNameOrEmailAddress = userByEmail.UserName;
}
private static AbpLoginResult GetAbpLoginResult(SignInResult result)
{
if (result.IsLockedOut)
{
return new AbpLoginResult(LoginResultType.LockedOut);
}
var identityUser = await UserManager.FindByNameAsync(login.UserNameOrEmailAddress);
if (result.RequiresTwoFactor)
{
return new AbpLoginResult(LoginResultType.RequiresTwoFactor);
}
if (identityUser == null)
{
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
}
if (result.IsNotAllowed)
{
return new AbpLoginResult(LoginResultType.NotAllowed);
}
await IdentityOptions.SetAsync();
return GetAbpLoginResult(await SignInManager.CheckPasswordSignInAsync(identityUser, login.Password, true));
if (!result.Succeeded)
{
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
}
protected virtual async Task ReplaceEmailToUsernameOfInputIfNeeds(UserLoginInfo login)
return new AbpLoginResult(LoginResultType.Success);
}
protected virtual void ValidateLoginInfo(UserLoginInfo login)
{
if (login == null)
{
if (!ValidationHelper.IsValidEmailAddress(login.UserNameOrEmailAddress))
{
return;
}
var userByUsername = await UserManager.FindByNameAsync(login.UserNameOrEmailAddress);
if (userByUsername != null)
{
return;
}
var userByEmail = await UserManager.FindByEmailAsync(login.UserNameOrEmailAddress);
if (userByEmail == null)
{
return;
}
login.UserNameOrEmailAddress = userByEmail.UserName;
throw new ArgumentException(nameof(login));
}
private static AbpLoginResult GetAbpLoginResult(SignInResult result)
if (login.UserNameOrEmailAddress.IsNullOrEmpty())
{
if (result.IsLockedOut)
{
return new AbpLoginResult(LoginResultType.LockedOut);
}
if (result.RequiresTwoFactor)
{
return new AbpLoginResult(LoginResultType.RequiresTwoFactor);
}
if (result.IsNotAllowed)
{
return new AbpLoginResult(LoginResultType.NotAllowed);
}
if (!result.Succeeded)
{
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
}
return new AbpLoginResult(LoginResultType.Success);
throw new ArgumentNullException(nameof(login.UserNameOrEmailAddress));
}
protected virtual void ValidateLoginInfo(UserLoginInfo login)
if (login.Password.IsNullOrEmpty())
{
if (login == null)
{
throw new ArgumentException(nameof(login));
}
if (login.UserNameOrEmailAddress.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(login.UserNameOrEmailAddress));
}
if (login.Password.IsNullOrEmpty())
{
throw new ArgumentNullException(nameof(login.Password));
}
throw new ArgumentNullException(nameof(login.Password));
}
}
protected virtual async Task CheckLocalLoginAsync()
protected virtual async Task CheckLocalLoginAsync()
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
{
throw new UserFriendlyException(L["LocalLoginDisabledMessage"]);
}
throw new UserFriendlyException(L["LocalLoginDisabledMessage"]);
}
}
}

19
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/AbpLoginResult.cs

@ -1,14 +1,13 @@
namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models
namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
public class AbpLoginResult
{
public class AbpLoginResult
public AbpLoginResult(LoginResultType result)
{
public AbpLoginResult(LoginResultType result)
{
Result = result;
}
Result = result;
}
public LoginResultType Result { get; }
public LoginResultType Result { get; }
public string Description => Result.ToString();
}
}
public string Description => Result.ToString();
}

19
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/LoginResultType.cs

@ -1,15 +1,14 @@
namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models
namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
public enum LoginResultType : byte
{
public enum LoginResultType : byte
{
Success = 1,
Success = 1,
InvalidUserNameOrPassword = 2,
InvalidUserNameOrPassword = 2,
NotAllowed = 3,
NotAllowed = 3,
LockedOut = 4,
LockedOut = 4,
RequiresTwoFactor = 5
}
}
RequiresTwoFactor = 5
}

25
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/UserLoginInfo.cs

@ -2,20 +2,19 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models
namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
public class UserLoginInfo
{
public class UserLoginInfo
{
[Required]
[StringLength(255)]
public string UserNameOrEmailAddress { get; set; }
[Required]
[StringLength(255)]
public string UserNameOrEmailAddress { get; set; }
[Required]
[StringLength(32)]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
[Required]
[StringLength(32)]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
public bool RememberMe { get; set; }
}

11
modules/account/src/Volo.Abp.Account.Web/Modules/Account/Components/Toolbar/UserLoginLink/UserLoginLinkViewComponent.cs

@ -1,13 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace Volo.Abp.Account.Web.Modules.Account.Components.Toolbar.UserLoginLink
namespace Volo.Abp.Account.Web.Modules.Account.Components.Toolbar.UserLoginLink;
public class UserLoginLinkViewComponent : AbpViewComponent
{
public class UserLoginLinkViewComponent : AbpViewComponent
public virtual IViewComponentResult Invoke()
{
public virtual IViewComponentResult Invoke()
{
return View("~/Modules/Account/Components/Toolbar/UserLoginLink/Default.cshtml");
}
return View("~/Modules/Account/Components/Toolbar/UserLoginLink/Default.cshtml");
}
}

29
modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccessDenied.cshtml.cs

@ -1,24 +1,23 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class AccessDeniedModel : AccountPageModel
{
public class AccessDeniedModel : AccountPageModel
{
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
}

65
modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs

@ -10,49 +10,48 @@ using Volo.Abp.ExceptionHandling;
using Volo.Abp.Identity;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public abstract class AccountPageModel : AbpPageModel
{
public abstract class AccountPageModel : AbpPageModel
public IAccountAppService AccountAppService { get; set; }
public SignInManager<IdentityUser> SignInManager { get; set; }
public IdentityUserManager UserManager { get; set; }
public IdentitySecurityLogManager IdentitySecurityLogManager { get; set; }
public IOptions<IdentityOptions> IdentityOptions { get; set; }
public IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; set; }
protected AccountPageModel()
{
public IAccountAppService AccountAppService { get; set; }
public SignInManager<IdentityUser> SignInManager { get; set; }
public IdentityUserManager UserManager { get; set; }
public IdentitySecurityLogManager IdentitySecurityLogManager { get; set; }
public IOptions<IdentityOptions> IdentityOptions { get; set; }
public IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; set; }
protected AccountPageModel()
{
LocalizationResourceType = typeof(AccountResource);
ObjectMapperContext = typeof(AbpAccountWebModule);
}
LocalizationResourceType = typeof(AccountResource);
ObjectMapperContext = typeof(AbpAccountWebModule);
}
protected virtual void CheckCurrentTenant(Guid? tenantId)
protected virtual void CheckCurrentTenant(Guid? tenantId)
{
if (CurrentTenant.Id != tenantId)
{
if (CurrentTenant.Id != tenantId)
{
throw new ApplicationException($"Current tenant is different than given tenant. CurrentTenant.Id: {CurrentTenant.Id}, given tenantId: {tenantId}");
}
throw new ApplicationException($"Current tenant is different than given tenant. CurrentTenant.Id: {CurrentTenant.Id}, given tenantId: {tenantId}");
}
}
protected virtual void CheckIdentityErrors(IdentityResult identityResult)
protected virtual void CheckIdentityErrors(IdentityResult identityResult)
{
if (!identityResult.Succeeded)
{
if (!identityResult.Succeeded)
{
throw new UserFriendlyException("Operation failed: " + identityResult.Errors.Select(e => $"[{e.Code}] {e.Description}").JoinAsString(", "));
}
//identityResult.CheckErrors(LocalizationManager); //TODO: Get from old Abp
throw new UserFriendlyException("Operation failed: " + identityResult.Errors.Select(e => $"[{e.Code}] {e.Description}").JoinAsString(", "));
}
protected virtual string GetLocalizeExceptionMessage(Exception exception)
{
if (exception is ILocalizeErrorMessage || exception is IHasErrorCode)
{
return ExceptionToErrorInfoConverter.Convert(exception, false).Message;
}
//identityResult.CheckErrors(LocalizationManager); //TODO: Get from old Abp
}
return exception.Message;
protected virtual string GetLocalizeExceptionMessage(Exception exception)
{
if (exception is ILocalizeErrorMessage || exception is IHasErrorCode)
{
return ExceptionToErrorInfoConverter.Convert(exception, false).Message;
}
return exception.Message;
}
}

83
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/Password/AccountProfilePasswordManagementGroupViewComponent.cs

@ -7,54 +7,53 @@ using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.Password
namespace Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.Password;
public class AccountProfilePasswordManagementGroupViewComponent : AbpViewComponent
{
public class AccountProfilePasswordManagementGroupViewComponent : AbpViewComponent
protected IProfileAppService ProfileAppService { get; }
public AccountProfilePasswordManagementGroupViewComponent(
IProfileAppService profileAppService)
{
protected IProfileAppService ProfileAppService { get; }
ProfileAppService = profileAppService;
}
public AccountProfilePasswordManagementGroupViewComponent(
IProfileAppService profileAppService)
{
ProfileAppService = profileAppService;
}
public virtual async Task<IViewComponentResult> InvokeAsync()
{
var user = await ProfileAppService.GetAsync();
public virtual async Task<IViewComponentResult> InvokeAsync()
var model = new ChangePasswordInfoModel
{
var user = await ProfileAppService.GetAsync();
HideOldPasswordInput = !user.HasPassword
};
var model = new ChangePasswordInfoModel
{
HideOldPasswordInput = !user.HasPassword
};
return View("~/Pages/Account/Components/ProfileManagementGroup/Password/Default.cshtml", model);
}
return View("~/Pages/Account/Components/ProfileManagementGroup/Password/Default.cshtml", model);
}
public class ChangePasswordInfoModel
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[Display(Name = "DisplayName:CurrentPassword")]
[DataType(DataType.Password)]
[DisableAuditing]
public string CurrentPassword { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[Display(Name = "DisplayName:NewPassword")]
[DataType(DataType.Password)]
[DisableAuditing]
public string NewPassword { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[Display(Name = "DisplayName:NewPasswordConfirm")]
[DataType(DataType.Password)]
[DisableAuditing]
public string NewPasswordConfirm { get; set; }
public bool HideOldPasswordInput { get; set; }
}
public class ChangePasswordInfoModel
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[Display(Name = "DisplayName:CurrentPassword")]
[DataType(DataType.Password)]
[DisableAuditing]
public string CurrentPassword { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[Display(Name = "DisplayName:NewPassword")]
[DataType(DataType.Password)]
[DisableAuditing]
public string NewPassword { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[Display(Name = "DisplayName:NewPasswordConfirm")]
[DataType(DataType.Password)]
[DisableAuditing]
public string NewPasswordConfirm { get; set; }
public bool HideOldPasswordInput { get; set; }
}
}

85
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/AccountProfilePersonalInfoManagementGroupViewComponent.cs

@ -7,55 +7,54 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo
{
public class AccountProfilePersonalInfoManagementGroupViewComponent : AbpViewComponent
{
protected IProfileAppService ProfileAppService { get; }
public AccountProfilePersonalInfoManagementGroupViewComponent(
IProfileAppService profileAppService)
{
ProfileAppService = profileAppService;
ObjectMapperContext = typeof(AbpAccountWebModule);
}
public virtual async Task<IViewComponentResult> InvokeAsync()
{
var user = await ProfileAppService.GetAsync();
var model = ObjectMapper.Map<ProfileDto, PersonalInfoModel>(user);
namespace Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo;
return View("~/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml", model);
}
public class AccountProfilePersonalInfoManagementGroupViewComponent : AbpViewComponent
{
protected IProfileAppService ProfileAppService { get; }
public class PersonalInfoModel : IHasConcurrencyStamp
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
[Display(Name = "DisplayName:UserName")]
public string UserName { get; set; }
public AccountProfilePersonalInfoManagementGroupViewComponent(
IProfileAppService profileAppService)
{
ProfileAppService = profileAppService;
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
[Display(Name = "DisplayName:Email")]
public string Email { get; set; }
ObjectMapperContext = typeof(AbpAccountWebModule);
}
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxNameLength))]
[Display(Name = "DisplayName:Name")]
public string Name { get; set; }
public virtual async Task<IViewComponentResult> InvokeAsync()
{
var user = await ProfileAppService.GetAsync();
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxSurnameLength))]
[Display(Name = "DisplayName:Surname")]
public string Surname { get; set; }
var model = ObjectMapper.Map<ProfileDto, PersonalInfoModel>(user);
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
[Display(Name = "DisplayName:PhoneNumber")]
public string PhoneNumber { get; set; }
return View("~/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml", model);
}
[HiddenInput]
public string ConcurrencyStamp { get; set; }
}
public class PersonalInfoModel : IHasConcurrencyStamp
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
[Display(Name = "DisplayName:UserName")]
public string UserName { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
[Display(Name = "DisplayName:Email")]
public string Email { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxNameLength))]
[Display(Name = "DisplayName:Name")]
public string Name { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxSurnameLength))]
[Display(Name = "DisplayName:Surname")]
public string Surname { get; set; }
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPhoneNumberLength))]
[Display(Name = "DisplayName:PhoneNumber")]
public string PhoneNumber { get; set; }
[HiddenInput]
public string ConcurrencyStamp { get; set; }
}
}

86
modules/account/src/Volo.Abp.Account.Web/Pages/Account/ForgotPassword.cshtml.cs

@ -4,57 +4,55 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class ForgotPasswordModel : AccountPageModel
{
public class ForgotPasswordModel : AccountPageModel
{
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
[BindProperty]
public string Email { get; set; }
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
[BindProperty]
public string Email { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual async Task<IActionResult> OnPostAsync()
public virtual async Task<IActionResult> OnPostAsync()
{
try
{
try
{
await AccountAppService.SendPasswordResetCodeAsync(
new SendPasswordResetCodeDto
{
Email = Email,
AppName = "MVC", //TODO: Const!
ReturnUrl = ReturnUrl,
ReturnUrlHash = ReturnUrlHash
}
);
}
catch (UserFriendlyException e)
{
Alerts.Danger(GetLocalizeExceptionMessage(e));
return Page();
}
return RedirectToPage(
"./PasswordResetLinkSent",
new
await AccountAppService.SendPasswordResetCodeAsync(
new SendPasswordResetCodeDto
{
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
Email = Email,
AppName = "MVC", //TODO: Const!
ReturnUrl = ReturnUrl,
ReturnUrlHash = ReturnUrlHash
}
);
}
catch (UserFriendlyException e)
{
Alerts.Danger(GetLocalizeExceptionMessage(e));
return Page();
}
return RedirectToPage(
"./PasswordResetLinkSent",
new {
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
}
}

39
modules/account/src/Volo.Abp.Account.Web/Pages/Account/LoggedOut.cshtml.cs

@ -1,30 +1,29 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class LoggedOutModel : AccountPageModel
{
public class LoggedOutModel : AccountPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ClientName { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ClientName { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string SignOutIframeUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string SignOutIframeUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string PostLogoutRedirectUri { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string PostLogoutRedirectUri { get; set; }
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
}

464
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs

@ -20,317 +20,315 @@ using Volo.Abp.Validation;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
namespace Volo.Abp.Account.Web.Pages.Account
{
public class LoginModel : AccountPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
namespace Volo.Abp.Account.Web.Pages.Account;
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty]
public LoginInputModel LoginInput { get; set; }
public class LoginModel : AccountPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
public bool EnableLocalLogin { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
//TODO: Why there is an ExternalProviders if only the VisibleExternalProviders is used.
public IEnumerable<ExternalProviderModel> ExternalProviders { get; set; }
public IEnumerable<ExternalProviderModel> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));
[BindProperty]
public LoginInputModel LoginInput { get; set; }
public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;
public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;
public bool EnableLocalLogin { get; set; }
//Optional IdentityServer services
//public IIdentityServerInteractionService Interaction { get; set; }
//public IClientStore ClientStore { get; set; }
//public IEventService IdentityServerEvents { get; set; }
//TODO: Why there is an ExternalProviders if only the VisibleExternalProviders is used.
public IEnumerable<ExternalProviderModel> ExternalProviders { get; set; }
public IEnumerable<ExternalProviderModel> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));
protected IAuthenticationSchemeProvider SchemeProvider { get; }
protected AbpAccountOptions AccountOptions { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;
public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;
public bool ShowCancelButton { get; set; }
//Optional IdentityServer services
//public IIdentityServerInteractionService Interaction { get; set; }
//public IClientStore ClientStore { get; set; }
//public IEventService IdentityServerEvents { get; set; }
public LoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IOptions<IdentityOptions> identityOptions)
{
SchemeProvider = schemeProvider;
IdentityOptions = identityOptions;
AccountOptions = accountOptions.Value;
}
protected IAuthenticationSchemeProvider SchemeProvider { get; }
protected AbpAccountOptions AccountOptions { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public virtual async Task<IActionResult> OnGetAsync()
{
LoginInput = new LoginInputModel();
public bool ShowCancelButton { get; set; }
ExternalProviders = await GetExternalProviders();
public LoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IOptions<IdentityOptions> identityOptions)
{
SchemeProvider = schemeProvider;
IdentityOptions = identityOptions;
AccountOptions = accountOptions.Value;
}
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
public virtual async Task<IActionResult> OnGetAsync()
{
LoginInput = new LoginInputModel();
if (IsExternalLoginOnly)
{
//return await ExternalLogin(vm.ExternalLoginScheme, returnUrl);
throw new NotImplementedException();
}
ExternalProviders = await GetExternalProviders();
return Page();
}
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
public virtual async Task<IActionResult> OnPostAsync(string action)
if (IsExternalLoginOnly)
{
await CheckLocalLoginAsync();
ValidateModel();
ExternalProviders = await GetExternalProviders();
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
await ReplaceEmailToUsernameOfInputIfNeeds();
//return await ExternalLogin(vm.ExternalLoginScheme, returnUrl);
throw new NotImplementedException();
}
await IdentityOptions.SetAsync();
return Page();
}
var result = await SignInManager.PasswordSignInAsync(
LoginInput.UserNameOrEmailAddress,
LoginInput.Password,
LoginInput.RememberMe,
true
);
public virtual async Task<IActionResult> OnPostAsync(string action)
{
await CheckLocalLoginAsync();
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress
});
ValidateModel();
if (result.RequiresTwoFactor)
{
return await TwoFactorLoginResultAsync();
}
ExternalProviders = await GetExternalProviders();
if (result.IsLockedOut)
{
Alerts.Warning(L["UserLockedOutMessage"]);
return Page();
}
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
if (result.IsNotAllowed)
{
Alerts.Warning(L["LoginIsNotAllowed"]);
return Page();
}
await ReplaceEmailToUsernameOfInputIfNeeds();
if (!result.Succeeded)
{
Alerts.Danger(L["InvalidUserNameOrPassword"]);
return Page();
}
await IdentityOptions.SetAsync();
//TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
var result = await SignInManager.PasswordSignInAsync(
LoginInput.UserNameOrEmailAddress,
LoginInput.Password,
LoginInput.RememberMe,
true
);
Debug.Assert(user != null, nameof(user) + " != null");
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress
});
return RedirectSafely(ReturnUrl, ReturnUrlHash);
if (result.RequiresTwoFactor)
{
return await TwoFactorLoginResultAsync();
}
/// <summary>
/// Override this method to add 2FA for your application.
/// </summary>
protected virtual Task<IActionResult> TwoFactorLoginResultAsync()
if (result.IsLockedOut)
{
throw new NotImplementedException();
Alerts.Warning(L["UserLockedOutMessage"]);
return Page();
}
protected virtual async Task<List<ExternalProviderModel>> GetExternalProviders()
if (result.IsNotAllowed)
{
var schemes = await SchemeProvider.GetAllSchemesAsync();
return schemes
.Where(x => x.DisplayName != null || x.Name.Equals(AccountOptions.WindowsAuthenticationSchemeName, StringComparison.OrdinalIgnoreCase))
.Select(x => new ExternalProviderModel
{
DisplayName = x.DisplayName,
AuthenticationScheme = x.Name
})
.ToList();
Alerts.Warning(L["LoginIsNotAllowed"]);
return Page();
}
public virtual async Task<IActionResult> OnPostExternalLogin(string provider)
if (!result.Succeeded)
{
var redirectUrl = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash });
var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
properties.Items["scheme"] = provider;
return await Task.FromResult(Challenge(properties, provider));
Alerts.Danger(L["InvalidUserNameOrPassword"]);
return Page();
}
public virtual async Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null)
{
//TODO: Did not implemented Identity Server 4 sample for this method (see ExternalLoginCallback in Quickstart of IDS4 sample)
/* Also did not implement these:
* - Logout(string logoutId)
*/
//TODO: Find a way of getting user's id from the logged in user and do not query it again like that!
var user = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress) ??
await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
if (remoteError != null)
{
Logger.LogWarning($"External login callback error: {remoteError}");
return RedirectToPage("./Login");
}
Debug.Assert(user != null, nameof(user) + " != null");
await IdentityOptions.SetAsync();
return RedirectSafely(ReturnUrl, ReturnUrlHash);
}
var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
Logger.LogWarning("External login info is not available");
return RedirectToPage("./Login");
}
/// <summary>
/// Override this method to add 2FA for your application.
/// </summary>
protected virtual Task<IActionResult> TwoFactorLoginResultAsync()
{
throw new NotImplementedException();
}
var result = await SignInManager.ExternalLoginSignInAsync(
loginInfo.LoginProvider,
loginInfo.ProviderKey,
isPersistent: false,
bypassTwoFactor: true
);
protected virtual async Task<List<ExternalProviderModel>> GetExternalProviders()
{
var schemes = await SchemeProvider.GetAllSchemesAsync();
if (!result.Succeeded)
return schemes
.Where(x => x.DisplayName != null || x.Name.Equals(AccountOptions.WindowsAuthenticationSchemeName, StringComparison.OrdinalIgnoreCase))
.Select(x => new ExternalProviderModel
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = "Login" + result
});
}
DisplayName = x.DisplayName,
AuthenticationScheme = x.Name
})
.ToList();
}
if (result.IsLockedOut)
{
Logger.LogWarning($"External login callback error: user is locked out!");
throw new UserFriendlyException("Cannot proceed because user is locked out!");
}
public virtual async Task<IActionResult> OnPostExternalLogin(string provider)
{
var redirectUrl = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash });
var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
properties.Items["scheme"] = provider;
if (result.IsNotAllowed)
{
Logger.LogWarning($"External login callback error: user is not allowed!");
throw new UserFriendlyException("Cannot proceed because user is not allowed!");
}
return await Task.FromResult(Challenge(properties, provider));
}
if (result.Succeeded)
{
return RedirectSafely(returnUrl, returnUrlHash);
}
public virtual async Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null)
{
//TODO: Did not implemented Identity Server 4 sample for this method (see ExternalLoginCallback in Quickstart of IDS4 sample)
/* Also did not implement these:
* - Logout(string logoutId)
*/
//TODO: Handle other cases for result!
if (remoteError != null)
{
Logger.LogWarning($"External login callback error: {remoteError}");
return RedirectToPage("./Login");
}
var email = loginInfo.Principal.FindFirstValue(AbpClaimTypes.Email);
if (email.IsNullOrWhiteSpace())
{
return RedirectToPage("./Register", new
{
IsExternalLogin = true,
ExternalLoginAuthSchema = loginInfo.LoginProvider,
ReturnUrl = returnUrl
});
}
await IdentityOptions.SetAsync();
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
user = await CreateExternalUserAsync(loginInfo);
}
else
{
if (await UserManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey) == null)
{
CheckIdentityErrors(await UserManager.AddLoginAsync(user, loginInfo));
}
}
var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
Logger.LogWarning("External login info is not available");
return RedirectToPage("./Login");
}
await SignInManager.SignInAsync(user, false);
var result = await SignInManager.ExternalLoginSignInAsync(
loginInfo.LoginProvider,
loginInfo.ProviderKey,
isPersistent: false,
bypassTwoFactor: true
);
if (!result.Succeeded)
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),
UserName = user.Name
Action = "Login" + result
});
return RedirectSafely(returnUrl, returnUrlHash);
}
protected virtual async Task<IdentityUser> CreateExternalUserAsync(ExternalLoginInfo info)
if (result.IsLockedOut)
{
await IdentityOptions.SetAsync();
Logger.LogWarning($"External login callback error: user is locked out!");
throw new UserFriendlyException("Cannot proceed because user is locked out!");
}
var emailAddress = info.Principal.FindFirstValue(AbpClaimTypes.Email);
if (result.IsNotAllowed)
{
Logger.LogWarning($"External login callback error: user is not allowed!");
throw new UserFriendlyException("Cannot proceed because user is not allowed!");
}
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
if (result.Succeeded)
{
return RedirectSafely(returnUrl, returnUrlHash);
}
CheckIdentityErrors(await UserManager.CreateAsync(user));
CheckIdentityErrors(await UserManager.SetEmailAsync(user, emailAddress));
CheckIdentityErrors(await UserManager.AddLoginAsync(user, info));
CheckIdentityErrors(await UserManager.AddDefaultRolesAsync(user));
//TODO: Handle other cases for result!
return user;
var email = loginInfo.Principal.FindFirstValue(AbpClaimTypes.Email);
if (email.IsNullOrWhiteSpace())
{
return RedirectToPage("./Register", new {
IsExternalLogin = true,
ExternalLoginAuthSchema = loginInfo.LoginProvider,
ReturnUrl = returnUrl
});
}
protected virtual async Task ReplaceEmailToUsernameOfInputIfNeeds()
var user = await UserManager.FindByEmailAsync(email);
if (user == null)
{
user = await CreateExternalUserAsync(loginInfo);
}
else
{
if (!ValidationHelper.IsValidEmailAddress(LoginInput.UserNameOrEmailAddress))
if (await UserManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey) == null)
{
return;
CheckIdentityErrors(await UserManager.AddLoginAsync(user, loginInfo));
}
}
var userByUsername = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress);
if (userByUsername != null)
{
return;
}
await SignInManager.SignInAsync(user, false);
var userByEmail = await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
if (userByEmail == null)
{
return;
}
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),
UserName = user.Name
});
LoginInput.UserNameOrEmailAddress = userByEmail.UserName;
}
return RedirectSafely(returnUrl, returnUrlHash);
}
protected virtual async Task<IdentityUser> CreateExternalUserAsync(ExternalLoginInfo info)
{
await IdentityOptions.SetAsync();
var emailAddress = info.Principal.FindFirstValue(AbpClaimTypes.Email);
protected virtual async Task CheckLocalLoginAsync()
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
CheckIdentityErrors(await UserManager.CreateAsync(user));
CheckIdentityErrors(await UserManager.SetEmailAsync(user, emailAddress));
CheckIdentityErrors(await UserManager.AddLoginAsync(user, info));
CheckIdentityErrors(await UserManager.AddDefaultRolesAsync(user));
return user;
}
protected virtual async Task ReplaceEmailToUsernameOfInputIfNeeds()
{
if (!ValidationHelper.IsValidEmailAddress(LoginInput.UserNameOrEmailAddress))
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
{
throw new UserFriendlyException(L["LocalLoginDisabledMessage"]);
}
return;
}
public class LoginInputModel
var userByUsername = await UserManager.FindByNameAsync(LoginInput.UserNameOrEmailAddress);
if (userByUsername != null)
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string UserNameOrEmailAddress { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
return;
}
public bool RememberMe { get; set; }
var userByEmail = await UserManager.FindByEmailAsync(LoginInput.UserNameOrEmailAddress);
if (userByEmail == null)
{
return;
}
public class ExternalProviderModel
LoginInput.UserNameOrEmailAddress = userByEmail.UserName;
}
protected virtual async Task CheckLocalLoginAsync()
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
{
public string DisplayName { get; set; }
public string AuthenticationScheme { get; set; }
throw new UserFriendlyException(L["LocalLoginDisabledMessage"]);
}
}
public class LoginInputModel
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string UserNameOrEmailAddress { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
public class ExternalProviderModel
{
public string DisplayName { get; set; }
public string AuthenticationScheme { get; set; }
}
}

51
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs

@ -2,38 +2,37 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class LogoutModel : AccountPageModel
{
public class LogoutModel : AccountPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public virtual async Task<IActionResult> OnGetAsync()
public virtual async Task<IActionResult> OnGetAsync()
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
if (ReturnUrl != null)
{
return RedirectSafely(ReturnUrl, ReturnUrlHash);
}
return RedirectToPage("/Account/Login");
}
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
public virtual Task<IActionResult> OnPostAsync()
await SignInManager.SignOutAsync();
if (ReturnUrl != null)
{
return Task.FromResult<IActionResult>(Page());
return RedirectSafely(ReturnUrl, ReturnUrlHash);
}
return RedirectToPage("/Account/Login");
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
}

49
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Manage.cshtml.cs

@ -6,38 +6,37 @@ using Microsoft.Extensions.Options;
using Volo.Abp.Account.Web.ProfileManagement;
using Volo.Abp.Validation;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class ManageModel : AccountPageModel
{
public class ManageModel : AccountPageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
public ProfileManagementPageCreationContext ProfileManagementPageCreationContext { get; private set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
protected ProfileManagementPageOptions Options { get; }
public ProfileManagementPageCreationContext ProfileManagementPageCreationContext { get; private set; }
public ManageModel(IOptions<ProfileManagementPageOptions> options)
{
Options = options.Value;
}
protected ProfileManagementPageOptions Options { get; }
public virtual async Task<IActionResult> OnGetAsync()
{
ProfileManagementPageCreationContext = new ProfileManagementPageCreationContext(ServiceProvider);
foreach (var contributor in Options.Contributors)
{
await contributor.ConfigureAsync(ProfileManagementPageCreationContext);
}
public ManageModel(IOptions<ProfileManagementPageOptions> options)
{
Options = options.Value;
}
return Page();
}
public virtual async Task<IActionResult> OnGetAsync()
{
ProfileManagementPageCreationContext = new ProfileManagementPageCreationContext(ServiceProvider);
public virtual Task<IActionResult> OnPostAsync()
foreach (var contributor in Options.Contributors)
{
return Task.FromResult<IActionResult>(Page());
await contributor.ConfigureAsync(ProfileManagementPageCreationContext);
}
return Page();
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
}

29
modules/account/src/Volo.Abp.Account.Web/Pages/Account/PasswordResetLinkSent.cshtml.cs

@ -1,24 +1,23 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class PasswordResetLinkSentModel : AccountPageModel
{
public class PasswordResetLinkSentModel : AccountPageModel
{
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnPostAsync()
{
return Task.FromResult<IActionResult>(Page());
}
}

239
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs

@ -13,165 +13,164 @@ using Volo.Abp.Settings;
using Volo.Abp.Validation;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
public class RegisterModel : AccountPageModel
{
public class RegisterModel : AccountPageModel
{
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty]
public PostInput Input { get; set; }
[BindProperty]
public PostInput Input { get; set; }
[BindProperty(SupportsGet = true)]
public bool IsExternalLogin { get; set; }
[BindProperty(SupportsGet = true)]
public bool IsExternalLogin { get; set; }
[BindProperty(SupportsGet = true)]
public string ExternalLoginAuthSchema { get; set; }
[BindProperty(SupportsGet = true)]
public string ExternalLoginAuthSchema { get; set; }
public RegisterModel(IAccountAppService accountAppService)
{
AccountAppService = accountAppService;
}
public RegisterModel(IAccountAppService accountAppService)
{
AccountAppService = accountAppService;
}
public virtual async Task<IActionResult> OnGetAsync()
{
await CheckSelfRegistrationAsync();
await TrySetEmailAsync();
return Page();
}
public virtual async Task<IActionResult> OnGetAsync()
{
await CheckSelfRegistrationAsync();
await TrySetEmailAsync();
return Page();
}
private async Task TrySetEmailAsync()
private async Task TrySetEmailAsync()
{
if (IsExternalLogin)
{
if (IsExternalLogin)
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (externalLoginInfo == null)
{
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (externalLoginInfo == null)
{
return;
}
if (!externalLoginInfo.Principal.Identities.Any())
{
return;
}
return;
}
var identity = externalLoginInfo.Principal.Identities.First();
var emailClaim = identity.FindFirst(ClaimTypes.Email);
if (!externalLoginInfo.Principal.Identities.Any())
{
return;
}
if (emailClaim == null)
{
return;
}
var identity = externalLoginInfo.Principal.Identities.First();
var emailClaim = identity.FindFirst(ClaimTypes.Email);
Input = new PostInput {EmailAddress = emailClaim.Value};
if (emailClaim == null)
{
return;
}
Input = new PostInput { EmailAddress = emailClaim.Value };
}
}
public virtual async Task<IActionResult> OnPostAsync()
public virtual async Task<IActionResult> OnPostAsync()
{
try
{
try
{
await CheckSelfRegistrationAsync();
await CheckSelfRegistrationAsync();
if (IsExternalLogin)
{
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (externalLoginInfo == null)
{
Logger.LogWarning("External login info is not available");
return RedirectToPage("./Login");
}
await RegisterExternalUserAsync(externalLoginInfo, Input.EmailAddress);
}
else
if (IsExternalLogin)
{
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (externalLoginInfo == null)
{
await RegisterLocalUserAsync();
Logger.LogWarning("External login info is not available");
return RedirectToPage("./Login");
}
return Redirect(ReturnUrl ?? "~/"); //TODO: How to ensure safety? IdentityServer requires it however it should be checked somehow!
await RegisterExternalUserAsync(externalLoginInfo, Input.EmailAddress);
}
catch (BusinessException e)
else
{
Alerts.Danger(GetLocalizeExceptionMessage(e));
return Page();
await RegisterLocalUserAsync();
}
}
protected virtual async Task RegisterLocalUserAsync()
return Redirect(ReturnUrl ?? "~/"); //TODO: How to ensure safety? IdentityServer requires it however it should be checked somehow!
}
catch (BusinessException e)
{
ValidateModel();
var userDto = await AccountAppService.RegisterAsync(
new RegisterDto
{
AppName = "MVC",
EmailAddress = Input.EmailAddress,
Password = Input.Password,
UserName = Input.UserName
}
);
var user = await UserManager.GetByIdAsync(userDto.Id);
await SignInManager.SignInAsync(user, isPersistent: true);
Alerts.Danger(GetLocalizeExceptionMessage(e));
return Page();
}
}
protected virtual async Task RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string emailAddress)
{
await IdentityOptions.SetAsync();
protected virtual async Task RegisterLocalUserAsync()
{
ValidateModel();
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
var userDto = await AccountAppService.RegisterAsync(
new RegisterDto
{
AppName = "MVC",
EmailAddress = Input.EmailAddress,
Password = Input.Password,
UserName = Input.UserName
}
);
var user = await UserManager.GetByIdAsync(userDto.Id);
await SignInManager.SignInAsync(user, isPersistent: true);
}
(await UserManager.CreateAsync(user)).CheckErrors();
(await UserManager.AddDefaultRolesAsync(user)).CheckErrors();
protected virtual async Task RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string emailAddress)
{
await IdentityOptions.SetAsync();
var userLoginAlreadyExists = user.Logins.Any(x =>
x.TenantId == user.TenantId &&
x.LoginProvider == externalLoginInfo.LoginProvider &&
x.ProviderKey == externalLoginInfo.ProviderKey);
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
if (!userLoginAlreadyExists)
{
(await UserManager.AddLoginAsync(user, new UserLoginInfo(
externalLoginInfo.LoginProvider,
externalLoginInfo.ProviderKey,
externalLoginInfo.ProviderDisplayName
))).CheckErrors();
}
(await UserManager.CreateAsync(user)).CheckErrors();
(await UserManager.AddDefaultRolesAsync(user)).CheckErrors();
await SignInManager.SignInAsync(user, isPersistent: true);
}
var userLoginAlreadyExists = user.Logins.Any(x =>
x.TenantId == user.TenantId &&
x.LoginProvider == externalLoginInfo.LoginProvider &&
x.ProviderKey == externalLoginInfo.ProviderKey);
protected virtual async Task CheckSelfRegistrationAsync()
if (!userLoginAlreadyExists)
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled) ||
!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
{
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
}
(await UserManager.AddLoginAsync(user, new UserLoginInfo(
externalLoginInfo.LoginProvider,
externalLoginInfo.ProviderKey,
externalLoginInfo.ProviderDisplayName
))).CheckErrors();
}
public class PostInput
await SignInManager.SignInAsync(user, isPersistent: true);
}
protected virtual async Task CheckSelfRegistrationAsync()
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled) ||
!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
public string UserName { get; set; }
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string EmailAddress { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
}
}
public class PostInput
{
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))]
public string UserName { get; set; }
[Required]
[EmailAddress]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))]
public string EmailAddress { get; set; }
[Required]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DataType(DataType.Password)]
[DisableAuditing]
public string Password { get; set; }
}
}

138
modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPassword.cshtml.cs

@ -6,95 +6,93 @@ using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
//TODO: Implement live password complexity check on the razor view!
public class ResetPasswordModel : AccountPageModel
{
//TODO: Implement live password complexity check on the razor view!
public class ResetPasswordModel : AccountPageModel
{
[Required]
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid UserId { get; set; }
[Required]
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid UserId { get; set; }
[Required]
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ResetToken { get; set; }
[Required]
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ResetToken { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[Required]
[BindProperty]
[DataType(DataType.Password)]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DisableAuditing]
public string Password { get; set; }
[Required]
[BindProperty]
[DataType(DataType.Password)]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DisableAuditing]
public string Password { get; set; }
[Required]
[BindProperty]
[DataType(DataType.Password)]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DisableAuditing]
public string ConfirmPassword { get; set; }
[Required]
[BindProperty]
[DataType(DataType.Password)]
[DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxPasswordLength))]
[DisableAuditing]
public string ConfirmPassword { get; set; }
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual Task<IActionResult> OnGetAsync()
{
return Task.FromResult<IActionResult>(Page());
}
public virtual async Task<IActionResult> OnPostAsync()
public virtual async Task<IActionResult> OnPostAsync()
{
try
{
try
{
ValidateModel();
ValidateModel();
await AccountAppService.ResetPasswordAsync(
new ResetPasswordDto
{
UserId = UserId,
ResetToken = ResetToken,
Password = Password
}
);
}
catch (AbpIdentityResultException e)
{
if (!string.IsNullOrWhiteSpace(e.Message))
await AccountAppService.ResetPasswordAsync(
new ResetPasswordDto
{
Alerts.Warning(GetLocalizeExceptionMessage(e));
return Page();
UserId = UserId,
ResetToken = ResetToken,
Password = Password
}
throw;
}
catch (AbpValidationException e)
);
}
catch (AbpIdentityResultException e)
{
if (!string.IsNullOrWhiteSpace(e.Message))
{
Alerts.Warning(GetLocalizeExceptionMessage(e));
return Page();
}
//TODO: Try to automatically login!
return RedirectToPage("./ResetPasswordConfirmation", new
{
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
throw;
}
protected override void ValidateModel()
catch (AbpValidationException e)
{
if (!Equals(Password, ConfirmPassword))
{
ModelState.AddModelError("ConfirmPassword",
L["'{0}' and '{1}' do not match.", "ConfirmPassword", "Password"]);
}
return Page();
}
//TODO: Try to automatically login!
return RedirectToPage("./ResetPasswordConfirmation", new {
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
}
base.ValidateModel();
protected override void ValidateModel()
{
if (!Equals(Password, ConfirmPassword))
{
ModelState.AddModelError("ConfirmPassword",
L["'{0}' and '{1}' do not match.", "ConfirmPassword", "Password"]);
}
base.ValidateModel();
}
}

25
modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPasswordConfirmation.cshtml.cs

@ -3,22 +3,21 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.Account.Web.Pages.Account
namespace Volo.Abp.Account.Web.Pages.Account;
[AllowAnonymous]
public class ResetPasswordConfirmationModel : AccountPageModel
{
[AllowAnonymous]
public class ResetPasswordConfirmationModel : AccountPageModel
{
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public virtual Task<IActionResult> OnGetAsync()
{
ReturnUrl = GetRedirectUrl(ReturnUrl, ReturnUrlHash);
public virtual Task<IActionResult> OnGetAsync()
{
ReturnUrl = GetRedirectUrl(ReturnUrl, ReturnUrlHash);
return Task.FromResult<IActionResult>(Page());
}
return Task.FromResult<IActionResult>(Page());
}
}

51
modules/account/src/Volo.Abp.Account.Web/ProfileManagement/AccountProfileManagementPageContributor.cs

@ -7,42 +7,41 @@ using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.Perso
using Volo.Abp.Identity;
using Volo.Abp.Users;
namespace Volo.Abp.Account.Web.ProfileManagement
namespace Volo.Abp.Account.Web.ProfileManagement;
public class AccountProfileManagementPageContributor : IProfileManagementPageContributor
{
public class AccountProfileManagementPageContributor : IProfileManagementPageContributor
public async Task ConfigureAsync(ProfileManagementPageCreationContext context)
{
public async Task ConfigureAsync(ProfileManagementPageCreationContext context)
{
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<AccountResource>>();
if (await IsPasswordChangeEnabled(context))
{
context.Groups.Add(
new ProfileManagementPageGroup(
"Volo.Abp.Account.Password",
l["ProfileTab:Password"],
typeof(AccountProfilePasswordManagementGroupViewComponent)
)
);
}
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<AccountResource>>();
if (await IsPasswordChangeEnabled(context))
{
context.Groups.Add(
new ProfileManagementPageGroup(
"Volo.Abp.Account.PersonalInfo",
l["ProfileTab:PersonalInfo"],
typeof(AccountProfilePersonalInfoManagementGroupViewComponent)
"Volo.Abp.Account.Password",
l["ProfileTab:Password"],
typeof(AccountProfilePasswordManagementGroupViewComponent)
)
);
}
protected virtual async Task<bool> IsPasswordChangeEnabled(ProfileManagementPageCreationContext context)
{
var userManager = context.ServiceProvider.GetRequiredService<IdentityUserManager>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
context.Groups.Add(
new ProfileManagementPageGroup(
"Volo.Abp.Account.PersonalInfo",
l["ProfileTab:PersonalInfo"],
typeof(AccountProfilePersonalInfoManagementGroupViewComponent)
)
);
}
protected virtual async Task<bool> IsPasswordChangeEnabled(ProfileManagementPageCreationContext context)
{
var userManager = context.ServiceProvider.GetRequiredService<IdentityUserManager>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
var user = await userManager.GetByIdAsync(currentUser.GetId());
var user = await userManager.GetByIdAsync(currentUser.GetId());
return !user.IsExternal;
}
return !user.IsExternal;
}
}

9
modules/account/src/Volo.Abp.Account.Web/ProfileManagement/IProfileManagementPageContributor.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks;
namespace Volo.Abp.Account.Web.ProfileManagement
namespace Volo.Abp.Account.Web.ProfileManagement;
public interface IProfileManagementPageContributor
{
public interface IProfileManagementPageContributor
{
Task ConfigureAsync(ProfileManagementPageCreationContext context);
}
Task ConfigureAsync(ProfileManagementPageCreationContext context);
}

19
modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageCreationContext.cs

@ -1,19 +1,18 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Account.Web.ProfileManagement
namespace Volo.Abp.Account.Web.ProfileManagement;
public class ProfileManagementPageCreationContext
{
public class ProfileManagementPageCreationContext
{
public IServiceProvider ServiceProvider { get; }
public IServiceProvider ServiceProvider { get; }
public List<ProfileManagementPageGroup> Groups { get; }
public List<ProfileManagementPageGroup> Groups { get; }
public ProfileManagementPageCreationContext(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
public ProfileManagementPageCreationContext(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
Groups = new List<ProfileManagementPageGroup>();
}
Groups = new List<ProfileManagementPageGroup>();
}
}

54
modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageGroup.cs

@ -1,39 +1,35 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.Account.Web.ProfileManagement
namespace Volo.Abp.Account.Web.ProfileManagement;
public class ProfileManagementPageGroup
{
public class ProfileManagementPageGroup
{
public string Id
{
get => _id;
set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id));
}
private string _id;
public string Id {
get => _id;
set => _id = Check.NotNullOrWhiteSpace(value, nameof(Id));
}
private string _id;
public string DisplayName
{
get => _displayName;
set => _displayName = Check.NotNullOrWhiteSpace(value, nameof(DisplayName));
}
private string _displayName;
public string DisplayName {
get => _displayName;
set => _displayName = Check.NotNullOrWhiteSpace(value, nameof(DisplayName));
}
private string _displayName;
public Type ComponentType
{
get => _componentType;
set => _componentType = Check.NotNull(value, nameof(ComponentType));
}
private Type _componentType;
public Type ComponentType {
get => _componentType;
set => _componentType = Check.NotNull(value, nameof(ComponentType));
}
private Type _componentType;
public object Parameter { get; set; }
public object Parameter { get; set; }
public ProfileManagementPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null)
{
Id = id;
DisplayName = displayName;
ComponentType = componentType;
Parameter = parameter;
}
public ProfileManagementPageGroup([NotNull] string id, [NotNull] string displayName, [NotNull] Type componentType, object parameter = null)
{
Id = id;
DisplayName = displayName;
ComponentType = componentType;
Parameter = parameter;
}
}

15
modules/account/src/Volo.Abp.Account.Web/ProfileManagement/ProfileManagementPageOptions.cs

@ -1,14 +1,13 @@
using System.Collections.Generic;
namespace Volo.Abp.Account.Web.ProfileManagement
namespace Volo.Abp.Account.Web.ProfileManagement;
public class ProfileManagementPageOptions
{
public class ProfileManagementPageOptions
{
public List<IProfileManagementPageContributor> Contributors { get; }
public List<IProfileManagementPageContributor> Contributors { get; }
public ProfileManagementPageOptions()
{
Contributors = new List<IProfileManagementPageContributor>();
}
public ProfileManagementPageOptions()
{
Contributors = new List<IProfileManagementPageContributor>();
}
}

37
modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AbpAccountApplicationTestBase.cs

@ -5,32 +5,31 @@ using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Testing;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class AbpAccountApplicationTestBase : AbpIntegratedTest<AbpAccountApplicationTestModule>
{
public class AbpAccountApplicationTestBase : AbpIntegratedTest<AbpAccountApplicationTestModule>
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.UseAutofac();
}
options.UseAutofac();
}
protected virtual IdentityUser GetUser(string userName)
protected virtual IdentityUser GetUser(string userName)
{
var user = UsingDbContext(context => context.Users.FirstOrDefault(u => u.UserName == userName));
if (user == null)
{
var user = UsingDbContext(context => context.Users.FirstOrDefault(u => u.UserName == userName));
if (user == null)
{
throw new EntityNotFoundException();
}
return user;
throw new EntityNotFoundException();
}
protected virtual T UsingDbContext<T>(Func<IIdentityDbContext, T> action)
return user;
}
protected virtual T UsingDbContext<T>(Func<IIdentityDbContext, T> action)
{
using (var dbContext = GetRequiredService<IIdentityDbContext>())
{
using (var dbContext = GetRequiredService<IIdentityDbContext>())
{
return action.Invoke(dbContext);
}
return action.Invoke(dbContext);
}
}
}

97
modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AbpAccountApplicationTestModule.cs

@ -14,69 +14,68 @@ using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.Threading;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpTestBaseModule),
typeof(AbpAuthorizationModule),
typeof(AbpIdentityAspNetCoreModule),
typeof(AbpAccountApplicationModule),
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqliteModule)
)]
public class AbpAccountApplicationTestModule : AbpModule
{
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpTestBaseModule),
typeof(AbpAuthorizationModule),
typeof(AbpIdentityAspNetCoreModule),
typeof(AbpAccountApplicationModule),
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqliteModule)
)]
public class AbpAccountApplicationTestModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAlwaysAllowAuthorization();
context.Services.AddAlwaysAllowAuthorization();
var sqliteConnection = CreateDatabaseAndGetConnection();
var sqliteConnection = CreateDatabaseAndGetConnection();
Configure<AbpDbContextOptions>(options =>
Configure<AbpDbContextOptions>(options =>
{
options.Configure(abpDbContextConfigurationContext =>
{
options.Configure(abpDbContextConfigurationContext =>
{
abpDbContextConfigurationContext.DbContextOptions.UseSqlite(sqliteConnection);
});
abpDbContextConfigurationContext.DbContextOptions.UseSqlite(sqliteConnection);
});
}
private static SqliteConnection CreateDatabaseAndGetConnection()
{
var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();
});
}
private static SqliteConnection CreateDatabaseAndGetConnection()
{
var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();
new IdentityDbContext(
new DbContextOptionsBuilder<IdentityDbContext>().UseSqlite(connection).Options
).GetService<IRelationalDatabaseCreator>().CreateTables();
new IdentityDbContext(
new DbContextOptionsBuilder<IdentityDbContext>().UseSqlite(connection).Options
).GetService<IRelationalDatabaseCreator>().CreateTables();
new PermissionManagementDbContext(
new DbContextOptionsBuilder<PermissionManagementDbContext>().UseSqlite(connection).Options
).GetService<IRelationalDatabaseCreator>().CreateTables();
new PermissionManagementDbContext(
new DbContextOptionsBuilder<PermissionManagementDbContext>().UseSqlite(connection).Options
).GetService<IRelationalDatabaseCreator>().CreateTables();
return connection;
}
return connection;
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
SeedTestData(context);
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
SeedTestData(context);
}
private static void SeedTestData(ApplicationInitializationContext context)
private static void SeedTestData(ApplicationInitializationContext context)
{
using (var scope = context.ServiceProvider.CreateScope())
{
using (var scope = context.ServiceProvider.CreateScope())
var dataSeeder = scope.ServiceProvider.GetRequiredService<IDataSeeder>();
AsyncHelper.RunSync(async () =>
{
var dataSeeder = scope.ServiceProvider.GetRequiredService<IDataSeeder>();
AsyncHelper.RunSync(async () =>
{
await dataSeeder.SeedAsync();
await scope.ServiceProvider
.GetRequiredService<AbpAccountTestDataBuilder>()
.Build();
});
}
await dataSeeder.SeedAsync();
await scope.ServiceProvider
.GetRequiredService<AbpAccountTestDataBuilder>()
.Build();
});
}
}
}

69
modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AccountAppService_Tests.cs

@ -5,48 +5,47 @@ using Shouldly;
using Volo.Abp.Identity;
using Xunit;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class AccountAppService_Tests : AbpAccountApplicationTestBase
{
public class AccountAppService_Tests : AbpAccountApplicationTestBase
private readonly IAccountAppService _accountAppService;
private readonly IIdentityUserRepository _identityUserRepository;
private readonly ILookupNormalizer _lookupNormalizer;
private readonly IdentityUserManager _userManager;
private readonly IOptions<IdentityOptions> _identityOptions;
public AccountAppService_Tests()
{
private readonly IAccountAppService _accountAppService;
private readonly IIdentityUserRepository _identityUserRepository;
private readonly ILookupNormalizer _lookupNormalizer;
private readonly IdentityUserManager _userManager;
private readonly IOptions<IdentityOptions> _identityOptions;
_accountAppService = GetRequiredService<IAccountAppService>();
_identityUserRepository = GetRequiredService<IIdentityUserRepository>();
_lookupNormalizer = GetRequiredService<ILookupNormalizer>();
_userManager = GetRequiredService<IdentityUserManager>();
_identityOptions = GetRequiredService<IOptions<IdentityOptions>>();
}
public AccountAppService_Tests()
{
_accountAppService = GetRequiredService<IAccountAppService>();
_identityUserRepository = GetRequiredService<IIdentityUserRepository>();
_lookupNormalizer = GetRequiredService<ILookupNormalizer>();
_userManager = GetRequiredService<IdentityUserManager>();
_identityOptions = GetRequiredService<IOptions<IdentityOptions>>();
}
[Fact]
public async Task RegisterAsync()
{
await _identityOptions.SetAsync();
[Fact]
public async Task RegisterAsync()
{
await _identityOptions.SetAsync();
var registerDto = new RegisterDto
{
UserName = "bob.lee",
EmailAddress = "bob.lee@abp.io",
Password = "P@ssW0rd",
AppName = "MVC"
};
var registerDto = new RegisterDto
{
UserName = "bob.lee",
EmailAddress = "bob.lee@abp.io",
Password = "P@ssW0rd",
AppName = "MVC"
};
await _accountAppService.RegisterAsync(registerDto);
await _accountAppService.RegisterAsync(registerDto);
var user = await _identityUserRepository.FindByNormalizedUserNameAsync(
_lookupNormalizer.NormalizeName("bob.lee"));
var user = await _identityUserRepository.FindByNormalizedUserNameAsync(
_lookupNormalizer.NormalizeName("bob.lee"));
user.ShouldNotBeNull();
user.UserName.ShouldBe("bob.lee");
user.Email.ShouldBe("bob.lee@abp.io");
user.ShouldNotBeNull();
user.UserName.ShouldBe("bob.lee");
user.Email.ShouldBe("bob.lee@abp.io");
(await _userManager.CheckPasswordAsync(user, "P@ssW0rd")).ShouldBeTrue();
}
(await _userManager.CheckPasswordAsync(user, "P@ssW0rd")).ShouldBeTrue();
}
}

133
modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/ProfileAppService_Tests.cs

@ -6,85 +6,84 @@ using Shouldly;
using Volo.Abp.Users;
using Xunit;
namespace Volo.Abp.Account
namespace Volo.Abp.Account;
public class ProfileAppService_Tests : AbpAccountApplicationTestBase
{
public class ProfileAppService_Tests : AbpAccountApplicationTestBase
private readonly IProfileAppService _profileAppService;
private readonly AccountTestData _testData;
private ICurrentUser _currentUser;
public ProfileAppService_Tests()
{
private readonly IProfileAppService _profileAppService;
private readonly AccountTestData _testData;
private ICurrentUser _currentUser;
_profileAppService = GetRequiredService<IProfileAppService>();
_testData = GetRequiredService<AccountTestData>();
}
public ProfileAppService_Tests()
{
_profileAppService = GetRequiredService<IProfileAppService>();
_testData = GetRequiredService<AccountTestData>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
_currentUser = Substitute.For<ICurrentUser>();
services.AddSingleton(_currentUser);
}
protected override void AfterAddApplication(IServiceCollection services)
{
_currentUser = Substitute.For<ICurrentUser>();
services.AddSingleton(_currentUser);
}
[Fact]
public async Task GetAsync()
{
//Arrange
_currentUser.Id.Returns(_testData.UserJohnId);
_currentUser.IsAuthenticated.Returns(true);
[Fact]
public async Task GetAsync()
{
//Arrange
_currentUser.Id.Returns(_testData.UserJohnId);
_currentUser.IsAuthenticated.Returns(true);
//Act
var result = await _profileAppService.GetAsync();
//Act
var result = await _profileAppService.GetAsync();
//Assert
var johnNash = GetUser("john.nash");
//Assert
var johnNash = GetUser("john.nash");
result.UserName.ShouldBe(johnNash.UserName);
result.Email.ShouldBe(johnNash.Email);
result.PhoneNumber.ShouldBe(johnNash.PhoneNumber);
}
result.UserName.ShouldBe(johnNash.UserName);
result.Email.ShouldBe(johnNash.Email);
result.PhoneNumber.ShouldBe(johnNash.PhoneNumber);
}
[Fact]
public async Task UpdateAsync()
{
//Arrange
_currentUser.Id.Returns(_testData.UserJohnId);
_currentUser.IsAuthenticated.Returns(true);
[Fact]
public async Task UpdateAsync()
{
//Arrange
_currentUser.Id.Returns(_testData.UserJohnId);
_currentUser.IsAuthenticated.Returns(true);
var input = new UpdateProfileDto
{
UserName = CreateRandomString(),
PhoneNumber = CreateRandomPhoneNumber(),
Email = CreateRandomEmail(),
Name = CreateRandomString(),
Surname = CreateRandomString()
};
//Act
var result = await _profileAppService.UpdateAsync(input);
//Assert
result.UserName.ShouldBe(input.UserName);
result.Email.ShouldBe(input.Email);
result.PhoneNumber.ShouldBe(input.PhoneNumber);
result.Surname.ShouldBe(input.Surname);
result.Name.ShouldBe(input.Name);
}
private static string CreateRandomEmail()
var input = new UpdateProfileDto
{
return CreateRandomString() + "@abp.io";
}
UserName = CreateRandomString(),
PhoneNumber = CreateRandomPhoneNumber(),
Email = CreateRandomEmail(),
Name = CreateRandomString(),
Surname = CreateRandomString()
};
private static string CreateRandomString()
{
return Guid.NewGuid().ToString("N").Left(16);
}
//Act
var result = await _profileAppService.UpdateAsync(input);
private static string CreateRandomPhoneNumber()
{
return RandomHelper.GetRandom(10000000, 100000000).ToString();
}
//Assert
result.UserName.ShouldBe(input.UserName);
result.Email.ShouldBe(input.Email);
result.PhoneNumber.ShouldBe(input.PhoneNumber);
result.Surname.ShouldBe(input.Surname);
result.Name.ShouldBe(input.Name);
}
private static string CreateRandomEmail()
{
return CreateRandomString() + "@abp.io";
}
private static string CreateRandomString()
{
return Guid.NewGuid().ToString("N").Left(16);
}
private static string CreateRandomPhoneNumber()
{
return RandomHelper.GetRandom(10000000, 100000000).ToString();
}
}

Loading…
Cancel
Save