aboutsummaryrefslogtreecommitdiff
path: root/BackEnd
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-04-08 17:02:44 +0800
committercrupest <crupest@outlook.com>2022-04-08 17:02:44 +0800
commit07c1d43fce1932317e9d8a9232490ccce1f253f0 (patch)
tree3e9c7f1264ad81b4032f20d348fe0e04030b6897 /BackEnd
parent9e559fc918d4b4485ef589184348686927ebd63c (diff)
downloadtimeline-07c1d43fce1932317e9d8a9232490ccce1f253f0.tar.gz
timeline-07c1d43fce1932317e9d8a9232490ccce1f253f0.tar.bz2
timeline-07c1d43fce1932317e9d8a9232490ccce1f253f0.zip
...
Diffstat (limited to 'BackEnd')
-rw-r--r--BackEnd/Timeline/Controllers/TimelinePostController.cs2
-rw-r--r--BackEnd/Timeline/Controllers/TimelineV2Controller.cs108
-rw-r--r--BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs9
-rw-r--r--BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs43
-rw-r--r--BackEnd/Timeline/Helpers/InvalidModelResponseFactory.cs5
5 files changed, 143 insertions, 24 deletions
diff --git a/BackEnd/Timeline/Controllers/TimelinePostController.cs b/BackEnd/Timeline/Controllers/TimelinePostController.cs
index c49c95fc..fee80adb 100644
--- a/BackEnd/Timeline/Controllers/TimelinePostController.cs
+++ b/BackEnd/Timeline/Controllers/TimelinePostController.cs
@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Timeline.Entities;
+using Timeline.Filters;
using Timeline.Helpers.Cache;
using Timeline.Models;
using Timeline.Models.Http;
@@ -24,6 +25,7 @@ namespace Timeline.Controllers
/// </summary>
[ApiController]
[Route("timelines/{timeline}/posts")]
+ [CatchMultipleTimelineException]
[ProducesErrorResponseType(typeof(CommonResponse))]
public class TimelinePostController : MyControllerBase
{
diff --git a/BackEnd/Timeline/Controllers/TimelineV2Controller.cs b/BackEnd/Timeline/Controllers/TimelineV2Controller.cs
index 7543c2a8..c82fde2b 100644
--- a/BackEnd/Timeline/Controllers/TimelineV2Controller.cs
+++ b/BackEnd/Timeline/Controllers/TimelineV2Controller.cs
@@ -1,10 +1,12 @@
-using System;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Timeline.Entities;
using Timeline.Models.Http;
+using Timeline.Models.Validation;
using Timeline.Services.Mapper;
using Timeline.Services.Timeline;
+using Timeline.Services.User;
namespace Timeline.Controllers
{
@@ -13,21 +15,117 @@ namespace Timeline.Controllers
public class TimelineV2Controller : MyControllerBase
{
private ITimelineService _timelineService;
+ private IGenericMapper _mapper;
private TimelineMapper _timelineMapper;
+ private IUserService _userService;
- public TimelineV2Controller(ITimelineService timelineService, TimelineMapper timelineMapper)
+ public TimelineV2Controller(ITimelineService timelineService, IGenericMapper mapper, TimelineMapper timelineMapper, IUserService userService)
{
_timelineService = timelineService;
+ _mapper = mapper;
_timelineMapper = timelineMapper;
+ _userService = userService;
}
[HttpGet("{owner}/{timeline}")]
- public async Task<ActionResult<HttpTimeline>> Get([FromRoute] string owner, [FromRoute] string timeline)
+ public async Task<ActionResult<HttpTimeline>> GetAsync([FromRoute][Username] string owner, [FromRoute][TimelineName] string timeline)
{
var timelineId = await _timelineService.GetTimelineIdAsync(owner, timeline);
var t = await _timelineService.GetTimelineAsync(timelineId);
return await _timelineMapper.MapAsync(t, Url, User);
}
+
+ [HttpPatch("{owner}/{timeline}")]
+ [Authorize]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
+ public async Task<ActionResult<HttpTimeline>> PatchAsync([FromRoute][Username] string owner, [FromRoute][TimelineName] string timeline, [FromBody] HttpTimelinePatchRequest body)
+ {
+ var timelineId = await _timelineService.GetTimelineIdAsync(owner, timeline);
+ if (!UserHasPermission(UserPermission.AllTimelineManagement) && !await _timelineService.HasManagePermissionAsync(timelineId, GetAuthUserId()))
+ {
+ return Forbid();
+ }
+ await _timelineService.ChangePropertyAsync(timelineId, _mapper.AutoMapperMap<TimelineChangePropertyParams>(body));
+ var t = await _timelineService.GetTimelineAsync(timelineId);
+ return await _timelineMapper.MapAsync(t, Url, User);
+ }
+
+ [HttpDelete("{owner}/{timeline}")]
+ [Authorize]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
+ public async Task<ActionResult> DeleteAsync([FromRoute][Username] string owner, [FromRoute][TimelineName] string timeline)
+ {
+ var timelineId = await _timelineService.GetTimelineIdAsync(owner, timeline);
+ if (!UserHasPermission(UserPermission.AllTimelineManagement) && !await _timelineService.HasManagePermissionAsync(timelineId, GetAuthUserId()))
+ {
+ return Forbid();
+ }
+ await _timelineService.DeleteTimelineAsync(timelineId);
+ return NoContent();
+ }
+
+ [HttpPut("{owner}/{timeline}/members/{member}")]
+ [Authorize]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
+ public async Task<ActionResult> MemberPutAsync([FromRoute][Username] string owner, [FromRoute][TimelineName] string timeline, [FromRoute][Username] string member)
+ {
+ var timelineId = await _timelineService.GetTimelineIdAsync(owner, timeline);
+ if (!UserHasPermission(UserPermission.AllTimelineManagement) && !await _timelineService.HasManagePermissionAsync(timelineId, GetAuthUserId()))
+ {
+ return Forbid();
+ }
+
+ var userId = await _userService.GetUserIdByUsernameAsync(member);
+ await _timelineService.AddMemberAsync(timelineId, userId);
+ return NoContent();
+ }
+
+ [HttpDelete("{owner}/{timeline}/members/{member}")]
+ [Authorize]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
+ public async Task<ActionResult> MemberDeleteAsync([FromRoute][Username] string owner, [FromRoute][TimelineName] string timeline, [FromRoute][Username] string member)
+ {
+ var timelineId = await _timelineService.GetTimelineIdAsync(owner, timeline);
+ if (!UserHasPermission(UserPermission.AllTimelineManagement) && !await _timelineService.HasManagePermissionAsync(timelineId, GetAuthUserId()))
+ {
+ return Forbid();
+ }
+
+ var userId = await _userService.GetUserIdByUsernameAsync(member);
+ await _timelineService.RemoveMemberAsync(timelineId, userId);
+ return NoContent();
+ }
+
+ [HttpPost]
+ [Authorize]
+ [ProducesResponseType(StatusCodes.Status201Created)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
+ public async Task<ActionResult<HttpTimeline>> TimelineCreate([FromBody] HttpTimelineCreateRequest body)
+ {
+ var authUserId = GetAuthUserId();
+ var authUser = await _userService.GetUserAsync(authUserId);
+ var timeline = await _timelineService.CreateTimelineAsync(authUserId, body.Name);
+ var result = await _timelineMapper.MapAsync(timeline, Url, User);
+ return CreatedAtAction(nameof(GetAsync), new { owner = authUser.Username, timeline = body.Name }, result);
+ }
}
}
diff --git a/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs b/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs
index 67b260d2..a1d1c0e6 100644
--- a/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs
+++ b/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs
@@ -21,7 +21,14 @@ namespace Timeline.Filters
{
if (context.Exception is EntityAlreadyExistException e)
{
- context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
+ if (context.HttpContext.Request.Path.StartsWithSegments("/api/v2"))
+ {
+ context.Result = new UnprocessableEntityObjectResult(new CommonResponse(ErrorCodes.Conflict.Default, "An entity with given key already exists."));
+ }
+ else
+ {
+ context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
+ }
}
}
}
diff --git a/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs b/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs
index d97ffe9f..876f792a 100644
--- a/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs
+++ b/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs
@@ -23,25 +23,32 @@ namespace Timeline.Filters
{
if (context.Exception is EntityNotExistException e)
{
- if (HttpMethods.IsGet(context.HttpContext.Request.Method))
- {
- context.Result = new NotFoundObjectResult(MakeCommonResponse(e));
- }
- else if (HttpMethods.IsDelete(context.HttpContext.Request.Method))
- {
- if (context.ActionDescriptor.EndpointMetadata.OfType<NotEntityDeleteAttribute>().Any())
- {
- context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
+ if (context.HttpContext.Request.Path.StartsWithSegments("/api/v2"))
+ {
+ context.Result = new NotFoundObjectResult(new CommonResponse(ErrorCodes.NotExist.Default, "The entity does not exist."));
+ }
+ else
+ {
+ if (HttpMethods.IsGet(context.HttpContext.Request.Method))
+ {
+ context.Result = new NotFoundObjectResult(MakeCommonResponse(e));
+ }
+ else if (HttpMethods.IsDelete(context.HttpContext.Request.Method))
+ {
+ if (context.ActionDescriptor.EndpointMetadata.OfType<NotEntityDeleteAttribute>().Any())
+ {
+ context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
+ }
+ else
+ {
+ context.Result = new OkObjectResult(CommonDeleteResponse.NotExist());
+ }
+ }
+ else
+ {
+ context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
}
- else
- {
- context.Result = new OkObjectResult(CommonDeleteResponse.NotExist());
- }
- }
- else
- {
- context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
- }
+ }
}
}
}
diff --git a/BackEnd/Timeline/Helpers/InvalidModelResponseFactory.cs b/BackEnd/Timeline/Helpers/InvalidModelResponseFactory.cs
index 121aee6a..906ac566 100644
--- a/BackEnd/Timeline/Helpers/InvalidModelResponseFactory.cs
+++ b/BackEnd/Timeline/Helpers/InvalidModelResponseFactory.cs
@@ -8,6 +8,11 @@ namespace Timeline.Helpers
{
public static IActionResult Factory(ActionContext context)
{
+ if (context.HttpContext.Request.Path.StartsWithSegments("/api/v2"))
+ {
+ return new UnprocessableEntityObjectResult(new CommonResponse(ErrorCodes.Common.InvalidModel, "Request is of bad format."));
+ }
+
var modelState = context.ModelState;
var messageBuilder = new StringBuilder();