diff --git a/WebApi/DataManagers/AdministratorDataManager.cs b/WebApi/DataManagers/AdministratorDataManager.cs index 40254b1..ef020df 100644 --- a/WebApi/DataManagers/AdministratorDataManager.cs +++ b/WebApi/DataManagers/AdministratorDataManager.cs @@ -17,6 +17,11 @@ namespace DataManagers return await Task.FromResult((await manager.addAdmin(admin.ToEntity())).ToModel()); } + public async Task getAdministrator(int id) + { + return (await manager.getAdministrator(id))?.ToModel(); + } + public async Task getAdministratorByUsername(string username) { return await Task.FromResult((await manager.getAdministratorByUsername(username))?.ToModel()); @@ -56,5 +61,10 @@ namespace DataManagers { return await manager.setPassword(username, newHashedPassword); } + + public async Task updateAdministrator(int id, Administrator admin) + { + return (await manager.updateAdministrator(id, admin.ToEntity()))?.ToModel(); + } } } diff --git a/WebApi/EntityManagers/AdministratorEntityManager.cs b/WebApi/EntityManagers/AdministratorEntityManager.cs index 41ff329..4d9fd18 100644 --- a/WebApi/EntityManagers/AdministratorEntityManager.cs +++ b/WebApi/EntityManagers/AdministratorEntityManager.cs @@ -19,7 +19,7 @@ namespace EntityManagers public async Task addAdmin(AdministratorEntity admin) { - var tmp = await dbContext.Administrators.Where(a => a.Equals(admin)).FirstOrDefaultAsync(); + var tmp = await dbContext.Administrators.Where(a => a.Username == admin.Username && a.HashedPassword == admin.HashedPassword).FirstOrDefaultAsync(); if (tmp != null) // <=> he already exist { return tmp!; @@ -29,6 +29,11 @@ namespace EntityManagers return await dbContext.Administrators.Where(a => a.Equals(admin)).FirstAsync(); // to get } + public async Task getAdministrator(int id) + { + return await dbContext.Administrators.SingleOrDefaultAsync(a => a.Id == id); + } + public async Task getAdministratorByUsername(string username) { return await dbContext.Administrators.Where(a => a.Username == username).FirstOrDefaultAsync(); @@ -58,7 +63,7 @@ namespace EntityManagers public async Task removeAdmin(AdministratorEntity admin) { - var tmp = await dbContext.Administrators.Where(a => a.Equals(admin)).FirstOrDefaultAsync(); + var tmp = await dbContext.Administrators.Where(a => a.Username == admin.Username && a.HashedPassword == admin.HashedPassword).FirstOrDefaultAsync(); if(tmp == null) return await Task.FromResult(tmp); dbContext.Administrators.Remove(tmp); dbContext.SaveChanges(); @@ -67,7 +72,7 @@ namespace EntityManagers public async Task removeAdmin(int id) { - var tmp = dbContext.Administrators.Where(a => a.Id == id).FirstOrDefaultAsync().Result; + var tmp = await getAdministrator(id); if (tmp == null) return await Task.FromResult(tmp); dbContext.Administrators.Remove(tmp); dbContext.SaveChanges(); @@ -82,5 +87,15 @@ namespace EntityManagers await dbContext.SaveChangesAsync(); return await Task.FromResult(true); } + + public async Task updateAdministrator(int id, AdministratorEntity admin) + { + var tmp = await getAdministrator(id); + if (tmp == null) return null; + tmp.Username = admin.Username; + tmp.HashedPassword = admin.HashedPassword; + await dbContext.SaveChangesAsync(); + return tmp; + } } } diff --git a/WebApi/ManagerInterfaces/IAdministratorManager.cs b/WebApi/ManagerInterfaces/IAdministratorManager.cs index e1ff970..2a6118e 100644 --- a/WebApi/ManagerInterfaces/IAdministratorManager.cs +++ b/WebApi/ManagerInterfaces/IAdministratorManager.cs @@ -45,7 +45,7 @@ namespace ManagerInterfaces /// /// get a part of all administrators /// - /// the actual page + /// the actual page /// number of T element in a page /// the order criteria /// @@ -55,7 +55,13 @@ namespace ManagerInterfaces /// does not exist (<=> (nb-1)*count outside /// boundaries (0, getNbElement()-1))) /// - public Task<(int nbPages, IEnumerable? administrators)> getAdministrators(int nb, int count, AdministratorOrderCriteria orderCriteria = AdministratorOrderCriteria.ById); + public Task<(int nbPages, IEnumerable? administrators)> getAdministrators(int page, int count, AdministratorOrderCriteria orderCriteria = AdministratorOrderCriteria.ById); + /// + /// get an administrator by his identifier + /// + /// the identifier of the administrator + /// the administrator that corresponde or null if there isn't any + public Task getAdministrator(int id); /// /// get an administrator by his username /// @@ -72,5 +78,12 @@ namespace ManagerInterfaces /// false otherwise (no administrator with this username /// public Task setPassword(string username, string newHashedPassword); + /// + /// upadte an administrator + /// + /// the id of the administrator to update + /// the admin that contains all properties to modify + /// the administrator updated or null if he don't exist + public Task updateAdministrator(int id, T admin); } } diff --git a/WebApi/ServiceManagers/AdministratorServiceManager.cs b/WebApi/ServiceManagers/AdministratorServiceManager.cs index 834b644..7ab5c96 100644 --- a/WebApi/ServiceManagers/AdministratorServiceManager.cs +++ b/WebApi/ServiceManagers/AdministratorServiceManager.cs @@ -23,6 +23,11 @@ namespace ServiceManagers return await Task.FromResult((await manager.addAdmin(admin.ToModel())).ToDto()); } + public async Task getAdministrator(int id) + { + return (await manager.getAdministrator(id))?.ToDto(); + } + public async Task getAdministratorByUsername(string username) { return await Task.FromResult((await manager.getAdministratorByUsername(username))?.ToDto()); @@ -62,5 +67,10 @@ namespace ServiceManagers { return await manager.setPassword(username, newHashedPassword); } + + public async Task updateAdministrator(int id, AdministratorDto admin) + { + return (await manager.updateAdministrator(id, admin.ToModel()))?.ToDto(); + } } } diff --git a/WebApi/WebApi/Controllers/AdministratorController.cs b/WebApi/WebApi/Controllers/AdministratorController.cs index 55f775b..90254fc 100644 --- a/WebApi/WebApi/Controllers/AdministratorController.cs +++ b/WebApi/WebApi/Controllers/AdministratorController.cs @@ -40,12 +40,7 @@ namespace WebApi.Controllers /// administrator already in the database that equals the one we wanted to add when status code = 208 /// no content when status code = 500 /// - [HttpPost("add/administrator/")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status202Accepted)] - [ProducesResponseType(StatusCodes.Status208AlreadyReported)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task PostAdministrator([FromBody] AdministratorDto administrator) + public async Task PostAdministrator(AdministratorDto administrator) { int count = mgr.getNbElements(); // count : number of elements before opperation var tmp = await mgr.addAdmin(administrator); // tmp : administrator recieve by the addAdmin method @@ -54,6 +49,7 @@ namespace WebApi.Controllers if(tmp.Username == administrator.Username) { // it was already in the database + logger.LogInformation(message: $"want to add an administrator already in the database : {tmp.ToString()}"); return StatusCode(208, tmp); } else @@ -70,7 +66,7 @@ namespace WebApi.Controllers // added if (tmp.Username == administrator.Username) { - logger.LogInformation(message: $"administrator added : {tmp.ToString()}"); + logger.LogTrace(message: $"administrator added : {tmp.ToString()}"); // the administrator has been added and we recieved him return StatusCode(202, tmp); } @@ -79,8 +75,8 @@ namespace WebApi.Controllers // the administrator may be added but we do not recieved him if (mgr.getAdministratorByUsername(administrator.Username) != null) { - logger.LogError(message: $"administrator added but not recieved : {tmp.ToString()}"); // he is added + logger.LogError(message: $"administrator added but not recieved"); return Ok(); // not 202 to make a difference between 2 cases } else @@ -95,28 +91,67 @@ namespace WebApi.Controllers return StatusCode(500); } - [HttpGet("administrators")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] + /// + /// get a part of all administrators + /// + /// the actual page + /// number of T element in a page + /// the order criteria + /// + /// status code : + /// 200 if we got a set + /// 204 if we got an empty set + /// 400 if we got nothing + /// + /// return content : + /// a tuple of the number of page and + /// all T element in the database for + /// the page nb if status code = 200 + /// the number of page for count element if status code = 204 + /// nothing if status code = 400 + /// public async Task GetSomeAdministrators(int page, int count = 10, AdministratorOrderCriteria orderCriteria = AdministratorOrderCriteria.ById) { var tmp = await mgr.getAdministrators(page, count, orderCriteria); if (tmp.administrators == null) { - return BadRequest(); + logger.LogInformation(message: "get admin : bad request (page or/and count incorrect)"); + return BadRequest(tmp.nbPages); } else if (tmp.administrators.Count() == 0) { + logger.LogWarning(message: $"get admin : no content. number of element : {mgr.getNbElements()}, page wanted : {page}, number of elements in a page : {count}"); return NoContent(); } else { + logger.LogTrace(message: $"get admins : page = {page}, count = {count}, order criteria = {orderCriteria switch + { + AdministratorOrderCriteria.ById => "byId", + AdministratorOrderCriteria.ByUserName => "byUsername", + _ => "none" + }}"); return Ok(tmp); } } - [HttpDelete()] + /// + /// delete an administrator + /// + /// the id of the administrator to delete + /// + /// + /// status code : + /// 200 if the administrator is removed + /// 204 if the administrator is removed + /// 400 if the id is incorrect + /// 500 if there was an internal error that doesn't allow to continue + /// return content : + /// aministrator deleted when status code = 200 + /// no content when status code = 204 + /// no content when status code = 400 + /// no content when status code = 500 + /// public async Task DeleteAdministrator(int id) { if (id < 0) @@ -126,7 +161,35 @@ namespace WebApi.Controllers } int count = mgr.getNbElements(); // count : number of elements before opperation var tmp = await mgr.removeAdmin(id); - if (tmp == null) return StatusCode(403); + if (tmp == null) // we don't recieve the administrator + { + if(mgr.getNbElements() == count) // he is not deleted + { + if (mgr.getAdministrator(id) != null) + { + logger.LogCritical(message: "remove administrator fail : administrator not removed and not recieved"); + return StatusCode(500); + } + else + { + logger.LogInformation(message: "trying to remove an administrator with an id who don't exist"); + return BadRequest(); + } + } + else // he may be deleted + { + if (mgr.getAdministrator(id) == null) // he must be deleted + { + logger.LogError(message: "administrator removed but not returned"); + return NoContent(); + } + else // he is not deleted + { + logger.LogCritical(message: "remove administrator fail : administrator to remove not remove\ninstead, anotherone is deleted and we recieved nothing"); + return StatusCode(500); + } + } + } if(mgr.getNbElements() == count) { // <=> we have recieved an administrator which should be deleted @@ -135,8 +198,96 @@ namespace WebApi.Controllers logger.LogCritical(message: $"administrator \"{tmp.ToString()}\"should be delete but it isn't"); return StatusCode(500); } - logger.LogInformation(message: $"administrator removed {tmp.ToString()}"); + logger.LogTrace(message: $"administrator removed {tmp.ToString()}"); return Ok(tmp); } + + /// + /// update an administrator + /// + /// id of the administrator to update + /// an administrator who contains all properties to change + /// + /// status code : + /// 200 if the administrator is modified + /// 204 if we wanted to modify an administrator who don't exist + /// 208 if the new username of the administrator is already used + /// 500 if there was an internal error that doesn't allow to continue + /// + /// return content : + /// the administrator modified when status code = 200 + /// nothing when status code = 204 + /// the administrator that already have the username when status code = 208 + /// nothing when status code = 500 + /// + public async Task PutAdministrator(int id, AdministratorDto administrator) + { + var tmp = await mgr.getAdministratorByUsername(administrator.Username); + if (tmp != null) + { + logger.LogTrace(message: "Want to modify into an administrator who already exist"); + return StatusCode(StatusCodes.Status208AlreadyReported, tmp); + } + tmp = await mgr.updateAdministrator(id, administrator); + if(tmp == null) + { + tmp = await mgr.getAdministrator(id); + if (tmp == null) // Ok, it don't exist + { + logger.LogWarning(message: "Want to modify an administrator who don't exist"); + return NoContent(); + } + else + { + if (tmp.Username == administrator.Username && tmp.HashedPassword == administrator.HashedPassword) + { + logger.LogError(message: "Administrator changed but not recieved"); + return Ok(tmp); + } + else + { + logger.LogCritical(message: "administrator haven't changed and we recieved nothing"); + return StatusCode(500); + } + } + } + else if(tmp.Id == id) // we recieve him + { + if(tmp.HashedPassword == administrator.HashedPassword + && tmp.Username == administrator.Username) // he is changed + { + logger.LogTrace(message: $"administrator with id {id} modified in {administrator.ToString()}"); + return Ok(tmp); + } + else // he haven't changed + { + var tmp2 = (await mgr.getAdministratorByUsername(administrator.Username)); + if(tmp2 != null) // it change another administrator + logger.LogCritical(message: "administrator should have changed but he haven't. Instead, another one changed"); + else // nothing have changed + logger.LogCritical(message: "administrator should have changed but he haven't and we recieved him"); + return StatusCode(500); + } + } + else // we recieve another one + { + var tmp2 = await mgr.getAdministrator(id); + if (tmp2 == null) + { // ok, he d'ont exist. + logger.LogError(message: "Want to modify an administrator who don't exist but recieved a random one"); + return NoContent(); + } + else if (tmp2.Username == administrator.Username && tmp2.HashedPassword == administrator.HashedPassword) + { + logger.LogError(message: $"administrator modified but recieved a random one"); + return Ok(tmp2); + } + else + { + logger.LogCritical(message: "administrator that we wanted to modify not modified"); + return StatusCode(500); + } + } + } } } diff --git a/WebApi/WebApi/Controllers/FrontController.cs b/WebApi/WebApi/Controllers/FrontController.cs index 144e6a6..08ec160 100644 --- a/WebApi/WebApi/Controllers/FrontController.cs +++ b/WebApi/WebApi/Controllers/FrontController.cs @@ -1,4 +1,9 @@ -namespace WebApi.Controllers +using DbConnectionLibrairie; +using DTOs; +using Microsoft.AspNetCore.Mvc; +using OrderCriterias; + +namespace WebApi.Controllers { public class FrontController { @@ -10,6 +15,126 @@ private PlayerController playerController; private QuestionController questionController; + public FrontController( + MyDbContext dbContext, + Logger logAdmin, + Logger logAnswer, + Logger logChapter, + Logger logLobby, + Logger logPlayer, + Logger logQuestion + ) + { + administratorController = new AdministratorController(dbContext, logAdmin); + answerController = new AnswerController(dbContext, logAnswer); + chapterController = new ChapterController(dbContext, logChapter); + lobbyController = new LobbyController(dbContext, logLobby); + playerController = new PlayerController(dbContext, logPlayer); + questionController = new QuestionController(dbContext, logQuestion); + } + + /// + /// add an administrator + /// + /// the administrator to add + /// + /// status code : + /// 200 if the administrator is added + /// 202 if the administrator is added + /// 208 if the administrator was already in the database + /// 500 if there was an internal error that doesn't allow to continue + /// return content : + /// no content when status code = 200 + /// administrator added when status code = 202 + /// administrator already in the database that equals the one we wanted to add when status code = 208 + /// no content when status code = 500 + /// + [HttpPost("add/administrator/")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status208AlreadyReported)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task PostAdministrator([FromBody] AdministratorDto administrator) + => await administratorController.PostAdministrator(administrator); + + /// + /// get a part of all administrators + /// + /// the actual page + /// number of T element in a page + /// the order criteria + /// + /// status code : + /// 200 if we got a set + /// 204 if we got an empty set + /// 400 if we got nothing + /// + /// return content : + /// a tuple of the number of page and + /// all T element in the database for + /// the page nb if status code = 200 + /// the number of page for count element if status code = 204 + /// nothing if status code = 400 + /// + [HttpGet("administrators")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task GetSomeAdministrators([FromQuery] int page, int count = 10, + AdministratorOrderCriteria orderCriteria = AdministratorOrderCriteria.ById) + => await administratorController.GetSomeAdministrators(page, count, orderCriteria); + + /// + /// delete an administrator + /// + /// the id of the administrator to delete + /// + /// + /// status code : + /// 200 if the administrator is removed + /// 204 if the administrator is removed + /// 400 if the id is incorrect + /// 500 if there was an internal error that doesn't allow to continue + /// return content : + /// aministrator deleted when status code = 200 + /// no content when status code = 204 + /// no content when status code = 400 + /// no content when status code = 500 + /// + [HttpDelete("delete/administrator")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task DeleteAdministrator([FromQuery] int id) + => await administratorController.DeleteAdministrator(id); + + /// + /// update an administrator + /// + /// id of the administrator to update + /// an administrator who contains all properties to change + /// + /// status code : + /// 200 if the administrator is modified + /// 204 if we wanted to modify an administrator who don't exist + /// 208 if the new username of the administrator is already used + /// 500 if there was an internal error that doesn't allow to continue + /// + /// return content : + /// the administrator modified when status code = 200 + /// nothing when status code = 204 + /// the administrator that already have the username when status code = 208 + /// nothing when status code = 500 + /// + [HttpPut("update/administrator")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status208AlreadyReported)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task PutAdministrator([FromQuery] int id, [FromBody] AdministratorDto administrator) + => await administratorController.PutAdministrator(id, administrator); + } }