Created one part of all endpoints to admin the user
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARepositoryBaseOfT_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5023b5be698d783ffe9f42b2e944a85a7a66b61bc5e19c76c591036343fd16_003FRepositoryBaseOfT_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="9.3.1" />
|
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="9.3.1" />
|
||||||
<PackageReference Include="AutoMapper" Version="16.0.0" />
|
<PackageReference Include="AutoMapper" Version="16.0.0" />
|
||||||
<PackageReference Include="AutoMapper.Collection" Version="13.0.0" />
|
<PackageReference Include="AutoMapper.Collection" Version="13.0.0" />
|
||||||
|
<PackageReference Include="BCrypt.Net-Next" Version="4.1.0" />
|
||||||
<PackageReference Include="FastEndpoints" Version="7.2.0" />
|
<PackageReference Include="FastEndpoints" Version="7.2.0" />
|
||||||
<PackageReference Include="FastEndpoints.Security" Version="7.2.0" />
|
<PackageReference Include="FastEndpoints.Security" Version="7.2.0" />
|
||||||
<PackageReference Include="FastEndpoints.Swagger" Version="7.2.0" />
|
<PackageReference Include="FastEndpoints.Swagger" Version="7.2.0" />
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.20" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.20" />
|
||||||
|
<PackageReference Include="PasswordGenerator" Version="2.1.0" />
|
||||||
<PackageReference Include="Plainquire.Page" Version="7.0.1" />
|
<PackageReference Include="Plainquire.Page" Version="7.0.1" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class CreateUserDto
|
||||||
|
{
|
||||||
|
public string? FirstName { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? Username { get; set; }
|
||||||
|
public string? Email { get; set; }
|
||||||
|
public string? Password { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class GetUserChallengeDto
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class GetUserDetailsDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? FirstName { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? Username { get; set; }
|
||||||
|
public string? Email { get; set; }
|
||||||
|
public int DesignationId { get; set; }
|
||||||
|
public DateTime CreationDate { get; set; }
|
||||||
|
public GetUserStatsDto? GetUserStatsDto { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class GetUserDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? FirstName { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? Username { get; set; }
|
||||||
|
public int DesignationId { get; set; }
|
||||||
|
public GetUserStatsDto? GetUserStatsDto { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class GetUserProofDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? Proof { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class GetUserStatsDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Score { get; set; }
|
||||||
|
public int TotalWin { get; set; }
|
||||||
|
public int TotalChallenge { get; set; }
|
||||||
|
public int TotalPodium { get; set; }
|
||||||
|
public int TotalBonusChallenge { get; set; }
|
||||||
|
public int Series { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class PatchUserDesignationDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int DesignationId { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class PatchUserPasswordDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? Password { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace BeReadyBackend.DTO.Users;
|
||||||
|
|
||||||
|
public class UpdateUserDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? FirstName { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public string? Username { get; set; }
|
||||||
|
public string? Email { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
|
using BeReadyBackend.Models;
|
||||||
|
using BeReadyBackend.Repositories;
|
||||||
|
using BeReadyBackend.Specifications.Users;
|
||||||
|
using FastEndpoints;
|
||||||
|
using PasswordGenerator;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Endpoints.Users;
|
||||||
|
|
||||||
|
public class CreateUserEndpoint(UsersRepository usersRepository, AutoMapper.IMapper mapper) : Endpoint<CreateUserDto>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Post("/Users/");
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CreateUserDto req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
User? user = await usersRepository.FirstOrDefaultAsync(new GetUserByCriteriaSpec(req.Username!, req.Email!, null), ct);
|
||||||
|
|
||||||
|
if (user is not null)
|
||||||
|
{
|
||||||
|
await Send.StringAsync("Un utilisateur possède déjà ce pseudo ou cette email", 400, cancellation: ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string salt = new Password().IncludeLowercase().IncludeUppercase().IncludeNumeric().LengthRequired(24).Next();
|
||||||
|
|
||||||
|
user = mapper.Map<User>(req);
|
||||||
|
|
||||||
|
user.CreationDate = DateTime.Now;
|
||||||
|
user.Salt = salt;
|
||||||
|
user.Password = BCrypt.Net.BCrypt.HashPassword(req.Password + salt);
|
||||||
|
user.Score = 0;
|
||||||
|
user.TotalWin = 0;
|
||||||
|
user.TotalChallenge = 0;
|
||||||
|
user.TotalPodium = 0;
|
||||||
|
user.TotalBonusChallenge = 0;
|
||||||
|
user.Series = 0;
|
||||||
|
|
||||||
|
await usersRepository.AddAsync(user, ct);
|
||||||
|
await Send.OkAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using BeReadyBackend.Models;
|
||||||
|
using BeReadyBackend.Repositories;
|
||||||
|
using BeReadyBackend.Specifications.Users;
|
||||||
|
using FastEndpoints;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Endpoints.Users;
|
||||||
|
|
||||||
|
public class DeleteUserRequest
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeleteUserEndpoint(UsersRepository usersRepository) : Endpoint<DeleteUserRequest>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Delete("/Users/{@id}", x=>new {x.Id});
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(DeleteUserRequest req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.Id), ct);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
await Send.NotFoundAsync(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await usersRepository.DeleteAsync(user, ct);
|
||||||
|
await Send.OkAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
|
using BeReadyBackend.Repositories;
|
||||||
|
using BeReadyBackend.Specifications.Users;
|
||||||
|
using FastEndpoints;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Endpoints.Users;
|
||||||
|
|
||||||
|
public class GetOverallRankingEndpoint(UsersRepository usersRepository) : EndpointWithoutRequest<List<GetUserDto>>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Get("/OverallRanking/");
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
{
|
||||||
|
await Send.OkAsync(await usersRepository.ProjectToListAsync<GetUserDto>(new GetUsersByScoreSpec(), ct), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
|
using BeReadyBackend.Models;
|
||||||
|
using BeReadyBackend.Repositories;
|
||||||
|
using BeReadyBackend.Specifications.Users;
|
||||||
|
using FastEndpoints;
|
||||||
|
using PasswordGenerator;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Endpoints.Users;
|
||||||
|
|
||||||
|
public class PatchUserDesignationEndpoint(UsersRepository usersRepository, AutoMapper.IMapper mapper) : Endpoint<PatchUserDesignationDto>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Patch("/Users/{@Id}/Designation", x => new {x.Id});
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(PatchUserDesignationDto req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.Id), ct);
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
await Send.NotFoundAsync(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper.Map(req, user);
|
||||||
|
|
||||||
|
await usersRepository.SaveChangesAsync(ct);
|
||||||
|
await Send.OkAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
|
using BeReadyBackend.Models;
|
||||||
|
using BeReadyBackend.Repositories;
|
||||||
|
using BeReadyBackend.Specifications.Users;
|
||||||
|
using FastEndpoints;
|
||||||
|
using PasswordGenerator;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Endpoints.Users;
|
||||||
|
|
||||||
|
public class PatchUserPasswordEndpoint(UsersRepository usersRepository) : Endpoint<PatchUserPasswordDto>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Patch("/Users/{@Id}/Password", x => new {x.Id});
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(PatchUserPasswordDto req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.Id), ct);
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
await Send.NotFoundAsync(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string salt = new Password().IncludeLowercase().IncludeUppercase().IncludeNumeric().LengthRequired(24).Next();
|
||||||
|
user.Password = BCrypt.Net.BCrypt.HashPassword(req.Password + salt);
|
||||||
|
|
||||||
|
await usersRepository.SaveChangesAsync(ct);
|
||||||
|
await Send.OkAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
|
using BeReadyBackend.Models;
|
||||||
|
using BeReadyBackend.Repositories;
|
||||||
|
using BeReadyBackend.Specifications.Users;
|
||||||
|
using FastEndpoints;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Endpoints.Users;
|
||||||
|
|
||||||
|
public class UpdateUserEndpoint(UsersRepository usersRepository, AutoMapper.IMapper mapper) : Endpoint<UpdateUserDto>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Put("/Users/{@Id}/", x => new {x.Id});
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(UpdateUserDto req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
User? user = await usersRepository.FirstOrDefaultAsync(new GetUserByCriteriaSpec(req.Username!, req.Email!, req.Id), ct);
|
||||||
|
|
||||||
|
if (user is not null)
|
||||||
|
{
|
||||||
|
await Send.StringAsync("Un utilisateur possède déjà ce pseudo ou cette email", 400, cancellation: ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.Id), ct);
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
await Send.NotFoundAsync(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper.Map(req, user);
|
||||||
|
|
||||||
|
await usersRepository.SaveChangesAsync(ct);
|
||||||
|
await Send.OkAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using BeReadyBackend.DTO.Achievements;
|
using BeReadyBackend.DTO.Achievements;
|
||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
using BeReadyBackend.Models;
|
using BeReadyBackend.Models;
|
||||||
|
|
||||||
namespace BeReadyBackend.MappingProfiles;
|
namespace BeReadyBackend.MappingProfiles;
|
||||||
@@ -9,5 +10,11 @@ public class DtoToEntityMappings : Profile
|
|||||||
public DtoToEntityMappings()
|
public DtoToEntityMappings()
|
||||||
{
|
{
|
||||||
CreateMap<UnlockAchievementDto, UserAchievement>();
|
CreateMap<UnlockAchievementDto, UserAchievement>();
|
||||||
|
|
||||||
|
CreateMap<CreateUserDto, User>();
|
||||||
|
CreateMap<UpdateUserDto, User>()
|
||||||
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
|
CreateMap<PatchUserDesignationDto, User>()
|
||||||
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using BeReadyBackend.DTO.Achievements;
|
using BeReadyBackend.DTO.Achievements;
|
||||||
|
using BeReadyBackend.DTO.Users;
|
||||||
using BeReadyBackend.Models;
|
using BeReadyBackend.Models;
|
||||||
|
|
||||||
namespace BeReadyBackend.MappingProfiles;
|
namespace BeReadyBackend.MappingProfiles;
|
||||||
@@ -14,5 +15,17 @@ public class EntityToDtoMappings : Profile
|
|||||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Achievement!.Id))
|
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Achievement!.Id))
|
||||||
.ForMember(dest => dest.Label, opt => opt.MapFrom(src => src.Achievement!.Label))
|
.ForMember(dest => dest.Label, opt => opt.MapFrom(src => src.Achievement!.Label))
|
||||||
.ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Achievement!.Description));
|
.ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Achievement!.Description));
|
||||||
|
|
||||||
|
CreateMap<User, GetUserDto>()
|
||||||
|
.ForMember(dest => dest.GetUserStatsDto, opt => opt.MapFrom(src => src));
|
||||||
|
|
||||||
|
CreateMap<User, GetUserDetailsDto>()
|
||||||
|
.ForMember(dest => dest.GetUserStatsDto, opt => opt.MapFrom(src => src));
|
||||||
|
|
||||||
|
CreateMap<User, GetUserStatsDto>();
|
||||||
|
|
||||||
|
CreateMap<User, GetUserChallengeDto>();
|
||||||
|
|
||||||
|
CreateMap<User, GetUserProofDto>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Ardalis.Specification;
|
||||||
|
using BeReadyBackend.Models;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Specifications.Users;
|
||||||
|
|
||||||
|
public class GetUserByCriteriaSpec : SingleResultSpecification<User>
|
||||||
|
{
|
||||||
|
public GetUserByCriteriaSpec(string username, string email, int? id)
|
||||||
|
{
|
||||||
|
Query
|
||||||
|
.Where(x => (x.Username == username || x.Email == email) && x.Id != id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Ardalis.Specification;
|
||||||
|
using BeReadyBackend.Models;
|
||||||
|
|
||||||
|
namespace BeReadyBackend.Specifications.Users;
|
||||||
|
|
||||||
|
public class GetUsersByScoreSpec : Specification<User>
|
||||||
|
{
|
||||||
|
public GetUsersByScoreSpec()
|
||||||
|
{
|
||||||
|
Query
|
||||||
|
.OrderByDescending(x => x.Score);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user