Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/GraphQL.AspNetCore3/AuthorizationVisitorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ public virtual async ValueTask EnterAsync(ASTNode node, ValidationContext contex
_onlyAnonymousSelected.Push(ti);

// Fields, unlike types, are validated immediately.
if (!fieldAnonymousAllowed) {
await ValidateAsync(field, node, context);
}
await ValidateAsync(field, node, context);
}

// prep for descendants, if any
Expand Down
31 changes: 31 additions & 0 deletions src/Tests/AuthorizationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,37 @@ public async Task EndToEnd(bool authenticated)
actual.ShouldBe(@"{""errors"":[{""message"":""Access denied for field \u0027parent\u0027 on type \u0027QueryType\u0027."",""locations"":[{""line"":1,""column"":3}],""extensions"":{""code"":""ACCESS_DENIED"",""codes"":[""ACCESS_DENIED""]}}]}");
}

[Theory]
[InlineData("Role1", false, false)] // User with Role1, child requires Role2 - should fail at child level
[InlineData("Role2", false, false)] // User with Role2, query requires Role1 - should fail at query level
[InlineData("Role1,Role2", false, true)] // User with both roles - should pass
[InlineData(null, false, false)] // Unauthenticated user - should fail at query level
[InlineData("Role1", true, false)] // User with Role1, child requires Role2 and is anonymous - should fail
[InlineData("Role2", true, true)] // User with Role2, child requires Role2 and is anonymous - should pass
[InlineData("Role1,Role2", true, true)] // User with both roles, child is anonymous - should pass
[InlineData(null, true, false)] // Unauthenticated user, child is anonymous - should fail due as Role2 missing
public void BothAnonymousAndRequirements(string? userRoles, bool childIsAnonymous, bool expectedIsValid)
{
// Set up query to require Role1
_query.AuthorizeWithRoles("Role1");

// Set up child field to require Role2 and optionally be anonymous
_field.AuthorizeWithRoles("Role2");
if (childIsAnonymous)
_field.AllowAnonymous();

// Set up user principal based on test parameters
if (userRoles != null)
{
var roles = userRoles.Split(',');
var claims = roles.Select(role => new Claim(ClaimTypes.Role, role)).ToArray();
_principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookie"));
}

var ret = Validate(@"{ parent { child } }");
ret.IsValid.ShouldBe(expectedIsValid);
}

public enum Mode
{
None,
Expand Down
Loading