Seed identity & permission data for a tenant via event handlers.

pull/7577/head
Halil İbrahim Kalkan 5 years ago
parent 6d50fc998d
commit a8b4e0dfa9

@ -1,10 +1,12 @@
using System;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus;
namespace Volo.Abp.MultiTenancy
{
[Serializable]
[EventName("abp.multi_tenancy.tenant.created")]
public class TenantCreatedEto
public class TenantCreatedEto : EtoBase
{
public Guid Id { get; set; }

@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
@ -57,6 +59,20 @@ namespace Volo.Abp.Identity
});
context.Services.AddAbpDynamicOptions<IdentityOptions, AbpIdentityOptionsManager>();
Configure<AbpDistributedEventBusOptions>(options =>
{
var serviceProvider = context.Services.GetServiceProviderOrNull();
if (serviceProvider != null)
{
var abpIdentityOptions = serviceProvider.GetRequiredService<IOptions<AbpIdentityOptions>>().Value;
if (!abpIdentityOptions.IsDistributedEventHandlingEnabled)
{
var identityDomainAssembly = typeof(AbpIdentityDomainModule).Assembly;
options.Handlers.RemoveAll(x => x.Assembly == identityDomainAssembly);
}
}
});
}
public override void PostConfigureServices(ServiceConfigurationContext context)

@ -4,6 +4,11 @@
{
public ExternalLoginProviderDictionary ExternalLoginProviders { get; }
/// <summary>
/// Default: true.
/// </summary>
public bool IsDistributedEventHandlingEnabled { get; } = true;
public AbpIdentityOptions()
{
ExternalLoginProviders = new ExternalLoginProviderDictionary();

@ -49,58 +49,61 @@ namespace Volo.Abp.Identity
Check.NotNullOrWhiteSpace(adminEmail, nameof(adminEmail));
Check.NotNullOrWhiteSpace(adminPassword, nameof(adminPassword));
await IdentityOptions.SetAsync();
var result = new IdentityDataSeedResult();
using (CurrentTenant.Change(tenantId))
{
//"admin" user
const string adminUserName = "admin";
var adminUser = await UserRepository.FindByNormalizedUserNameAsync(
LookupNormalizer.NormalizeName(adminUserName)
);
await IdentityOptions.SetAsync();
if (adminUser != null)
using (IdentityOptions.Value.Password.ClearRequirements())
{
return result;
}
var result = new IdentityDataSeedResult();
//"admin" user
const string adminUserName = "admin";
var adminUser = await UserRepository.FindByNormalizedUserNameAsync(
LookupNormalizer.NormalizeName(adminUserName)
);
adminUser = new IdentityUser(
GuidGenerator.Create(),
adminUserName,
adminEmail,
tenantId
)
{
Name = adminUserName
};
(await UserManager.CreateAsync(adminUser, adminPassword)).CheckErrors();
result.CreatedAdminUser = true;
if (adminUser != null)
{
return result;
}
//"admin" role
const string adminRoleName = "admin";
var adminRole = await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName(adminRoleName));
if (adminRole == null)
{
adminRole = new IdentityRole(
adminUser = new IdentityUser(
GuidGenerator.Create(),
adminRoleName,
adminUserName,
adminEmail,
tenantId
)
{
IsStatic = true,
IsPublic = true
Name = adminUserName
};
(await RoleManager.CreateAsync(adminRole)).CheckErrors();
result.CreatedAdminRole = true;
}
(await UserManager.CreateAsync(adminUser, adminPassword)).CheckErrors();
result.CreatedAdminUser = true;
//"admin" role
const string adminRoleName = "admin";
var adminRole =
await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName(adminRoleName));
if (adminRole == null)
{
adminRole = new IdentityRole(
GuidGenerator.Create(),
adminRoleName,
tenantId
)
{
IsStatic = true,
IsPublic = true
};
(await UserManager.AddToRoleAsync(adminUser, adminRoleName)).CheckErrors();
(await RoleManager.CreateAsync(adminRole)).CheckErrors();
result.CreatedAdminRole = true;
}
return result;
(await UserManager.AddToRoleAsync(adminUser, adminRoleName)).CheckErrors();
return result;
}
}
}
}

@ -0,0 +1,32 @@
using System.Threading.Tasks;
using AutoMapper.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity
{
public class IdentityTenantCreatedHandler : IDistributedEventHandler<TenantCreatedEto>, ITransientDependency
{
public ILogger<IdentityTenantCreatedHandler> Logger { get; set; }
protected IIdentityDataSeeder IdentityDataSeeder { get; }
public IdentityTenantCreatedHandler(IIdentityDataSeeder identityDataSeeder)
{
IdentityDataSeeder = identityDataSeeder;
Logger = NullLogger<IdentityTenantCreatedHandler>.Instance;
}
public async Task HandleEventAsync(TenantCreatedEto eventData)
{
await IdentityDataSeeder.SeedAsync(
eventData.Properties.GetOrDefault("AdminEmail") as string ?? "admin@abp.io",
eventData.Properties.GetOrDefault("AdminPassword") as string ?? "1q2w3E*",
eventData.Id
);
}
}
}

@ -0,0 +1,35 @@
using System;
using Microsoft.AspNetCore.Identity;
namespace Volo.Abp.Identity
{
public static class PasswordOptionsExtensions
{
public static IDisposable ClearRequirements(this PasswordOptions options)
{
var oldRequireDigit = options.RequireDigit;
var oldRequiredLength = options.RequiredLength;
var oldRequireLowercase = options.RequireLowercase;
var oldRequireUppercase = options.RequireUppercase;
var oldRequiredUniqueChars = options.RequiredUniqueChars;
var oldRequireNonAlphanumeric = options.RequireNonAlphanumeric;
options.RequireDigit = false;
options.RequiredLength = 1;
options.RequireLowercase = false;
options.RequireUppercase = false;
options.RequiredUniqueChars = 1;
options.RequireNonAlphanumeric = false;
return new DisposeAction(() =>
{
options.RequireDigit = oldRequireDigit;
options.RequiredLength = oldRequiredLength;
options.RequireLowercase = oldRequireLowercase;
options.RequireUppercase = oldRequireUppercase;
options.RequiredUniqueChars = oldRequiredUniqueChars;
options.RequireNonAlphanumeric = oldRequireNonAlphanumeric;
});
}
}
}

@ -1,6 +1,10 @@
using Volo.Abp.Authorization;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Authorization;
using Volo.Abp.Caching;
using Volo.Abp.Domain;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
@ -13,6 +17,21 @@ namespace Volo.Abp.PermissionManagement
[DependsOn(typeof(AbpJsonModule))]
public class AbpPermissionManagementDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDistributedEventBusOptions>(options =>
{
var serviceProvider = context.Services.GetServiceProviderOrNull();
if (serviceProvider != null)
{
var abpIdentityOptions = serviceProvider.GetRequiredService<IOptions<PermissionManagementOptions>>().Value;
if (!abpIdentityOptions.IsDistributedEventHandlingEnabled)
{
var identityDomainAssembly = typeof(AbpPermissionManagementDomainModule).Assembly;
options.Handlers.RemoveAll(x => x.Assembly == identityDomainAssembly);
}
}
});
}
}
}

@ -10,7 +10,6 @@ namespace Volo.Abp.PermissionManagement
public class PermissionDataSeedContributor : IDataSeedContributor, ITransientDependency
{
protected ICurrentTenant CurrentTenant { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }

@ -5,11 +5,15 @@ namespace Volo.Abp.PermissionManagement
{
public class PermissionManagementOptions
{
//TODO: rename to Providers
public ITypeList<IPermissionManagementProvider> ManagementProviders { get; }
public Dictionary<string, string> ProviderPolicies { get; }
/// <summary>
/// Default: true.
/// </summary>
public bool IsDistributedEventHandlingEnabled { get; } = true;
public PermissionManagementOptions()
{
ManagementProviders = new TypeList<IPermissionManagementProvider>();

@ -0,0 +1,38 @@
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.PermissionManagement
{
public class PermissionTenantCreatedHandler : IDistributedEventHandler<TenantCreatedEto>, ITransientDependency
{
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
protected IPermissionDataSeeder PermissionDataSeeder { get; }
public PermissionTenantCreatedHandler(IPermissionDefinitionManager permissionDefinitionManager, IPermissionDataSeeder permissionDataSeeder)
{
PermissionDefinitionManager = permissionDefinitionManager;
PermissionDataSeeder = permissionDataSeeder;
}
public async Task HandleEventAsync(TenantCreatedEto eventData)
{
var permissionNames = PermissionDefinitionManager
.GetPermissions()
.Where(p => p.MultiTenancySide.HasFlag(MultiTenancySides.Tenant))
.Where(p => !p.Providers.Any() || p.Providers.Contains(RolePermissionValueProvider.ProviderName))
.Select(p => p.Name)
.ToArray();
await PermissionDataSeeder.SeedAsync(
RolePermissionValueProvider.ProviderName,
"admin",
permissionNames,
eventData.Id
);
}
}
}
Loading…
Cancel
Save