aboutsummaryrefslogtreecommitdiff
path: root/Timeline/Controllers
diff options
context:
space:
mode:
author杨宇千 <crupest@outlook.com>2019-11-20 18:21:17 +0800
committerGitHub <noreply@github.com>2019-11-20 18:21:17 +0800
commit751467deb8ae18909ebd2b241bbb64f1f9da8295 (patch)
tree788b8acdf1141c757cb3226d3cd5f64594386b8f /Timeline/Controllers
parent2de7fa95bb5ad0a10f74fb390bac464a250dee42 (diff)
parent33318b9244a82fee6d711aa15f853e1590ff13f7 (diff)
downloadtimeline-751467deb8ae18909ebd2b241bbb64f1f9da8295.tar.gz
timeline-751467deb8ae18909ebd2b241bbb64f1f9da8295.tar.bz2
timeline-751467deb8ae18909ebd2b241bbb64f1f9da8295.zip
Merge pull request #54 from crupest/timeline
Add core feature Timeline (currently only personal timeline)
Diffstat (limited to 'Timeline/Controllers')
-rw-r--r--Timeline/Controllers/PersonalTimelineController.cs168
1 files changed, 168 insertions, 0 deletions
diff --git a/Timeline/Controllers/PersonalTimelineController.cs b/Timeline/Controllers/PersonalTimelineController.cs
new file mode 100644
index 00000000..c864ed39
--- /dev/null
+++ b/Timeline/Controllers/PersonalTimelineController.cs
@@ -0,0 +1,168 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Threading.Tasks;
+using Timeline.Auth;
+using Timeline.Filters;
+using Timeline.Models;
+using Timeline.Models.Http;
+using Timeline.Models.Validation;
+using Timeline.Services;
+using static Timeline.Resources.Controllers.TimelineController;
+
+namespace Timeline
+{
+ public static partial class ErrorCodes
+ {
+ public static partial class Http
+ {
+ public static class Timeline // ccc = 004
+ {
+ public const int PostListGetForbid = 10040101;
+ public const int PostOperationCreateForbid = 10040102;
+ public const int PostOperationDeleteForbid = 10040103;
+ public const int PostOperationDeleteNotExist = 10040201;
+ public const int ChangeMemberUserNotExist = 10040301;
+ }
+ }
+ }
+}
+
+namespace Timeline.Controllers
+{
+ [ApiController]
+ public class PersonalTimelineController : Controller
+ {
+ private readonly ILogger<PersonalTimelineController> _logger;
+
+ private readonly IPersonalTimelineService _service;
+
+ private bool IsAdmin()
+ {
+ if (User != null)
+ {
+ return User.IsAdministrator();
+ }
+ return false;
+ }
+
+ private string? GetAuthUsername()
+ {
+ if (User == null)
+ {
+ return null;
+ }
+ else
+ {
+ return User.Identity.Name;
+ }
+ }
+
+ public PersonalTimelineController(ILogger<PersonalTimelineController> logger, IPersonalTimelineService service)
+ {
+ _logger = logger;
+ _service = service;
+ }
+
+ [HttpGet("users/{username}/timeline")]
+ [CatchTimelineNotExistException]
+ public async Task<ActionResult<BaseTimelineInfo>> TimelineGet([FromRoute][Username] string username)
+ {
+ return await _service.GetTimeline(username);
+ }
+
+ [HttpGet("users/{username}/timeline/posts")]
+ [CatchTimelineNotExistException]
+ public async Task<ActionResult<IList<TimelinePostInfo>>> PostListGet([FromRoute][Username] string username)
+ {
+ if (!IsAdmin() && !await _service.HasReadPermission(username, GetAuthUsername()))
+ {
+ return StatusCode(StatusCodes.Status403Forbidden,
+ new CommonResponse(ErrorCodes.Http.Timeline.PostListGetForbid, MessagePostListGetForbid));
+ }
+
+ return await _service.GetPosts(username);
+ }
+
+ [HttpPost("users/{username}/timeline/postop/create")]
+ [Authorize]
+ [CatchTimelineNotExistException]
+ public async Task<ActionResult<TimelinePostCreateResponse>> PostOperationCreate([FromRoute][Username] string username, [FromBody] TimelinePostCreateRequest body)
+ {
+ if (!IsAdmin() && !await _service.IsMemberOf(username, GetAuthUsername()!))
+ {
+ return StatusCode(StatusCodes.Status403Forbidden,
+ new CommonResponse(ErrorCodes.Http.Timeline.PostOperationCreateForbid, MessagePostOperationCreateForbid));
+ }
+
+ var res = await _service.CreatePost(username, User.Identity.Name!, body.Content, body.Time);
+ return res;
+ }
+
+ [HttpPost("users/{username}/timeline/postop/delete")]
+ [Authorize]
+ [CatchTimelineNotExistException]
+ public async Task<ActionResult> PostOperationDelete([FromRoute][Username] string username, [FromBody] TimelinePostDeleteRequest body)
+ {
+ try
+ {
+ var postId = body.Id!.Value;
+ if (!IsAdmin() && !await _service.HasPostModifyPermission(username, postId, GetAuthUsername()!))
+ {
+ return StatusCode(StatusCodes.Status403Forbidden,
+ new CommonResponse(ErrorCodes.Http.Timeline.PostOperationDeleteForbid, MessagePostOperationCreateForbid));
+ }
+ await _service.DeletePost(username, postId);
+ }
+ catch (TimelinePostNotExistException)
+ {
+ return BadRequest(new CommonResponse(
+ ErrorCodes.Http.Timeline.PostOperationDeleteNotExist,
+ MessagePostOperationDeleteNotExist));
+ }
+ return Ok();
+ }
+
+ [HttpPost("users/{username}/timeline/op/property")]
+ [Authorize]
+ [SelfOrAdmin]
+ [CatchTimelineNotExistException]
+ public async Task<ActionResult> TimelineChangeProperty([FromRoute][Username] string username, [FromBody] TimelinePropertyChangeRequest body)
+ {
+ await _service.ChangeProperty(username, body);
+ return Ok();
+ }
+
+ [HttpPost("users/{username}/timeline/op/member")]
+ [Authorize]
+ [SelfOrAdmin]
+ [CatchTimelineNotExistException]
+ public async Task<ActionResult> TimelineChangeMember([FromRoute][Username] string username, [FromBody] TimelineMemberChangeRequest body)
+ {
+ try
+ {
+ await _service.ChangeMember(username, body.Add, body.Remove);
+ return Ok();
+ }
+ catch (TimelineMemberOperationUserException e)
+ {
+ if (e.InnerException is UsernameBadFormatException)
+ {
+ return BadRequest(CommonResponse.InvalidModel(
+ string.Format(CultureInfo.CurrentCulture, MessageMemberUsernameBadFormat, e.Index, e.Operation)));
+ }
+ else if (e.InnerException is UserNotExistException)
+ {
+ return BadRequest(new CommonResponse(ErrorCodes.Http.Timeline.ChangeMemberUserNotExist,
+ string.Format(CultureInfo.CurrentCulture, MessageMemberUserNotExist, e.Index, e.Operation)));
+ }
+
+ _logger.LogError(e, LogUnknownTimelineMemberOperationUserException);
+ throw;
+ }
+ }
+ }
+}