Browse Source

Merge pull request #578 from abpframework/User-Personal-settings

Personal settings #309
pull/594/head
Halil İbrahim Kalkan 8 years ago
committed by GitHub
parent
commit
a4a27ad0c0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json
  2. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json
  3. 2
      modules/account/src/Volo.Abp.Account.Web/AbpAccountUserMenuContributor.cs
  4. 16
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IProfileAppService.cs
  5. 6
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDtoBase.cs
  6. 6
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserDto.cs
  7. 15
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/ProfileDto.cs
  8. 22
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/UpdateProfileDto.cs
  9. 4
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs
  10. 44
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/ProfileAppService.cs
  11. 4
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserConsts.cs
  12. 13
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs
  13. 2
      modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/IdentityUserExtensions.cs
  14. 30
      modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs
  15. 12
      modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebAutoMapperProfile.cs
  16. 3
      modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs
  17. 7
      modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json
  18. 5
      modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json
  19. 20
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml
  20. 66
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs
  21. 18
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/personal-settings-modal.js
  22. 2
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml
  23. 6
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs
  24. 14
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml
  25. 6
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml.cs
  26. 97
      modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/ProfileAppService_Tests.cs
  27. 4
      modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/IUserData.cs
  28. 8
      modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/UserData.cs
  29. 4
      modules/users/src/Volo.Abp.Users.Domain.Shared/Volo/Abp/Users/AbpUserConsts.cs
  30. 2
      modules/users/src/Volo.Abp.Users.Domain/Volo/Abp/Users/AbpUserExtensions.cs
  31. 6
      modules/users/src/Volo.Abp.Users.Domain/Volo/Abp/Users/IUser.cs
  32. 2
      modules/users/src/Volo.Abp.Users.EntityFrameworkCore/Volo/Abp/Users/EntityFrameworkCore/AbpUsersDbContextModelCreatingExtensions.cs

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json

@ -34,6 +34,7 @@
"PagerPrevious": "Previous",
"PagerInfo": "Showing {0} to {1} of {2} entries.",
"DatatableActionDropdownDefaultText": "Actions",
"ChangePassword": "Change password"
"ChangePassword": "Change password",
"PersonalInfo": "Personal info"
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json

@ -34,6 +34,7 @@
"PagerPrevious": "Önceki",
"PagerInfo": "{2} kayıttan {0} ile {1} arası gösteriliyor.",
"DatatableActionDropdownDefaultText": "İşlemler",
"ChangePassword": "Şifre değiştir"
"ChangePassword": "Şifre değiştir",
"PersonalInfo": "Kişisel Bilgiler"
}
}

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

@ -24,6 +24,8 @@ namespace Volo.Abp.Account.Web
context.Menu.AddItem(new ApplicationMenuItem("Account.ChangePassword", l["ChangePassword"], icon: "fa fa-key", url: "#", elementId: "abp-account-change-password"));
context.Menu.AddItem(new ApplicationMenuItem("Account.PersonalSettings", l["PersonalInfo"], icon: "fa fa-info", url: "#", elementId: "abp-account-personal-settings"));
context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000));
return Task.CompletedTask;

16
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IProfileAppService.cs

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Services;
namespace Volo.Abp.Identity
{
public interface IProfileAppService : IApplicationService
{
Task<ProfileDto> GetAsync();
Task<ProfileDto> UpdateAsync(UpdateProfileDto input);
}
}

6
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDtoBase.cs

@ -9,6 +9,12 @@ namespace Volo.Abp.Identity
[StringLength(IdentityUserConsts.MaxUserNameLength)]
public string UserName { get; set; }
[StringLength(IdentityUserConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(IdentityUserConsts.MaxSurnameLength)]
public string Surname { get; set; }
[Required]
[EmailAddress]
[StringLength(IdentityUserConsts.MaxEmailLength)]

6
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserDto.cs

@ -4,12 +4,16 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity
{
public class IdentityUserDto : EntityDto<Guid>, IMultiTenant
public class IdentityUserDto : FullAuditedEntityDto<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
public string UserName { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }

15
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/ProfileDto.cs

@ -0,0 +1,15 @@
namespace Volo.Abp.Identity
{
public class ProfileDto
{
public string UserName { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string PhoneNumber { get; set; }
}
}

22
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/UpdateProfileDto.cs

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
namespace Volo.Abp.Identity
{
public class UpdateProfileDto
{
[StringLength(IdentityUserConsts.MaxUserNameLength)]
public string UserName { get; set; }
[StringLength(IdentityUserConsts.MaxEmailLength)]
public string Email { get; set; }
[StringLength(IdentityUserConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(IdentityUserConsts.MaxSurnameLength)]
public string Surname { get; set; }
[StringLength(IdentityUserConsts.MaxPhoneNumberLength)]
public string PhoneNumber { get; set; }
}
}

4
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Authentication;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
@ -149,6 +150,9 @@ namespace Volo.Abp.Identity
(await _userManager.SetTwoFactorEnabledAsync(user, input.TwoFactorEnabled)).CheckErrors();
(await _userManager.SetLockoutEnabledAsync(user, input.LockoutEnabled)).CheckErrors();
user.Name = input.Name;
user.Surname = input.Surname;
if (input.RoleNames != null)
{
(await _userManager.SetRolesAsync(user, input.RoleNames)).CheckErrors();

44
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/ProfileAppService.cs

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.Users;
namespace Volo.Abp.Identity
{
[Authorize]
public class ProfileAppService : IdentityAppServiceBase, IProfileAppService
{
private readonly IdentityUserManager _userManager;
public ProfileAppService(IdentityUserManager userManager)
{
_userManager = userManager;
}
public async Task<ProfileDto> GetAsync()
{
return ObjectMapper.Map<IdentityUser, ProfileDto>(
await _userManager.GetByIdAsync(CurrentUser.GetId())
);
}
public async Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{
var user = await _userManager.GetByIdAsync(CurrentUser.GetId());
(await _userManager.SetUserNameAsync(user, input.UserName)).CheckErrors();
(await _userManager.SetEmailAsync(user, input.Email)).CheckErrors();
(await _userManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
user.Name = input.Name;
user.Surname = input.Surname;
(await _userManager.UpdateAsync(user)).CheckErrors();
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<IdentityUser, ProfileDto>(user);
}
}
}

4
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserConsts.cs

@ -6,6 +6,10 @@ namespace Volo.Abp.Identity
{
public const int MaxUserNameLength = AbpUserConsts.MaxUserNameLength;
public const int MaxNameLength = AbpUserConsts.MaxNameLength;
public const int MaxSurnameLength = AbpUserConsts.MaxSurnameLength;
public const int MaxNormalizedUserNameLength = MaxUserNameLength;
public const int MaxEmailLength = AbpUserConsts.MaxEmailLength;

13
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs

@ -8,12 +8,13 @@ using Microsoft.AspNetCore.Identity;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Guids;
using Volo.Abp.Users;
namespace Volo.Abp.Identity
{
public class IdentityUser : AggregateRoot<Guid>, IHasConcurrencyStamp, IUser, IHasExtraProperties
public class IdentityUser : FullAuditedAggregateRoot<Guid>, IHasConcurrencyStamp, IUser, IHasExtraProperties
{
public virtual Guid? TenantId { get; protected set; }
@ -28,6 +29,16 @@ namespace Volo.Abp.Identity
[DisableAuditing]
public virtual string NormalizedUserName { get; protected internal set; }
/// <summary>
/// Gets or sets the Name for the user.
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// Gets or sets the Surame for the user.
/// </summary>
public virtual string Surname { get; set; }
/// <summary>
/// Gets or sets the email address for this user.
/// </summary>

2
modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/IdentityUserExtensions.cs

@ -10,6 +10,8 @@ namespace Volo.Abp.Identity
user.Id,
user.UserName,
user.Email,
user.Name,
user.Surname,
user.EmailConfirmed,
user.PhoneNumber,
user.PhoneNumberConfirmed,

30
modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.Identity
{
[RemoteService]
[Area("identity")]
[ControllerName("Profile")]
public class ProfileController : IProfileAppService
{
private readonly IProfileAppService _profileAppService;
public ProfileController(IProfileAppService profileAppService)
{
_profileAppService = profileAppService;
}
public Task<ProfileDto> GetAsync()
{
return _profileAppService.GetAsync();
}
public Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{
return _profileAppService.UpdateAsync(input);
}
}
}

12
modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebAutoMapperProfile.cs

@ -1,5 +1,6 @@
using AutoMapper;
using Volo.Abp.Identity.Web.Pages.Identity.Roles;
using Volo.Abp.Identity.Web.Pages.Identity.Shared;
using CreateUserModalModel = Volo.Abp.Identity.Web.Pages.Identity.Users.CreateModalModel;
using EditUserModalModel = Volo.Abp.Identity.Web.Pages.Identity.Users.EditModalModel;
@ -11,6 +12,7 @@ namespace Volo.Abp.Identity.Web
{
CreateUserMappings();
CreateRoleMappings();
CreateProfileMappings();
}
private void CreateUserMappings()
@ -31,6 +33,10 @@ namespace Volo.Abp.Identity.Web
CreateMap<IdentityRoleDto, EditUserModalModel.AssignedRoleViewModel>()
.ForMember(dest => dest.IsAssigned, opt => opt.Ignore());
CreateMap<ProfileDto, PersonalSettingsInfoModel>();
CreateMap<PersonalSettingsInfoModel, UpdateProfileDto>();
}
private void CreateRoleMappings()
@ -44,5 +50,11 @@ namespace Volo.Abp.Identity.Web
//EditModal
CreateMap<EditModalModel.RoleInfoModel, IdentityRoleUpdateDto>();
}
private void CreateProfileMappings()
{
CreateMap<ProfileDto, PersonalSettingsInfoModel>();
CreateMap<PersonalSettingsInfoModel, UpdateProfileDto>();
}
}
}

3
modules/identity/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs

@ -75,7 +75,8 @@ namespace Volo.Abp.Identity.Web
options
.ScriptBundles
.Get(StandardBundles.Scripts.Global)
.AddFiles("/Pages/Identity/Shared/change-password-modal.js");
.AddFiles("/Pages/Identity/Shared/change-password-modal.js")
.AddFiles("/Pages/Identity/Shared/personal-settings-modal.js");
});
}
}

7
modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json

@ -13,10 +13,14 @@
"DisplayName:IsPublic": "Public",
"Roles": "Roles",
"Password": "Password",
"PersonalInfo": "Personal Info",
"PersonalSettings": "Personal settings",
"UserDeletionConfirmationMessage": "User '{0}' will be deleted. Do you confirm that?",
"RoleDeletionConfirmationMessage": "Role '{0}' will be deleted. Do you confirm that?",
"DisplayName:RoleName": "Role name",
"DisplayName:UserName": "User name",
"DisplayName:Name": "Name",
"DisplayName:Surname": "Surname",
"DisplayName:Password": "Password",
"DisplayName:EmailAddress": "Email address",
"DisplayName:PhoneNumber": "Phone number",
@ -29,6 +33,7 @@
"DisplayName:CurrentPassword": "Current password",
"DisplayName:NewPassword": "New password",
"DisplayName:NewPasswordConfirm": "Confirm new password",
"PasswordChangedMessage": "Your password has been changed successfully."
"PasswordChangedMessage": "Your password has been changed successfully.",
"PersonalSettingsSavedMessage": "Your personal settings has been saved successfully."
}
}

5
modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json

@ -13,10 +13,14 @@
"UserInformations": "Kullanıcı bilgileri",
"Roles": "Roller",
"Password": "Şifre",
"PersonalInfo": "Kişisel bilgi",
"PersonalSettings": "Kişisel Ayarlar",
"UserDeletionConfirmationMessage": "{0} kullanıcısı silinecektir. Onaylıyor musunuz?",
"RoleDeletionConfirmationMessage": "'{0}' rolü silinecektir. Onaylıyor musunuz?",
"DisplayName:RoleName": "Rol adı",
"DisplayName:UserName": "Kullanıcı adı",
"DisplayName:Name": "Adı",
"DisplayName:Surname": "Soyadı",
"DisplayName:Password": "Şifre",
"DisplayName:EmailAddress": "E-posta adresi",
"DisplayName:PhoneNumber": "Telefon numarası",
@ -30,6 +34,7 @@
"DisplayName:NewPassword": "Yeni şifre",
"DisplayName:NewPasswordConfirm": "Yeni şifre (tekrar)",
"PasswordChangedMessage": "Şifreniz başarıyla değiştirildi.",
"PersonalSettingsSavedMessage": "Kişisel bilgileriniz başarıyla kaydedildi.",
"Identity.StaticRoleRenamingErrorMessage": "Bir Sabit rolün ismi değiştirilemez.",
"Identity.StaticRoleDeletionErrorMessage": "Bir Sabit rol silinemez."
}

20
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml

@ -0,0 +1,20 @@
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Identity.Localization
@using Volo.Abp.Identity.Web.Pages.Identity.Shared
@model PersonalSettingsModal
@inject IHtmlLocalizer<IdentityResource> L
@{
Layout = null;
}
<abp-dynamic-form abp-model="@Model.PersonalSettingsInfoModel" asp-page="/Identity/Shared/PersonalSettingsModal">
<abp-modal>
<abp-modal-header title="@L["PersonalSettings"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

66
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs

@ -0,0 +1,66 @@
using System.ComponentModel.DataAnnotations;
using System.Security.Authentication;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.Identity.Localization;
namespace Volo.Abp.Identity.Web.Pages.Identity.Shared
{
public class PersonalSettingsModal : AbpPageModel
{
[BindProperty]
public PersonalSettingsInfoModel PersonalSettingsInfoModel { get; set; }
private readonly IProfileAppService _profileAppService;
public PersonalSettingsModal(IProfileAppService profileAppService)
{
_profileAppService = profileAppService;
}
public async Task OnGetAsync()
{
var user = await _profileAppService.GetAsync();
PersonalSettingsInfoModel = ObjectMapper.Map<ProfileDto, PersonalSettingsInfoModel>(user);
}
public async Task<IActionResult> OnPostAsync()
{
ValidateModel();
var updateDto = ObjectMapper.Map<PersonalSettingsInfoModel, UpdateProfileDto>(PersonalSettingsInfoModel);
await _profileAppService.UpdateAsync(updateDto);
return NoContent();
}
}
public class PersonalSettingsInfoModel
{
[Required]
[StringLength(IdentityUserConsts.MaxUserNameLength)]
[Display(Name = "DisplayName:UserName")]
public string UserName { get; set; }
[Required]
[StringLength(IdentityUserConsts.MaxEmailLength)]
[Display(Name = "DisplayName:Email")]
public string Email { get; set; }
[StringLength(IdentityUserConsts.MaxNameLength)]
[Display(Name = "DisplayName:Name")]
public string Name { get; set; }
[StringLength(IdentityUserConsts.MaxSurnameLength)]
[Display(Name = "DisplayName:Surname")]
public string Surname { get; set; }
[StringLength(IdentityUserConsts.MaxPhoneNumberLength)]
[Display(Name = "DisplayName:PhoneNumber")]
public string PhoneNumber { get; set; }
}
}

18
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/personal-settings-modal.js

@ -0,0 +1,18 @@
(function ($) {
var l = abp.localization.getResource('AbpIdentity');
var _personalSettingsModal = new abp.ModalManager(abp.appPath + 'Identity/Shared/PersonalSettingsModal');
$(function () {
$("#abp-account-personal-settings").click(function (e) {
e.preventDefault();
_personalSettingsModal.open();
});
_personalSettingsModal.onResult(function () {
//abp.message.success(l("PersonalSettingsSavedMessage"));
});
});
})(jQuery);

2
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml

@ -15,6 +15,8 @@
<abp-tab title="@L["UserInformations"].Value">
@* TODO: Can we use dynamic form? *@
<abp-input asp-for="UserInfo.UserName" />
<abp-input asp-for="UserInfo.Name" />
<abp-input asp-for="UserInfo.Surname" />
<abp-input asp-for="UserInfo.Password" />
<abp-input asp-for="UserInfo.Email" />
<abp-input asp-for="UserInfo.PhoneNumber" />

6
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs

@ -56,6 +56,12 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Users
[StringLength(IdentityUserConsts.MaxUserNameLength)]
public string UserName { get; set; }
[StringLength(IdentityUserConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(IdentityUserConsts.MaxSurnameLength)]
public string Surname { get; set; }
[Required]
[StringLength(IdentityUserConsts.MaxPasswordLength)]
[DataType(DataType.Password)]

14
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml

@ -14,12 +14,14 @@
<abp-tabs name="create-user-modal-tabs">
<abp-tab title="@L["UserInformations"].Value">
@* TODO: Can we use dynamic form? *@
<input asp-for="UserInfo.Id"/>
<abp-input asp-for="UserInfo.UserName"/>
<abp-input asp-for="UserInfo.Email"/>
<abp-input asp-for="UserInfo.PhoneNumber"/>
<abp-input asp-for="UserInfo.LockoutEnabled"/>
<abp-input asp-for="UserInfo.TwoFactorEnabled"/>
<input asp-for="UserInfo.Id" />
<abp-input asp-for="UserInfo.UserName" />
<abp-input asp-for="UserInfo.Name" />
<abp-input asp-for="UserInfo.Surname" />
<abp-input asp-for="UserInfo.Email" />
<abp-input asp-for="UserInfo.PhoneNumber" />
<abp-input asp-for="UserInfo.LockoutEnabled" />
<abp-input asp-for="UserInfo.TwoFactorEnabled" />
</abp-tab>
<abp-tab title="@L["Roles"].Value">
@for (var i = 0; i < Model.Roles.Length; i++)

6
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml.cs

@ -63,6 +63,12 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Users
[StringLength(IdentityUserConsts.MaxUserNameLength)]
public string UserName { get; set; }
[StringLength(IdentityUserConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(IdentityUserConsts.MaxSurnameLength)]
public string Surname { get; set; }
[Required]
[EmailAddress]
[StringLength(IdentityUserConsts.MaxEmailLength)]

97
modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/ProfileAppService_Tests.cs

@ -0,0 +1,97 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
using Volo.Abp.Users;
using Xunit;
namespace Volo.Abp.Identity
{
public class ProfileAppService_Tests : AbpIdentityApplicationTestBase
{
private readonly IProfileAppService _profileAppService;
private readonly IIdentityUserRepository _userRepository;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IdentityTestData _testData;
private ICurrentUser _currentUser;
public ProfileAppService_Tests()
{
_profileAppService = GetRequiredService<IProfileAppService>();
_userRepository = GetRequiredService<IIdentityUserRepository>();
_signInManager = GetRequiredService<SignInManager<IdentityUser>>();
_testData = GetRequiredService<IdentityTestData>();
}
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);
//Act
var result = await _profileAppService.GetAsync();
//Assert
var johnNash = GetUser("john.nash");
result.UserName.ShouldBe(johnNash.UserName);
result.Email.ShouldBe(johnNash.Email);
result.PhoneNumber.ShouldBe(johnNash.PhoneNumber);
}
[Fact]
public async Task UpdateAsync()
{
//Arrange
//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()
{
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();
}
}
}

4
modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/IUserData.cs

@ -11,6 +11,10 @@ namespace Volo.Abp.Users
string UserName { get; }
string Name { get; }
string Surname { get; }
[CanBeNull]
string Email { get; }

8
modules/users/src/Volo.Abp.Users.Abstractions/Volo/Abp/Users/UserData.cs

@ -9,6 +9,10 @@ namespace Volo.Abp.Users
public string UserName { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
@ -28,6 +32,8 @@ namespace Volo.Abp.Users
Guid id,
[NotNull] string userName,
[CanBeNull] string email = null,
[CanBeNull] string name = null,
[CanBeNull] string surname = null,
bool emailConfirmed = false,
[CanBeNull] string phoneNumber = null,
bool phoneNumberConfirmed = false,
@ -36,6 +42,8 @@ namespace Volo.Abp.Users
Id = id;
UserName = userName;
Email = email;
Name = name;
Surname = surname;
EmailConfirmed = emailConfirmed;
PhoneNumber = phoneNumber;
PhoneNumberConfirmed = phoneNumberConfirmed;

4
modules/users/src/Volo.Abp.Users.Domain.Shared/Volo/Abp/Users/AbpUserConsts.cs

@ -3,6 +3,10 @@ namespace Volo.Abp.Users
public class AbpUserConsts
{
public const int MaxUserNameLength = 256;
public const int MaxNameLength = 64;
public const int MaxSurnameLength = 64;
public const int MaxEmailLength = 256;

2
modules/users/src/Volo.Abp.Users.Domain/Volo/Abp/Users/AbpUserExtensions.cs

@ -7,6 +7,8 @@ namespace Volo.Abp.Users
return new UserData(
user.Id,
user.UserName,
user.Name,
user.Surname,
user.Email,
user.EmailConfirmed,
user.PhoneNumber,

6
modules/users/src/Volo.Abp.Users.Domain/Volo/Abp/Users/IUser.cs

@ -12,6 +12,12 @@ namespace Volo.Abp.Users
[CanBeNull]
string Email { get; }
[CanBeNull]
string Name { get; }
[CanBeNull]
string Surname { get; }
bool EmailConfirmed { get; }
[CanBeNull]

2
modules/users/src/Volo.Abp.Users.EntityFrameworkCore/Volo/Abp/Users/EntityFrameworkCore/AbpUsersDbContextModelCreatingExtensions.cs

@ -12,6 +12,8 @@ namespace Volo.Abp.Users.EntityFrameworkCore
b.Property(u => u.TenantId).HasColumnName(nameof(IUser.TenantId));
b.Property(u => u.UserName).IsRequired().HasMaxLength(AbpUserConsts.MaxUserNameLength).HasColumnName(nameof(IUser.UserName));
b.Property(u => u.Email).HasMaxLength(AbpUserConsts.MaxEmailLength).HasColumnName(nameof(IUser.Email));
b.Property(u => u.Name).HasMaxLength(AbpUserConsts.MaxNameLength).HasColumnName(nameof(IUser.Name));
b.Property(u => u.Surname).HasMaxLength(AbpUserConsts.MaxSurnameLength).HasColumnName(nameof(IUser.Surname));
b.Property(u => u.EmailConfirmed).HasDefaultValue(false).HasColumnName(nameof(IUser.EmailConfirmed));
b.Property(u => u.PhoneNumber).HasMaxLength(AbpUserConsts.MaxPhoneNumberLength).HasColumnName(nameof(IUser.PhoneNumber));
b.Property(u => u.PhoneNumberConfirmed).HasDefaultValue(false).HasColumnName(nameof(IUser.PhoneNumberConfirmed));

Loading…
Cancel
Save