diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs index 474e5cbd57..c335c3c338 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs @@ -7,5 +7,9 @@ namespace Volo.Abp.Identity [Required] [StringLength(IdentityRoleConsts.MaxNameLength)] public string Name { get; set; } + + public bool IsDefault { get; set; } + + public bool IsPublic { get; set; } } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleDto.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleDto.cs index 13aa96f41b..c25ceace56 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleDto.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleDto.cs @@ -6,5 +6,11 @@ namespace Volo.Abp.Identity public class IdentityRoleDto : EntityDto { public string Name { get; set; } + + public bool IsDefault { get; set; } + + public bool IsStatic { get; set; } + + public bool IsPublic { get; set; } } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs index b8cbcb67a9..0d3b883c05 100644 --- a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs +++ b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs @@ -69,7 +69,7 @@ namespace Volo.Abp.Identity [Authorize(IdentityPermissions.Roles.Create)] public async Task CreateAsync(IdentityRoleCreateDto input) { - var role = new IdentityRole(GuidGenerator.Create(), input.Name, CurrentTenant.Id); + var role = new IdentityRole(GuidGenerator.Create(), input.Name, input.IsDefault, false, input.IsPublic, CurrentTenant.Id); (await _roleManager.CreateAsync(role)).CheckErrors(); await CurrentUnitOfWork.SaveChangesAsync(); @@ -84,6 +84,9 @@ namespace Volo.Abp.Identity (await _roleManager.SetRoleNameAsync(role, input.Name)).CheckErrors(); + role.IsDefault = input.IsDefault; + role.IsPublic = input.IsPublic; + (await _roleManager.UpdateAsync(role)).CheckErrors(); await CurrentUnitOfWork.SaveChangesAsync(); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDataSeeder.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDataSeeder.cs index 02e0f320ac..cff165a1be 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDataSeeder.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDataSeeder.cs @@ -62,7 +62,7 @@ namespace Volo.Abp.Identity var adminRole = await _roleRepository.FindByNormalizedNameAsync(_lookupNormalizer.Normalize(adminRoleName)); if (adminRole == null) { - adminRole = new IdentityRole(_guidGenerator.Create(), adminRoleName, tenantId); + adminRole = new IdentityRole(_guidGenerator.Create(), adminRoleName, false, true, true, tenantId); CheckIdentityErrors(await _roleManager.CreateAsync(adminRole)); if (adminRolePermissions != null) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs index 8c5edd173f..33e2188032 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs @@ -39,12 +39,27 @@ namespace Volo.Abp.Identity [DisableAuditing] public virtual string ConcurrencyStamp { get; set; } + /// + /// A default role is automatically assigned to a new user + /// + public virtual bool IsDefault { get; set; } + + /// + /// A static role can not be deleted/renamed + /// + public virtual bool IsStatic { get; protected set; } + + /// + /// A user can see other user's public roles + /// + public virtual bool IsPublic { get; set; } + /// /// Initializes a new instance of . /// protected IdentityRole() { } - public IdentityRole(Guid id, [NotNull] string name, Guid? tenantId = null) + public IdentityRole(Guid id, [NotNull] string name, bool isDefault = false, bool isStatic = false, bool isPublic = false, Guid? tenantId = null) { Check.NotNull(name, nameof(name)); @@ -53,6 +68,9 @@ namespace Volo.Abp.Identity TenantId = tenantId; NormalizedName = name.ToUpperInvariant(); ConcurrencyStamp = Guid.NewGuid().ToString(); + IsDefault = isDefault; + IsStatic = isStatic; + IsPublic = isPublic; Claims = new Collection(); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs index e59a056566..25f4214147 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRoleManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; @@ -43,5 +44,35 @@ namespace Volo.Abp.Identity return role; } + + public List GetDefaultRoles() + { + if (Roles == null) + { + return new List(); + } + + return Roles.Where(r => r.IsDefault).ToList(); + } + + public override async Task SetRoleNameAsync(IdentityRole role, string name) + { + if (role.IsStatic && role.Name != name) + { + throw new AbpException("Static roles can not be renamed."); // TODO: localize & change exception type + } + + return await base.SetRoleNameAsync(role,name); + } + + public override async Task DeleteAsync(IdentityRole role) + { + if (role.IsStatic) + { + throw new AbpException("Static roles can not be deleted."); // TODO: localize & change exception type + } + + return await base.DeleteAsync(role); + } } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs index dff0faef2b..af5cfd19e8 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs @@ -97,6 +97,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore b.Property(r => r.Name).IsRequired().HasMaxLength(IdentityRoleConsts.MaxNameLength); b.Property(r => r.NormalizedName).IsRequired().HasMaxLength(IdentityRoleConsts.MaxNormalizedNameLength); + b.Property(r => r.IsDefault).HasColumnName(nameof(IdentityRole.IsDefault)); + b.Property(r => r.IsStatic).HasColumnName(nameof(IdentityRole.IsStatic)); + b.Property(r => r.IsPublic).HasColumnName(nameof(IdentityRole.IsPublic)); b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired(); diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json index e63e8fb4b2..3e97ea3700 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json +++ b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json @@ -8,6 +8,9 @@ "EmailAddress": "Email address", "PhoneNumber": "Phone number", "UserInformations": "User informations", + "DisplayName:IsDefault": "Default", + "DisplayName:IsStatic": "Static", + "DisplayName:IsPublic": "Public", "Roles": "Roles", "Password": "Password", "UserDeletionConfirmationMessage": "User '{0}' will be deleted. Do you confirm that?", diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json index 7484851424..c9a730f9a2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json +++ b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json @@ -6,6 +6,9 @@ "NewUser": "Yeni kullanıcı", "UserName": "Kullanıcı adı", "EmailAddress": "E-posta adresi", + "DisplayName:IsDefault": "Varsayılan", + "DisplayName:IsStatic": "Sabit", + "DisplayName:IsPublic": "Herkese Açık", "PhoneNumber": "Telefon numarası", "UserInformations": "Kullanıcı bilgileri", "Roles": "Roller", diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml index 833aa979c7..ce075d0b58 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml @@ -7,12 +7,14 @@ @{ Layout = null; } - +
- + + + - +
diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml.cs b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml.cs index bf91f4c5c6..7477439821 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml.cs @@ -33,6 +33,12 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Roles [StringLength(IdentityRoleConsts.MaxNameLength)] [Display(Name = "DisplayName:RoleName")] public string Name { get; set; } + + [Display(Name = "DisplayName:IsDefault")] + public bool IsDefault { get; set; } + + [Display(Name = "DisplayName:IsPublic")] + public bool IsPublic { get; set; } } } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml index 4f20d63091..c32671ca62 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml @@ -7,12 +7,15 @@ @{ Layout = null; } - +
- + + + + - \ No newline at end of file +
diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml.cs b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml.cs index 22a13c6795..58703c211e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml.cs @@ -44,6 +44,14 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Roles [StringLength(IdentityRoleConsts.MaxNameLength)] [Display(Name = "DisplayName:RoleName")] public string Name { get; set; } + + [Display(Name = "DisplayName:IsDefault")] + public bool IsDefault { get; set; } + + public bool IsStatic { get; set; } + + [Display(Name = "DisplayName:IsPublic")] + public bool IsPublic { get; set; } } } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/index.js b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/index.js index b450fa069c..ee013ff1e9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/index.js +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/index.js @@ -45,8 +45,8 @@ }, { text: l('Delete'), - visible: function () { - return true; //TODO: Check permission + visible: function (data) { + return !data.isStatic; //TODO: Check permission }, confirmMessage: function (data) { return l('RoleDeletionConfirmationMessage', data.record.name)}, action: function (data) { diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs index 5de2b3d1e3..ed80295c35 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml.cs @@ -28,9 +28,20 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Users { UserInfo = new UserInfoViewModel(); + var roleDtoList = await _identityRoleAppService.GetAllListAsync(); + Roles = ObjectMapper.Map, AssignedRoleViewModel[]>( await _identityRoleAppService.GetAllListAsync() ); + + var defaultRoles = roleDtoList.Where(r => r.IsDefault).ToList(); + foreach (var role in Roles) + { + if (defaultRoles.Any(r => r.Name == role.Name)) + { + role.IsAssigned = true; + } + } } public async Task OnPostAsync()