public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { // Suppress tag output.TagName = ""; output.TagMode = TagMode.StartTagAndEndTag; // Create a context for our success and failure tag helpers var authorizeContext = new AuthorizeContext(); context.Items.Add(typeof(AuthorizeContext), authorizeContext); // Required to invoke child tag helpers var content = await output.GetChildContentAsync(); // Find permission var permission = _permissionManager .GetPermissions()? .FirstOrDefault(p => p.Name.Equals(Permission, StringComparison.OrdinalIgnoreCase)); // We always need a permission if (permission == null) { return; } // Validate against registered permission handlers var result = await _authorizationService.AuthorizeAsync( ViewContext.HttpContext.User, Resource, new PermissionRequirement(permission)); // Authorization success if (result.Succeeded) { if (authorizeContext.Success != null) { output.Content.AppendHtml(authorizeContext.Success.Content); } } else { // Authorization failure if (authorizeContext.Fail != null) { output.Content.AppendHtml(authorizeContext.Fail.Content); } else { // Suppress output if authorization failed and we have // no failure content to display output.SuppressOutput(); } } }
protected override async Task HandleRequirementAsync( AuthorizationHandlerContext context, PermissionRequirement requirement) { if (context.HasSucceeded) { // This handler is not revoking any pre-existing grants. return; } // The resource represents the category we are checking against // For moderator permissions we always need a resource to test if (context.Resource == null) { return; } // We always need to be authenticated for moderator permissions to apply if (!context.User.Identity.IsAuthenticated) { return; } // Ensure we can convert our resource Id var validChannel = int.TryParse(context.Resource.ToString(), out var categoryId); if (!validChannel) { return; } // Get all moderators var moderators = await _moderatorStore .QueryAsync() .ToList(); // No need to check permissions if we don't have any moderators if (moderators == null) { return; } // Get supplied user var user = await _contextFacade.GetAuthenticatedUserAsync(context.User.Identity); // We need a user to perform access checks against if (user == null) { return; } // Get all moderator entries for given user and resource var userEntries = moderators.Data .Where(m => m.UserId == user.Id & m.CategoryId == categoryId) .ToList(); // No moderator entries for the user and resource if (!userEntries.Any()) { return; } // Reduce our user entries to only parents of current resource we are checking var moderatorsToExamine = new List <Moderator>(); foreach (var moderator in userEntries) { moderatorsToExamine.Add(moderator); } // Accumulate the set of permissions that would satisfy the access check var grantingNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // Accumulate permissions implied by supplied permission ImpliedPermissionNames(requirement.Permission, grantingNames); // Accumulate permissions that imply supplied permission var permissions = _permissionsManager.GetPermissions(); if (permissions != null) { InferredPermissionNames(requirement.Permission, permissions.ToList(), grantingNames); } // Determine if we satisfy any of the accumulated permissions foreach (var moderator in moderatorsToExamine) { foreach (var claim in moderator.Claims) { if (!String.Equals(claim.ClaimType, ModeratorPermission.ClaimTypeName, StringComparison.OrdinalIgnoreCase)) { continue; } var permissionName = claim.ClaimValue; if (grantingNames.Contains(permissionName)) { context.Succeed(requirement); return; } } } }