From 05ccb4d8f1bbe3fb64e117136b4a89bcfb0b0b33 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 27 Oct 2020 19:21:35 +0800 Subject: Split front and back end. --- Timeline/Controllers/TimelineController.cs | 491 ----------------------------- 1 file changed, 491 deletions(-) delete mode 100644 Timeline/Controllers/TimelineController.cs (limited to 'Timeline/Controllers/TimelineController.cs') diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs deleted file mode 100644 index 9a3147ea..00000000 --- a/Timeline/Controllers/TimelineController.cs +++ /dev/null @@ -1,491 +0,0 @@ -using AutoMapper; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Threading.Tasks; -using Timeline.Filters; -using Timeline.Helpers; -using Timeline.Models; -using Timeline.Models.Http; -using Timeline.Models.Validation; -using Timeline.Services; -using Timeline.Services.Exceptions; - -namespace Timeline.Controllers -{ - /// - /// Operations about timeline. - /// - [ApiController] - [CatchTimelineNotExistException] - [ProducesErrorResponseType(typeof(CommonResponse))] - public class TimelineController : Controller - { - private readonly ILogger _logger; - - private readonly IUserService _userService; - private readonly ITimelineService _service; - - private readonly IMapper _mapper; - - /// - /// - /// - public TimelineController(ILogger logger, IUserService userService, ITimelineService service, IMapper mapper) - { - _logger = logger; - _userService = userService; - _service = service; - _mapper = mapper; - } - - /// - /// List all timelines. - /// - /// A username. If set, only timelines related to the user will return. - /// Specify the relation type, may be 'own' or 'join'. If not set, both type will return. - /// "Private" or "Register" or "Public". If set, only timelines whose visibility is specified one will return. - /// The timeline list. - [HttpGet("timelines")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task>> TimelineList([FromQuery][Username] string? relate, [FromQuery][RegularExpression("(own)|(join)")] string? relateType, [FromQuery] string? visibility) - { - List? visibilityFilter = null; - if (visibility != null) - { - visibilityFilter = new List(); - var items = visibility.Split('|'); - foreach (var item in items) - { - if (item.Equals(nameof(TimelineVisibility.Private), StringComparison.OrdinalIgnoreCase)) - { - if (!visibilityFilter.Contains(TimelineVisibility.Private)) - visibilityFilter.Add(TimelineVisibility.Private); - } - else if (item.Equals(nameof(TimelineVisibility.Register), StringComparison.OrdinalIgnoreCase)) - { - if (!visibilityFilter.Contains(TimelineVisibility.Register)) - visibilityFilter.Add(TimelineVisibility.Register); - } - else if (item.Equals(nameof(TimelineVisibility.Public), StringComparison.OrdinalIgnoreCase)) - { - if (!visibilityFilter.Contains(TimelineVisibility.Public)) - visibilityFilter.Add(TimelineVisibility.Public); - } - else - { - return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_QueryVisibilityUnknown, item)); - } - } - } - - TimelineUserRelationship? relationship = null; - if (relate != null) - { - try - { - var relatedUserId = await _userService.GetUserIdByUsername(relate); - - relationship = new TimelineUserRelationship(relateType switch - { - "own" => TimelineUserRelationshipType.Own, - "join" => TimelineUserRelationshipType.Join, - _ => TimelineUserRelationshipType.Default - }, relatedUserId); - } - catch (UserNotExistException) - { - return BadRequest(ErrorResponse.TimelineController.QueryRelateNotExist()); - } - } - - var timelines = await _service.GetTimelines(relationship, visibilityFilter); - var result = _mapper.Map>(timelines); - return result; - } - - /// - /// Get info of a timeline. - /// - /// The timeline name. - /// A unique id. If specified and if-modified-since is also specified, the timeline info will return when unique id is not the specified one even if it is not modified. - /// Same effect as If-Modified-Since header and take precedence than it. - /// If specified, will return 304 if not modified. - /// The timeline info. - [HttpGet("timelines/{name}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status304NotModified)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> TimelineGet([FromRoute][GeneralTimelineName] string name, [FromQuery] string? checkUniqueId, [FromQuery(Name = "ifModifiedSince")] DateTime? queryIfModifiedSince, [FromHeader(Name = "If-Modified-Since")] DateTime? headerIfModifiedSince) - { - DateTime? ifModifiedSince = null; - if (queryIfModifiedSince.HasValue) - { - ifModifiedSince = queryIfModifiedSince.Value; - } - else if (headerIfModifiedSince != null) - { - ifModifiedSince = headerIfModifiedSince.Value; - } - - bool returnNotModified = false; - - if (ifModifiedSince.HasValue) - { - var lastModified = await _service.GetTimelineLastModifiedTime(name); - if (lastModified < ifModifiedSince.Value) - { - if (checkUniqueId != null) - { - var uniqueId = await _service.GetTimelineUniqueId(name); - if (uniqueId == checkUniqueId) - { - returnNotModified = true; - } - } - else - { - returnNotModified = true; - } - } - } - - if (returnNotModified) - { - return StatusCode(StatusCodes.Status304NotModified); - } - else - { - var timeline = await _service.GetTimeline(name); - var result = _mapper.Map(timeline); - return result; - } - } - - /// - /// Get posts of a timeline. - /// - /// The name of the timeline. - /// If set, only posts modified since the time will return. - /// If set to true, deleted post will also return. - /// The post list. - [HttpGet("timelines/{name}/posts")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> PostListGet([FromRoute][GeneralTimelineName] string name, [FromQuery] DateTime? modifiedSince, [FromQuery] bool? includeDeleted) - { - if (!this.IsAdministrator() && !await _service.HasReadPermission(name, this.GetOptionalUserId())) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - List posts = await _service.GetPosts(name, modifiedSince, includeDeleted ?? false); - - var result = _mapper.Map>(posts); - return result; - } - - /// - /// Get the data of a post. Usually a image post. - /// - /// Timeline name. - /// The id of the post. - /// If-None-Match header. - /// The data. - [HttpGet("timelines/{name}/posts/{id}/data")] - [Produces("image/png", "image/jpeg", "image/gif", "image/webp", "application/json", "text/json")] - [ProducesResponseType(typeof(byte[]), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status304NotModified)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PostDataGet([FromRoute][GeneralTimelineName] string name, [FromRoute] long id, [FromHeader(Name = "If-None-Match")] string? ifNoneMatch) - { - _ = ifNoneMatch; - if (!this.IsAdministrator() && !await _service.HasReadPermission(name, this.GetOptionalUserId())) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - try - { - return await DataCacheHelper.GenerateActionResult(this, () => _service.GetPostDataETag(name, id), async () => - { - var data = await _service.GetPostData(name, id); - return data; - }); - } - catch (TimelinePostNotExistException) - { - return NotFound(ErrorResponse.TimelineController.PostNotExist()); - } - catch (TimelinePostNoDataException) - { - return BadRequest(ErrorResponse.TimelineController.PostNoData()); - } - } - - /// - /// Create a new post. - /// - /// Timeline name. - /// - /// Info of new post. - [HttpPost("timelines/{name}/posts")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task> PostPost([FromRoute][GeneralTimelineName] string name, [FromBody] TimelinePostCreateRequest body) - { - var id = this.GetUserId(); - if (!this.IsAdministrator() && !await _service.IsMemberOf(name, id)) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - var content = body.Content; - - TimelinePost post; - - if (content.Type == TimelinePostContentTypes.Text) - { - var text = content.Text; - if (text == null) - { - return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_TextContentTextRequired)); - } - post = await _service.CreateTextPost(name, id, text, body.Time); - } - else if (content.Type == TimelinePostContentTypes.Image) - { - var base64Data = content.Data; - if (base64Data == null) - { - return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_ImageContentDataRequired)); - } - byte[] data; - try - { - data = Convert.FromBase64String(base64Data); - } - catch (FormatException) - { - return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_ImageContentDataNotBase64)); - } - - try - { - post = await _service.CreateImagePost(name, id, data, body.Time); - } - catch (ImageException) - { - return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_ImageContentDataNotImage)); - } - } - else - { - return BadRequest(ErrorResponse.Common.CustomMessage_InvalidModel(Resources.Messages.TimelineController_ContentUnknownType)); - } - - var result = _mapper.Map(post); - return result; - } - - /// - /// Delete a post. - /// - /// Timeline name. - /// Post id. - /// Info of deletion. - [HttpDelete("timelines/{name}/posts/{id}")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task> PostDelete([FromRoute][GeneralTimelineName] string name, [FromRoute] long id) - { - if (!this.IsAdministrator() && !await _service.HasPostModifyPermission(name, id, this.GetUserId())) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - try - { - await _service.DeletePost(name, id); - return CommonDeleteResponse.Delete(); - } - catch (TimelinePostNotExistException) - { - return CommonDeleteResponse.NotExist(); - } - } - - /// - /// Change properties of a timeline. - /// - /// Timeline name. - /// - /// The new info. - [HttpPatch("timelines/{name}")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task> TimelinePatch([FromRoute][GeneralTimelineName] string name, [FromBody] TimelinePatchRequest body) - { - if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId()))) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - await _service.ChangeProperty(name, _mapper.Map(body)); - var timeline = await _service.GetTimeline(name); - var result = _mapper.Map(timeline); - return result; - } - - /// - /// Add a member to timeline. - /// - /// Timeline name. - /// The new member's username. - [HttpPut("timelines/{name}/members/{member}")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task TimelineMemberPut([FromRoute][GeneralTimelineName] string name, [FromRoute][Username] string member) - { - if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId()))) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - try - { - await _service.ChangeMember(name, new List { member }, null); - return Ok(); - } - catch (UserNotExistException) - { - return BadRequest(ErrorResponse.TimelineController.MemberPut_NotExist()); - } - } - - /// - /// Remove a member from timeline. - /// - /// Timeline name. - /// The member's username. - [HttpDelete("timelines/{name}/members/{member}")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task TimelineMemberDelete([FromRoute][GeneralTimelineName] string name, [FromRoute][Username] string member) - { - if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId()))) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - try - { - await _service.ChangeMember(name, null, new List { member }); - return Ok(CommonDeleteResponse.Delete()); - } - catch (UserNotExistException) - { - return Ok(CommonDeleteResponse.NotExist()); - } - } - - /// - /// Create a timeline. - /// - /// - /// Info of new timeline. - [HttpPost("timelines")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task> TimelineCreate([FromBody] TimelineCreateRequest body) - { - var userId = this.GetUserId(); - - try - { - var timeline = await _service.CreateTimeline(body.Name, userId); - var result = _mapper.Map(timeline); - return result; - } - catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.Timeline) - { - return BadRequest(ErrorResponse.TimelineController.NameConflict()); - } - } - - /// - /// Delete a timeline. - /// - /// Timeline name. - /// Info of deletion. - [HttpDelete("timelines/{name}")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task> TimelineDelete([FromRoute][TimelineName] string name) - { - if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId()))) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - try - { - await _service.DeleteTimeline(name); - return CommonDeleteResponse.Delete(); - } - catch (TimelineNotExistException) - { - return CommonDeleteResponse.NotExist(); - } - } - - [HttpPost("timelineop/changename")] - [Authorize] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task> TimelineOpChangeName([FromBody] TimelineChangeNameRequest body) - { - if (!this.IsAdministrator() && !(await _service.HasManagePermission(body.OldName, this.GetUserId()))) - { - return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); - } - - try - { - var timeline = await _service.ChangeTimelineName(body.OldName, body.NewName); - return Ok(_mapper.Map(timeline)); - } - catch (EntityAlreadyExistException) - { - return BadRequest(ErrorResponse.TimelineController.NameConflict()); - } - } - } -} -- cgit v1.2.3