public async Task DeleteAsync(DeleteReply command) { var reply = await _dbContext.Posts .Include(x => x.CreatedByUser) .Include(x => x.Topic).ThenInclude(x => x.Forum).ThenInclude(x => x.Category) .Include(x => x.Topic).ThenInclude(x => x.Forum).ThenInclude(x => x.LastPost) .FirstOrDefaultAsync(x => x.Id == command.Id && x.TopicId == command.TopicId && x.Topic.ForumId == command.ForumId && x.Topic.Forum.Category.SiteId == command.SiteId && x.Status != PostStatusType.Deleted); if (reply == null) { throw new DataException($"Reply with Id {command.Id} not found."); } reply.Delete(); _dbContext.Events.Add(new Event(command.SiteId, command.UserId, EventType.Deleted, typeof(Post), command.Id)); if (reply.IsAnswer) { reply.Topic.SetAsAnswered(false); } reply.Topic.DecreaseRepliesCount(); reply.Topic.Forum.DecreaseRepliesCount(); reply.Topic.Forum.Category.DecreaseRepliesCount(); reply.CreatedByUser.DecreaseRepliesCount(); if (reply.Topic.Forum.LastPost != null && (reply.Id == reply.Topic.Forum.LastPostId || reply.Id == reply.Topic.Forum.LastPost.TopicId)) { var newLastPost = await _dbContext.Posts .Where(x => x.ForumId == reply.Topic.ForumId && x.Status == PostStatusType.Published && (x.Topic == null || x.Topic.Status == PostStatusType.Published) && x.Id != reply.Id) .OrderByDescending(x => x.CreatedOn) .FirstOrDefaultAsync(); if (newLastPost != null) { reply.Topic.Forum.UpdateLastPost(newLastPost.Id); } else { reply.Topic.Forum.UpdateLastPost(null); } } await _dbContext.SaveChangesAsync(); _cacheManager.Remove(CacheKeys.Forum(reply.Topic.ForumId)); }
public async Task <ActionResult> DeleteReply(Guid forumId, Guid topicId, Guid replyId) { var site = await _contextService.CurrentSiteAsync(); var user = await _contextService.CurrentUserAsync(); var command = new DeleteReply { Id = replyId, TopicId = topicId, ForumId = forumId, SiteId = site.Id, UserId = user.Id }; var replyUserId = await _dbContext.Posts .Where(x => x.Id == command.Id && x.TopicId == command.TopicId && x.Topic.ForumId == command.ForumId && x.Topic.Forum.Category.SiteId == command.SiteId && x.Status != PostStatusType.Deleted) .Select(x => x.CreatedBy) .FirstOrDefaultAsync(); var permissions = await _permissionModelBuilder.BuildPermissionModelsByForumId(site.Id, forumId); var canDelete = _securityService.HasPermission(PermissionType.Delete, permissions); var canModerate = _securityService.HasPermission(PermissionType.Moderate, permissions); var authorized = (canDelete && replyUserId == user.Id || canModerate) && !user.IsSuspended; if (!authorized) { _logger.LogWarning("Unauthorized access to delete reply.", new { SiteId = site.Id, ForumId = forumId, TopicId = topicId, ReplyId = replyId, User = User.Identity.Name }); return(Unauthorized()); } await _replyService.DeleteAsync(command); return(Ok()); }
/// <summary> /// /// </summary> /// <param name="threadId">The ID of the database.</param> /// <param name="collectionName">The human-readable name for the database.</param> /// <param name="values"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task DeleteAsync(ThreadId threadId, string collectionName, IEnumerable <string> values, CancellationToken cancellationToken = default) { DeleteRequest request = new() { DbID = ByteString.CopyFrom(threadId.Bytes), CollectionName = collectionName, }; request.InstanceIDs.AddRange(values); try { DeleteReply reply = await _apiClient.DeleteAsync(request, headers : _threadContext.Metadata, cancellationToken : cancellationToken); } catch (RpcException ex) { throw new InvalidOperationException(ex.Status.Detail); } }