mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 01:54:43 +00:00
Migrate Database.Seed to UserManager<ApplicationUser>
This commit is contained in:
@@ -12,9 +12,9 @@ WORKDIR /src
|
|||||||
# Copy the solution file and every project file first (preserving their real relative paths, since
|
# Copy the solution file and every project file first (preserving their real relative paths, since
|
||||||
# ProjectReference paths are resolved relative to the referencing .csproj's location), so the
|
# ProjectReference paths are resolved relative to the referencing .csproj's location), so the
|
||||||
# `dotnet restore` layer stays cached as long as no project file or package reference changes,
|
# `dotnet restore` layer stays cached as long as no project file or package reference changes,
|
||||||
# independent of source-only edits. Restoring against Core.slnx avoids hand-maintaining a per-project
|
# independent of source-only edits. Restoring against Biergarten.API.slnx avoids hand-maintaining a per-project
|
||||||
# dependency list here that silently drifts out of sync as ProjectReferences change.
|
# dependency list here that silently drifts out of sync as ProjectReferences change.
|
||||||
COPY ["Core.slnx", "./"]
|
COPY ["Biergarten.API.slnx", "./"]
|
||||||
COPY ["API/API.Core/API.Core.csproj", "API/API.Core/"]
|
COPY ["API/API.Core/API.Core.csproj", "API/API.Core/"]
|
||||||
COPY ["API/API.Specs/API.Specs.csproj", "API/API.Specs/"]
|
COPY ["API/API.Specs/API.Specs.csproj", "API/API.Specs/"]
|
||||||
COPY ["Database/Database.Migrations/Database.Migrations.csproj", "Database/Database.Migrations/"]
|
COPY ["Database/Database.Migrations/Database.Migrations.csproj", "Database/Database.Migrations/"]
|
||||||
@@ -38,7 +38,7 @@ COPY ["Infrastructure/Infrastructure.PasswordHashing/Infrastructure.PasswordHash
|
|||||||
COPY ["Infrastructure/Infrastructure.Sql/Infrastructure.Sql.csproj", "Infrastructure/Infrastructure.Sql/"]
|
COPY ["Infrastructure/Infrastructure.Sql/Infrastructure.Sql.csproj", "Infrastructure/Infrastructure.Sql/"]
|
||||||
COPY ["Shared/Shared.Application/Shared.Application.csproj", "Shared/Shared.Application/"]
|
COPY ["Shared/Shared.Application/Shared.Application.csproj", "Shared/Shared.Application/"]
|
||||||
COPY ["Shared/Shared.Contracts/Shared.Contracts.csproj", "Shared/Shared.Contracts/"]
|
COPY ["Shared/Shared.Contracts/Shared.Contracts.csproj", "Shared/Shared.Contracts/"]
|
||||||
RUN dotnet restore "Core.slnx"
|
RUN dotnet restore "Biergarten.API.slnx"
|
||||||
COPY . .
|
COPY . .
|
||||||
WORKDIR "/src/API/API.Core"
|
WORKDIR "/src/API/API.Core"
|
||||||
RUN dotnet build "./API.Core.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
RUN dotnet build "./API.Core.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ ARG BUILD_CONFIGURATION=Release
|
|||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
||||||
# See API.Core/Dockerfile for why this copies every project file (with real relative paths) and
|
# See API.Core/Dockerfile for why this copies every project file (with real relative paths) and
|
||||||
# restores against Core.slnx rather than hand-listing API.Specs' transitive dependencies.
|
# restores against Biergarten.API.slnx rather than hand-listing API.Specs' transitive dependencies.
|
||||||
COPY ["Core.slnx", "./"]
|
COPY ["Biergarten.API.slnx", "./"]
|
||||||
COPY ["API/API.Core/API.Core.csproj", "API/API.Core/"]
|
COPY ["API/API.Core/API.Core.csproj", "API/API.Core/"]
|
||||||
COPY ["API/API.Specs/API.Specs.csproj", "API/API.Specs/"]
|
COPY ["API/API.Specs/API.Specs.csproj", "API/API.Specs/"]
|
||||||
COPY ["Database/Database.Migrations/Database.Migrations.csproj", "Database/Database.Migrations/"]
|
COPY ["Database/Database.Migrations/Database.Migrations.csproj", "Database/Database.Migrations/"]
|
||||||
@@ -28,7 +28,7 @@ COPY ["Infrastructure/Infrastructure.PasswordHashing/Infrastructure.PasswordHash
|
|||||||
COPY ["Infrastructure/Infrastructure.Sql/Infrastructure.Sql.csproj", "Infrastructure/Infrastructure.Sql/"]
|
COPY ["Infrastructure/Infrastructure.Sql/Infrastructure.Sql.csproj", "Infrastructure/Infrastructure.Sql/"]
|
||||||
COPY ["Shared/Shared.Application/Shared.Application.csproj", "Shared/Shared.Application/"]
|
COPY ["Shared/Shared.Application/Shared.Application.csproj", "Shared/Shared.Application/"]
|
||||||
COPY ["Shared/Shared.Contracts/Shared.Contracts.csproj", "Shared/Shared.Contracts/"]
|
COPY ["Shared/Shared.Contracts/Shared.Contracts.csproj", "Shared/Shared.Contracts/"]
|
||||||
RUN dotnet restore "Core.slnx"
|
RUN dotnet restore "Biergarten.API.slnx"
|
||||||
COPY . .
|
COPY . .
|
||||||
WORKDIR "/src/API/API.Specs"
|
WORKDIR "/src/API/API.Specs"
|
||||||
RUN dotnet build "./API.Specs.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
RUN dotnet build "./API.Specs.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ using Database.Seed.PipelineData;
|
|||||||
using Database.Seed.Sqlite;
|
using Database.Seed.Sqlite;
|
||||||
using Domain.Entities;
|
using Domain.Entities;
|
||||||
using Features.Auth.DependencyInjection;
|
using Features.Auth.DependencyInjection;
|
||||||
using Features.Auth.Repository;
|
using Features.Auth.Identity;
|
||||||
using Features.Breweries.DependencyInjection;
|
using Features.Breweries.DependencyInjection;
|
||||||
using Features.Breweries.Repository;
|
using Features.Breweries.Repository;
|
||||||
using Features.Locations.DependencyInjection;
|
using Features.Locations.DependencyInjection;
|
||||||
using Features.Locations.Dtos;
|
using Features.Locations.Dtos;
|
||||||
using Features.Locations.Repository;
|
using Features.Locations.Repository;
|
||||||
using idunno.Password;
|
using idunno.Password;
|
||||||
using Infrastructure.PasswordHashing;
|
|
||||||
using Infrastructure.Sql.DependencyInjection;
|
using Infrastructure.Sql.DependencyInjection;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
@@ -36,10 +36,8 @@ static async Task<int> RunAsync()
|
|||||||
provider.GetRequiredService<IBreweryRepository>();
|
provider.GetRequiredService<IBreweryRepository>();
|
||||||
ILocationRepository locationRepository =
|
ILocationRepository locationRepository =
|
||||||
provider.GetRequiredService<ILocationRepository>();
|
provider.GetRequiredService<ILocationRepository>();
|
||||||
IAuthRepository authRepository =
|
UserManager<ApplicationUser> userManager =
|
||||||
provider.GetRequiredService<IAuthRepository>();
|
provider.GetRequiredService<UserManager<ApplicationUser>>();
|
||||||
IPasswordInfrastructure passwordInfrastructure =
|
|
||||||
provider.GetRequiredService<IPasswordInfrastructure>();
|
|
||||||
|
|
||||||
AnsiConsole.Write(new Rule("[bold green]Database Seeder[/]")
|
AnsiConsole.Write(new Rule("[bold green]Database Seeder[/]")
|
||||||
.LeftJustified());
|
.LeftJustified());
|
||||||
@@ -94,11 +92,7 @@ static async Task<int> RunAsync()
|
|||||||
"Loading user data into target database...",
|
"Loading user data into target database...",
|
||||||
async ctx =>
|
async ctx =>
|
||||||
{
|
{
|
||||||
postedByIds = await LoadUsersIntoDatabaseAsync(
|
postedByIds = await LoadUsersIntoDatabaseAsync(userManager, seedData.Users);
|
||||||
authRepository,
|
|
||||||
passwordInfrastructure,
|
|
||||||
seedData.Users
|
|
||||||
);
|
|
||||||
ctx.Status("User data loaded into target database.");
|
ctx.Status("User data loaded into target database.");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -132,8 +126,7 @@ static async Task<int> RunAsync()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async Task<IReadOnlyList<Guid>> LoadUsersIntoDatabaseAsync(
|
static async Task<IReadOnlyList<Guid>> LoadUsersIntoDatabaseAsync(
|
||||||
IAuthRepository authRepository,
|
UserManager<ApplicationUser> userManager,
|
||||||
IPasswordInfrastructure passwordInfrastructure,
|
|
||||||
IReadOnlyList<UserRecord> users
|
IReadOnlyList<UserRecord> users
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -141,22 +134,29 @@ static async Task<IReadOnlyList<Guid>> LoadUsersIntoDatabaseAsync(
|
|||||||
|
|
||||||
foreach (UserRecord userRecord in users)
|
foreach (UserRecord userRecord in users)
|
||||||
{
|
{
|
||||||
UserAccount userAccount = await authRepository.RegisterUserAsync(
|
ApplicationUser user = new()
|
||||||
new UserAccount()
|
{
|
||||||
{
|
FirstName = userRecord.User.FirstName,
|
||||||
FirstName = userRecord.User.FirstName,
|
LastName = userRecord.User.LastName,
|
||||||
LastName = userRecord.User.LastName,
|
DateOfBirth = DateTime.Parse(userRecord.DateOfBirth),
|
||||||
DateOfBirth = DateTime.Parse(userRecord.DateOfBirth),
|
UserName = userRecord.User.Username,
|
||||||
Username = userRecord.User.Username,
|
Email = userRecord.Email,
|
||||||
Email = userRecord.Email,
|
};
|
||||||
UserCredential = new UserCredential
|
|
||||||
{
|
// allowRepeatedCharacters: true -- 12 unique digits was requested from only 10 possible
|
||||||
Hash = passwordInfrastructure.Hash(
|
// digit characters (0-9), which idunno.Password rejects outright.
|
||||||
password: PasswordGenerator.Generate(64, 12, 12))
|
IdentityResult result = await userManager.CreateAsync(
|
||||||
}
|
user,
|
||||||
}
|
PasswordGenerator.Generate(64, 12, 12, allowRepeatedCharacters: true)
|
||||||
);
|
);
|
||||||
userAccountIds.Add(userAccount.UserAccountId);
|
|
||||||
|
if (!result.Succeeded)
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
$"Failed to seed user '{userRecord.User.Username}': "
|
||||||
|
+ string.Join("; ", result.Errors.Select(e => e.Description))
|
||||||
|
);
|
||||||
|
|
||||||
|
userAccountIds.Add(user.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return userAccountIds;
|
return userAccountIds;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
|||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN dotnet restore "Core.slnx"
|
RUN dotnet restore "Biergarten.API.slnx"
|
||||||
RUN dotnet build "Core.slnx" -c $BUILD_CONFIGURATION
|
RUN dotnet build "Biergarten.API.slnx" -c $BUILD_CONFIGURATION
|
||||||
|
|
||||||
# Runs every Features.*.Tests project (unit + DbMocker-backed repository tests). API.Specs is
|
# Runs every Features.*.Tests project (unit + DbMocker-backed repository tests). API.Specs is
|
||||||
# excluded here since it's a separate BDD/integration suite, run by its own compose service
|
# excluded here since it's a separate BDD/integration suite, run by its own compose service
|
||||||
|
|||||||
Reference in New Issue
Block a user