mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 02:39:03 +00:00
Update namespaces
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
using API.Core.Contracts.Auth;
|
||||
using API.Core.Contracts.Common;
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
using Infrastructure.Jwt;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Service.Core.Auth;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Service.Core.User;
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<Folder Name="/Infrastructure/">
|
||||
<Project Path="Infrastructure/Infrastructure.Jwt/Infrastructure.Jwt.csproj" />
|
||||
<Project Path="Infrastructure/Infrastructure.PasswordHashing/Infrastructure.PasswordHashing.csproj" />
|
||||
<Project Path="Infrastructure/Infrastructure.Repository.Tests/Repository.Tests.csproj" />
|
||||
<Project Path="Infrastructure/Infrastructure.Repository/Infrastructure.Repository.csproj" />
|
||||
<Project Path="Infrastructure\Infrastructure.Repository.Tests\Infrastructure.Repository.Tests.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Service/">
|
||||
<Project Path="Service/Service.Core/Service.Core.csproj" />
|
||||
|
||||
@@ -2,8 +2,5 @@ using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace DBSeed
|
||||
{
|
||||
internal interface ISeeder
|
||||
{
|
||||
Task SeedAsync(SqlConnection connection);
|
||||
}
|
||||
Task SeedAsync(SqlConnection connection);
|
||||
}
|
||||
@@ -1,328 +1,326 @@
|
||||
using System.Data;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace DBSeed
|
||||
namespace Database.Seed;
|
||||
|
||||
internal class LocationSeeder : ISeeder
|
||||
{
|
||||
private static readonly IReadOnlyList<(
|
||||
string CountryName,
|
||||
string CountryCode
|
||||
)> Countries =
|
||||
[
|
||||
("Canada", "CA"),
|
||||
("Mexico", "MX"),
|
||||
("United States", "US"),
|
||||
];
|
||||
|
||||
internal class LocationSeeder : ISeeder
|
||||
private static IReadOnlyList<(string StateProvinceName, string StateProvinceCode, string CountryCode)> States
|
||||
{
|
||||
private static readonly IReadOnlyList<(
|
||||
string CountryName,
|
||||
string CountryCode
|
||||
)> Countries =
|
||||
[
|
||||
("Canada", "CA"),
|
||||
("Mexico", "MX"),
|
||||
("United States", "US"),
|
||||
];
|
||||
get;
|
||||
} =
|
||||
[
|
||||
("Alabama", "US-AL", "US"),
|
||||
("Alaska", "US-AK", "US"),
|
||||
("Arizona", "US-AZ", "US"),
|
||||
("Arkansas", "US-AR", "US"),
|
||||
("California", "US-CA", "US"),
|
||||
("Colorado", "US-CO", "US"),
|
||||
("Connecticut", "US-CT", "US"),
|
||||
("Delaware", "US-DE", "US"),
|
||||
("Florida", "US-FL", "US"),
|
||||
("Georgia", "US-GA", "US"),
|
||||
("Hawaii", "US-HI", "US"),
|
||||
("Idaho", "US-ID", "US"),
|
||||
("Illinois", "US-IL", "US"),
|
||||
("Indiana", "US-IN", "US"),
|
||||
("Iowa", "US-IA", "US"),
|
||||
("Kansas", "US-KS", "US"),
|
||||
("Kentucky", "US-KY", "US"),
|
||||
("Louisiana", "US-LA", "US"),
|
||||
("Maine", "US-ME", "US"),
|
||||
("Maryland", "US-MD", "US"),
|
||||
("Massachusetts", "US-MA", "US"),
|
||||
("Michigan", "US-MI", "US"),
|
||||
("Minnesota", "US-MN", "US"),
|
||||
("Mississippi", "US-MS", "US"),
|
||||
("Missouri", "US-MO", "US"),
|
||||
("Montana", "US-MT", "US"),
|
||||
("Nebraska", "US-NE", "US"),
|
||||
("Nevada", "US-NV", "US"),
|
||||
("New Hampshire", "US-NH", "US"),
|
||||
("New Jersey", "US-NJ", "US"),
|
||||
("New Mexico", "US-NM", "US"),
|
||||
("New York", "US-NY", "US"),
|
||||
("North Carolina", "US-NC", "US"),
|
||||
("North Dakota", "US-ND", "US"),
|
||||
("Ohio", "US-OH", "US"),
|
||||
("Oklahoma", "US-OK", "US"),
|
||||
("Oregon", "US-OR", "US"),
|
||||
("Pennsylvania", "US-PA", "US"),
|
||||
("Rhode Island", "US-RI", "US"),
|
||||
("South Carolina", "US-SC", "US"),
|
||||
("South Dakota", "US-SD", "US"),
|
||||
("Tennessee", "US-TN", "US"),
|
||||
("Texas", "US-TX", "US"),
|
||||
("Utah", "US-UT", "US"),
|
||||
("Vermont", "US-VT", "US"),
|
||||
("Virginia", "US-VA", "US"),
|
||||
("Washington", "US-WA", "US"),
|
||||
("West Virginia", "US-WV", "US"),
|
||||
("Wisconsin", "US-WI", "US"),
|
||||
("Wyoming", "US-WY", "US"),
|
||||
("District of Columbia", "US-DC", "US"),
|
||||
("Puerto Rico", "US-PR", "US"),
|
||||
("U.S. Virgin Islands", "US-VI", "US"),
|
||||
("Guam", "US-GU", "US"),
|
||||
("Northern Mariana Islands", "US-MP", "US"),
|
||||
("American Samoa", "US-AS", "US"),
|
||||
("Ontario", "CA-ON", "CA"),
|
||||
("Québec", "CA-QC", "CA"),
|
||||
("Nova Scotia", "CA-NS", "CA"),
|
||||
("New Brunswick", "CA-NB", "CA"),
|
||||
("Manitoba", "CA-MB", "CA"),
|
||||
("British Columbia", "CA-BC", "CA"),
|
||||
("Prince Edward Island", "CA-PE", "CA"),
|
||||
("Saskatchewan", "CA-SK", "CA"),
|
||||
("Alberta", "CA-AB", "CA"),
|
||||
("Newfoundland and Labrador", "CA-NL", "CA"),
|
||||
("Northwest Territories", "CA-NT", "CA"),
|
||||
("Yukon", "CA-YT", "CA"),
|
||||
("Nunavut", "CA-NU", "CA"),
|
||||
("Aguascalientes", "MX-AGU", "MX"),
|
||||
("Baja California", "MX-BCN", "MX"),
|
||||
("Baja California Sur", "MX-BCS", "MX"),
|
||||
("Campeche", "MX-CAM", "MX"),
|
||||
("Chiapas", "MX-CHP", "MX"),
|
||||
("Chihuahua", "MX-CHH", "MX"),
|
||||
("Coahuila de Zaragoza", "MX-COA", "MX"),
|
||||
("Colima", "MX-COL", "MX"),
|
||||
("Durango", "MX-DUR", "MX"),
|
||||
("Guanajuato", "MX-GUA", "MX"),
|
||||
("Guerrero", "MX-GRO", "MX"),
|
||||
("Hidalgo", "MX-HID", "MX"),
|
||||
("Jalisco", "MX-JAL", "MX"),
|
||||
("México State", "MX-MEX", "MX"),
|
||||
("Michoacán de Ocampo", "MX-MIC", "MX"),
|
||||
("Morelos", "MX-MOR", "MX"),
|
||||
("Nayarit", "MX-NAY", "MX"),
|
||||
("Nuevo León", "MX-NLE", "MX"),
|
||||
("Oaxaca", "MX-OAX", "MX"),
|
||||
("Puebla", "MX-PUE", "MX"),
|
||||
("Querétaro", "MX-QUE", "MX"),
|
||||
("Quintana Roo", "MX-ROO", "MX"),
|
||||
("San Luis Potosí", "MX-SLP", "MX"),
|
||||
("Sinaloa", "MX-SIN", "MX"),
|
||||
("Sonora", "MX-SON", "MX"),
|
||||
("Tabasco", "MX-TAB", "MX"),
|
||||
("Tamaulipas", "MX-TAM", "MX"),
|
||||
("Tlaxcala", "MX-TLA", "MX"),
|
||||
("Veracruz de Ignacio de la Llave", "MX-VER", "MX"),
|
||||
("Yucatán", "MX-YUC", "MX"),
|
||||
("Zacatecas", "MX-ZAC", "MX"),
|
||||
("Ciudad de México", "MX-CMX", "MX"),
|
||||
];
|
||||
|
||||
private static IReadOnlyList<(string StateProvinceName, string StateProvinceCode, string CountryCode)> States
|
||||
private static IReadOnlyList<(string StateProvinceCode, string CityName)> Cities { get; } =
|
||||
[
|
||||
("US-CA", "Los Angeles"),
|
||||
("US-CA", "San Diego"),
|
||||
("US-CA", "San Francisco"),
|
||||
("US-CA", "Sacramento"),
|
||||
("US-TX", "Houston"),
|
||||
("US-TX", "Dallas"),
|
||||
("US-TX", "Austin"),
|
||||
("US-TX", "San Antonio"),
|
||||
("US-FL", "Miami"),
|
||||
("US-FL", "Orlando"),
|
||||
("US-FL", "Tampa"),
|
||||
("US-NY", "New York"),
|
||||
("US-NY", "Buffalo"),
|
||||
("US-NY", "Rochester"),
|
||||
("US-IL", "Chicago"),
|
||||
("US-IL", "Springfield"),
|
||||
("US-PA", "Philadelphia"),
|
||||
("US-PA", "Pittsburgh"),
|
||||
("US-AZ", "Phoenix"),
|
||||
("US-AZ", "Tucson"),
|
||||
("US-CO", "Denver"),
|
||||
("US-CO", "Colorado Springs"),
|
||||
("US-MA", "Boston"),
|
||||
("US-MA", "Worcester"),
|
||||
("US-WA", "Seattle"),
|
||||
("US-WA", "Spokane"),
|
||||
("US-GA", "Atlanta"),
|
||||
("US-GA", "Savannah"),
|
||||
("US-NV", "Las Vegas"),
|
||||
("US-NV", "Reno"),
|
||||
("US-MI", "Detroit"),
|
||||
("US-MI", "Grand Rapids"),
|
||||
("US-MN", "Minneapolis"),
|
||||
("US-MN", "Saint Paul"),
|
||||
("US-OH", "Columbus"),
|
||||
("US-OH", "Cleveland"),
|
||||
("US-OR", "Portland"),
|
||||
("US-OR", "Salem"),
|
||||
("US-TN", "Nashville"),
|
||||
("US-TN", "Memphis"),
|
||||
("US-VA", "Richmond"),
|
||||
("US-VA", "Virginia Beach"),
|
||||
("US-MD", "Baltimore"),
|
||||
("US-MD", "Frederick"),
|
||||
("US-DC", "Washington"),
|
||||
("US-UT", "Salt Lake City"),
|
||||
("US-UT", "Provo"),
|
||||
("US-LA", "New Orleans"),
|
||||
("US-LA", "Baton Rouge"),
|
||||
("US-KY", "Louisville"),
|
||||
("US-KY", "Lexington"),
|
||||
("US-IA", "Des Moines"),
|
||||
("US-IA", "Cedar Rapids"),
|
||||
("US-OK", "Oklahoma City"),
|
||||
("US-OK", "Tulsa"),
|
||||
("US-NE", "Omaha"),
|
||||
("US-NE", "Lincoln"),
|
||||
("US-MO", "Kansas City"),
|
||||
("US-MO", "St. Louis"),
|
||||
("US-NC", "Charlotte"),
|
||||
("US-NC", "Raleigh"),
|
||||
("US-SC", "Columbia"),
|
||||
("US-SC", "Charleston"),
|
||||
("US-WI", "Milwaukee"),
|
||||
("US-WI", "Madison"),
|
||||
("US-MN", "Duluth"),
|
||||
("US-AK", "Anchorage"),
|
||||
("US-HI", "Honolulu"),
|
||||
("CA-ON", "Toronto"),
|
||||
("CA-ON", "Ottawa"),
|
||||
("CA-QC", "Montréal"),
|
||||
("CA-QC", "Québec City"),
|
||||
("CA-BC", "Vancouver"),
|
||||
("CA-BC", "Victoria"),
|
||||
("CA-AB", "Calgary"),
|
||||
("CA-AB", "Edmonton"),
|
||||
("CA-MB", "Winnipeg"),
|
||||
("CA-NS", "Halifax"),
|
||||
("CA-SK", "Saskatoon"),
|
||||
("CA-SK", "Regina"),
|
||||
("CA-NB", "Moncton"),
|
||||
("CA-NB", "Saint John"),
|
||||
("CA-PE", "Charlottetown"),
|
||||
("CA-NL", "St. John's"),
|
||||
("CA-ON", "Hamilton"),
|
||||
("CA-ON", "London"),
|
||||
("CA-QC", "Gatineau"),
|
||||
("CA-QC", "Laval"),
|
||||
("CA-BC", "Kelowna"),
|
||||
("CA-AB", "Red Deer"),
|
||||
("CA-MB", "Brandon"),
|
||||
("MX-CMX", "Ciudad de México"),
|
||||
("MX-JAL", "Guadalajara"),
|
||||
("MX-NLE", "Monterrey"),
|
||||
("MX-PUE", "Puebla"),
|
||||
("MX-ROO", "Cancún"),
|
||||
("MX-GUA", "Guanajuato"),
|
||||
("MX-MIC", "Morelia"),
|
||||
("MX-BCN", "Tijuana"),
|
||||
("MX-JAL", "Zapopan"),
|
||||
("MX-NLE", "San Nicolás"),
|
||||
("MX-CAM", "Campeche"),
|
||||
("MX-TAB", "Villahermosa"),
|
||||
("MX-VER", "Veracruz"),
|
||||
("MX-OAX", "Oaxaca"),
|
||||
("MX-SLP", "San Luis Potosí"),
|
||||
("MX-CHH", "Chihuahua"),
|
||||
("MX-AGU", "Aguascalientes"),
|
||||
("MX-MEX", "Toluca"),
|
||||
("MX-COA", "Saltillo"),
|
||||
("MX-BCS", "La Paz"),
|
||||
("MX-NAY", "Tepic"),
|
||||
("MX-ZAC", "Zacatecas"),
|
||||
];
|
||||
|
||||
public async Task SeedAsync(SqlConnection connection)
|
||||
{
|
||||
foreach (var (countryName, countryCode) in Countries)
|
||||
{
|
||||
get;
|
||||
} =
|
||||
[
|
||||
("Alabama", "US-AL", "US"),
|
||||
("Alaska", "US-AK", "US"),
|
||||
("Arizona", "US-AZ", "US"),
|
||||
("Arkansas", "US-AR", "US"),
|
||||
("California", "US-CA", "US"),
|
||||
("Colorado", "US-CO", "US"),
|
||||
("Connecticut", "US-CT", "US"),
|
||||
("Delaware", "US-DE", "US"),
|
||||
("Florida", "US-FL", "US"),
|
||||
("Georgia", "US-GA", "US"),
|
||||
("Hawaii", "US-HI", "US"),
|
||||
("Idaho", "US-ID", "US"),
|
||||
("Illinois", "US-IL", "US"),
|
||||
("Indiana", "US-IN", "US"),
|
||||
("Iowa", "US-IA", "US"),
|
||||
("Kansas", "US-KS", "US"),
|
||||
("Kentucky", "US-KY", "US"),
|
||||
("Louisiana", "US-LA", "US"),
|
||||
("Maine", "US-ME", "US"),
|
||||
("Maryland", "US-MD", "US"),
|
||||
("Massachusetts", "US-MA", "US"),
|
||||
("Michigan", "US-MI", "US"),
|
||||
("Minnesota", "US-MN", "US"),
|
||||
("Mississippi", "US-MS", "US"),
|
||||
("Missouri", "US-MO", "US"),
|
||||
("Montana", "US-MT", "US"),
|
||||
("Nebraska", "US-NE", "US"),
|
||||
("Nevada", "US-NV", "US"),
|
||||
("New Hampshire", "US-NH", "US"),
|
||||
("New Jersey", "US-NJ", "US"),
|
||||
("New Mexico", "US-NM", "US"),
|
||||
("New York", "US-NY", "US"),
|
||||
("North Carolina", "US-NC", "US"),
|
||||
("North Dakota", "US-ND", "US"),
|
||||
("Ohio", "US-OH", "US"),
|
||||
("Oklahoma", "US-OK", "US"),
|
||||
("Oregon", "US-OR", "US"),
|
||||
("Pennsylvania", "US-PA", "US"),
|
||||
("Rhode Island", "US-RI", "US"),
|
||||
("South Carolina", "US-SC", "US"),
|
||||
("South Dakota", "US-SD", "US"),
|
||||
("Tennessee", "US-TN", "US"),
|
||||
("Texas", "US-TX", "US"),
|
||||
("Utah", "US-UT", "US"),
|
||||
("Vermont", "US-VT", "US"),
|
||||
("Virginia", "US-VA", "US"),
|
||||
("Washington", "US-WA", "US"),
|
||||
("West Virginia", "US-WV", "US"),
|
||||
("Wisconsin", "US-WI", "US"),
|
||||
("Wyoming", "US-WY", "US"),
|
||||
("District of Columbia", "US-DC", "US"),
|
||||
("Puerto Rico", "US-PR", "US"),
|
||||
("U.S. Virgin Islands", "US-VI", "US"),
|
||||
("Guam", "US-GU", "US"),
|
||||
("Northern Mariana Islands", "US-MP", "US"),
|
||||
("American Samoa", "US-AS", "US"),
|
||||
("Ontario", "CA-ON", "CA"),
|
||||
("Québec", "CA-QC", "CA"),
|
||||
("Nova Scotia", "CA-NS", "CA"),
|
||||
("New Brunswick", "CA-NB", "CA"),
|
||||
("Manitoba", "CA-MB", "CA"),
|
||||
("British Columbia", "CA-BC", "CA"),
|
||||
("Prince Edward Island", "CA-PE", "CA"),
|
||||
("Saskatchewan", "CA-SK", "CA"),
|
||||
("Alberta", "CA-AB", "CA"),
|
||||
("Newfoundland and Labrador", "CA-NL", "CA"),
|
||||
("Northwest Territories", "CA-NT", "CA"),
|
||||
("Yukon", "CA-YT", "CA"),
|
||||
("Nunavut", "CA-NU", "CA"),
|
||||
("Aguascalientes", "MX-AGU", "MX"),
|
||||
("Baja California", "MX-BCN", "MX"),
|
||||
("Baja California Sur", "MX-BCS", "MX"),
|
||||
("Campeche", "MX-CAM", "MX"),
|
||||
("Chiapas", "MX-CHP", "MX"),
|
||||
("Chihuahua", "MX-CHH", "MX"),
|
||||
("Coahuila de Zaragoza", "MX-COA", "MX"),
|
||||
("Colima", "MX-COL", "MX"),
|
||||
("Durango", "MX-DUR", "MX"),
|
||||
("Guanajuato", "MX-GUA", "MX"),
|
||||
("Guerrero", "MX-GRO", "MX"),
|
||||
("Hidalgo", "MX-HID", "MX"),
|
||||
("Jalisco", "MX-JAL", "MX"),
|
||||
("México State", "MX-MEX", "MX"),
|
||||
("Michoacán de Ocampo", "MX-MIC", "MX"),
|
||||
("Morelos", "MX-MOR", "MX"),
|
||||
("Nayarit", "MX-NAY", "MX"),
|
||||
("Nuevo León", "MX-NLE", "MX"),
|
||||
("Oaxaca", "MX-OAX", "MX"),
|
||||
("Puebla", "MX-PUE", "MX"),
|
||||
("Querétaro", "MX-QUE", "MX"),
|
||||
("Quintana Roo", "MX-ROO", "MX"),
|
||||
("San Luis Potosí", "MX-SLP", "MX"),
|
||||
("Sinaloa", "MX-SIN", "MX"),
|
||||
("Sonora", "MX-SON", "MX"),
|
||||
("Tabasco", "MX-TAB", "MX"),
|
||||
("Tamaulipas", "MX-TAM", "MX"),
|
||||
("Tlaxcala", "MX-TLA", "MX"),
|
||||
("Veracruz de Ignacio de la Llave", "MX-VER", "MX"),
|
||||
("Yucatán", "MX-YUC", "MX"),
|
||||
("Zacatecas", "MX-ZAC", "MX"),
|
||||
("Ciudad de México", "MX-CMX", "MX"),
|
||||
];
|
||||
|
||||
private static IReadOnlyList<(string StateProvinceCode, string CityName)> Cities { get; } =
|
||||
[
|
||||
("US-CA", "Los Angeles"),
|
||||
("US-CA", "San Diego"),
|
||||
("US-CA", "San Francisco"),
|
||||
("US-CA", "Sacramento"),
|
||||
("US-TX", "Houston"),
|
||||
("US-TX", "Dallas"),
|
||||
("US-TX", "Austin"),
|
||||
("US-TX", "San Antonio"),
|
||||
("US-FL", "Miami"),
|
||||
("US-FL", "Orlando"),
|
||||
("US-FL", "Tampa"),
|
||||
("US-NY", "New York"),
|
||||
("US-NY", "Buffalo"),
|
||||
("US-NY", "Rochester"),
|
||||
("US-IL", "Chicago"),
|
||||
("US-IL", "Springfield"),
|
||||
("US-PA", "Philadelphia"),
|
||||
("US-PA", "Pittsburgh"),
|
||||
("US-AZ", "Phoenix"),
|
||||
("US-AZ", "Tucson"),
|
||||
("US-CO", "Denver"),
|
||||
("US-CO", "Colorado Springs"),
|
||||
("US-MA", "Boston"),
|
||||
("US-MA", "Worcester"),
|
||||
("US-WA", "Seattle"),
|
||||
("US-WA", "Spokane"),
|
||||
("US-GA", "Atlanta"),
|
||||
("US-GA", "Savannah"),
|
||||
("US-NV", "Las Vegas"),
|
||||
("US-NV", "Reno"),
|
||||
("US-MI", "Detroit"),
|
||||
("US-MI", "Grand Rapids"),
|
||||
("US-MN", "Minneapolis"),
|
||||
("US-MN", "Saint Paul"),
|
||||
("US-OH", "Columbus"),
|
||||
("US-OH", "Cleveland"),
|
||||
("US-OR", "Portland"),
|
||||
("US-OR", "Salem"),
|
||||
("US-TN", "Nashville"),
|
||||
("US-TN", "Memphis"),
|
||||
("US-VA", "Richmond"),
|
||||
("US-VA", "Virginia Beach"),
|
||||
("US-MD", "Baltimore"),
|
||||
("US-MD", "Frederick"),
|
||||
("US-DC", "Washington"),
|
||||
("US-UT", "Salt Lake City"),
|
||||
("US-UT", "Provo"),
|
||||
("US-LA", "New Orleans"),
|
||||
("US-LA", "Baton Rouge"),
|
||||
("US-KY", "Louisville"),
|
||||
("US-KY", "Lexington"),
|
||||
("US-IA", "Des Moines"),
|
||||
("US-IA", "Cedar Rapids"),
|
||||
("US-OK", "Oklahoma City"),
|
||||
("US-OK", "Tulsa"),
|
||||
("US-NE", "Omaha"),
|
||||
("US-NE", "Lincoln"),
|
||||
("US-MO", "Kansas City"),
|
||||
("US-MO", "St. Louis"),
|
||||
("US-NC", "Charlotte"),
|
||||
("US-NC", "Raleigh"),
|
||||
("US-SC", "Columbia"),
|
||||
("US-SC", "Charleston"),
|
||||
("US-WI", "Milwaukee"),
|
||||
("US-WI", "Madison"),
|
||||
("US-MN", "Duluth"),
|
||||
("US-AK", "Anchorage"),
|
||||
("US-HI", "Honolulu"),
|
||||
("CA-ON", "Toronto"),
|
||||
("CA-ON", "Ottawa"),
|
||||
("CA-QC", "Montréal"),
|
||||
("CA-QC", "Québec City"),
|
||||
("CA-BC", "Vancouver"),
|
||||
("CA-BC", "Victoria"),
|
||||
("CA-AB", "Calgary"),
|
||||
("CA-AB", "Edmonton"),
|
||||
("CA-MB", "Winnipeg"),
|
||||
("CA-NS", "Halifax"),
|
||||
("CA-SK", "Saskatoon"),
|
||||
("CA-SK", "Regina"),
|
||||
("CA-NB", "Moncton"),
|
||||
("CA-NB", "Saint John"),
|
||||
("CA-PE", "Charlottetown"),
|
||||
("CA-NL", "St. John's"),
|
||||
("CA-ON", "Hamilton"),
|
||||
("CA-ON", "London"),
|
||||
("CA-QC", "Gatineau"),
|
||||
("CA-QC", "Laval"),
|
||||
("CA-BC", "Kelowna"),
|
||||
("CA-AB", "Red Deer"),
|
||||
("CA-MB", "Brandon"),
|
||||
("MX-CMX", "Ciudad de México"),
|
||||
("MX-JAL", "Guadalajara"),
|
||||
("MX-NLE", "Monterrey"),
|
||||
("MX-PUE", "Puebla"),
|
||||
("MX-ROO", "Cancún"),
|
||||
("MX-GUA", "Guanajuato"),
|
||||
("MX-MIC", "Morelia"),
|
||||
("MX-BCN", "Tijuana"),
|
||||
("MX-JAL", "Zapopan"),
|
||||
("MX-NLE", "San Nicolás"),
|
||||
("MX-CAM", "Campeche"),
|
||||
("MX-TAB", "Villahermosa"),
|
||||
("MX-VER", "Veracruz"),
|
||||
("MX-OAX", "Oaxaca"),
|
||||
("MX-SLP", "San Luis Potosí"),
|
||||
("MX-CHH", "Chihuahua"),
|
||||
("MX-AGU", "Aguascalientes"),
|
||||
("MX-MEX", "Toluca"),
|
||||
("MX-COA", "Saltillo"),
|
||||
("MX-BCS", "La Paz"),
|
||||
("MX-NAY", "Tepic"),
|
||||
("MX-ZAC", "Zacatecas"),
|
||||
];
|
||||
|
||||
public async Task SeedAsync(SqlConnection connection)
|
||||
{
|
||||
foreach (var (countryName, countryCode) in Countries)
|
||||
{
|
||||
await CreateCountryAsync(connection, countryName, countryCode);
|
||||
}
|
||||
|
||||
foreach (
|
||||
var (stateProvinceName, stateProvinceCode, countryCode) in States
|
||||
)
|
||||
{
|
||||
await CreateStateProvinceAsync(
|
||||
connection,
|
||||
stateProvinceName,
|
||||
stateProvinceCode,
|
||||
countryCode
|
||||
);
|
||||
}
|
||||
|
||||
foreach (var (stateProvinceCode, cityName) in Cities)
|
||||
{
|
||||
await CreateCityAsync(connection, cityName, stateProvinceCode);
|
||||
}
|
||||
await CreateCountryAsync(connection, countryName, countryCode);
|
||||
}
|
||||
|
||||
private static async Task CreateCountryAsync(
|
||||
SqlConnection connection,
|
||||
string countryName,
|
||||
string countryCode
|
||||
foreach (
|
||||
var (stateProvinceName, stateProvinceCode, countryCode) in States
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateCountry",
|
||||
connection
|
||||
await CreateStateProvinceAsync(
|
||||
connection,
|
||||
stateProvinceName,
|
||||
stateProvinceCode,
|
||||
countryCode
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue("@CountryName", countryName);
|
||||
command.Parameters.AddWithValue("@ISO3616_1", countryCode);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
private static async Task CreateStateProvinceAsync(
|
||||
SqlConnection connection,
|
||||
string stateProvinceName,
|
||||
string stateProvinceCode,
|
||||
string countryCode
|
||||
)
|
||||
foreach (var (stateProvinceCode, cityName) in Cities)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateStateProvince",
|
||||
connection
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue(
|
||||
"@StateProvinceName",
|
||||
stateProvinceName
|
||||
);
|
||||
command.Parameters.AddWithValue("@ISO3616_2", stateProvinceCode);
|
||||
command.Parameters.AddWithValue("@CountryCode", countryCode);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
private static async Task CreateCityAsync(
|
||||
SqlConnection connection,
|
||||
string cityName,
|
||||
string stateProvinceCode
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateCity",
|
||||
connection
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue("@CityName", cityName);
|
||||
command.Parameters.AddWithValue(
|
||||
"@StateProvinceCode",
|
||||
stateProvinceCode
|
||||
);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
await CreateCityAsync(connection, cityName, stateProvinceCode);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task CreateCountryAsync(
|
||||
SqlConnection connection,
|
||||
string countryName,
|
||||
string countryCode
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateCountry",
|
||||
connection
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue("@CountryName", countryName);
|
||||
command.Parameters.AddWithValue("@ISO3616_1", countryCode);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
private static async Task CreateStateProvinceAsync(
|
||||
SqlConnection connection,
|
||||
string stateProvinceName,
|
||||
string stateProvinceCode,
|
||||
string countryCode
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateStateProvince",
|
||||
connection
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue(
|
||||
"@StateProvinceName",
|
||||
stateProvinceName
|
||||
);
|
||||
command.Parameters.AddWithValue("@ISO3616_2", stateProvinceCode);
|
||||
command.Parameters.AddWithValue("@CountryCode", countryCode);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
private static async Task CreateCityAsync(
|
||||
SqlConnection connection,
|
||||
string cityName,
|
||||
string stateProvinceCode
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateCity",
|
||||
connection
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue("@CityName", cityName);
|
||||
command.Parameters.AddWithValue(
|
||||
"@StateProvinceCode",
|
||||
stateProvinceCode
|
||||
);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
using DBSeed;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using DbUp;
|
||||
using System.Reflection;
|
||||
using Database.Seed;
|
||||
|
||||
string BuildConnectionString()
|
||||
{
|
||||
var server = Environment.GetEnvironmentVariable("DB_SERVER")
|
||||
?? throw new InvalidOperationException("DB_SERVER environment variable is not set");
|
||||
?? throw new InvalidOperationException("DB_SERVER environment variable is not set");
|
||||
|
||||
var dbName = Environment.GetEnvironmentVariable("DB_NAME")
|
||||
?? throw new InvalidOperationException("DB_NAME environment variable is not set");
|
||||
?? throw new InvalidOperationException("DB_NAME environment variable is not set");
|
||||
|
||||
var user = Environment.GetEnvironmentVariable("DB_USER")
|
||||
?? throw new InvalidOperationException("DB_USER environment variable is not set");
|
||||
?? throw new InvalidOperationException("DB_USER environment variable is not set");
|
||||
|
||||
var password = Environment.GetEnvironmentVariable("DB_PASSWORD")
|
||||
?? throw new InvalidOperationException("DB_PASSWORD environment variable is not set");
|
||||
?? throw new InvalidOperationException("DB_PASSWORD environment variable is not set");
|
||||
|
||||
var trustServerCertificate = Environment.GetEnvironmentVariable("DB_TRUST_SERVER_CERTIFICATE")
|
||||
?? "True";
|
||||
?? "True";
|
||||
|
||||
var builder = new SqlConnectionStringBuilder
|
||||
{
|
||||
@@ -33,6 +33,7 @@ string BuildConnectionString()
|
||||
return builder.ConnectionString;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var connectionString = BuildConnectionString();
|
||||
@@ -72,7 +73,6 @@ try
|
||||
|
||||
using (connection)
|
||||
{
|
||||
|
||||
ISeeder[] seeders =
|
||||
[
|
||||
new LocationSeeder(),
|
||||
@@ -96,4 +96,4 @@ catch (Exception ex)
|
||||
Console.Error.WriteLine("Seed failed:");
|
||||
Console.Error.WriteLine(ex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,272 +1,267 @@
|
||||
using System.Data;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Domain.Core.Entities;
|
||||
using idunno.Password;
|
||||
using Konscious.Security.Cryptography;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace DBSeed
|
||||
namespace Database.Seed;
|
||||
|
||||
internal class UserSeeder : ISeeder
|
||||
{
|
||||
internal class UserSeeder : ISeeder
|
||||
private static readonly IReadOnlyList<(
|
||||
string FirstName,
|
||||
string LastName
|
||||
)> SeedNames =
|
||||
[
|
||||
("Aarya", "Mathews"),
|
||||
("Aiden", "Wells"),
|
||||
("Aleena", "Gonzalez"),
|
||||
("Alessandra", "Nelson"),
|
||||
("Amari", "Tucker"),
|
||||
("Ameer", "Huff"),
|
||||
("Amirah", "Hicks"),
|
||||
("Analia", "Dominguez"),
|
||||
("Anne", "Jenkins"),
|
||||
("Apollo", "Davis"),
|
||||
("Arianna", "White"),
|
||||
("Aubree", "Moore"),
|
||||
("Aubrielle", "Raymond"),
|
||||
("Aydin", "Odom"),
|
||||
("Bowen", "Casey"),
|
||||
("Brock", "Huber"),
|
||||
("Caiden", "Strong"),
|
||||
("Cecilia", "Rosales"),
|
||||
("Celeste", "Barber"),
|
||||
("Chance", "Small"),
|
||||
("Clara", "Roberts"),
|
||||
("Collins", "Brandt"),
|
||||
("Damir", "Wallace"),
|
||||
("Declan", "Crawford"),
|
||||
("Dennis", "Decker"),
|
||||
("Dylan", "Lang"),
|
||||
("Eliza", "Kane"),
|
||||
("Elle", "Poole"),
|
||||
("Elliott", "Miles"),
|
||||
("Emelia", "Lucas"),
|
||||
("Emilia", "Simpson"),
|
||||
("Emmett", "Lugo"),
|
||||
("Ethan", "Stephens"),
|
||||
("Etta", "Woods"),
|
||||
("Gael", "Moran"),
|
||||
("Grant", "Benson"),
|
||||
("Gwen", "James"),
|
||||
("Huxley", "Chen"),
|
||||
("Isabella", "Fisher"),
|
||||
("Ivan", "Mathis"),
|
||||
("Jamir", "McMillan"),
|
||||
("Jaxson", "Shields"),
|
||||
("Jimmy", "Richmond"),
|
||||
("Josiah", "Flores"),
|
||||
("Kaden", "Enriquez"),
|
||||
("Kai", "Lawson"),
|
||||
("Karsyn", "Adkins"),
|
||||
("Karsyn", "Proctor"),
|
||||
("Kayden", "Henson"),
|
||||
("Kaylie", "Spears"),
|
||||
("Kinslee", "Jones"),
|
||||
("Kora", "Guerra"),
|
||||
("Lane", "Skinner"),
|
||||
("Laylani", "Christian"),
|
||||
("Ledger", "Carroll"),
|
||||
("Leilany", "Small"),
|
||||
("Leland", "McCall"),
|
||||
("Leonard", "Calhoun"),
|
||||
("Levi", "Ochoa"),
|
||||
("Lillie", "Vang"),
|
||||
("Lola", "Sheppard"),
|
||||
("Luciana", "Poole"),
|
||||
("Maddox", "Hughes"),
|
||||
("Mara", "Blackwell"),
|
||||
("Marcellus", "Bartlett"),
|
||||
("Margo", "Koch"),
|
||||
("Maurice", "Gibson"),
|
||||
("Maxton", "Dodson"),
|
||||
("Mia", "Parrish"),
|
||||
("Millie", "Fuentes"),
|
||||
("Nellie", "Villanueva"),
|
||||
("Nicolas", "Mata"),
|
||||
("Nicolas", "Miller"),
|
||||
("Oakleigh", "Foster"),
|
||||
("Octavia", "Pierce"),
|
||||
("Paisley", "Allison"),
|
||||
("Quincy", "Andersen"),
|
||||
("Quincy", "Frazier"),
|
||||
("Raiden", "Roberts"),
|
||||
("Raquel", "Lara"),
|
||||
("Rudy", "McIntosh"),
|
||||
("Salvador", "Stein"),
|
||||
("Samantha", "Dickson"),
|
||||
("Solomon", "Richards"),
|
||||
("Sylvia", "Hanna"),
|
||||
("Talia", "Trujillo"),
|
||||
("Thalia", "Farrell"),
|
||||
("Trent", "Mayo"),
|
||||
("Trinity", "Cummings"),
|
||||
("Ty", "Perry"),
|
||||
("Tyler", "Romero"),
|
||||
("Valeria", "Pierce"),
|
||||
("Vance", "Neal"),
|
||||
("Whitney", "Bell"),
|
||||
("Wilder", "Graves"),
|
||||
("William", "Logan"),
|
||||
("Zara", "Wilkinson"),
|
||||
("Zaria", "Gibson"),
|
||||
("Zion", "Watkins"),
|
||||
("Zoie", "Armstrong"),
|
||||
];
|
||||
|
||||
public async Task SeedAsync(SqlConnection connection)
|
||||
{
|
||||
private static readonly IReadOnlyList<(
|
||||
string FirstName,
|
||||
string LastName
|
||||
)> SeedNames =
|
||||
[
|
||||
("Aarya", "Mathews"),
|
||||
("Aiden", "Wells"),
|
||||
("Aleena", "Gonzalez"),
|
||||
("Alessandra", "Nelson"),
|
||||
("Amari", "Tucker"),
|
||||
("Ameer", "Huff"),
|
||||
("Amirah", "Hicks"),
|
||||
("Analia", "Dominguez"),
|
||||
("Anne", "Jenkins"),
|
||||
("Apollo", "Davis"),
|
||||
("Arianna", "White"),
|
||||
("Aubree", "Moore"),
|
||||
("Aubrielle", "Raymond"),
|
||||
("Aydin", "Odom"),
|
||||
("Bowen", "Casey"),
|
||||
("Brock", "Huber"),
|
||||
("Caiden", "Strong"),
|
||||
("Cecilia", "Rosales"),
|
||||
("Celeste", "Barber"),
|
||||
("Chance", "Small"),
|
||||
("Clara", "Roberts"),
|
||||
("Collins", "Brandt"),
|
||||
("Damir", "Wallace"),
|
||||
("Declan", "Crawford"),
|
||||
("Dennis", "Decker"),
|
||||
("Dylan", "Lang"),
|
||||
("Eliza", "Kane"),
|
||||
("Elle", "Poole"),
|
||||
("Elliott", "Miles"),
|
||||
("Emelia", "Lucas"),
|
||||
("Emilia", "Simpson"),
|
||||
("Emmett", "Lugo"),
|
||||
("Ethan", "Stephens"),
|
||||
("Etta", "Woods"),
|
||||
("Gael", "Moran"),
|
||||
("Grant", "Benson"),
|
||||
("Gwen", "James"),
|
||||
("Huxley", "Chen"),
|
||||
("Isabella", "Fisher"),
|
||||
("Ivan", "Mathis"),
|
||||
("Jamir", "McMillan"),
|
||||
("Jaxson", "Shields"),
|
||||
("Jimmy", "Richmond"),
|
||||
("Josiah", "Flores"),
|
||||
("Kaden", "Enriquez"),
|
||||
("Kai", "Lawson"),
|
||||
("Karsyn", "Adkins"),
|
||||
("Karsyn", "Proctor"),
|
||||
("Kayden", "Henson"),
|
||||
("Kaylie", "Spears"),
|
||||
("Kinslee", "Jones"),
|
||||
("Kora", "Guerra"),
|
||||
("Lane", "Skinner"),
|
||||
("Laylani", "Christian"),
|
||||
("Ledger", "Carroll"),
|
||||
("Leilany", "Small"),
|
||||
("Leland", "McCall"),
|
||||
("Leonard", "Calhoun"),
|
||||
("Levi", "Ochoa"),
|
||||
("Lillie", "Vang"),
|
||||
("Lola", "Sheppard"),
|
||||
("Luciana", "Poole"),
|
||||
("Maddox", "Hughes"),
|
||||
("Mara", "Blackwell"),
|
||||
("Marcellus", "Bartlett"),
|
||||
("Margo", "Koch"),
|
||||
("Maurice", "Gibson"),
|
||||
("Maxton", "Dodson"),
|
||||
("Mia", "Parrish"),
|
||||
("Millie", "Fuentes"),
|
||||
("Nellie", "Villanueva"),
|
||||
("Nicolas", "Mata"),
|
||||
("Nicolas", "Miller"),
|
||||
("Oakleigh", "Foster"),
|
||||
("Octavia", "Pierce"),
|
||||
("Paisley", "Allison"),
|
||||
("Quincy", "Andersen"),
|
||||
("Quincy", "Frazier"),
|
||||
("Raiden", "Roberts"),
|
||||
("Raquel", "Lara"),
|
||||
("Rudy", "McIntosh"),
|
||||
("Salvador", "Stein"),
|
||||
("Samantha", "Dickson"),
|
||||
("Solomon", "Richards"),
|
||||
("Sylvia", "Hanna"),
|
||||
("Talia", "Trujillo"),
|
||||
("Thalia", "Farrell"),
|
||||
("Trent", "Mayo"),
|
||||
("Trinity", "Cummings"),
|
||||
("Ty", "Perry"),
|
||||
("Tyler", "Romero"),
|
||||
("Valeria", "Pierce"),
|
||||
("Vance", "Neal"),
|
||||
("Whitney", "Bell"),
|
||||
("Wilder", "Graves"),
|
||||
("William", "Logan"),
|
||||
("Zara", "Wilkinson"),
|
||||
("Zaria", "Gibson"),
|
||||
("Zion", "Watkins"),
|
||||
("Zoie", "Armstrong"),
|
||||
];
|
||||
var generator = new PasswordGenerator();
|
||||
var rng = new Random();
|
||||
int createdUsers = 0;
|
||||
int createdCredentials = 0;
|
||||
int createdVerifications = 0;
|
||||
|
||||
public async Task SeedAsync(SqlConnection connection)
|
||||
{
|
||||
var generator = new PasswordGenerator();
|
||||
var rng = new Random();
|
||||
int createdUsers = 0;
|
||||
int createdCredentials = 0;
|
||||
int createdVerifications = 0;
|
||||
const string firstName = "Test";
|
||||
const string lastName = "User";
|
||||
const string email = "test.user@thebiergarten.app";
|
||||
var dob = new DateTime(1985, 03, 01);
|
||||
var hash = GeneratePasswordHash("password");
|
||||
|
||||
{
|
||||
const string firstName = "Test";
|
||||
const string lastName = "User";
|
||||
const string email = "test.user@thebiergarten.app";
|
||||
var dob = new DateTime(1985, 03, 01);
|
||||
var hash = GeneratePasswordHash("password");
|
||||
|
||||
await RegisterUserAsync(
|
||||
connection,
|
||||
$"{firstName}.{lastName}",
|
||||
firstName,
|
||||
lastName,
|
||||
dob,
|
||||
email,
|
||||
hash
|
||||
);
|
||||
}
|
||||
foreach (var (firstName, lastName) in SeedNames)
|
||||
{
|
||||
// prepare user fields
|
||||
var username = $"{firstName[0]}.{lastName}";
|
||||
var email = $"{firstName}.{lastName}@thebiergarten.app";
|
||||
var dob = GenerateDateOfBirth(rng);
|
||||
|
||||
// generate a password and hash it
|
||||
string pwd = generator.Generate(
|
||||
length: 64,
|
||||
numberOfDigits: 10,
|
||||
numberOfSymbols: 10
|
||||
);
|
||||
string hash = GeneratePasswordHash(pwd);
|
||||
|
||||
|
||||
// register the user (creates account + credential)
|
||||
var id = await RegisterUserAsync(
|
||||
connection,
|
||||
username,
|
||||
firstName,
|
||||
lastName,
|
||||
dob,
|
||||
email,
|
||||
hash
|
||||
);
|
||||
createdUsers++;
|
||||
createdCredentials++;
|
||||
|
||||
|
||||
|
||||
|
||||
// add user verification
|
||||
if (await HasUserVerificationAsync(connection, id)) continue;
|
||||
|
||||
await AddUserVerificationAsync(connection, id);
|
||||
createdVerifications++;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Created {createdUsers} user accounts.");
|
||||
Console.WriteLine($"Added {createdCredentials} user credentials.");
|
||||
Console.WriteLine($"Added {createdVerifications} user verifications.");
|
||||
}
|
||||
|
||||
private static async Task<Guid> RegisterUserAsync(
|
||||
SqlConnection connection,
|
||||
string username,
|
||||
string firstName,
|
||||
string lastName,
|
||||
DateTime dateOfBirth,
|
||||
string email,
|
||||
string hash
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand("dbo.USP_RegisterUser", connection);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
|
||||
|
||||
command.Parameters.Add("@Username", SqlDbType.VarChar, 64).Value = username;
|
||||
command.Parameters.Add("@FirstName", SqlDbType.NVarChar, 128).Value = firstName;
|
||||
command.Parameters.Add("@LastName", SqlDbType.NVarChar, 128).Value = lastName;
|
||||
command.Parameters.Add("@DateOfBirth", SqlDbType.DateTime).Value = dateOfBirth;
|
||||
command.Parameters.Add("@Email", SqlDbType.VarChar, 128).Value = email;
|
||||
command.Parameters.Add("@Hash", SqlDbType.NVarChar, -1).Value = hash;
|
||||
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
|
||||
|
||||
return (Guid)result!;
|
||||
|
||||
}
|
||||
|
||||
private static string GeneratePasswordHash(string pwd)
|
||||
{
|
||||
byte[] salt = RandomNumberGenerator.GetBytes(16);
|
||||
|
||||
var argon2 = new Argon2id(Encoding.UTF8.GetBytes(pwd))
|
||||
{
|
||||
Salt = salt,
|
||||
DegreeOfParallelism = Math.Max(Environment.ProcessorCount, 1),
|
||||
MemorySize = 65536,
|
||||
Iterations = 4,
|
||||
};
|
||||
|
||||
byte[] hash = argon2.GetBytes(32);
|
||||
return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
|
||||
}
|
||||
|
||||
private static async Task<bool> HasUserVerificationAsync(
|
||||
SqlConnection connection,
|
||||
Guid userAccountId
|
||||
)
|
||||
{
|
||||
const string sql = """
|
||||
SELECT 1
|
||||
FROM dbo.UserVerification
|
||||
WHERE UserAccountId = @UserAccountId;
|
||||
""";
|
||||
await using var command = new SqlCommand(sql, connection);
|
||||
command.Parameters.AddWithValue("@UserAccountId", userAccountId);
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
return result is not null;
|
||||
}
|
||||
|
||||
private static async Task AddUserVerificationAsync(
|
||||
SqlConnection connection,
|
||||
Guid userAccountId
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateUserVerification",
|
||||
connection
|
||||
await RegisterUserAsync(
|
||||
connection,
|
||||
$"{firstName}.{lastName}",
|
||||
firstName,
|
||||
lastName,
|
||||
dob,
|
||||
email,
|
||||
hash
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue("@UserAccountID_", userAccountId);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
private static DateTime GenerateDateOfBirth(Random random)
|
||||
foreach (var (firstName, lastName) in SeedNames)
|
||||
{
|
||||
int age = 19 + random.Next(0, 30);
|
||||
DateTime baseDate = DateTime.UtcNow.Date.AddYears(-age);
|
||||
int offsetDays = random.Next(0, 365);
|
||||
return baseDate.AddDays(-offsetDays);
|
||||
// prepare user fields
|
||||
var username = $"{firstName[0]}.{lastName}";
|
||||
var email = $"{firstName}.{lastName}@thebiergarten.app";
|
||||
var dob = GenerateDateOfBirth(rng);
|
||||
|
||||
// generate a password and hash it
|
||||
string pwd = generator.Generate(
|
||||
length: 64,
|
||||
numberOfDigits: 10,
|
||||
numberOfSymbols: 10
|
||||
);
|
||||
string hash = GeneratePasswordHash(pwd);
|
||||
|
||||
|
||||
// register the user (creates account + credential)
|
||||
var id = await RegisterUserAsync(
|
||||
connection,
|
||||
username,
|
||||
firstName,
|
||||
lastName,
|
||||
dob,
|
||||
email,
|
||||
hash
|
||||
);
|
||||
createdUsers++;
|
||||
createdCredentials++;
|
||||
|
||||
|
||||
// add user verification
|
||||
if (await HasUserVerificationAsync(connection, id)) continue;
|
||||
|
||||
await AddUserVerificationAsync(connection, id);
|
||||
createdVerifications++;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Created {createdUsers} user accounts.");
|
||||
Console.WriteLine($"Added {createdCredentials} user credentials.");
|
||||
Console.WriteLine($"Added {createdVerifications} user verifications.");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<Guid> RegisterUserAsync(
|
||||
SqlConnection connection,
|
||||
string username,
|
||||
string firstName,
|
||||
string lastName,
|
||||
DateTime dateOfBirth,
|
||||
string email,
|
||||
string hash
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand("dbo.USP_RegisterUser", connection);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
|
||||
|
||||
command.Parameters.Add("@Username", SqlDbType.VarChar, 64).Value = username;
|
||||
command.Parameters.Add("@FirstName", SqlDbType.NVarChar, 128).Value = firstName;
|
||||
command.Parameters.Add("@LastName", SqlDbType.NVarChar, 128).Value = lastName;
|
||||
command.Parameters.Add("@DateOfBirth", SqlDbType.DateTime).Value = dateOfBirth;
|
||||
command.Parameters.Add("@Email", SqlDbType.VarChar, 128).Value = email;
|
||||
command.Parameters.Add("@Hash", SqlDbType.NVarChar, -1).Value = hash;
|
||||
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
|
||||
|
||||
return (Guid)result!;
|
||||
}
|
||||
|
||||
private static string GeneratePasswordHash(string pwd)
|
||||
{
|
||||
byte[] salt = RandomNumberGenerator.GetBytes(16);
|
||||
|
||||
var argon2 = new Argon2id(Encoding.UTF8.GetBytes(pwd))
|
||||
{
|
||||
Salt = salt,
|
||||
DegreeOfParallelism = Math.Max(Environment.ProcessorCount, 1),
|
||||
MemorySize = 65536,
|
||||
Iterations = 4,
|
||||
};
|
||||
|
||||
byte[] hash = argon2.GetBytes(32);
|
||||
return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
|
||||
}
|
||||
|
||||
private static async Task<bool> HasUserVerificationAsync(
|
||||
SqlConnection connection,
|
||||
Guid userAccountId
|
||||
)
|
||||
{
|
||||
const string sql = """
|
||||
SELECT 1
|
||||
FROM dbo.UserVerification
|
||||
WHERE UserAccountId = @UserAccountId;
|
||||
""";
|
||||
await using var command = new SqlCommand(sql, connection);
|
||||
command.Parameters.AddWithValue("@UserAccountId", userAccountId);
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
return result is not null;
|
||||
}
|
||||
|
||||
private static async Task AddUserVerificationAsync(
|
||||
SqlConnection connection,
|
||||
Guid userAccountId
|
||||
)
|
||||
{
|
||||
await using var command = new SqlCommand(
|
||||
"dbo.USP_CreateUserVerification",
|
||||
connection
|
||||
);
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.Parameters.AddWithValue("@UserAccountID_", userAccountId);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
private static DateTime GenerateDateOfBirth(Random random)
|
||||
{
|
||||
int age = 19 + random.Next(0, 30);
|
||||
DateTime baseDate = DateTime.UtcNow.Date.AddYears(-age);
|
||||
int offsetDays = random.Next(0, 365);
|
||||
return baseDate.AddDays(-offsetDays);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Domain.Core.Entities;
|
||||
namespace Domain.Entities;
|
||||
|
||||
public class UserAccount
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Domain.Core.Entities;
|
||||
namespace Domain.Entities;
|
||||
|
||||
public class UserCredential
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Domain.Core.Entities;
|
||||
namespace Domain.Entities;
|
||||
|
||||
public class UserVerification
|
||||
{
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
using Infrastructure.Repository.Sql;
|
||||
|
||||
namespace Infrastructure.Repository.Auth;
|
||||
|
||||
public class AuthRepository
|
||||
: Repository<Domain.Core.Entities.UserAccount>,
|
||||
public class AuthRepository(ISqlConnectionFactory connectionFactory)
|
||||
: Repository<Domain.Entities.UserAccount>(connectionFactory),
|
||||
IAuthRepository
|
||||
{
|
||||
public AuthRepository(ISqlConnectionFactory connectionFactory)
|
||||
: base(connectionFactory) { }
|
||||
|
||||
public async Task<Domain.Core.Entities.UserAccount> RegisterUserAsync(
|
||||
public async Task<Domain.Entities.UserAccount> RegisterUserAsync(
|
||||
string username,
|
||||
string firstName,
|
||||
string lastName,
|
||||
@@ -37,7 +34,7 @@ public class AuthRepository
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
var userAccountId = result != null ? (Guid)result : Guid.Empty;
|
||||
|
||||
return new Domain.Core.Entities.UserAccount
|
||||
return new Domain.Entities.UserAccount
|
||||
{
|
||||
UserAccountId = userAccountId,
|
||||
Username = username,
|
||||
@@ -49,7 +46,7 @@ public class AuthRepository
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetUserByEmailAsync(
|
||||
public async Task<Domain.Entities.UserAccount?> GetUserByEmailAsync(
|
||||
string email
|
||||
)
|
||||
{
|
||||
@@ -64,7 +61,7 @@ public class AuthRepository
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetUserByUsernameAsync(
|
||||
public async Task<Domain.Entities.UserAccount?> GetUserByUsernameAsync(
|
||||
string username
|
||||
)
|
||||
{
|
||||
@@ -115,11 +112,11 @@ public class AuthRepository
|
||||
/// <summary>
|
||||
/// Maps a data reader row to a UserAccount entity.
|
||||
/// </summary>
|
||||
protected override Domain.Core.Entities.UserAccount MapToEntity(
|
||||
protected override Domain.Entities.UserAccount MapToEntity(
|
||||
DbDataReader reader
|
||||
)
|
||||
{
|
||||
return new Domain.Core.Entities.UserAccount
|
||||
return new Domain.Entities.UserAccount
|
||||
{
|
||||
UserAccountId = reader.GetGuid(
|
||||
reader.GetOrdinal("UserAccountId")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
|
||||
namespace Infrastructure.Repository.Auth;
|
||||
|
||||
@@ -18,7 +18,7 @@ public interface IAuthRepository
|
||||
/// <param name="dateOfBirth">User's date of birth</param>
|
||||
/// <param name="passwordHash">Hashed password</param>
|
||||
/// <returns>The newly created UserAccount with generated ID</returns>
|
||||
Task<Domain.Core.Entities.UserAccount> RegisterUserAsync(
|
||||
Task<Domain.Entities.UserAccount> RegisterUserAsync(
|
||||
string username,
|
||||
string firstName,
|
||||
string lastName,
|
||||
@@ -33,7 +33,7 @@ public interface IAuthRepository
|
||||
/// </summary>
|
||||
/// <param name="email">Email address to search for</param>
|
||||
/// <returns>UserAccount if found, null otherwise</returns>
|
||||
Task<Domain.Core.Entities.UserAccount?> GetUserByEmailAsync(
|
||||
Task<Domain.Entities.UserAccount?> GetUserByEmailAsync(
|
||||
string email
|
||||
);
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface IAuthRepository
|
||||
/// </summary>
|
||||
/// <param name="username">Username to search for</param>
|
||||
/// <returns>UserAccount if found, null otherwise</returns>
|
||||
Task<Domain.Core.Entities.UserAccount?> GetUserByUsernameAsync(
|
||||
Task<Domain.Entities.UserAccount?> GetUserByUsernameAsync(
|
||||
string username
|
||||
);
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@ namespace Infrastructure.Repository.UserAccount;
|
||||
|
||||
public interface IUserAccountRepository
|
||||
{
|
||||
Task<Domain.Core.Entities.UserAccount?> GetByIdAsync(Guid id);
|
||||
Task<IEnumerable<Domain.Core.Entities.UserAccount>> GetAllAsync(
|
||||
Task<Domain.Entities.UserAccount?> GetByIdAsync(Guid id);
|
||||
Task<IEnumerable<Domain.Entities.UserAccount>> GetAllAsync(
|
||||
int? limit,
|
||||
int? offset
|
||||
);
|
||||
Task UpdateAsync(Domain.Core.Entities.UserAccount userAccount);
|
||||
Task UpdateAsync(Domain.Entities.UserAccount userAccount);
|
||||
Task DeleteAsync(Guid id);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetByUsernameAsync(
|
||||
Task<Domain.Entities.UserAccount?> GetByUsernameAsync(
|
||||
string username
|
||||
);
|
||||
Task<Domain.Core.Entities.UserAccount?> GetByEmailAsync(string email);
|
||||
Task<Domain.Entities.UserAccount?> GetByEmailAsync(string email);
|
||||
}
|
||||
@@ -5,10 +5,10 @@ using Infrastructure.Repository.Sql;
|
||||
namespace Infrastructure.Repository.UserAccount;
|
||||
|
||||
public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
: Repository<Domain.Core.Entities.UserAccount>(connectionFactory),
|
||||
: Repository<Domain.Entities.UserAccount>(connectionFactory),
|
||||
IUserAccountRepository
|
||||
{
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetByIdAsync(
|
||||
public async Task<Domain.Entities.UserAccount?> GetByIdAsync(
|
||||
Guid id
|
||||
)
|
||||
{
|
||||
@@ -24,7 +24,7 @@ public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
}
|
||||
|
||||
public async Task<
|
||||
IEnumerable<Domain.Core.Entities.UserAccount>
|
||||
IEnumerable<Domain.Entities.UserAccount>
|
||||
> GetAllAsync(int? limit, int? offset)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
@@ -39,7 +39,7 @@ public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
AddParameter(command, "@Offset", offset.Value);
|
||||
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
var users = new List<Domain.Core.Entities.UserAccount>();
|
||||
var users = new List<Domain.Entities.UserAccount>();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
@@ -50,7 +50,7 @@ public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(
|
||||
Domain.Core.Entities.UserAccount userAccount
|
||||
Domain.Entities.UserAccount userAccount
|
||||
)
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
@@ -79,7 +79,7 @@ public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetByUsernameAsync(
|
||||
public async Task<Domain.Entities.UserAccount?> GetByUsernameAsync(
|
||||
string username
|
||||
)
|
||||
{
|
||||
@@ -94,7 +94,7 @@ public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
public async Task<Domain.Core.Entities.UserAccount?> GetByEmailAsync(
|
||||
public async Task<Domain.Entities.UserAccount?> GetByEmailAsync(
|
||||
string email
|
||||
)
|
||||
{
|
||||
@@ -109,11 +109,11 @@ public class UserAccountRepository(ISqlConnectionFactory connectionFactory)
|
||||
return await reader.ReadAsync() ? MapToEntity(reader) : null;
|
||||
}
|
||||
|
||||
protected override Domain.Core.Entities.UserAccount MapToEntity(
|
||||
protected override Domain.Entities.UserAccount MapToEntity(
|
||||
DbDataReader reader
|
||||
)
|
||||
{
|
||||
return new Domain.Core.Entities.UserAccount
|
||||
return new Domain.Entities.UserAccount
|
||||
{
|
||||
UserAccountId = reader.GetGuid(
|
||||
reader.GetOrdinal("UserAccountId")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
using Infrastructure.PasswordHashing;
|
||||
using Infrastructure.Repository.Auth;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
|
||||
namespace Service.Core.Auth;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
|
||||
namespace Service.Core.User;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Domain.Core.Entities;
|
||||
using Domain.Entities;
|
||||
using Infrastructure.Repository.UserAccount;
|
||||
|
||||
namespace Service.Core.User;
|
||||
|
||||
Reference in New Issue
Block a user