Improved ArticleEditor submit permission validation
This commit is contained in:
		
							parent
							
								
									5e5dee0c0c
								
							
						
					
					
						commit
						ce0ffbe711
					
				|  | @ -3,12 +3,10 @@ | ||||||
| @using Wave.Data | @using Wave.Data | ||||||
| @using Microsoft.EntityFrameworkCore | @using Microsoft.EntityFrameworkCore | ||||||
| @using System.ComponentModel.DataAnnotations | @using System.ComponentModel.DataAnnotations | ||||||
| @using Markdig |  | ||||||
| @using Microsoft.AspNetCore.Authorization |  | ||||||
| @using Microsoft.AspNetCore.Identity | @using Microsoft.AspNetCore.Identity | ||||||
| @using Wave.Utilities | @using Wave.Utilities | ||||||
| 
 | 
 | ||||||
| @attribute [Authorize(Policy = "ArticleEditPermissions")] | @attribute [Authorize(Policy = "ArticleEditOrReviewPermissions")] | ||||||
| @inject IDbContextFactory<ApplicationDbContext> ContextFactory | @inject IDbContextFactory<ApplicationDbContext> ContextFactory | ||||||
| @inject NavigationManager Navigation | @inject NavigationManager Navigation | ||||||
| @inject UserManager<ApplicationUser> UserManager | @inject UserManager<ApplicationUser> UserManager | ||||||
|  | @ -106,6 +104,8 @@ | ||||||
|         var user = await UserManager.GetUserAsync(state.User); |         var user = await UserManager.GetUserAsync(state.User); | ||||||
|         User = user ?? throw new ApplicationException("???2"); |         User = user ?? throw new ApplicationException("???2"); | ||||||
|         IsAdmin = await UserManager.IsInRoleAsync(User, "Admin"); |         IsAdmin = await UserManager.IsInRoleAsync(User, "Admin"); | ||||||
|  | 
 | ||||||
|  |         // TODO properly check if user can edit this article (see HandleRoles) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private async Task OnValidSubmit() { |     private async Task OnValidSubmit() { | ||||||
|  | @ -130,12 +130,8 @@ | ||||||
|         } |         } | ||||||
|         if (Model.PublishDate is not null) article.PublishDate = Model.PublishDate.Value; |         if (Model.PublishDate is not null) article.PublishDate = Model.PublishDate.Value; | ||||||
| 
 | 
 | ||||||
|         if (User.Id != article.Author.Id && !IsAdmin)  |  | ||||||
|             throw new ApplicationException("You do not have permissions to edit this article"); |  | ||||||
|         if (User.Id != article.Author.Id) { |  | ||||||
| 	        article.Reviewer = User; // If an admin edits this article, add them as reviewer |  | ||||||
|         } |  | ||||||
|         article.LastModified = DateTimeOffset.UtcNow; |         article.LastModified = DateTimeOffset.UtcNow; | ||||||
|  |         HandleRoles(article, User); | ||||||
| 
 | 
 | ||||||
|         article.BodyHtml = MarkdownUtilities.Parse(article.Body); |         article.BodyHtml = MarkdownUtilities.Parse(article.Body); | ||||||
|          |          | ||||||
|  | @ -147,6 +143,27 @@ | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private async Task HandleRoles(Article article, ApplicationUser me) { | ||||||
|  |         // it's our draft | ||||||
|  |         if (article.Status is ArticleStatus.Draft && article.Author.Id == me.Id) return; | ||||||
|  | 
 | ||||||
|  |         var roles = await UserManager.GetRolesAsync(me); | ||||||
|  | 
 | ||||||
|  |         // reviewers and admins can review articles | ||||||
|  |         if (article.Status is ArticleStatus.InReview && roles.Any(r => r is "Admin" or "Reviewer")) { | ||||||
|  |             article.Reviewer = me; | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // published articles may only be edited my admins or moderators  | ||||||
|  |         if (article.Status is ArticleStatus.Published && roles.Any(r => r is "Admin" or "Reviewer")) { | ||||||
|  |             article.Reviewer = me; // TODO replace with editor or something? | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         throw new ApplicationException("You do not have permissions to edit this article"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private sealed class InputModel { |     private sealed class InputModel { | ||||||
|         public Guid? Id { get; set; } |         public Guid? Id { get; set; } | ||||||
|         [Required(AllowEmptyStrings = false), MaxLength(256)] |         [Required(AllowEmptyStrings = false), MaxLength(256)] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue