204 lines
8.1 KiB
C#
Raw Normal View History

namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure
{
using AspNetCore.Identity;
using EntityFrameworkCore;
using Extensions.Logging;
2017-06-20 12:54:32 -07:00
using global::eShopOnContainers.Identity;
2017-01-30 11:35:16 +01:00
using global::Identity.API.Data;
using global::Identity.API.Models;
2017-06-20 12:54:32 -07:00
using Identity.API.Extensions;
using Microsoft.AspNetCore.Builder;
2017-06-20 12:54:32 -07:00
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
2017-06-20 12:54:32 -07:00
using System.IO;
using System.Linq;
using System.Security.Cryptography;
2017-06-20 12:54:32 -07:00
using System.Text.RegularExpressions;
using System.Threading.Tasks;
public class ApplicationContextSeed
{
private readonly IPasswordHasher<ApplicationUser> _passwordHasher;
public ApplicationContextSeed(IPasswordHasher<ApplicationUser> passwordHasher)
{
_passwordHasher = passwordHasher;
}
2017-06-20 12:54:32 -07:00
public async Task SeedAsync(IApplicationBuilder applicationBuilder, IHostingEnvironment env, ILoggerFactory loggerFactory, int? retry = 0)
{
int retryForAvaiability = retry.Value;
try
{
2017-06-20 12:54:32 -07:00
var log = loggerFactory.CreateLogger("application seed");
var context = (ApplicationDbContext)applicationBuilder
.ApplicationServices.GetService(typeof(ApplicationDbContext));
context.Database.Migrate();
2017-06-20 12:54:32 -07:00
var settings = (AppSettings)applicationBuilder
.ApplicationServices.GetRequiredService<IOptions<AppSettings>>().Value;
var useCustomizationData = settings.UseCustomizationData;
var contentRootPath = env.ContentRootPath;
if (!context.Users.Any())
{
2017-06-20 12:54:32 -07:00
context.Users.AddRange(useCustomizationData
? GetUsersFromFile(contentRootPath, log)
: GetDefaultUser());
await context.SaveChangesAsync();
}
}
catch (Exception ex)
{
if (retryForAvaiability < 10)
{
retryForAvaiability++;
var log = loggerFactory.CreateLogger("catalog seed");
log.LogError(ex.Message);
2017-06-20 12:54:32 -07:00
await SeedAsync(applicationBuilder, env, loggerFactory, retryForAvaiability);
}
}
}
2017-06-20 12:54:32 -07:00
private IEnumerable<ApplicationUser> GetUsersFromFile(string contentRootPath, ILogger log)
{
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)
{
log.LogError(ex.Message);
return GetDefaultUser();
}
List<ApplicationUser> users = File.ReadAllLines(csvFileUsers)
.Skip(1) // skip header column
.Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)") )
.SelectTry(column => CreateApplicationUser(column, csvheaders))
.OnCaughtException(ex => { log.LogError(ex.Message); return null; })
.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();
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(),
CardNumber = column[Array.IndexOf(headers, "cardnumber")].Trim(),
CardType = cardtype,
City = column[Array.IndexOf(headers, "city")].Trim(),
Country = column[Array.IndexOf(headers, "country")].Trim(),
Email = column[Array.IndexOf(headers, "email")].Trim(),
Expiration = column[Array.IndexOf(headers, "expiration")].Trim(),
Id = Guid.NewGuid().ToString(),
LastName = column[Array.IndexOf(headers, "lastname")].Trim(),
Name = column[Array.IndexOf(headers, "name")].Trim(),
PhoneNumber = column[Array.IndexOf(headers, "phonenumber")].Trim(),
UserName = column[Array.IndexOf(headers, "username")].Trim(),
ZipCode = column[Array.IndexOf(headers, "zipcode")].Trim(),
State = column[Array.IndexOf(headers, "state")].Trim(),
Street = column[Array.IndexOf(headers, "street")].Trim(),
SecurityNumber = column[Array.IndexOf(headers, "securitynumber")].Trim(),
NormalizedEmail = column[Array.IndexOf(headers, "normalizedemail")].Trim(),
NormalizedUserName = column[Array.IndexOf(headers, "normalizedusername")].Trim(),
SecurityStamp = Guid.NewGuid().ToString("D"),
PasswordHash = column[Array.IndexOf(headers, "password")].Trim(), // Note: This is the password
};
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/20",
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;
}
}
}