diff --git a/ldap-cesi/Configurations/Conf.cs b/ldap-cesi/Configurations/Conf.cs index 0798afe..fa10ddd 100644 --- a/ldap-cesi/Configurations/Conf.cs +++ b/ldap-cesi/Configurations/Conf.cs @@ -1,6 +1,8 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; +using FluentValidation; +using FluentValidation.AspNetCore; using ldap_cesi.Context; using ldap_cesi.Repository; using ldap_cesi.Repository.Services; @@ -48,6 +50,8 @@ public static class Conf builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(); + builder.Services.AddValidatorsFromAssemblyContaining(); + builder.Services.AddFluentValidationAutoValidation(); } public static void AddEFCoreConfiguration(this WebApplicationBuilder builder) { diff --git a/ldap-cesi/Controllers/RoleController.cs b/ldap-cesi/Controllers/RoleController.cs index 28d6554..d865d03 100644 --- a/ldap-cesi/Controllers/RoleController.cs +++ b/ldap-cesi/Controllers/RoleController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using ldap_cesi.DTOs.Inputs.Role; using ldap_cesi.Services.Interfaces; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; namespace ldap_cesi.Controllers { @@ -17,68 +17,72 @@ namespace ldap_cesi.Controllers } // GET: api/Role + /// + /// Endpoint qui retourne tous les rôles + /// + /// Un tableau de rôle [HttpGet] + [Authorize(Roles = "admin")] public async Task GetAllRoles() { var result = await _roleService.GetAll(); - if (result.Success) - { - return Ok(result.Data); - } - return StatusCode(result.StatusCode, result.Message); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } // GET: api/Role/{id} + /// + /// Endpoint qui retourne le role + /// + /// L'id du rôle. + /// Le role update [HttpGet("{id}")] + [Authorize(Roles = "admin")] public async Task GetRoleById(int id) { var result = await _roleService.GetById(id); - if (result.Success) - { - return Ok(result.Data); - } - return StatusCode(result.StatusCode, result.Message); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } // POST: api/Role + /// + /// Endpoint créer le Role + /// + /// Le nom du rôle. + /// Response. [HttpPost] + [Authorize(Roles = "admin")] public async Task CreateRole([FromBody] RoleCreateDto roleDto) { var result = await _roleService.Create(roleDto); - if (result.Success) - { - return CreatedAtAction(nameof(GetRoleById), new { id = result.Data }, result.Data); - } - return StatusCode(result.StatusCode, result.Message); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } - // PUT: api/Role/{id} - [HttpPut("{id}")] - public async Task UpdateRole(int id, [FromBody] RoleUpdateDto roleDto) + // PUT: api/Role + /// + /// Endpoint qui met à jour un role. + /// + /// Les informations du role à mettre à jour. Id, nom + /// Le role mis à jour. + [HttpPut] + [Authorize(Roles = "admin")] + public async Task UpdateRole([FromBody] RoleUpdateDto roleDto) { - if (id != roleDto.Id) - { - return BadRequest("Role ID mismatch"); - } - var result = await _roleService.Update(roleDto); - if (result.Success) - { - return NoContent(); - } - return StatusCode(result.StatusCode, result.Message); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } // DELETE: api/Role/{id} + /// + /// Endpoint qui supprime un rôle. + /// + /// L'ID du rôle à supprimer. + /// Un message de confirmation de suppression. [HttpDelete("{id}")] + [Authorize(Roles = "admin")] public async Task DeleteRole(int id) { var result = await _roleService.Delete(id); - if (result.Success) - { - return NoContent(); - } - return StatusCode(result.StatusCode, result.Message); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } } } diff --git a/ldap-cesi/Controllers/SalarieController.cs b/ldap-cesi/Controllers/SalarieController.cs index 3928aa0..6873f7c 100644 --- a/ldap-cesi/Controllers/SalarieController.cs +++ b/ldap-cesi/Controllers/SalarieController.cs @@ -56,11 +56,21 @@ public class SalarieController : ControllerBase /// L'ID du salarié. /// Le salarié correspondant à l'ID. [HttpGet("/complet/{id}")] - [Authorize(Roles = "admin")] public async Task GetSalarieCompletById(int id) { var result = await _salarieService.GetCompletById(id); return result.Success ? Ok(result.Data) : BadRequest(result.Message); + } + + /// + /// Endpoint qui retourne tout les salariés et les relations qu'il détient + /// + /// Tous les salariés avec leurs relations + [HttpGet("all")] + public async Task GetAllSariesWithRelations() + { + var result = await _salarieService.GetAllWithRelationsAsync(s => s.IdServiceNavigation, s => s.IdSiteNavigation); + return result.Success ? Ok(result.Data) : BadRequest(result.Message); } /// diff --git a/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs b/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs index 59652a2..e11af07 100644 --- a/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs +++ b/ldap-cesi/DTOs/Inputs/Role/RoleCreateDto.cs @@ -1,3 +1,4 @@ + namespace ldap_cesi.DTOs.Inputs.Role; public class RoleCreateDto diff --git a/ldap-cesi/Mapper/AutoMapperProfile.cs b/ldap-cesi/Mapper/AutoMapperProfile.cs index 8d3924e..9d159bf 100644 --- a/ldap-cesi/Mapper/AutoMapperProfile.cs +++ b/ldap-cesi/Mapper/AutoMapperProfile.cs @@ -1,5 +1,6 @@ using AutoMapper; using ldap_cesi.DTOs; +using ldap_cesi.DTOs.Inputs.Role; using ldap_cesi.DTOs.Inputs.Salarie; using ldap_cesi.DTOs.Inputs.Service; using ldap_cesi.DTOs.Inputs.Site; @@ -17,6 +18,7 @@ public class AutoMapperProfile : Profile CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); CreateMap() .ForMember(dest => dest.TelephoneFixe, opt => opt.MapFrom(src => src.TelephoneFix)) @@ -29,14 +31,14 @@ public class AutoMapperProfile : Profile //OUTPUTS MAPPER CreateMap() .ForMember(dest => dest.RoleNom, opt => opt.MapFrom(src => src.IdRoleNavigation.Nom)); - CreateMap() + CreateMap() .ForMember(dest => dest.Service, opt => opt.MapFrom(src => src.IdServiceNavigation)) .ForMember(dest => dest.Site, opt => opt.MapFrom(src => src.IdSiteNavigation)); + CreateMap(); + CreateMap(); + CreateMap(); CreateMap() .ForMember(dest => dest.Service, opt => opt.MapFrom(src => src.IdServiceNavigation.Nom)) .ForMember(dest => dest.Site, opt => opt.MapFrom(src => src.IdSiteNavigation.Ville)); - CreateMap(); - CreateMap(); - CreateMap(); } } \ No newline at end of file diff --git a/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs b/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs index 1daf9fb..223565b 100644 --- a/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs +++ b/ldap-cesi/Repositories/Interfaces/IRepositoryBase.cs @@ -10,6 +10,8 @@ public interface IRepositoryBase where TEntity : class Task> GetAllAsync(CancellationToken cancellationToken = default); Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default); Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default); + Task GetWithRelationsAsync(int id, params Expression>[] relationsAInclude); + Task> GetAllWithRelationsAsync(params Expression>[] relationsAInclude); Task FirstOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/ldap-cesi/Repositories/RepositoryBase.cs b/ldap-cesi/Repositories/RepositoryBase.cs index 3253321..d7fc138 100644 --- a/ldap-cesi/Repositories/RepositoryBase.cs +++ b/ldap-cesi/Repositories/RepositoryBase.cs @@ -9,10 +9,11 @@ namespace ldap_cesi.Repository; public class RepositoryBase : IRepositoryBase where TEntity : class { protected readonly PgContext _context; - + protected readonly DbSet _dbSet; public RepositoryBase(PgContext context) { _context = context ?? throw new ArgumentNullException(nameof(context)); + _dbSet = context.Set(); } public virtual async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) { @@ -113,5 +114,28 @@ public class RepositoryBase : IRepositoryBase where TEntity : throw new Exception("Erreur qui concerne le listing des entités", ex); } } + public virtual async Task> GetAllWithRelationsAsync(params Expression>[] relationInclues) + { + IQueryable query = _dbSet; + + foreach (var relationInclue in relationInclues) + { + query = query.Include(relationInclue); + } + + return await query.ToListAsync(); + } + + public virtual async Task GetWithRelationsAsync(int id, params Expression>[] relationInclues) + { + IQueryable query = _dbSet; + + foreach (var relationInclue in relationInclues) + { + query = query.Include(relationInclue); + } + + return await query.FirstOrDefaultAsync(e => EF.Property(e, "Id") == id); + } } \ No newline at end of file diff --git a/ldap-cesi/Services/Interfaces/IRoleService.cs b/ldap-cesi/Services/Interfaces/IRoleService.cs index e4b46ab..41e1c2a 100644 --- a/ldap-cesi/Services/Interfaces/IRoleService.cs +++ b/ldap-cesi/Services/Interfaces/IRoleService.cs @@ -1,9 +1,6 @@ -using ldap_cesi.Repository.Services; -using ldap_cesi.Services.Interfaces; using ldap_cesi.Entities; using ldap_cesi.DTOs; using ldap_cesi.DTOs.Inputs.Role; -using AutoMapper; namespace ldap_cesi.Services.Interfaces { diff --git a/ldap-cesi/Services/Interfaces/ISalarieService.cs b/ldap-cesi/Services/Interfaces/ISalarieService.cs index 893a742..af59cd0 100644 --- a/ldap-cesi/Services/Interfaces/ISalarieService.cs +++ b/ldap-cesi/Services/Interfaces/ISalarieService.cs @@ -12,5 +12,5 @@ public interface ISalarieService : IServiceBase>> GetAllWithoutIService(); Task>> GetSalariesBySite(int siteId); Task>> GetSalariesByService(int serviceId); - Task> GetCompletById(int id); + Task> GetCompletById(int id); } \ No newline at end of file diff --git a/ldap-cesi/Services/Interfaces/IServiceBase.cs b/ldap-cesi/Services/Interfaces/IServiceBase.cs index f1f4df4..a28d769 100644 --- a/ldap-cesi/Services/Interfaces/IServiceBase.cs +++ b/ldap-cesi/Services/Interfaces/IServiceBase.cs @@ -1,3 +1,4 @@ +using System.Linq.Expressions; using ldap_cesi.Models; namespace ldap_cesi.Services.Interfaces; @@ -10,6 +11,8 @@ public interface IServiceBase { Task>> GetAll(); Task> GetById(int id); + Task> GetByIdWithRelations(int id, params Expression>[] relationsAInclures); // préciser avec une ou des fonctions lambda les relations à inclure dans la réponse + Task>> GetAllWithRelationsAsync(params Expression>[] relationsAInclure); Task> Create(TCreateDto dto); Task> Update(TUpdateDto dto); Task> Delete(int id); diff --git a/ldap-cesi/Services/RoleService.cs b/ldap-cesi/Services/RoleService.cs index 43eba92..c6e44df 100644 --- a/ldap-cesi/Services/RoleService.cs +++ b/ldap-cesi/Services/RoleService.cs @@ -4,13 +4,14 @@ using ldap_cesi.Entities; using ldap_cesi.DTOs; using ldap_cesi.DTOs.Inputs.Role; using AutoMapper; +using ldap_cesi.Validator.Role; namespace ldap_cesi.Services; public class RoleService : ServiceBase,IRoleService { - public RoleService(IRepositoryRole repositoryRole, IMapper mapper, ILogger logger) - : base(repositoryRole, mapper, logger) + public RoleService(IRepositoryRole repositoryRole, IMapper mapper, ILogger logger, RoleCreateValidator roleCreateValidator, RoleUpdateValidator roleUpdateValidator) + : base(repositoryRole, mapper, logger, roleCreateValidator, roleUpdateValidator) { } } \ No newline at end of file diff --git a/ldap-cesi/Services/SalarieService.cs b/ldap-cesi/Services/SalarieService.cs index 1d8a393..40a28b7 100644 --- a/ldap-cesi/Services/SalarieService.cs +++ b/ldap-cesi/Services/SalarieService.cs @@ -18,7 +18,9 @@ public class SalarieService : ServiceBase logger) : base(repositorySalarie, mapper, logger) + public SalarieService(IRepositorySalarie repositorySalarie, IMapper mapper, IRepositorySite repositorySite, IRepositoryService repositoryService, + ILogger logger, SalarieCreateValidator salarieCreateValidator, SalarieUpdateValidator salarieUpdateValidator) + : base(repositorySalarie, mapper, logger, salarieCreateValidator, salarieUpdateValidator) { _repositorySalarie = repositorySalarie; _repositorySite = repositorySite; @@ -48,11 +50,11 @@ public class SalarieService : ServiceBase> GetCompletById(int id) + public async Task> GetCompletById(int id) { var salarie = await _repositorySalarie.GetSalarieWithRelationsAsync(id); - var salarieOutput = _mapper.Map(salarie); - return new ResponseDataModel + var salarieOutput = _mapper.Map(salarie); + return new ResponseDataModel { Success = true, Data = salarieOutput, diff --git a/ldap-cesi/Services/ServiceBase.cs b/ldap-cesi/Services/ServiceBase.cs index e560fd3..c8e444a 100644 --- a/ldap-cesi/Services/ServiceBase.cs +++ b/ldap-cesi/Services/ServiceBase.cs @@ -7,7 +7,9 @@ using ldap_cesi.Services.Interfaces; using ldap_cesi.Validator.Site; using Microsoft.Extensions.Logging; using System.Collections.Generic; +using System.Linq.Expressions; using System.Threading.Tasks; +using FluentValidation; namespace ldap_cesi.Services; @@ -20,12 +22,16 @@ public class ServiceBase : IServiceBase _repository; protected readonly IMapper _mapper; protected readonly ILogger> _logger; + protected readonly IValidator _createDtoValidator; + protected readonly IValidator _updateDtoValidator; - public ServiceBase(IRepositoryBase repository, IMapper mapper, ILogger> logger) + public ServiceBase(IRepositoryBase repository, IMapper mapper, ILogger> logger, IValidator createDtoValidator, IValidator updateDtoValidator) { _repository = repository; _mapper = mapper; _logger = logger; + _createDtoValidator = createDtoValidator; + _updateDtoValidator = updateDtoValidator; } public virtual async Task>> GetAll() @@ -87,11 +93,83 @@ public class ServiceBase : IServiceBase>> GetAllWithRelationsAsync(params Expression>[] relationsAInclure) + { + try + { + var entities = await _repository.GetAllWithRelationsAsync(relationsAInclure); + var dtos = _mapper.Map>(entities); + return new ResponseDataModel> + { + Success = true, + Data = dtos, + StatusCode = 200, + Message = "Liste des entités récupérée avec succès." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Une erreur s'est produite lors de la récupération des entités."); + return new ResponseDataModel> + { + Success = false, + Message = "Une erreur s'est produite lors de la récupération des entités.", + StatusCode = 500 + }; + } + } + + public virtual async Task> GetByIdWithRelations(int id, params Expression>[] relationsAInclure) + { + try + { + var entity = await _repository.GetWithRelationsAsync(id, relationsAInclure); + if (entity == null) + { + return new ResponseDataModel + { + Success = false, + Message = $"Aucune entité trouvée avec l'identifiant {id}.", + StatusCode = 404 + }; + } + + var dto = _mapper.Map(entity); + return new ResponseDataModel + { + Success = true, + Data = dto, + StatusCode = 200, + Message = "Entité avec relations récupérée avec succès." + }; + } + catch (Exception ex) + { + _logger.LogError(ex, $"Une erreur s'est produite lors de la récupération de l'entité avec l'identifiant {id}."); + return new ResponseDataModel + { + Success = false, + Message = "Une erreur s'est produite lors de la récupération de l'entité avec relations.", + StatusCode = 500 + }; + } + } public virtual async Task> Create(TCreateDto dto) { try { + var validationResult = _createDtoValidator.Validate(dto); + if (!validationResult.IsValid) + { + return new ResponseDataModel + { + Success = false, + Message = string.Join("; ", validationResult.Errors.Select(e => e.ErrorMessage)), + StatusCode = 400 + }; + } var entity = _mapper.Map(dto); var createdEntity = await _repository.AddAsync(entity); return new ResponseDataModel @@ -118,6 +196,16 @@ public class ServiceBase : IServiceBase + { + Success = false, + Message = string.Join("; ", validationResult.Errors.Select(e => e.ErrorMessage)), + StatusCode = 400 + }; + } var entity = _mapper.Map(dto); bool isUpdated = await _repository.UpdateAsync(entity); return new ResponseDataModel diff --git a/ldap-cesi/Services/ServiceService.cs b/ldap-cesi/Services/ServiceService.cs index 7cb9b6e..193fe2c 100644 --- a/ldap-cesi/Services/ServiceService.cs +++ b/ldap-cesi/Services/ServiceService.cs @@ -13,7 +13,8 @@ namespace ldap_cesi.Services; public class ServiceService : ServiceBase, IServiceService { - public ServiceService(IRepositoryService repositoryService, IMapper mapper, ILogger logger) : base(repositoryService, mapper, logger) + public ServiceService(IRepositoryService repositoryService, IMapper mapper, ILogger logger, ServiceCreateValidator serviceCreateValidator, ServiceUpdateValidator serviceUpdateValidator) + : base(repositoryService, mapper, logger, serviceCreateValidator, serviceUpdateValidator) { } diff --git a/ldap-cesi/Services/UtilisateurService.cs b/ldap-cesi/Services/UtilisateurService.cs index b908c5a..3abf032 100644 --- a/ldap-cesi/Services/UtilisateurService.cs +++ b/ldap-cesi/Services/UtilisateurService.cs @@ -47,7 +47,7 @@ public class UtilisateurService : IUtilisateurService public async Task> Login(UtilisateurLoginDto utilisateurInput) { - var validation = new UtilisateurCreateValidator(); + var validation = new UtilisateurLoginValidator(); var result = validation.Validate(utilisateurInput); if (!result.IsValid) { diff --git a/ldap-cesi/Validator/Role/RoleCreateValidator.cs b/ldap-cesi/Validator/Role/RoleCreateValidator.cs new file mode 100644 index 0000000..ff2e572 --- /dev/null +++ b/ldap-cesi/Validator/Role/RoleCreateValidator.cs @@ -0,0 +1,14 @@ +using FluentValidation; +using ldap_cesi.DTOs.Inputs.Role; + +namespace ldap_cesi.Validator.Role; + +public class RoleCreateValidator : AbstractValidator +{ + public RoleCreateValidator() + { + RuleFor(x => x.Nom) + .NotEmpty().WithMessage("Le nom est requis.") + .MaximumLength(50).WithMessage("Le nom ne doit pas dépasser 50 caractères."); + } +} \ No newline at end of file diff --git a/ldap-cesi/Validator/Role/RoleUpdateValidator.cs b/ldap-cesi/Validator/Role/RoleUpdateValidator.cs new file mode 100644 index 0000000..1bdec9d --- /dev/null +++ b/ldap-cesi/Validator/Role/RoleUpdateValidator.cs @@ -0,0 +1,16 @@ +using FluentValidation; +using ldap_cesi.DTOs.Inputs.Role; + +namespace ldap_cesi.Validator.Role; + +public class RoleUpdateValidator : AbstractValidator +{ + public RoleUpdateValidator() + { + RuleFor(x => x.Nom) + .NotEmpty().WithMessage("Le nom est requis.") + .MaximumLength(50).WithMessage("Le nom ne doit pas dépasser 50 caractères."); + RuleFor(x => x.Id) + .NotEmpty().WithMessage("L'identifiant du Rôle est requis."); + } +} \ No newline at end of file diff --git a/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs b/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs index a53fc1c..c23c02a 100644 --- a/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs +++ b/ldap-cesi/Validator/Salarie/SalarieCreateValidator.cs @@ -16,11 +16,15 @@ public class SalarieCreateValidator : AbstractValidator .MaximumLength(50).WithMessage("Le prénom ne doit pas dépasser 50 caractères."); RuleFor(x => x.TelephoneFix) - .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .Matches(@"^(\+33|0)[1-9](\d{2}){4}$") + .WithMessage("Le numéro de téléphone fixe n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone fixe ne doit pas dépasser 15 caractères."); RuleFor(x => x.TelephonePortable) .NotEmpty().WithMessage("Le téléphone portable est requis.") + .Matches(@"^(\+33|0)[6-7](\d{2}){4}$") + .WithMessage("Le numéro de téléphone portable n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone portable ne doit pas dépasser 15 caractères."); RuleFor(x => x.Email) diff --git a/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs b/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs index a755c82..d364149 100644 --- a/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs +++ b/ldap-cesi/Validator/Salarie/SalarieUpdateValidator.cs @@ -18,11 +18,15 @@ public class SalarieUpdateValidator : AbstractValidator .MaximumLength(50).WithMessage("Le prénom ne doit pas dépasser 50 caractères."); RuleFor(x => x.TelephoneFixe) - .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .NotEmpty().WithMessage("Le téléphone fixe est requis.") + .Matches(@"^(\+33|0)[1-9](\d{2}){4}$") + .WithMessage("Le numéro de téléphone fixe n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone fixe ne doit pas dépasser 15 caractères."); RuleFor(x => x.TelephonePortable) .NotEmpty().WithMessage("Le téléphone portable est requis.") + .Matches(@"^(\+33|0)[6-7](\d{2}){4}$") + .WithMessage("Le numéro de téléphone portable n'est pas valide. Format attendu : +33XXXXXXXXX ou 0XXXXXXXXX.") .MaximumLength(15).WithMessage("Le téléphone portable ne doit pas dépasser 15 caractères."); RuleFor(x => x.Email) diff --git a/ldap-cesi/Validator/Utilisateur/UtilisateurCreateValidator.cs b/ldap-cesi/Validator/Utilisateur/UtilisateurLoginValidator.cs similarity index 54% rename from ldap-cesi/Validator/Utilisateur/UtilisateurCreateValidator.cs rename to ldap-cesi/Validator/Utilisateur/UtilisateurLoginValidator.cs index 154b071..aa2e28f 100644 --- a/ldap-cesi/Validator/Utilisateur/UtilisateurCreateValidator.cs +++ b/ldap-cesi/Validator/Utilisateur/UtilisateurLoginValidator.cs @@ -3,16 +3,18 @@ using ldap_cesi.DTOs.Inputs; namespace ldap_cesi.Validator.Utilisateur; -public class UtilisateurCreateValidator : AbstractValidator +public class UtilisateurLoginValidator : AbstractValidator { - public UtilisateurCreateValidator() + public UtilisateurLoginValidator() { RuleFor(x => x.Email) .NotEmpty().WithMessage("L'email est requis.") - .EmailAddress().WithMessage("L'email n'est pas valide."); + .EmailAddress().WithMessage("L'email n'est pas valide.") + .MaximumLength(50).WithMessage("L'email ne doit pas dépasser 50 caractères."); RuleFor(x => x.MotDePasse) .NotEmpty().WithMessage("Le mot de passe est requis.") - .MinimumLength(6).WithMessage("Le mot de passe doit contenir au moins 6 caractères."); + .MinimumLength(6).WithMessage("Le mot de passe doit contenir au moins 6 caractères.") + .MaximumLength(20).WithMessage("Le mot de passe ne doit pas dépasser 20 caractères."); } } \ No newline at end of file