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="AutoMapper" Version="16.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.Security" Version="7.2.0" />
|
||||
<PackageReference Include="FastEndpoints.Swagger" Version="7.2.0" />
|
||||
@@ -20,6 +21,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<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="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||
</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 BeReadyBackend.DTO.Achievements;
|
||||
using BeReadyBackend.DTO.Users;
|
||||
using BeReadyBackend.Models;
|
||||
|
||||
namespace BeReadyBackend.MappingProfiles;
|
||||
@@ -9,5 +10,11 @@ public class DtoToEntityMappings : Profile
|
||||
public DtoToEntityMappings()
|
||||
{
|
||||
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 BeReadyBackend.DTO.Achievements;
|
||||
using BeReadyBackend.DTO.Users;
|
||||
using BeReadyBackend.Models;
|
||||
|
||||
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.Label, opt => opt.MapFrom(src => src.Achievement!.Label))
|
||||
.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