Initial ...
This commit is contained in:
@@ -0,0 +1,428 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using IdentityServer4.EntityFramework.DbContexts;
|
||||
using IdentityServer4.EntityFramework.Mappers;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using xCommons.Extensions;
|
||||
using xIdentityModels.Descriptors;
|
||||
using xIdentityModels.Extensions;
|
||||
using xIds.Constants;
|
||||
using xIds.Interfaces;
|
||||
using xIds.Models;
|
||||
|
||||
namespace xIds.Extensions
|
||||
{
|
||||
public static class XDbSeeder
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve DbSeedDescriptor from appSetting Configuration
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static XDbSeedDescriptor GetXDbSeedDescriptor(this IConfiguration configuration)
|
||||
{
|
||||
//
|
||||
var dbSeedSection = configuration.GetSection(ConfigurationNodeNames.DB_SEED_NODE_NAME);
|
||||
return dbSeedSection.Get<XDbSeedDescriptor>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register XDbSeedDescriptor as Singleton Service
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXDebSeederDescriptor(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
)
|
||||
{
|
||||
//
|
||||
var dbSeedDescriptor = configuration.GetXDbSeedDescriptor();
|
||||
if (!dbSeedDescriptor.IsNull())
|
||||
{
|
||||
services.AddSingleton<XDbSeedDescriptor>(dbSeedDescriptor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Error: DbSeeder Configuration not found in AppSetting ...");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Base Required Data to XIdentitySer DbContexts
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task SeedData(
|
||||
this IApplicationBuilder app,
|
||||
ILogger logger
|
||||
)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Start Add/Update XIdentityServer Descriptors ...");
|
||||
|
||||
//
|
||||
// Create Scope ...
|
||||
using (var scope = app.ApplicationServices.CreateScope())
|
||||
{
|
||||
//
|
||||
// Retrieve Required Configurations ...
|
||||
var dbSeedDescriptor = scope.ServiceProvider.GetService<XDbSeedDescriptor>();
|
||||
if (dbSeedDescriptor.IsNull())
|
||||
{
|
||||
//
|
||||
Console.WriteLine("DbSeeder is Null ...");
|
||||
return;
|
||||
}
|
||||
logger.LogInformation($"Update Exists Descriptors: {dbSeedDescriptor.UpdateExists.ToString()}");
|
||||
|
||||
//
|
||||
// Retrieve Required Services ...
|
||||
var identityProvider = scope.ServiceProvider.GetService<IXIdentityManager>();
|
||||
|
||||
//
|
||||
// Retrieve DbContexts ...
|
||||
var grantDbContext = scope.ServiceProvider.GetService<PersistedGrantDbContext>();
|
||||
var configDbContext = scope.ServiceProvider.GetService<ConfigurationDbContext>();
|
||||
|
||||
//
|
||||
#region Clients ...
|
||||
//
|
||||
logger.LogInformation($"Start Seeding Clients ...");
|
||||
|
||||
//
|
||||
var dClients = dbSeedDescriptor.Clients;
|
||||
var hasClient = configDbContext.Clients.Any();
|
||||
if ((!hasClient ||
|
||||
(hasClient && dbSeedDescriptor.UpdateExists)) &&
|
||||
dClients.HasChild())
|
||||
{
|
||||
//
|
||||
var clientEntities = dClients.Select(dc => dc.ToEntity());
|
||||
|
||||
//
|
||||
foreach (var client in clientEntities)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add/Update: {client.ClientId}");
|
||||
|
||||
//
|
||||
// Retrieve Exists Client ...
|
||||
var existsClient = configDbContext.Clients
|
||||
.Include(c => c.AllowedCorsOrigins)
|
||||
.Include(c => c.AllowedGrantTypes)
|
||||
.Include(c => c.AllowedScopes)
|
||||
.Include(c => c.Claims)
|
||||
.Include(c => c.ClientSecrets)
|
||||
.FirstOrDefault(cl => cl.ClientId == client.ClientId);
|
||||
|
||||
//
|
||||
var isExistsClient = !existsClient.IsNull();
|
||||
var isSameContent = isExistsClient &&
|
||||
existsClient.IsSameContent(client, propertyBlackList: new[] { nameof(existsClient.Id) });
|
||||
|
||||
//
|
||||
if (isExistsClient)
|
||||
{
|
||||
//
|
||||
if (!isSameContent)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Update Client: {existsClient.ClientId}");
|
||||
|
||||
//
|
||||
existsClient = existsClient.UpdateData(client, propertyBlackList: new[] { nameof(existsClient.Id) });
|
||||
configDbContext.Clients.Update(existsClient);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add Client: {client.ClientId}");
|
||||
|
||||
//
|
||||
await configDbContext.Clients.AddAsync(client);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save Changes on Config Db Context ...
|
||||
await configDbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//
|
||||
logger.LogInformation($"Finish Seeding Clients ...");
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region IdentityResources ...
|
||||
//
|
||||
logger.LogInformation($"Start Seeding Identity Resources ...");
|
||||
|
||||
//
|
||||
var dIdentityResources = dbSeedDescriptor.IdentityResources;
|
||||
var hasIdentityResources = configDbContext.IdentityResources.Any();
|
||||
if ((!hasIdentityResources ||
|
||||
(hasIdentityResources && dbSeedDescriptor.UpdateExists)) &&
|
||||
dIdentityResources.HasChild())
|
||||
{
|
||||
//
|
||||
var identityResourceEntities = dIdentityResources.Select(di => di.ToEntity());
|
||||
|
||||
//
|
||||
foreach (var identityResource in identityResourceEntities)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add/Update: {identityResource.DisplayName}");
|
||||
|
||||
//
|
||||
// Retrieve Exists IdentityResource ...
|
||||
var existsIdentityResource = configDbContext.IdentityResources
|
||||
.AsNoTracking()
|
||||
.FirstOrDefault(ir => ir.Name == identityResource.Name);
|
||||
|
||||
//
|
||||
var isExistsResource = !existsIdentityResource.IsNull();
|
||||
var isSameContent = isExistsResource &&
|
||||
existsIdentityResource.IsSameContent(identityResource, propertyBlackList: new[] { nameof(existsIdentityResource.Id) });
|
||||
|
||||
//
|
||||
if (isExistsResource &&
|
||||
dbSeedDescriptor.UpdateExists)
|
||||
{
|
||||
//
|
||||
if (!isSameContent)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Update IdentityResource: {identityResource.DisplayName}");
|
||||
|
||||
//
|
||||
existsIdentityResource = existsIdentityResource.UpdateData(identityResource, propertyBlackList: new[] { nameof(existsIdentityResource.Id) });
|
||||
configDbContext.IdentityResources.Update(existsIdentityResource);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add IdentityResource: {identityResource.DisplayName}");
|
||||
|
||||
//
|
||||
await configDbContext.IdentityResources.AddAsync(identityResource);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save Changes on Config Db Context ...
|
||||
// await configDbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//
|
||||
logger.LogInformation($"Finish Seeding Identity Resources ...");
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Api Resources ...
|
||||
//
|
||||
logger.LogInformation($"Start Seeding Api Resources ...");
|
||||
|
||||
//
|
||||
var dApiResources = dbSeedDescriptor.ApiResources;
|
||||
var hasApiResources = configDbContext.ApiResources.Any();
|
||||
if ((!hasApiResources ||
|
||||
(hasApiResources && dbSeedDescriptor.UpdateExists)) &&
|
||||
dApiResources.HasChild())
|
||||
{
|
||||
//
|
||||
var apiResourceEntities = dApiResources.Select(da => da.ToEntity());
|
||||
|
||||
//
|
||||
foreach (var apiResource in apiResourceEntities)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add/Update: {apiResource.DisplayName}");
|
||||
|
||||
//
|
||||
// Retrieve Exists ApiResource ...
|
||||
var existsApiResource = configDbContext.ApiResources
|
||||
.Include(r => r.Secrets)
|
||||
.Include(r => r.Scopes)
|
||||
.FirstOrDefault(ar => ar.Name == apiResource.Name);
|
||||
|
||||
//
|
||||
var isExistsResource = !existsApiResource.IsNull();
|
||||
var isSameContent = isExistsResource &&
|
||||
existsApiResource.IsSameContent(apiResource, propertyBlackList: new[] { nameof(existsApiResource.Id) });
|
||||
|
||||
//
|
||||
if (isExistsResource &&
|
||||
dbSeedDescriptor.UpdateExists)
|
||||
{
|
||||
//
|
||||
if (!isSameContent)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Update ApiResource: {existsApiResource.DisplayName}");
|
||||
|
||||
//
|
||||
existsApiResource = existsApiResource.UpdateData(apiResource, propertyBlackList: new[] { nameof(existsApiResource.Id) });
|
||||
configDbContext.ApiResources.Update(existsApiResource);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add ApiResource: {apiResource.DisplayName}");
|
||||
|
||||
//
|
||||
await configDbContext.ApiResources.AddAsync(apiResource);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save Changes on Config Db Context ...
|
||||
// await configDbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//
|
||||
logger.LogInformation($"Finish Seeding Api Resources ...");
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Api Scopes ...
|
||||
//
|
||||
logger.LogInformation($"Start Seeding Scopes ...");
|
||||
|
||||
//
|
||||
var dScopes = dbSeedDescriptor.ApiScopes;
|
||||
var hasScope = configDbContext.ApiScopes.Any();
|
||||
if ((!hasScope ||
|
||||
(hasScope && dbSeedDescriptor.UpdateExists)) &&
|
||||
dScopes.HasChild())
|
||||
{
|
||||
//
|
||||
var apiScopeEntities = dScopes.Select(dc => dc.ToEntity());
|
||||
|
||||
//
|
||||
foreach (var apiScope in apiScopeEntities)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add/Update: {apiScope.DisplayName}");
|
||||
|
||||
//
|
||||
// Retrieve Exists Client ...
|
||||
var existsScope = configDbContext.ApiScopes
|
||||
.FirstOrDefault(sc => sc.Name == apiScope.Name);
|
||||
|
||||
//
|
||||
var isExistsScope = !existsScope.IsNull();
|
||||
var isSameContent = isExistsScope &&
|
||||
existsScope.IsSameContent(apiScope, propertyBlackList: new[] { nameof(existsScope.Id) });
|
||||
|
||||
//
|
||||
if (isExistsScope &&
|
||||
dbSeedDescriptor.UpdateExists)
|
||||
{
|
||||
//
|
||||
if (!isSameContent)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Update ApiScope: {existsScope.Name}");
|
||||
|
||||
//
|
||||
existsScope = existsScope.UpdateData(apiScope, propertyBlackList: new[] { nameof(existsScope.Id) });
|
||||
configDbContext.ApiScopes.Update(existsScope);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add ApiScope: {apiScope.Name}");
|
||||
|
||||
//
|
||||
await configDbContext.ApiScopes.AddAsync(apiScope);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save Changes on Config Db Context ...
|
||||
await configDbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//
|
||||
logger.LogInformation($"Finish Seeding Scopes ...");
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Users ...
|
||||
//
|
||||
logger.LogInformation($"Start Seeding Users ...");
|
||||
|
||||
//
|
||||
var configUsers = dbSeedDescriptor.Users;
|
||||
var hasUser = identityProvider.GetUsersDbSet().Any();
|
||||
if ((!hasUser ||
|
||||
(hasUser && dbSeedDescriptor.UpdateExists)) &&
|
||||
configUsers.HasChild())
|
||||
{
|
||||
foreach (var user in configUsers)
|
||||
{
|
||||
//
|
||||
logger.LogInformation($"Add/Update User: {user.UserName}");
|
||||
|
||||
//
|
||||
var isUserExists = await identityProvider.IsUserExistsAsync(user.UserName);
|
||||
if (isUserExists &&
|
||||
dbSeedDescriptor.UpdateExists)
|
||||
{
|
||||
//
|
||||
var existsUser = await identityProvider.GetUserAsync(user.UserName);
|
||||
var isSame = existsUser.IsSameAs(user);
|
||||
if (!isSame)
|
||||
{
|
||||
//
|
||||
// Update Entity ...
|
||||
existsUser = existsUser.UpdateData(user, propertyWhiteList: new[] {
|
||||
nameof (XIdentityUserDescriptor.FirstName),
|
||||
nameof (XIdentityUserDescriptor.LastName),
|
||||
nameof (XIdentityUserDescriptor.UserName),
|
||||
nameof (XIdentityUserDescriptor.Email),
|
||||
nameof (XIdentityUserDescriptor.EmailConfirmed),
|
||||
nameof (XIdentityUserDescriptor.PhoneNumber),
|
||||
nameof (XIdentityUserDescriptor.PhoneNumberConfirmed),
|
||||
nameof (XIdentityUserDescriptor.IsEnable),
|
||||
nameof (XIdentityUserDescriptor.IsBanned),
|
||||
nameof (XIdentityUserDescriptor.DateOfBirth)
|
||||
}, propertyValueProviders: new[] {
|
||||
new KeyValuePair<string, Func<XIdentityUserDescriptor, object>> (
|
||||
nameof (XIdentityUserDescriptor.DateOfBirth),
|
||||
(user) => DateTime.Parse (user.DateOfBirth))
|
||||
});
|
||||
|
||||
//
|
||||
await identityProvider.UpdateUserAsync(existsUser, false, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await identityProvider.CreateUserAsync(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
logger.LogInformation($"Finish Seeding Users ...");
|
||||
#endregion
|
||||
}
|
||||
|
||||
//
|
||||
logger.LogInformation($"Finish Add/Update XIdentityServer Descriptors ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user