private bool CheckPostsSaveRoles(AdminPostSave postSave, Post editedPost, ApplicationUser newAuthor)
        {
            if (!postSave.Id.HasValue && !HttpContext.UserHasClaimPermission(PermissionClaims.CreateNewPosts))
            {
                return(false);
            }

            if (postSave.Id.HasValue && !HttpContext.UserHasClaimPermission(PermissionClaims.EditOtherUsersPosts) &&
                !(editedPost.Author.UserName == User.Identity.Name && HttpContext.UserHasClaimPermission(PermissionClaims.EditOwnPosts)))
            {
                return(false);
            }

            if (!HttpContext.UserHasClaimPermission(PermissionClaims.EditOtherUsersPosts) && newAuthor.UserName != User.Identity.Name)
            {
                return(false);
            }

            if (postSave.IsPublished && (!postSave.Id.HasValue || !editedPost.IsPublished))
            {
                string authorUserName = newAuthor.UserName;

                if (!(authorUserName != User.Identity.Name && HttpContext.UserHasClaimPermission(PermissionClaims.PublishOtherUsersPosts)) &&
                    !(authorUserName == User.Identity.Name && HttpContext.UserHasClaimPermission(PermissionClaims.PublishOwnPosts)))
                {
                    return(false);
                }
            }
            return(true);
        }
        public virtual ActionResult Edit([Bind(Prefix = "Post")] AdminPostSave postSave)
        {
            Post editedPost = postSave.Id.HasValue ? db.Posts.Include(x => x.Author).Include(x => x.PostTags).ThenInclude(x => x.Tag).Include(x => x.PostCategories).ThenInclude(x => x.Category).Single(x => x.Id == postSave.Id)
                                  : db.Posts.Add(new Post
            {
                CreationDate = DateTime.UtcNow,
                Slug         = postSave.Slug,
            }).Entity;

            var newAuthor = userRepository.GetById(postSave.AuthorId); //postSave.AuthorId.HasValue ? userRepository.GetById(postSave.AuthorId.Value) : userRepository.GetByUsername(User.Identity.Name);

            if (CheckPostsSaveRoles(postSave, editedPost, newAuthor) == false)
            {
                return(Forbid());
            }

            editedPost.Author = newAuthor;
            editedPost.LastModificationDate = DateTime.UtcNow;
            postSave.FillPost(editedPost, dateTimeUtil);

            if (db.Posts.Any(x => x.Slug == editedPost.Slug && x.Id != editedPost.Id))
            {
                ModelState.AddModelError("Post.Slug", "This slug already exists");
            }

            IEnumerable <string> tags = from tag in (postSave.Tags ?? string.Empty).Split(new[] { ',' })
                                        where !string.IsNullOrWhiteSpace(tag)
                                        select tag.Trim();

            var existingTags = editedPost.PostTags.Select(x => x.Tag.Name).ToList();

            foreach (var removedTag in editedPost.PostTags.Where(x => tags.Contains(x.Tag.Name, StringComparer.OrdinalIgnoreCase) == false).ToList())
            {
                editedPost.PostTags.Remove(removedTag);
            }

            foreach (var item in postRepository.GetOrCreateTags(tags.Where(x => existingTags.Contains(x, StringComparer.OrdinalIgnoreCase) == false)))
            {
                editedPost.PostTags.Add(new PostTag()
                {
                    Tag = item
                });
            }

            postSave.SelectedCategories = postSave.SelectedCategories ?? Enumerable.Empty <int>();
            var categoriesToAdd = postSave.SelectedCategories.Except(editedPost.PostCategories.Select(x => x.CategoryId));

            foreach (var removedCategory in editedPost.PostCategories.Where(x => postSave.SelectedCategories.Contains(x.CategoryId) == false).ToList())
            {
                editedPost.PostCategories.Remove(removedCategory);
            }

            foreach (Category category in db.Categories.Where(x => categoriesToAdd.Contains(x.Id)))
            {
                editedPost.PostCategories.Add(new PostCategory()
                {
                    Category = category
                });
            }

            if (ModelState.IsValid)
            {
                db.SaveChanges();
                CreatePostRevision(editedPost);
                return(RedirectToAction("Details", "Post", new { postSlug = editedPost.Slug }));
            }

            return(View(CreateAdminPostEdit(editedPost)));
        }