Browse Source

update userManager logic for organization unit

pull/2563/head
Mehmet Perk 7 years ago
parent
commit
1b56ed47bb
  1. 5
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDtoBase.cs
  2. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
  3. 7
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs
  4. 8
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs
  5. 6
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs
  6. 126
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs
  7. 8
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserOrganizationUnit.cs
  8. 2
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/IOrganizationUnitRepository.cs
  9. 5
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs
  10. 4
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs

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

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations; using System;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Volo.Abp.Identity namespace Volo.Abp.Identity
@ -29,5 +30,7 @@ namespace Volo.Abp.Identity
[CanBeNull] [CanBeNull]
public string[] RoleNames { get; set; } public string[] RoleNames { get; set; }
public Guid[] OrganizationUnits { get; set; }
} }
} }

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json

@ -64,6 +64,7 @@
"Identity.StaticRoleRenamingErrorMessage": "Static roles can not be renamed.", "Identity.StaticRoleRenamingErrorMessage": "Static roles can not be renamed.",
"Identity.StaticRoleDeletionErrorMessage": "Static roles can not be deleted.", "Identity.StaticRoleDeletionErrorMessage": "Static roles can not be deleted.",
"Identity.OrganizationUnit.DuplicateDisplayNameWarning": "There is already an organization unit with name {0}. Two units with same name can not be created in same level.", "Identity.OrganizationUnit.DuplicateDisplayNameWarning": "There is already an organization unit with name {0}. Two units with same name can not be created in same level.",
"Identity.OrganizationUnit.MaxUserMembershipCount": "Maximum allowed organization unit membership count for a user",
"Volo.Abp.Identity:010001": "You can not delete your own account!", "Volo.Abp.Identity:010001": "You can not delete your own account!",
"Permission:IdentityManagement": "Identity management", "Permission:IdentityManagement": "Identity management",
"Permission:RoleManagement": "Role management", "Permission:RoleManagement": "Role management",

7
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Settings/IdentitySettingNames.cs

@ -40,5 +40,12 @@
public const string IsUserNameUpdateEnabled = UserPrefix + ".IsUserNameUpdateEnabled"; public const string IsUserNameUpdateEnabled = UserPrefix + ".IsUserNameUpdateEnabled";
public const string IsEmailUpdateEnabled = UserPrefix + ".IsEmailUpdateEnabled"; public const string IsEmailUpdateEnabled = UserPrefix + ".IsEmailUpdateEnabled";
} }
public static class OrganizationUnit
{
private const string OrganizationUnitPrefix = Prefix + ".OrganizationUnit";
public const string MaxUserMembershipCount = OrganizationUnitPrefix + ".MaxUserMembershipCount";
}
} }
} }

8
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentitySettingDefinitionProvider.cs

@ -57,7 +57,7 @@ namespace Volo.Abp.Identity
new SettingDefinition( new SettingDefinition(
IdentitySettingNames.Lockout.LockoutDuration, IdentitySettingNames.Lockout.LockoutDuration,
(5*60).ToString(), L("DisplayName:Abp.Identity.Lockout.LockoutDuration"), (5 * 60).ToString(), L("DisplayName:Abp.Identity.Lockout.LockoutDuration"),
L("Description:Abp.Identity.Lockout.LockoutDuration"), L("Description:Abp.Identity.Lockout.LockoutDuration"),
true), true),
@ -88,6 +88,12 @@ namespace Volo.Abp.Identity
IdentitySettingNames.User.IsEmailUpdateEnabled, IdentitySettingNames.User.IsEmailUpdateEnabled,
true.ToString(), L("DisplayName:Abp.Identity.User.IsEmailUpdateEnabled"), true.ToString(), L("DisplayName:Abp.Identity.User.IsEmailUpdateEnabled"),
L("Description:Abp.Identity.User.IsEmailUpdateEnabled"), L("Description:Abp.Identity.User.IsEmailUpdateEnabled"),
true),
new SettingDefinition(
IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount,
int.MaxValue.ToString(), L("Identity.OrganizationUnit.MaxUserMembershipCount"),
L("Identity.OrganizationUnit.MaxUserMembershipCount"),
true) true)
); );
} }

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

@ -129,7 +129,7 @@ namespace Volo.Abp.Identity
/// <summary> /// <summary>
/// Navigation property for this organization units. /// Navigation property for this organization units.
/// </summary> /// </summary>
public virtual ICollection<OrganizationUnitUser> OrganizationUnits { get; protected set; } public virtual ICollection<IdentityUserOrganizationUnit> OrganizationUnits { get; protected set; }
protected IdentityUser() protected IdentityUser()
{ {
@ -154,7 +154,7 @@ namespace Volo.Abp.Identity
Claims = new Collection<IdentityUserClaim>(); Claims = new Collection<IdentityUserClaim>();
Logins = new Collection<IdentityUserLogin>(); Logins = new Collection<IdentityUserLogin>();
Tokens = new Collection<IdentityUserToken>(); Tokens = new Collection<IdentityUserToken>();
OrganizationUnits = new Collection<OrganizationUnitUser>(); OrganizationUnits = new Collection<IdentityUserOrganizationUnit>();
ExtraProperties = new Dictionary<string, object>(); ExtraProperties = new Dictionary<string, object>();
} }
@ -293,7 +293,7 @@ namespace Volo.Abp.Identity
return; return;
} }
OrganizationUnits.Add(new OrganizationUnitUser(TenantId, Id, organizationUnitId)); OrganizationUnits.Add(new IdentityUserOrganizationUnit(TenantId, Id, organizationUnitId));
} }
public virtual void RemoveOrganizationUnit(Guid organizationUnitId) public virtual void RemoveOrganizationUnit(Guid organizationUnitId)

126
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs

@ -9,7 +9,12 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using Volo.Abp.Identity.Organizations;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.Uow;
using Volo.Abp.Settings;
using Volo.Abp.Identity.Settings;
namespace Volo.Abp.Identity namespace Volo.Abp.Identity
{ {
@ -18,6 +23,9 @@ namespace Volo.Abp.Identity
protected override CancellationToken CancellationToken => _cancellationTokenProvider.Token; protected override CancellationToken CancellationToken => _cancellationTokenProvider.Token;
private readonly ICancellationTokenProvider _cancellationTokenProvider; private readonly ICancellationTokenProvider _cancellationTokenProvider;
protected IOrganizationUnitRepository _organizationUnitRepository { get; private set; }
protected IIdentityUserRepository _identityUserRepository { get; private set; }
private readonly ISettingProvider _settingProvider;
public IdentityUserManager( public IdentityUserManager(
IdentityUserStore store, IdentityUserStore store,
@ -28,7 +36,10 @@ namespace Volo.Abp.Identity
ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors,
IServiceProvider services, IServiceProvider services,
ILogger<IdentityUserManager> logger, ILogger<IdentityUserManager> logger,
ICancellationTokenProvider cancellationTokenProvider) ICancellationTokenProvider cancellationTokenProvider,
IOrganizationUnitRepository organizationUnitRepository,
IIdentityUserRepository identityUserRepository,
ISettingProvider settingProvider)
: base( : base(
store, store,
optionsAccessor, optionsAccessor,
@ -41,6 +52,9 @@ namespace Volo.Abp.Identity
logger) logger)
{ {
_cancellationTokenProvider = cancellationTokenProvider; _cancellationTokenProvider = cancellationTokenProvider;
_organizationUnitRepository = organizationUnitRepository;
_identityUserRepository = identityUserRepository;
_settingProvider = settingProvider;
} }
public virtual async Task<IdentityUser> GetByIdAsync(Guid id) public virtual async Task<IdentityUser> GetByIdAsync(Guid id)
@ -75,5 +89,115 @@ namespace Volo.Abp.Identity
return IdentityResult.Success; return IdentityResult.Success;
} }
public virtual async Task<bool> IsInOrganizationUnitAsync(Guid userId, Guid ouId)
{
return await IsInOrganizationUnitAsync(
await GetByIdAsync(userId),
await _organizationUnitRepository.GetAsync(ouId)
);
}
public virtual Task<bool> IsInOrganizationUnitAsync(IdentityUser user, OrganizationUnit ou)
{
return Task.FromResult(user.IsInOrganizationUnit(ou.Id));
}
public virtual async Task AddToOrganizationUnitAsync(Guid userId, Guid ouId)
{
await AddToOrganizationUnitAsync(
await GetByIdAsync(userId),
await _organizationUnitRepository.GetAsync(ouId)
);
}
public virtual async Task AddToOrganizationUnitAsync(IdentityUser user, OrganizationUnit ou)
{
await _identityUserRepository.EnsureCollectionLoadedAsync(user, u => u.OrganizationUnits, _cancellationTokenProvider.Token).ConfigureAwait(false);
var currentOus = user.OrganizationUnits;
if (currentOus.Any(cou => cou.Id == ou.Id))
{
return;
}
await CheckMaxUserOrganizationUnitMembershipCountAsync(user.TenantId, currentOus.Count + 1);
user.AddOrganizationUnit(ou.Id);
}
public virtual async Task RemoveFromOrganizationUnitAsync(Guid userId, Guid ouId)
{
await RemoveFromOrganizationUnitAsync(
await GetByIdAsync(userId),
await _organizationUnitRepository.GetAsync(ouId)
);
}
public virtual async Task RemoveFromOrganizationUnitAsync(IdentityUser user, OrganizationUnit ou)
{
await _identityUserRepository.EnsureCollectionLoadedAsync(user, u => u.OrganizationUnits, _cancellationTokenProvider.Token).ConfigureAwait(false);
user.RemoveOrganizationUnit(ou.Id);
}
public virtual async Task SetOrganizationUnitsAsync(Guid userId, params Guid[] organizationUnitIds)
{
await SetOrganizationUnitsAsync(
await GetByIdAsync(userId),
organizationUnitIds
);
}
public virtual async Task SetOrganizationUnitsAsync(IdentityUser user, params Guid[] organizationUnitIds)
{
Check.NotNull(user, nameof(user));
Check.NotNull(organizationUnitIds, nameof(organizationUnitIds));
await CheckMaxUserOrganizationUnitMembershipCountAsync(user.TenantId, organizationUnitIds.Length);
var currentOus = user.OrganizationUnits;
//Remove from removed OUs
foreach (var currentOu in currentOus)
{
if (!organizationUnitIds.Contains(currentOu.Id))
{
await RemoveFromOrganizationUnitAsync(user.Id, currentOu.Id);
}
}
//Add to added OUs
foreach (var organizationUnitId in organizationUnitIds)
{
if (currentOus.All(ou => ou.Id != organizationUnitId))
{
await AddToOrganizationUnitAsync(
user,
await _organizationUnitRepository.GetAsync(organizationUnitId)
);
}
}
}
private async Task CheckMaxUserOrganizationUnitMembershipCountAsync(Guid? tenantId, int requestedCount)
{
var maxCount = await _settingProvider.GetAsync<int>(IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount).ConfigureAwait(false);
if (requestedCount > maxCount)
{
throw new AbpException(string.Format("Can not set more than {0} organization unit for a user!", maxCount));
}
}
[UnitOfWork]
public virtual async Task<List<OrganizationUnit>> GetOrganizationUnitsAsync(IdentityUser user)
{
await _identityUserRepository.EnsureCollectionLoadedAsync(user, u => u.OrganizationUnits, _cancellationTokenProvider.Token).ConfigureAwait(false);
var ouOfUser = user.OrganizationUnits;
return await _organizationUnitRepository.GetListAsync(ouOfUser.Select(t => t.OrganizationUnitId));
}
} }
} }

8
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnitUser.cs → modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserOrganizationUnit.cs

@ -2,12 +2,12 @@
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity.Organizations namespace Volo.Abp.Identity
{ {
/// <summary> /// <summary>
/// Represents membership of a User to an OU. /// Represents membership of a User to an OU.
/// </summary> /// </summary>
public class OrganizationUnitUser : CreationAuditedEntity<Guid>, IMultiTenant, ISoftDelete public class IdentityUserOrganizationUnit : CreationAuditedEntity<Guid>, IMultiTenant, ISoftDelete
{ {
/// <summary> /// <summary>
@ -33,7 +33,7 @@ namespace Volo.Abp.Identity.Organizations
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="UserOrganizationUnit"/> class. /// Initializes a new instance of the <see cref="UserOrganizationUnit"/> class.
/// </summary> /// </summary>
public OrganizationUnitUser() public IdentityUserOrganizationUnit()
{ {
} }
@ -44,7 +44,7 @@ namespace Volo.Abp.Identity.Organizations
/// <param name="tenantId">TenantId</param> /// <param name="tenantId">TenantId</param>
/// <param name="userId">Id of the User.</param> /// <param name="userId">Id of the User.</param>
/// <param name="organizationUnitId">Id of the <see cref="OrganizationUnit"/>.</param> /// <param name="organizationUnitId">Id of the <see cref="OrganizationUnit"/>.</param>
public OrganizationUnitUser(Guid? tenantId, Guid userId, Guid organizationUnitId) public IdentityUserOrganizationUnit(Guid? tenantId, Guid userId, Guid organizationUnitId)
{ {
TenantId = tenantId; TenantId = tenantId;
UserId = userId; UserId = userId;

2
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/IOrganizationUnitRepository.cs

@ -10,5 +10,7 @@ namespace Volo.Abp.Identity.Organizations
Task<List<OrganizationUnit>> GetChildrenAsync(Guid? parentId); Task<List<OrganizationUnit>> GetChildrenAsync(Guid? parentId);
Task<List<OrganizationUnit>> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId); Task<List<OrganizationUnit>> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId);
Task<List<OrganizationUnit>> GetListAsync(IEnumerable<Guid> ids);
} }
} }

5
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs

@ -28,5 +28,10 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
return await DbSet.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value) return await DbSet.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value)
.ToListAsync(); .ToListAsync();
} }
public async Task<List<OrganizationUnit>> GetListAsync(IEnumerable<Guid> ids)
{
return await DbSet.Where(t => ids.Contains(t.Id)).ToListAsync();
}
} }
} }

4
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs

@ -165,9 +165,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
b.HasIndex(ou => new { ou.RoleId, ou.OrganizationUnitId }); b.HasIndex(ou => new { ou.RoleId, ou.OrganizationUnitId });
}); });
builder.Entity<OrganizationUnitUser>(b => builder.Entity<IdentityUserOrganizationUnit>(b =>
{ {
b.ToTable(options.TablePrefix + "OrganizationUnitUsers", options.Schema); b.ToTable(options.TablePrefix + "UserOrganizationUnits", options.Schema);
b.HasKey(ou => new { ou.OrganizationUnitId, ou.UserId }); b.HasKey(ou => new { ou.OrganizationUnitId, ou.UserId });

Loading…
Cancel
Save