diff --git a/Application/GetCommentById/GetCommentByIdQuery.cs b/Application/GetCommentById/GetCommentByIdQuery.cs new file mode 100644 index 0000000..70b6644 --- /dev/null +++ b/Application/GetCommentById/GetCommentByIdQuery.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations; +using MediatR; + +namespace MyHN.Application +{ + public class GetCommentByIdQuery : IRequest + { + [Required] + public Guid Id { get; set; } + + public GetCommentByIdQuery(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/Application/GetCommentById/GetCommentByIdQueryHandler.cs b/Application/GetCommentById/GetCommentByIdQueryHandler.cs new file mode 100644 index 0000000..9b25e60 --- /dev/null +++ b/Application/GetCommentById/GetCommentByIdQueryHandler.cs @@ -0,0 +1,34 @@ +using System.Threading; +using System.Threading.Tasks; +using MediatR; +using System.Linq; +using MyHN.Domain; + +namespace MyHN.Application +{ + public class GetCommentByIdQueryHandler : IRequestHandler + { + private readonly IContext _context; + + public GetCommentByIdQueryHandler(IContext context) + { + _context = context; + } + + public Task Handle(GetCommentByIdQuery request, CancellationToken cancellationToken) + { + var result = from comment in _context.Comments + where comment.Id == request.Id + select new CommentDto + { + Id = comment.Id, + CreatedAt = comment.CreatedAt, + Content = comment.Content, + UpvotesCount = comment.Votes.Count(v => v.Direction == VoteType.Up), + DownvotesCount = comment.Votes.Count(v => v.Direction == VoteType.Down) + }; + + return Task.FromResult(result.Single()); + } + } +} \ No newline at end of file diff --git a/Apps/Api/Controllers/AccountsController.cs b/Apps/Api/Controllers/AccountsController.cs index 92d4f24..1dc8dd7 100644 --- a/Apps/Api/Controllers/AccountsController.cs +++ b/Apps/Api/Controllers/AccountsController.cs @@ -31,6 +31,11 @@ namespace Api.Controllers _factory = factory; } + /// + /// Permet de créer un nouveau compte utilisateur sur la plateforme. + /// + /// + /// [HttpPost] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -46,9 +51,14 @@ namespace Api.Controllers return NoContent(); } + /// + /// Permet de récupèrer un jeton pour un utilisateur afin d'effectuer des appels authentifiés. + /// + /// + /// [HttpPost("token")] [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(TokenViewModel), StatusCodes.Status200OK)] public async Task Login(LoginViewModel request) { var user = await _userManager.FindByNameAsync(request.Username); @@ -80,7 +90,7 @@ namespace Api.Controllers SecurityAlgorithms.HmacSha256Signature), }; - return Ok(new JwtSecurityTokenHandler().CreateEncodedJwt(tokenDescriptor)); + return Ok(new TokenViewModel(user.UserName, new JwtSecurityTokenHandler().CreateEncodedJwt(tokenDescriptor))); } } } \ No newline at end of file diff --git a/Apps/Api/Controllers/CommentsController.cs b/Apps/Api/Controllers/CommentsController.cs index 37cb269..d2e71b1 100644 --- a/Apps/Api/Controllers/CommentsController.cs +++ b/Apps/Api/Controllers/CommentsController.cs @@ -33,7 +33,15 @@ namespace Api.Controllers public async Task CreateComment(CommentLinkCommand command) { var commentId = await _bus.Send(command); - return Created($"comments/{commentId}", null); + return CreatedAtAction(nameof(GetById), new { id = commentId }, null); + } + + [HttpGet("{id:guid}")] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(typeof(CommentDto), StatusCodes.Status200OK)] + public async Task GetById(Guid id) + { + return await _bus.Send(new GetCommentByIdQuery(id)); } /// @@ -75,15 +83,5 @@ namespace Api.Controllers }); return NoContent(); } - - [HttpGet("me")] - public IActionResult Me() - { - return Ok(new - { - UserId = User.Identity.Name, - Authenticated = User.Identity.IsAuthenticated - }); - } } } \ No newline at end of file diff --git a/Apps/Api/Models/TokenViewModel.cs b/Apps/Api/Models/TokenViewModel.cs new file mode 100644 index 0000000..7416ef3 --- /dev/null +++ b/Apps/Api/Models/TokenViewModel.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; + +namespace Api.Models +{ + public class TokenViewModel + { + [Required] + public string Token { get; set; } + + [Required] + public string Username { get; set; } + + public TokenViewModel(string username, string token) + { + Token = token; + Username = username; + } + } +} \ No newline at end of file diff --git a/Apps/Api/swagger.json b/Apps/Api/swagger.json index aa3fed3..2e83684 100644 --- a/Apps/Api/swagger.json +++ b/Apps/Api/swagger.json @@ -11,6 +11,7 @@ "tags": [ "Accounts" ], + "summary": "Permet de créer un nouveau compte utilisateur sur la plateforme.", "operationId": "Accounts_Register", "requestBody": { "x-name": "request", @@ -46,6 +47,7 @@ "tags": [ "Accounts" ], + "summary": "Permet de récupèrer un jeton pour un utilisateur afin d'effectuer des appels authentifiés.", "operationId": "Accounts_Login", "requestBody": { "x-name": "request", @@ -75,7 +77,7 @@ "content": { "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/TokenViewModel" } } } @@ -139,6 +141,48 @@ } } }, + "/api/comments/{id}": { + "get": { + "tags": [ + "Comments" + ], + "operationId": "Comments_GetById", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "guid" + }, + "x-position": 1 + } + ], + "responses": { + "404": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentDto" + } + } + } + } + } + } + }, "/api/comments/{id}/upvote": { "put": { "tags": [ @@ -231,27 +275,6 @@ } } }, - "/api/comments/me": { - "get": { - "tags": [ - "Comments" - ], - "operationId": "Comments_Me", - "responses": { - "200": { - "description": "", - "content": { - "application/octet-stream": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - } - } - } - }, "/api/links": { "get": { "tags": [ @@ -551,6 +574,24 @@ } } }, + "TokenViewModel": { + "type": "object", + "additionalProperties": false, + "required": [ + "token", + "username" + ], + "properties": { + "token": { + "type": "string", + "minLength": 1 + }, + "username": { + "type": "string", + "minLength": 1 + } + } + }, "LoginViewModel": { "type": "object", "additionalProperties": false, @@ -588,6 +629,32 @@ } } }, + "CommentDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "format": "guid" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "content": { + "type": "string", + "nullable": true + }, + "upvotesCount": { + "type": "integer", + "format": "int32" + }, + "downvotesCount": { + "type": "integer", + "format": "int32" + } + } + }, "LinkDto": { "type": "object", "additionalProperties": false, @@ -618,32 +685,6 @@ } } }, - "CommentDto": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "format": "guid" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "content": { - "type": "string", - "nullable": true - }, - "upvotesCount": { - "type": "integer", - "format": "int32" - }, - "downvotesCount": { - "type": "integer", - "format": "int32" - } - } - }, "CreateLinkCommand": { "type": "object", "additionalProperties": false,