eShopOnContainers/src/Services/Identity/Identity.API/Data/ApplicationDbContextSeed.cs

236 lines
9.6 KiB
C#
Raw Normal View History

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.eShopOnContainers.Services.Identity.API.Extensions;
using Microsoft.eShopOnContainers.Services.Identity.API.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Identity.API.Data
{
public class ApplicationDbContextSeed
{
private readonly IPasswordHasher<ApplicationUser> _passwordHasher = new PasswordHasher<ApplicationUser>();
2021-01-20 17:57:32 +01:00
public async Task SeedAsync(ApplicationDbContext context, IWebHostEnvironment env,
ILogger<ApplicationDbContextSeed> logger, IOptions<AppSettings> settings, int? retry = 0)
{
int retryForAvaiability = retry.Value;
try
{
var useCustomizationData = settings.Value.UseCustomizationData;
2017-06-20 12:54:32 -07:00
var contentRootPath = env.ContentRootPath;
var webroot = env.WebRootPath;
2017-06-20 12:54:32 -07:00
if (!context.Users.Any())
{
context.Users.AddRange(useCustomizationData
? GetUsersFromFile(contentRootPath, logger)
2017-06-20 12:54:32 -07:00
: GetDefaultUser());
await context.SaveChangesAsync();
}
if (useCustomizationData)
{
GetPreconfiguredImages(contentRootPath, webroot, logger);
}
}
catch (Exception ex)
{
if (retryForAvaiability < 10)
{
retryForAvaiability++;
2021-01-20 17:57:32 +01:00
2019-02-22 15:05:28 +00:00
logger.LogError(ex, "EXCEPTION ERROR while migrating {DbContextName}", nameof(ApplicationDbContext));
2021-01-20 17:57:32 +01:00
await SeedAsync(context, env, logger, settings, retryForAvaiability);
}
}
}
private IEnumerable<ApplicationUser> GetUsersFromFile(string contentRootPath, ILogger logger)
2017-06-20 12:54:32 -07:00
{
string csvFileUsers = Path.Combine(contentRootPath, "Setup", "Users.csv");
if (!File.Exists(csvFileUsers))
{
return GetDefaultUser();
}
string[] csvheaders;
try
{
string[] requiredHeaders = {
"cardholdername", "cardnumber", "cardtype", "city", "country",
"email", "expiration", "lastname", "name", "phonenumber",
"username", "zipcode", "state", "street", "securitynumber",
"normalizedemail", "normalizedusername", "password"
};
csvheaders = GetHeaders(requiredHeaders, csvFileUsers);
}
catch (Exception ex)
{
2019-02-22 15:05:28 +00:00
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message);
2017-06-20 12:54:32 -07:00
return GetDefaultUser();
}
List<ApplicationUser> users = File.ReadAllLines(csvFileUsers)
.Skip(1) // skip header column
2021-01-20 17:57:32 +01:00
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"))
2017-06-20 12:54:32 -07:00
.SelectTry(column => CreateApplicationUser(column, csvheaders))
2019-02-22 15:05:28 +00:00
.OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; })
2017-06-20 12:54:32 -07:00
.Where(x => x != null)
.ToList();
return users;
}
private ApplicationUser CreateApplicationUser(string[] column, string[] headers)
{
2017-06-20 12:54:32 -07:00
if (column.Count() != headers.Count())
{
throw new Exception($"column count '{column.Count()}' not the same as headers count'{headers.Count()}'");
}
string cardtypeString = column[Array.IndexOf(headers, "cardtype")].Trim('"').Trim();
2017-06-20 12:54:32 -07:00
if (!int.TryParse(cardtypeString, out int cardtype))
{
throw new Exception($"cardtype='{cardtypeString}' is not a number");
}
var user = new ApplicationUser
{
CardHolderName = column[Array.IndexOf(headers, "cardholdername")].Trim('"').Trim(),
CardNumber = column[Array.IndexOf(headers, "cardnumber")].Trim('"').Trim(),
2017-06-20 12:54:32 -07:00
CardType = cardtype,
City = column[Array.IndexOf(headers, "city")].Trim('"').Trim(),
Country = column[Array.IndexOf(headers, "country")].Trim('"').Trim(),
Email = column[Array.IndexOf(headers, "email")].Trim('"').Trim(),
Expiration = column[Array.IndexOf(headers, "expiration")].Trim('"').Trim(),
2017-06-20 12:54:32 -07:00
Id = Guid.NewGuid().ToString(),
LastName = column[Array.IndexOf(headers, "lastname")].Trim('"').Trim(),
Name = column[Array.IndexOf(headers, "name")].Trim('"').Trim(),
PhoneNumber = column[Array.IndexOf(headers, "phonenumber")].Trim('"').Trim(),
UserName = column[Array.IndexOf(headers, "username")].Trim('"').Trim(),
ZipCode = column[Array.IndexOf(headers, "zipcode")].Trim('"').Trim(),
State = column[Array.IndexOf(headers, "state")].Trim('"').Trim(),
Street = column[Array.IndexOf(headers, "street")].Trim('"').Trim(),
SecurityNumber = column[Array.IndexOf(headers, "securitynumber")].Trim('"').Trim(),
NormalizedEmail = column[Array.IndexOf(headers, "normalizedemail")].Trim('"').Trim(),
NormalizedUserName = column[Array.IndexOf(headers, "normalizedusername")].Trim('"').Trim(),
2017-06-20 12:54:32 -07:00
SecurityStamp = Guid.NewGuid().ToString("D"),
PasswordHash = column[Array.IndexOf(headers, "password")].Trim('"').Trim(), // Note: This is the password
2017-06-20 12:54:32 -07:00
};
user.PasswordHash = _passwordHasher.HashPassword(user, user.PasswordHash);
return user;
}
private IEnumerable<ApplicationUser> GetDefaultUser()
{
var user =
new ApplicationUser()
{
2016-12-14 18:23:57 +01:00
CardHolderName = "DemoUser",
CardNumber = "4012888888881881",
CardType = 1,
2016-12-14 18:23:57 +01:00
City = "Redmond",
Country = "U.S.",
Email = "demouser@microsoft.com",
Expiration = "12/21",
2017-06-20 12:54:32 -07:00
Id = Guid.NewGuid().ToString(),
LastName = "DemoLastName",
Name = "DemoUser",
PhoneNumber = "1234567890",
UserName = "demouser@microsoft.com",
ZipCode = "98052",
State = "WA",
Street = "15703 NE 61st Ct",
SecurityNumber = "535",
NormalizedEmail = "DEMOUSER@MICROSOFT.COM",
NormalizedUserName = "DEMOUSER@MICROSOFT.COM",
SecurityStamp = Guid.NewGuid().ToString("D"),
};
2016-12-14 18:23:57 +01:00
user.PasswordHash = _passwordHasher.HashPassword(user, "Pass@word1");
2017-06-20 12:54:32 -07:00
return new List<ApplicationUser>()
{
user
};
}
static string[] GetHeaders(string[] requiredHeaders, string csvfile)
{
string[] csvheaders = File.ReadLines(csvfile).First().ToLowerInvariant().Split(',');
if (csvheaders.Count() != requiredHeaders.Count())
{
throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is different then read header '{csvheaders.Count()}'");
}
foreach (var requiredHeader in requiredHeaders)
{
if (!csvheaders.Contains(requiredHeader))
{
throw new Exception($"does not contain required header '{requiredHeader}'");
}
}
return csvheaders;
}
static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger logger)
{
try
{
string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip");
if (!File.Exists(imagesZipFile))
{
2019-02-22 15:05:28 +00:00
logger.LogError("Zip file '{ZipFileName}' does not exists.", imagesZipFile);
return;
}
string imagePath = Path.Combine(webroot, "images");
string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray();
using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
if (imageFiles.Contains(entry.Name))
{
string destinationFilename = Path.Combine(imagePath, entry.Name);
if (File.Exists(destinationFilename))
{
File.Delete(destinationFilename);
}
entry.ExtractToFile(destinationFilename);
}
else
{
2019-02-22 15:05:28 +00:00
logger.LogWarning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile);
}
}
}
}
catch (Exception ex)
{
2019-02-22 15:05:28 +00:00
logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); ;
}
}
}
}