Skip to content

Commit 21a1a5e

Browse files
authored
Merge pull request #7 from Harsche/feature/update-dotnet-version
Upgrade to .NET 10.0 and configure dynamic DbInitializer
2 parents 2560cb8 + 3ebd6da commit 21a1a5e

11 files changed

Lines changed: 75 additions & 59 deletions
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ jobs:
6666
docker rm game-collection-api || true
6767
6868
# Run the new container
69-
# IMPORTANT: Change '8080:80' to map your desired host port to the container's port.
7069
docker run -d \
7170
--name game-collection-api \
7271
-p 8080:8080 \
72+
-e ASPNETCORE_ENVIRONMENT=Production \
73+
-e "Jwt__Key=${{ secrets.JWT_SECRET_KEY }}" \
74+
-e "DefaultAdminPassword=${{ secrets.DEFAULT_ADMIN_PASSWORD }}" \
7375
ghcr.io/harsche/game-collection-api:latest

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,12 @@ CodeCoverage/
5151
# NUnit
5252
*.VisualState.xml
5353
TestResult.xml
54-
nunit-*.xml
54+
nunit-*.xml
55+
56+
# Database files
57+
**/**.db
58+
**/**.db-shm
59+
**/**.db-wal
60+
61+
# Repomix
62+
.repomix/

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
1+
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
22
WORKDIR /app
33
EXPOSE 8080
44

5-
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
5+
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
66
WORKDIR /src
77
COPY . .
88
RUN dotnet restore

GameCollectionAPI/Data/AppDbContext.cs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,5 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
1818
new Role { Id = (int)RoleType.Admin, Name = RoleType.Admin.ToString() },
1919
new Role { Id = (int)RoleType.User, Name = RoleType.User.ToString() }
2020
);
21-
22-
// Add default admin user with ID -1
23-
var adminUser = User.FromCreateDto(
24-
new DTOs.Users.UserCreateDto
25-
{
26-
Username = "Admin",
27-
Password = "admin",
28-
}
29-
);
30-
adminUser.Id = -1;
31-
adminUser.CreatedDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc);
32-
adminUser.RoleId = (int)RoleType.Admin;
33-
modelBuilder.Entity<User>().HasData(adminUser);
3421
}
3522
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
2+
using GameCollectionAPI.Models;
3+
using Microsoft.AspNetCore.Identity;
4+
using Microsoft.EntityFrameworkCore;
5+
6+
namespace GameCollectionAPI.Data;
7+
8+
public static class DbInitializer
9+
{
10+
11+
public static async Task InitializeDatabaseAsync(this IHost host)
12+
{
13+
using var scope = host.Services.CreateScope();
14+
var services = scope.ServiceProvider;
15+
var context = services.GetRequiredService<AppDbContext>();
16+
17+
// Database migration
18+
await context.Database.MigrateAsync();
19+
20+
// Seed admin user
21+
if (!await context.Users.AnyAsync(u => u.RoleId == (int)RoleType.Admin))
22+
{
23+
var configuration = services.GetRequiredService<IConfiguration>();
24+
var adminUsername = configuration["DefaultAdminUsername"] ?? "Admin";
25+
var adminPassword = configuration["DefaultAdminPassword"];
26+
27+
if (adminPassword == null)
28+
{
29+
throw new Exception("Default admin password not provided.");
30+
}
31+
32+
var adminUser = new User
33+
{
34+
Id = -1,
35+
Username = adminUsername,
36+
CreatedDate = DateTime.UtcNow,
37+
RoleId = (int)RoleType.Admin
38+
};
39+
40+
var hasher = new PasswordHasher<User>();
41+
adminUser.PasswordHash = hasher.HashPassword(adminUser, adminPassword);
42+
43+
context.Users.Add(adminUser);
44+
await context.SaveChangesAsync();
45+
}
46+
}
47+
}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<UserSecretsId>a5fe0efc-96d9-41b0-93c1-556182146f8e</UserSecretsId>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.19" />
12-
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
13-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.18" />
14-
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.18">
11+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.9" />
12+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.9" />
13+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.9" />
14+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.9">
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
<PrivateAssets>all</PrivateAssets>
1717
</PackageReference>
18-
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.18" />
19-
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.18">
18+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.9" />
19+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.9">
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
<PrivateAssets>all</PrivateAssets>
2222
</PackageReference>
23-
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
23+
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
2424
</ItemGroup>
2525

2626
</Project>

GameCollectionAPI/Migrations/20250831143809_AddUsersAndRoles.Designer.cs

Lines changed: 1 addition & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

GameCollectionAPI/Migrations/20250831143809_AddUsersAndRoles.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using Microsoft.EntityFrameworkCore.Migrations;
33

44
#nullable disable
@@ -57,11 +57,6 @@ protected override void Up(MigrationBuilder migrationBuilder)
5757
{ 2, "User" }
5858
});
5959

60-
migrationBuilder.InsertData(
61-
table: "Users",
62-
columns: new[] { "Id", "CreatedDate", "PasswordHash", "RoleId", "Username" },
63-
values: new object[] { -1, new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), "AQAAAAIAAYagAAAAEK1L5Fzxzxrba0kq9JHNqrHPo5Nv/dlL2zitQkEg5nCnVT1eecOwJzGj9q/C+Ho06Q==", 1, "Admin" });
64-
6560
migrationBuilder.CreateIndex(
6661
name: "IX_Users_RoleId",
6762
table: "Users",

GameCollectionAPI/Migrations/AppDbContextModelSnapshot.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// <auto-generated />
1+
// <auto-generated />
22
using System;
33
using GameCollectionAPI.Data;
44
using Microsoft.EntityFrameworkCore;
@@ -103,15 +103,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
103103

104104
b.ToTable("Users");
105105

106-
b.HasData(
107-
new
108-
{
109-
Id = -1,
110-
CreatedDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
111-
PasswordHash = "AQAAAAIAAYagAAAAEK1L5Fzxzxrba0kq9JHNqrHPo5Nv/dlL2zitQkEg5nCnVT1eecOwJzGj9q/C+Ho06Q==",
112-
RoleId = 1,
113-
Username = "Admin"
114-
});
115106
});
116107

117108
modelBuilder.Entity("GameCollectionAPI.Models.User", b =>

GameCollectionAPI/Program.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,14 @@
4040
ValidateIssuerSigningKey = true,
4141
ValidIssuer = jwtSettings["Issuer"],
4242
ValidAudience = jwtSettings["Audience"],
43-
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"]))
43+
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"] ?? ""))
4444

4545
};
4646
});
4747

4848
var app = builder.Build();
4949

50-
using (var scope = app.Services.CreateScope())
51-
{
52-
var services = scope.ServiceProvider;
53-
var context = services.GetRequiredService<AppDbContext>();
54-
await context.Database.MigrateAsync();
55-
}
50+
await app.InitializeDatabaseAsync();
5651

5752
// Configure the HTTP request pipeline.
5853
if (app.Environment.IsDevelopment())

0 commit comments

Comments
 (0)