Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
169535d
Add WebAPI project named GameCollectionAPI
Harsche Aug 2, 2025
79a6813
Remove weather forecast endpoint and related model from Program.cs
Harsche Aug 2, 2025
90a7403
Add Game model
Harsche Aug 3, 2025
827ac5d
Add controllers to app configuration
Harsche Aug 3, 2025
8cbca38
Add EntityFrameworkCore and initial ApplicationDbContext
Harsche Aug 3, 2025
2cbc00b
Add new EntityFramework packages
Harsche Aug 3, 2025
47868a6
Configure SQLite
Harsche Aug 3, 2025
6645d4f
Add initial GamesController
Harsche Aug 3, 2025
77f89e9
Cretae first migration
Harsche Aug 3, 2025
9d428d4
Add Microsoft.EntityFrameworkCore.Design package
Harsche Aug 3, 2025
ddd9d1d
Update games controller
Harsche Aug 3, 2025
78bb932
Enhance GamesController with improved response type annotations and v…
Harsche Aug 3, 2025
c21fb4e
Add XML documentation for GamesController
Harsche Aug 3, 2025
151c317
Add DTOs for Game and use them in GamesController
Harsche Aug 3, 2025
bb8a3c9
Implement GameRepository and IGameRepository for data access; update …
Harsche Aug 17, 2025
c2b5c30
Implement GameService class and use it in GamesController
Harsche Aug 23, 2025
4ef974a
Add XML docs to GameService
Harsche Aug 23, 2025
2a51595
Add required keyword to fields that are required
Harsche Aug 23, 2025
1367d18
Merge pull request #1 from Harsche/feature/add-games
Harsche Aug 23, 2025
a3bef90
Implement user management features including UserController, UserServ…
Harsche Aug 30, 2025
495d57f
Add JWT authentication configuration and update appsettings for issue…
Harsche Aug 31, 2025
c32b704
Add user and role management with initial data seeding; update User a…
Harsche Aug 31, 2025
e24bfcb
Implement authentication features with JWT support
Harsche Aug 31, 2025
98daf35
Update XML docs
Harsche Aug 31, 2025
db733d3
Fix various issues; update admin user seed logic
Harsche Aug 31, 2025
3d9c4f7
Merge pull request #2 from Harsche/feature/add-users-and-auth
Harsche Aug 31, 2025
8a0d8ce
Remove query during model creation. Automatically apply migrations a…
Harsche Aug 31, 2025
d9f4bbb
Add Dockerfile and update appsettings.json structure
Harsche Aug 31, 2025
57d54e3
Merge pull request #5 from Harsche/prepare-for-ci-cd
Harsche Aug 31, 2025
d986c72
Merge pull request #4 from Harsche/github-actions
Harsche Aug 31, 2025
79ceb17
Merge branch 'main' into dev
Harsche Sep 1, 2025
e5d5905
Update github actions
Harsche Sep 1, 2025
922282b
feat(controllers): secure UsersController with role-based and ownersh…
Harsche Jul 1, 2026
9d63455
feat(controllers): add authorization security and document API respon…
Harsche Jul 1, 2026
1475a47
fix(auth): use UTC time for token expiration and register auth middle…
Harsche Jul 1, 2026
2560cb8
Merge pull request #6 from Harsche/feature/access-fixes
Harsche Jul 1, 2026
67cc231
build: upgrade project to .NET 10.0
Harsche Jul 1, 2026
c2843d7
fix: address potential null reference exceptions and update gitignore
Harsche Jul 1, 2026
6287d99
feat(database): configure database initialization and admin user seeding
Harsche Jul 1, 2026
3ebd6da
ci(workflow): rename workflow and configure container environment var…
Harsche Jul 1, 2026
21a1a5e
Merge pull request #7 from Harsche/feature/update-dotnet-version
Harsche Jul 1, 2026
2ebdb45
ci: separate PR validation from deployment workflow
Harsche Jul 1, 2026
211de97
chore(docker): run container as non-root user
Harsche Jul 1, 2026
c73ec5e
feat(auth): validate JWT secret key on application startup
Harsche Jul 1, 2026
b397c06
ci(github-actions): update docker actions and improve deployment scri…
Harsche Jul 1, 2026
535176f
fix(controllers): improve user ID validation in UsersController
Harsche Jul 1, 2026
32b3d83
fix(controllers): use CreatedAtRoute instead of CreatedAtAction in Us…
Harsche Jul 1, 2026
2748a27
feat(database): add unique index to Username and update seeder
Harsche Jul 1, 2026
1ff770b
feat(dto): add minimum password length validation to AuthDto
Harsche Jul 1, 2026
3da5aee
refactor(dto): update validation constraints in UserCreateDto
Harsche Jul 1, 2026
37fff9e
refactor(database): prevent cascade delete on User-Role relationship
Harsche Jul 1, 2026
48fe30a
feat(auth): register authorization services
Harsche Jul 1, 2026
ad037ef
fix(auth): allow password verification to succeed when rehash is needed
Harsche Jul 1, 2026
1f75c4f
fix(service): allow updating username to the current value without du…
Harsche Jul 1, 2026
be838ea
ci(workflow): disable credential persistence in pr-validation checkout
Harsche Jul 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 0 additions & 51 deletions .github/workflows/blank.yml

This file was deleted.

77 changes: 77 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: CI

on:
push:
branches: ["main"]

workflow_dispatch:


jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
Comment thread
Harsche marked this conversation as resolved.

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Log in to GitHub Container Registry
- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Build and push the Docker image to GHCR
- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
push: true
tags: ghcr.io/harsche/game-collection-api:latest

- name: List built images
run: docker images

deploy:
needs: build
runs-on: ubuntu-latest
environment: oracle-vm
permissions:
contents: read

steps:
- name: Deploy to Oracle VM
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.ORACLE_VM_HOST }}
username: ${{ secrets.ORACLE_VM_USERNAME }}
key: ${{ secrets.ORACLE_VM_SSH_KEY }}
script: |
GH_ACTOR="${{ github.actor }}"
# Log in to GitHub Container Registry
echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u "$GH_ACTOR" --password-stdin

# Pull the latest image
docker pull ghcr.io/harsche/game-collection-api:latest

# Stop and remove the old container if it exists
docker stop game-collection-api || true
docker rm game-collection-api || true

# Run the new container
docker run -d \
--name game-collection-api \
-p 8080:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e "Jwt__Key=${{ secrets.JWT_SECRET_KEY }}" \
-e "DefaultAdminPassword=${{ secrets.DEFAULT_ADMIN_PASSWORD }}" \
ghcr.io/harsche/game-collection-api:latest
26 changes: 26 additions & 0 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: PR Validation

on:
pull_request:
branches: ["main", "dev"]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
Comment thread
Harsche marked this conversation as resolved.
with:
persist-credentials: false

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Build the Docker image to verify compilation and packaging (push is set to false)
- name: Build Docker image
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile
push: false
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,12 @@ CodeCoverage/
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
nunit-*.xml

# Database files
**/**.db
**/**.db-shm
**/**.db-wal

# Repomix
.repomix/
10 changes: 10 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"github.copilot.chat.commitMessageGeneration.instructions": [

{
"text": "Use max 50 characters for commit messages and cover the main changes. Descriptions can be longer. Descriptions should provide additional context and details about the changes made and must be clear and concise and formatted as a bullet list."


}
]
}
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
USER $APP_UID
ENTRYPOINT ["dotnet", "GameCollectionAPI.dll"]
Comment thread
Harsche marked this conversation as resolved.

24 changes: 24 additions & 0 deletions GameCollectionAPI.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameCollectionAPI", "GameCollectionAPI\GameCollectionAPI.csproj", "{1AD172C0-6E37-BB3F-BC22-F837FB4B7FD7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1AD172C0-6E37-BB3F-BC22-F837FB4B7FD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AD172C0-6E37-BB3F-BC22-F837FB4B7FD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AD172C0-6E37-BB3F-BC22-F837FB4B7FD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AD172C0-6E37-BB3F-BC22-F837FB4B7FD7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CF7C9A84-D357-417C-852F-432620A32AAD}
EndGlobalSection
EndGlobal
66 changes: 66 additions & 0 deletions GameCollectionAPI/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using GameCollectionAPI.DTOs;
using GameCollectionAPI.Exceptions;
using GameCollectionAPI.Services;
using Microsoft.AspNetCore.Mvc;

namespace GameCollectionAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private IAuthService _authService;

public AuthController(IAuthService authService)
{
_authService = authService;
}

/// <summary>
/// Registers a new user.
/// </summary>
/// <param name="authDto">Authentication DTO containing user details.</param>
/// <returns>The created user.</returns>
[HttpPost("Register")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<IActionResult> Register([FromBody] AuthDto authDto)
{
if (authDto == null) { return BadRequest(); }

try
{
var createdUser = await _authService.RegisterUserAsync(authDto);
return CreatedAtRoute("GetUserById", new { id = createdUser.Id }, createdUser);
}
catch (DuplicateUsernameException ex)
{
return Conflict(new { message = ex.Message });
}
}

/// <summary>
/// Logs in a user and returns a JWT token.
/// </summary>
/// <param name="authDto">Authentication DTO containing user credentials.</param>
/// <returns>A JWT token if credentials are valid; Unauthorized otherwise.</returns>
[HttpPost("Login")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Login([FromBody] AuthDto authDto)
{
if (authDto == null) { return BadRequest(); }

try
{
var token = await _authService.LoginUserAsync(authDto);
return Ok(new { jwt = token });
}
catch (InvalidDataException)
{
return Unauthorized(new { message = "Invalid credentials" });
}
}
}
}
Loading
Loading