1 Commits

Author SHA1 Message Date
bccd9671b9 test
All checks were successful
Main Build Process / generate documentation (pull_request) Successful in 34s
2024-09-08 19:57:23 +02:00
33 changed files with 157 additions and 852 deletions

View File

@@ -6,7 +6,6 @@ root = true
dotnet_diagnostic.IDE1006.severity = warning
dotnet_diagnostic.IDE0005.severity = error
dotnet_diagnostic.CA5394.severity = none
dotnet_diagnostic.CA1848.severity = none #optimisatio logger pas nécessaire
# Exclude generated code
[src/**/Migrations/*.cs]

View File

@@ -1,36 +1,40 @@
name: "Generation data pour merge sur master"
name: "Main Build Process"
# Runs on main branch commits,
# every commit in a pull request, any published release.
on:
pull_request:
types:
- closed
push:
branches: ["main"]
pull_request:
branches: ["main"]
release:
types: [published]
jobs:
generateData:
if: github.event.pull_request.merged == true
asciidoc:
name: "generate documentation"
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Get build container
id: adocbuild
uses: tonynv/asciidoctor-action@master
with:
program: "asciidoctor -D docs --backend=html5 -o index.html documentation/readme.adoc"
- name: Print execution time
run: echo "Time ${{ steps.adocbuild.outputs.time }}"
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: Doc
path: ./docs
retention-days: 5
- name: build docker images
run: docker build -t gitea.borealian.ovh/mcmuzzle/ludikzone:latest -f ./docker-prod/Dockerfile .
- name: upload image
run: |
echo "${{ secrets.PERSO_GITEAPASSWORD}}" | docker login gitea.borealian.ovh --username mcmuzzle --password-stdin
docker push gitea.borealian.ovh/mcmuzzle/ludikzone:latest
- name: Checkout code
uses: actions/checkout@v2
- name: Get build container
id: adocbuild
uses: tonynv/asciidoctor-action@master
with:
program: "asciidoctor -D docs --backend=html5 -o index.html documentation/readme.adoc"
- name: Print execution time
run: echo "Time ${{ steps.adocbuild.outputs.time }}"
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: Doc
path: ./docs
retention-days: 5
- name: build docker images
run: docker build -t gitea.borealian.ovh/mcmuzzle/ludikzone:latest -f ./docker-prod/Dockerfile .
- name: upload image
run: |
echo "${{ secrets.PERSO_GITEAPASSWORD}}" | docker login gitea.borealian.ovh --username mcmuzzle --password-stdin
docker push gitea.borealian.ovh/mcmuzzle/ludikzone:latest

View File

@@ -1,27 +0,0 @@
name: "Generation data pour merge sur master"
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
reviewProcess:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: '10.0.x'
- name: Install dependencies
run: dotnet restore ./src/LudikZone.sln
- name: Build
run: dotnet build ./src/LudikZone.sln
- name: Test with the dotnet CLI
run: dotnet test ./src/LudikZone.sln

View File

@@ -1,6 +1,6 @@
services:
postgresql:
image: postgres:17
image: postgres:16
ports:
- "${DB_PORT:-5432}:5432"
volumes:

View File

@@ -1,9 +1,9 @@
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["src/LudikZoneBlazor/LudikZoneBlazor.csproj", "src/LudikZoneBlazor/LudikZoneBlazor.csproj"]
RUN dotnet restore "src/LudikZoneBlazor/LudikZoneBlazor.csproj"

View File

@@ -1,6 +1,6 @@
services:
postgresql:
image: postgres:17
image: postgres:16
ports:
- "${DB_PORT:-5432}:5432"
volumes:

View File

@@ -1,11 +0,0 @@
{
"extends": [
"config:base"
],
"packageRules": [
{
"updateTypes": ["minor", "patch", "pin", "digest"],
"automerge": false
}
]
}

View File

@@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisMode>All</AnalysisMode>
</PropertyGroup>
</Project>

View File

@@ -1,20 +0,0 @@
namespace LudikZone.model;
/// <summary>
/// Informations relative a un jeu précis
/// </summary>
public class Game
{
/// <summary> Identifiant unique d'un jeu </summary>
public int Id { get; init; }
/// <summary> le nom du jeu </summary>
public required string Name { get; init; }
/// <summary> Le nombre minimum de joueur pour une partie </summary>
public int MinPlayerCount { get; init; }
/// <summary> Le nombre maximum de joueur pour une partie </summary>
public int MaxPlayerCount { get; init; }
}

View File

@@ -5,8 +5,6 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LudikZoneBlazor", "LudikZoneBlazor\LudikZoneBlazor.csproj", "{79AF398A-0AC3-425C-BA51-B6CFBEECAC28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LudikZone.model", "LudikZone.model\LudikZone.model.csproj", "{C50658FF-0EE9-4EE8-AAA3-FAF4B9F622EA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -20,9 +18,5 @@ Global
{79AF398A-0AC3-425C-BA51-B6CFBEECAC28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79AF398A-0AC3-425C-BA51-B6CFBEECAC28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79AF398A-0AC3-425C-BA51-B6CFBEECAC28}.Release|Any CPU.Build.0 = Release|Any CPU
{C50658FF-0EE9-4EE8-AAA3-FAF4B9F622EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C50658FF-0EE9-4EE8-AAA3-FAF4B9F622EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C50658FF-0EE9-4EE8-AAA3-FAF4B9F622EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C50658FF-0EE9-4EE8-AAA3-FAF4B9F622EA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -45,7 +45,7 @@ internal static class IdentityComponentsEndpointRouteBuilderExtensions
SignInManager<ApplicationUser> signInManager,
[FromForm] string returnUrl) =>
{
await signInManager.SignOutAsync().ConfigureAwait(true);
await signInManager.SignOutAsync();
return TypedResults.LocalRedirect($"~/{returnUrl}");
});
@@ -57,7 +57,7 @@ internal static class IdentityComponentsEndpointRouteBuilderExtensions
[FromForm] string provider) =>
{
// Clear the existing external cookie to ensure a clean login process
await context.SignOutAsync(IdentityConstants.ExternalScheme).ConfigureAwait(false);
await context.SignOutAsync(IdentityConstants.ExternalScheme);
var redirectUrl = UriHelper.BuildRelative(
context.Request.PathBase,
@@ -76,13 +76,13 @@ internal static class IdentityComponentsEndpointRouteBuilderExtensions
[FromServices] UserManager<ApplicationUser> userManager,
[FromServices] AuthenticationStateProvider authenticationStateProvider) =>
{
var user = await userManager.GetUserAsync(context.User).ConfigureAwait(false);
var user = await userManager.GetUserAsync(context.User);
if (user is null)
{
return Results.NotFound($"Unable to load user with ID '{userManager.GetUserId(context.User)}'.");
}
var userId = await userManager.GetUserIdAsync(user).ConfigureAwait(false);
var userId = await userManager.GetUserIdAsync(user);
downloadLogger.LogInformation("User with ID '{UserId}' asked for their personal data.", userId);
// Only include personal data for download
@@ -94,13 +94,13 @@ internal static class IdentityComponentsEndpointRouteBuilderExtensions
personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null");
}
var logins = await userManager.GetLoginsAsync(user).ConfigureAwait(false);
var logins = await userManager.GetLoginsAsync(user);
foreach (var l in logins)
{
personalData.Add($"{l.LoginProvider} external login provider key", l.ProviderKey);
}
personalData.Add("Authenticator Key", (await userManager.GetAuthenticatorKeyAsync(user).ConfigureAwait(false))!);
personalData.Add("Authenticator Key", (await userManager.GetAuthenticatorKeyAsync(user))!);
var fileBytes = JsonSerializer.SerializeToUtf8Bytes(personalData);
context.Response.Headers.TryAdd("Content-Disposition", "attachment; filename=PersonalData.json");

View File

@@ -4,12 +4,10 @@ using LudikZoneBlazor.Data;
namespace LudikZoneBlazor.Components.Account;
#pragma warning disable CA1812 // Elle est instanciée en Injection de dependance
/// <summary> Remove the "else if (EmailSender is IdentityNoOpEmailSender)" block from RegisterConfirmation.razor after updating with a real implementation. </summary>
// Remove the "else if (EmailSender is IdentityNoOpEmailSender)" block from RegisterConfirmation.razor after updating with a real implementation.
internal sealed class IdentityNoOpEmailSender : IEmailSender<ApplicationUser>
{
private readonly NoOpEmailSender emailSender = new NoOpEmailSender();
private readonly IEmailSender emailSender = new NoOpEmailSender();
public Task SendConfirmationLinkAsync(ApplicationUser user, string email, string confirmationLink) =>
emailSender.SendEmailAsync(email, "Confirm your email", $"Please confirm your account by <a href='{confirmationLink}'>clicking here</a>.");
@@ -20,5 +18,3 @@ internal sealed class IdentityNoOpEmailSender : IEmailSender<ApplicationUser>
public Task SendPasswordResetCodeAsync(ApplicationUser user, string email, string resetCode) =>
emailSender.SendEmailAsync(email, "Reset your password", $"Please reset your password using the following code: {resetCode}");
}
#pragma warning restore CA1812

View File

@@ -3,8 +3,6 @@ using Microsoft.AspNetCore.Components;
namespace LudikZoneBlazor.Components.Account;
#pragma warning disable CA1812 // Elle est instanciée en Injection de dependance
internal sealed class IdentityRedirectManager(NavigationManager navigationManager)
{
public const string StatusCookieName = "Identity.StatusMessage";
@@ -58,5 +56,3 @@ internal sealed class IdentityRedirectManager(NavigationManager navigationManage
public void RedirectToCurrentPageWithStatus(string message, HttpContext context)
=> RedirectToWithStatus(CurrentPath, message, context);
}
#pragma warning restore CA1812

View File

@@ -7,8 +7,6 @@ using LudikZoneBlazor.Data;
namespace LudikZoneBlazor.Components.Account;
#pragma warning disable CA1812 // Elle est instanciée en Injection de dependance
// This is a server-side AuthenticationStateProvider that revalidates the security stamp for the connected user
// every 30 minutes an interactive circuit is connected.
internal sealed class IdentityRevalidatingAuthenticationStateProvider(
@@ -23,14 +21,14 @@ internal sealed class IdentityRevalidatingAuthenticationStateProvider(
AuthenticationState authenticationState, CancellationToken cancellationToken)
{
// Get the user manager from a new scope to ensure it fetches fresh data
using AsyncServiceScope scope = scopeFactory.CreateAsyncScope();
await using var scope = scopeFactory.CreateAsyncScope();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
return await ValidateSecurityStampAsync(userManager, authenticationState.User).ConfigureAwait(false);
return await ValidateSecurityStampAsync(userManager, authenticationState.User);
}
private async Task<bool> ValidateSecurityStampAsync(UserManager<ApplicationUser> userManager, ClaimsPrincipal principal)
{
var user = await userManager.GetUserAsync(principal).ConfigureAwait(false);
var user = await userManager.GetUserAsync(principal);
if (user is null)
{
return false;
@@ -42,10 +40,8 @@ internal sealed class IdentityRevalidatingAuthenticationStateProvider(
else
{
var principalStamp = principal.FindFirstValue(options.Value.ClaimsIdentity.SecurityStampClaimType);
var userStamp = await userManager.GetSecurityStampAsync(user).ConfigureAwait(false);
var userStamp = await userManager.GetSecurityStampAsync(user);
return principalStamp == userStamp;
}
}
}
#pragma warning restore CA1812

View File

@@ -3,13 +3,11 @@ using LudikZoneBlazor.Data;
namespace LudikZoneBlazor.Components.Account;
#pragma warning disable CA1812 // Elle est instanciée en Injection de dependance
internal sealed class IdentityUserAccessor(UserManager<ApplicationUser> userManager, IdentityRedirectManager redirectManager)
{
public async Task<ApplicationUser> GetRequiredUserAsync(HttpContext context)
{
var user = await userManager.GetUserAsync(context.User).ConfigureAwait(false);
var user = await userManager.GetUserAsync(context.User);
if (user is null)
{
@@ -19,5 +17,3 @@ internal sealed class IdentityUserAccessor(UserManager<ApplicationUser> userMana
return user;
}
}
#pragma warning restore CA1812

View File

@@ -1,10 +0,0 @@
@using LudikZone.model
<MudPaper Height="140px" Width="140px">
@Game.Name
</MudPaper>
@code {
[Parameter]
public required Game Game { get; set; }
}

View File

@@ -4,11 +4,12 @@
<MudNavMenu>
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
<MudNavLink Href="Games" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.VideogameAsset">Games</MudNavLink>
<MudNavLink Href="counter" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Counter</MudNavLink>
<MudNavLink Href="weather" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.List">Weather</MudNavLink>
<MudNavLink Href="auth" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Lock">Auth Required</MudNavLink>
<AuthorizeView>
<Authorized>
<MudNavLink Href="Account/Manage" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Person">
@context.User.Identity?.Name</MudNavLink>
<MudNavLink Href="Account/Manage" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Person">@context.User.Identity?.Name</MudNavLink>
<form action="Account/Logout" method="post">
<AntiforgeryToken />
<input type="hidden" name="ReturnUrl" value="@currentUrl" />
@@ -18,10 +19,8 @@
</form>
</Authorized>
<NotAuthorized>
<MudNavLink Href="Account/Register" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Person">
Register</MudNavLink>
<MudNavLink Href="Account/Login" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Password">Login
</MudNavLink>
<MudNavLink Href="Account/Register" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Person">Register</MudNavLink>
<MudNavLink Href="Account/Login" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Password">Login</MudNavLink>
</NotAuthorized>
</AuthorizeView>
</MudNavMenu>
@@ -47,3 +46,5 @@
NavigationManager.LocationChanged -= OnLocationChanged;
}
}

View File

@@ -0,0 +1,14 @@
@page "/auth"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
<PageTitle>Auth</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">You are authenticated!</MudText>
<AuthorizeView>
<MudText Class="mb-4">Hello @context.User.Identity?.Name!</MudText>
</AuthorizeView>

View File

@@ -0,0 +1,18 @@
@page "/counter"
<PageTitle>Counter</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Counter</MudText>
<MudText Typo="Typo.body1" Class="mb-4">Current count: @currentCount</MudText>
<MudButton Color="Color.Primary" Variant="Variant.Filled" @onclick="IncrementCount">Click me</MudButton>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@@ -1,31 +0,0 @@
@page "/games"
@using LudikZoneBlazor.Components.Games
@using LudikZoneBlazor.Data
@using Microsoft.AspNetCore.Authorization
@using LudikZone.model
@inject IStringLocalizer<Games> localizer
@inject ApplicationDbContext context
<PageTitle>@localizer["Games"]</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">@localizer["Game list"]</MudText>
<MudGrid Spacing="10" Justify="Justify.Center">
@foreach (var g in GetGames())
{
<MudItem>
<GameIcon Game=@g />
</MudItem>
}
</MudGrid>
@code {
private List<Game> GetGames()
{
return context.Games.ToList();
}
}

View File

@@ -39,16 +39,11 @@
<br />
<MudText Typo="Typo.h6" GutterBottom="true">Prerendering</MudText>
<MudText Typo="Typo.body2" GutterBottom="true">
If you're exploring the features of .NET 8 Blazor,<br /> you might be pleasantly surprised to learn that each page
is prerendered on the server,<br /> regardless of the selected render mode.<br /><br />
This means that you'll need to inject all necessary services on the server,<br /> even when opting for the wasm
(WebAssembly) render mode.<br /><br />
This prerendering functionality is crucial to ensuring that WebAssembly mode feels fast and responsive,<br />
especially when it comes to initial page load times.<br /><br />
For more information on how to detect prerendering and leverage the RenderContext, you can refer to the following
link:
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issuecomment-1783568121" Target="_blank"
Typo="Typo.body2" Color="Color.Primary">
If you're exploring the features of .NET 8 Blazor,<br /> you might be pleasantly surprised to learn that each page is prerendered on the server,<br /> regardless of the selected render mode.<br /><br />
This means that you'll need to inject all necessary services on the server,<br /> even when opting for the wasm (WebAssembly) render mode.<br /><br />
This prerendering functionality is crucial to ensuring that WebAssembly mode feels fast and responsive,<br /> especially when it comes to initial page load times.<br /><br />
For more information on how to detect prerendering and leverage the RenderContext, you can refer to the following link:
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issuecomment-1783568121" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
More details
</MudLink>
</MudText>
@@ -57,8 +52,7 @@
<MudText Typo="Typo.h6" GutterBottom="true">InteractiveAuto</MudText>
<MudText Typo="Typo.body2">
A discussion on how to achieve this can be found here:
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issue-1950424116" Target="_blank" Typo="Typo.body2"
Color="Color.Primary">
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issue-1950424116" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
More details
</MudLink>
</MudText>

View File

@@ -0,0 +1,60 @@
@page "/weather"
<PageTitle>Weather</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Weather forecast</MudText>
<MudText Typo="Typo.body1" Class="mb-8">This component demonstrates fetching data from the server.</MudText>
@if (forecasts == null)
{
<MudProgressCircular Color="Color.Default" Indeterminate="true" />
}
else
{
<MudTable Items="forecasts" Hover="true" SortLabel="Sort By" Elevation="0" AllowUnsorted="false">
<HeaderContent>
<MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<WeatherForecast, object>(x=>x.Date)">Date</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureC)">Temp. (C)</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureF)">Temp. (F)</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.Summary!)">Summary</MudTableSortLabel></MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Date">@context.Date</MudTd>
<MudTd DataLabel="Temp. (C)">@context.TemperatureC</MudTd>
<MudTd DataLabel="Temp. (F)">@context.TemperatureF</MudTd>
<MudTd DataLabel="Summary">@context.Summary</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="new int[]{50, 100}" />
</PagerContent>
</MudTable>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate a loading indicator
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

View File

@@ -12,4 +12,3 @@
@using MudBlazor.Services
@using LudikZoneBlazor
@using LudikZoneBlazor.Components
@using Microsoft.Extensions.Localization

View File

@@ -1,18 +1,8 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using LudikZone.model;
namespace LudikZoneBlazor.Data;
/// <summary>
/// Le context BDD de l'application
/// </summary>
/// <param name="options"></param>
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : IdentityDbContext<ApplicationUser>(options)
{
/// <summary> Tout les jeux existant sur la plateforme </summary>
public virtual DbSet<Game> Games => Set<Game>();
}

View File

@@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Identity;
namespace LudikZoneBlazor.Data;
/// <summary> Add profile data for application users by adding properties to the ApplicationUser class </summary>
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
}

View File

@@ -4,11 +4,6 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisMode>All</AnalysisMode>
<UserSecretsId>aspnet-LudikZoneBlazor-b18f2a2e-d082-4232-8521-6cacaa2a4ba2</UserSecretsId>
</PropertyGroup>
@@ -22,9 +17,4 @@
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LudikZone.model\LudikZone.model.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable

View File

@@ -1,300 +0,0 @@
// <auto-generated />
using System;
using LudikZoneBlazor.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace LudikZoneBlazor.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20240910202256_AjoutGames")]
partial class AjoutGames
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("LudikZone.model.Game", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("MaxPlayerCount")
.HasColumnType("integer");
b.Property<int>("MinPlayerCount")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Games");
});
modelBuilder.Entity("LudikZoneBlazor.Data.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("AccessFailedCount")
.HasColumnType("integer");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("boolean");
b.Property<bool>("LockoutEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("timestamp with time zone");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.HasColumnType("text");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("boolean");
b.Property<string>("SecurityStamp")
.HasColumnType("text");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("boolean");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("ProviderKey")
.HasColumnType("text");
b.Property<string>("ProviderDisplayName")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("RoleId")
.HasColumnType("text");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Value")
.HasColumnType("text");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("LudikZoneBlazor.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("LudikZoneBlazor.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LudikZoneBlazor.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("LudikZoneBlazor.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,37 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace LudikZoneBlazor.Migrations
{
/// <inheritdoc />
public partial class AjoutGames : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Games",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
MinPlayerCount = table.Column<int>(type: "integer", nullable: false),
MaxPlayerCount = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Games", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Games");
}
}
}

View File

@@ -22,29 +22,6 @@ namespace LudikZoneBlazor.Migrations
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("LudikZone.model.Game", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("MaxPlayerCount")
.HasColumnType("integer");
b.Property<int>("MinPlayerCount")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Games");
});
modelBuilder.Entity("LudikZoneBlazor.Data.ApplicationUser", b =>
{
b.Property<string>("Id")

View File

@@ -49,10 +49,6 @@ builder.Services.AddIdentityCore<ApplicationUser>(options => options.SignIn.Requ
builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
// Begin I18N configuration
builder.Services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
// End I18N configuration
var app = builder.Build();
// Configure the HTTP request pipeline.
@@ -78,17 +74,6 @@ app.MapRazorComponents<App>()
// Add additional endpoints required by the Identity /Account Razor components.
app.MapAdditionalIdentityEndpoints();
// Begin I18N configuration
var supportedCultures = new[] { "fr", "en" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
// End I18N configuration
// Appliquer les migrations automatiquement lors du démarrage
using (var scope = app.Services.CreateScope())
{

View File

@@ -1,128 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Games" xml:space="preserve">
<value>Games anglais 4</value>
<comment>comment game</comment>
</data>
<data name="Game list" xml:space="preserve">
<value>Game list</value>
<comment>title game list</comment>
</data>
</root>

View File

@@ -1,128 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Games" xml:space="preserve">
<value>Games francais 4</value>
<comment>comment game</comment>
</data>
<data name="Game list" xml:space="preserve">
<value>Liste des jeux</value>
<comment>Titre de la liste des jeux</comment>
</data>
</root>