diff --git a/EPAServeur/Controllers/CollaborateursApi.cs b/EPAServeur/Controllers/CollaborateursApi.cs index c727c50..444d5f8 100644 --- a/EPAServeur/Controllers/CollaborateursApi.cs +++ b/EPAServeur/Controllers/CollaborateursApi.cs @@ -25,6 +25,7 @@ using IO.Swagger.ClientCollaborateur; using Microsoft.AspNetCore.Server.Kestrel.Core; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication.JwtBearer; +using EPAServeur.Security; namespace IO.Swagger.Controllers { @@ -36,10 +37,12 @@ namespace IO.Swagger.Controllers { private readonly ICollaborateurService collaborateurService; private readonly ILogger logger; - public CollaborateursApiController(ICollaborateurService _collaborateurService, ILogger _logger) + private readonly IAuthorizationService authorizationService; + public CollaborateursApiController(ICollaborateurService _collaborateurService, ILogger _logger, IAuthorizationService _authorizationService) { collaborateurService = _collaborateurService; logger = _logger; + authorizationService = _authorizationService; } /// /// @@ -51,7 +54,7 @@ namespace IO.Swagger.Controllers /// Ressource n'a pas été trouvée [HttpGet] [Route("/api/collaborateurs/{idCollaborateur}")] - //[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "RH,Assistante,Commercial")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = "RH,Assistante,Commercial,Collaborateur")] [ValidateModelState] [SwaggerOperation("GetCollaborateurById")] [SwaggerResponse(statusCode: 200, type: typeof(CollaborateurDTO), description: "OK")] @@ -86,6 +89,23 @@ namespace IO.Swagger.Controllers logger.LogError("Une erreur inconnue est survenue lors de la récupération du collaborateur {idCollaborateur}", idCollaborateur); } logger.LogInformation("Collaborateur {id} trouvée", idCollaborateur); + + // Si l'utilisateur connecté est un collaborateur, on vérifie si il est autorisé à accéder au détail du collaborateur + if (User.IsInRole("Collaborateur")) + { + if (!(await authorizationService.AuthorizeAsync(User, collaborateurDTO, "SameMailRequirement")).Succeeded) + { + ErreurDTO erreurDTO = new ErreurDTO() + { + Code = "403", + Message = "Accès interdit", + }; + return StatusCode(403, erreurDTO); + } + + } + + return Ok(collaborateurDTO); } diff --git a/EPAServeur/Security/CollaborateurAuthorizationHandler.cs b/EPAServeur/Security/CollaborateurAuthorizationHandler.cs new file mode 100644 index 0000000..d9c83d1 --- /dev/null +++ b/EPAServeur/Security/CollaborateurAuthorizationHandler.cs @@ -0,0 +1,42 @@ +using EPAServeur.IServices; +using EPAServeur.Services; +using IO.Swagger.DTO; +using Microsoft.AspNetCore.Authorization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace EPAServeur.Security +{ + /// + /// Handler permettant de vérifier que l'utilisateur connecté valide bien le requirement + /// + public class CollaborateurAuthorizationHandler : AuthorizationHandler + { + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SameMailCollaborateurRequirement requirement, CollaborateurDTO collaborateur) + { + + if (!context.User.HasClaim(c => c.Type == ClaimTypes.Email)) + { + return Task.FromResult(0); + } + + // Récupération du mail du collaborateur dans le claim + var mailClaim = context.User.FindFirst(c => c.Type == ClaimTypes.Email).Value; + + // Vérifie si le mail du collaborateur connecté est égal au mail apside de l'objet collaborateurDTO + if (mailClaim.ToLower() == collaborateur.MailApside.ToLower()) + { + context.Succeed(requirement); + } + else + { + context.Fail(); + } + + return Task.CompletedTask; + } + } +} diff --git a/EPAServeur/Security/SameMailCollaborateurRequirement.cs b/EPAServeur/Security/SameMailCollaborateurRequirement.cs new file mode 100644 index 0000000..9e80105 --- /dev/null +++ b/EPAServeur/Security/SameMailCollaborateurRequirement.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Authorization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EPAServeur.Security +{ + /// + /// Spécification d’autorisation utilisé dans la classe CollaborateurAuthorizationHandler + /// + public class SameMailCollaborateurRequirement: IAuthorizationRequirement + { + + } +} diff --git a/EPAServeur/Startup.cs b/EPAServeur/Startup.cs index e46b8f2..dee1899 100644 --- a/EPAServeur/Startup.cs +++ b/EPAServeur/Startup.cs @@ -1,8 +1,10 @@ using EPAServeur.Context; using EPAServeur.IServices; +using EPAServeur.Security; using EPAServeur.Services; using IO.Swagger.ApiCollaborateur; using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -84,6 +86,12 @@ namespace EPAServeur }; }); + services.AddAuthorization(options => + { + options.AddPolicy("SameMailRequirement", + policy => policy.Requirements.Add(new SameMailCollaborateurRequirement())); + }); + services.AddDbContext(b => b.UseMySQL(Configuration["Data:DefaultConnection:ConnectionString"])); var optionBuider = new DbContextOptionsBuilder() @@ -118,6 +126,9 @@ namespace EPAServeur services.AddScoped(); services.AddScoped(); + //Handlers + services.AddSingleton(); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.