Skip to content

Commit 348ec20

Browse files
committed
Fixed more auth issues
1 parent 7a75b6e commit 348ec20

File tree

68 files changed

+220
-240
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+220
-240
lines changed

src/All.slnx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
<Folder Name="/HotChocolate/Core/test/">
111111
<Project Path="HotChocolate/Core/test/Abstractions.Tests/HotChocolate.Abstractions.Tests.csproj" />
112112
<Project Path="HotChocolate/Core/test/Authorization.Tests/HotChocolate.Authorization.Tests.csproj" />
113+
<Project Path="HotChocolate/Core/test/Execution.Abstractions.Tests/HotChocolate.Execution.Abstractions.Tests.csproj" />
113114
<Project Path="HotChocolate/Core/test/Execution.Tests/HotChocolate.Execution.Tests.csproj" />
114115
<Project Path="HotChocolate/Core/test/Features.Tests/HotChocolate.Features.Tests.csproj" />
115116
<Project Path="HotChocolate/Core/test/Fetching.Tests/HotChocolate.Fetching.Tests.csproj" />
@@ -135,9 +136,6 @@
135136
<Project Path="HotChocolate/Core/test/Utilities/HotChocolate.Tests.Utilities.csproj" />
136137
<Project Path="HotChocolate/Core/test/Validation.Tests/HotChocolate.Validation.Tests.csproj" />
137138
</Folder>
138-
<Folder Name="/HotChocolate/Core/test/Execution.Abstractions.Tests/">
139-
<Project Path="HotChocolate/Core/test/Execution.Abstractions.Tests/HotChocolate.Execution.Abstractions.Tests.csproj" />
140-
</Folder>
141139
<Folder Name="/HotChocolate/CostAnalysis/" />
142140
<Folder Name="/HotChocolate/CostAnalysis/src/">
143141
<Project Path="HotChocolate/CostAnalysis/src/CostAnalysis/HotChocolate.CostAnalysis.csproj" />

src/HotChocolate/AspNetCore/src/AspNetCore.Authorization/DefaultAuthorizationHandler.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Security.Claims;
22
using HotChocolate.Authorization;
3+
using HotChocolate.Features;
34
using HotChocolate.Resolvers;
45
using Microsoft.AspNetCore.Authorization;
56
using IAuthorizationHandler = HotChocolate.Authorization.IAuthorizationHandler;
@@ -48,7 +49,7 @@ public DefaultAuthorizationHandler(
4849
}
4950

5051
/// <summary>
51-
/// Authorize current directive using Microsoft.AspNetCore.Authorization.
52+
/// Authorize the current directive using Microsoft.AspNetCore.Authorization.
5253
/// </summary>
5354
/// <param name="context">The current middleware context.</param>
5455
/// <param name="directive">The authorization directive.</param>
@@ -62,7 +63,7 @@ public async ValueTask<AuthorizeResult> AuthorizeAsync(
6263
AuthorizeDirective directive,
6364
CancellationToken ct)
6465
{
65-
var userState = GetUserState(context.ContextData);
66+
var userState = GetUserState(context);
6667
var user = userState.User;
6768
bool authenticated;
6869

@@ -72,10 +73,10 @@ public async ValueTask<AuthorizeResult> AuthorizeAsync(
7273
}
7374
else
7475
{
75-
// if the authenticated state is not yet set we will determine it and update the state.
76+
// if the authenticated state is not yet set, we will determine it and update the state.
7677
authenticated = user.Identities.Any(t => t.IsAuthenticated);
7778
userState = userState.SetIsAuthenticated(authenticated);
78-
SetUserState(context.ContextData, userState);
79+
SetUserState(context, userState);
7980
}
8081

8182
return await AuthorizeAsync(
@@ -91,7 +92,7 @@ public async ValueTask<AuthorizeResult> AuthorizeAsync(
9192
IReadOnlyList<AuthorizeDirective> directives,
9293
CancellationToken ct)
9394
{
94-
var userState = GetUserState(context.ContextData);
95+
var userState = GetUserState(context);
9596
var user = userState.User;
9697
bool authenticated;
9798

@@ -101,10 +102,10 @@ public async ValueTask<AuthorizeResult> AuthorizeAsync(
101102
}
102103
else
103104
{
104-
// if the authenticated state is not yet set we will determine it and update the state.
105+
// if the authenticated state is not yet set, we will determine it and update the state.
105106
authenticated = user.Identities.Any(t => t.IsAuthenticated);
106107
userState = userState.SetIsAuthenticated(authenticated);
107-
SetUserState(context.ContextData, userState);
108+
SetUserState(context, userState);
108109
}
109110

110111
foreach (var directive in directives)
@@ -196,20 +197,19 @@ private async Task<AuthorizationPolicy> BuildAuthorizationPolicy(
196197
return policyBuilder.Build();
197198
}
198199

199-
private static UserState GetUserState(IDictionary<string, object?> contextData)
200+
private static UserState GetUserState(IFeatureProvider featureProvider)
200201
{
201-
if (contextData.TryGetValue(WellKnownContextData.UserState, out var value) &&
202-
value is UserState p)
202+
if (featureProvider.Features.TryGet<UserState>(out var state))
203203
{
204-
return p;
204+
return state;
205205
}
206206

207207
throw new MissingStateException(
208208
"Authorization",
209-
WellKnownContextData.UserState,
209+
"HotChocolate.Authorization.UserState",
210210
StateKind.Global);
211211
}
212212

213-
private static void SetUserState(IDictionary<string, object?> contextData, UserState state)
214-
=> contextData[WellKnownContextData.UserState] = state;
213+
private static void SetUserState(IFeatureProvider featureProvider, UserState state)
214+
=> featureProvider.Features.Set(state);
215215
}

src/HotChocolate/AspNetCore/src/AspNetCore/DefaultHttpRequestInterceptor.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,21 @@ public virtual ValueTask OnCreateAsync(
1818
{
1919
var userState = new UserState(context.User);
2020

21+
requestBuilder.Features.Set(userState);
22+
requestBuilder.Features.Set(context);
23+
requestBuilder.Features.Set(context.User);
24+
2125
requestBuilder.TrySetServices(context.RequestServices);
2226
requestBuilder.TryAddGlobalState(nameof(HttpContext), context);
2327
requestBuilder.TryAddGlobalState(nameof(CancellationToken), context.RequestAborted);
2428
requestBuilder.TryAddGlobalState(nameof(ClaimsPrincipal), userState.User);
25-
requestBuilder.TryAddGlobalState(WellKnownContextData.UserState, userState);
2629

2730
if (context.IncludeQueryPlan())
2831
{
2932
requestBuilder.TryAddGlobalState(WellKnownContextData.IncludeQueryPlan, true);
3033
}
3134

32-
var costSwitch = context.TryGetCostSwitch();
33-
if (costSwitch is not null)
35+
if (context.TryGetCostSwitch() is { } costSwitch)
3436
{
3537
requestBuilder.TryAddGlobalState(costSwitch, true);
3638
}

src/HotChocolate/AspNetCore/src/AspNetCore/DefaultSocketSessionInterceptor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ public virtual ValueTask OnRequestAsync(
2525
var userState = new UserState(context.User);
2626
var serviceScopeFactory = session.Connection.RequestServices.GetService<IServiceScopeFactory>();
2727

28+
requestBuilder.Features.Set(userState);
29+
requestBuilder.Features.Set(context);
30+
requestBuilder.Features.Set(context.User);
31+
2832
requestBuilder.TryAddGlobalState(nameof(IServiceScopeFactory), serviceScopeFactory);
2933
requestBuilder.TryAddGlobalState(nameof(CancellationToken), session.Connection.RequestAborted);
3034
requestBuilder.TryAddGlobalState(nameof(HttpContext), context);
3135
requestBuilder.TryAddGlobalState(nameof(ISocketSession), session);
3236
requestBuilder.TryAddGlobalState(OperationSessionId, operationSessionId);
33-
3437
requestBuilder.TryAddGlobalState(nameof(ClaimsPrincipal), userState.User);
35-
requestBuilder.TryAddGlobalState(WellKnownContextData.UserState, userState);
3638

3739
if (context.IncludeQueryPlan())
3840
{

src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HttpContextExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public static bool IncludeQueryPlan(this HttpContext context)
3030
public static string? TryGetCostSwitch(this HttpContext context)
3131
{
3232
var headers = context.Request.Headers;
33+
3334
if (headers.TryGetValue(HttpHeaderKeys.Cost, out var values))
3435
{
3536
var value = values.FirstOrDefault();

src/HotChocolate/Core/src/Abstractions/MissingStateException.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace HotChocolate;
44

55
/// <summary>
6-
/// This exception can be thrown if a feature that is dependant on a well-known state
6+
/// This exception can be thrown if a feature that is dependent on a well-known state
77
/// cannot retrieve it.
88
/// </summary>
99
public sealed class MissingStateException : Exception
@@ -39,7 +39,7 @@ public MissingStateException(string feature, string key, StateKind kind)
3939
public string Key { get; }
4040

4141
/// <summary>
42-
/// Gets the state store that is missing the state.
42+
/// Gets the state store missing the state.
4343
/// </summary>
4444
public StateKind Kind { get; }
4545
}

src/HotChocolate/Core/src/Abstractions/UserState.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
namespace HotChocolate;
44

55
/// <summary>
6-
/// The Hot Chocolate user state can be provided by GraphQL server implementations
7-
/// and authorization implementations are depending on this state being added to
6+
/// The Hot Chocolate user state can be provided by GraphQL server implementations,
7+
/// and authorization implementations depend on this state being added to
88
/// the global state.
99
/// </summary>
1010
public sealed class UserState : IEquatable<UserState>
@@ -13,10 +13,10 @@ public sealed class UserState : IEquatable<UserState>
1313
/// Initializes a new instance of <see cref="UserState"/>.
1414
/// </summary>
1515
/// <param name="user">
16-
/// The currently signed in user.
16+
/// The current signed-in user.
1717
/// </param>
1818
/// <param name="isAuthenticated">
19-
/// Specifies if the currently signed in user is authenticated.
19+
/// Specifies if the currently signed-in user is authenticated.
2020
/// </param>
2121
public UserState(ClaimsPrincipal user, bool? isAuthenticated = null)
2222
{
@@ -25,13 +25,13 @@ public UserState(ClaimsPrincipal user, bool? isAuthenticated = null)
2525
}
2626

2727
/// <summary>
28-
/// The currently signed in user.
28+
/// The current signed-in user.
2929
/// </summary>
3030
public ClaimsPrincipal User { get; }
3131

3232
/// <summary>
33-
/// Specifies if the currently signed in user is authenticated.
34-
/// If this property is null it means that this state has not yet been determined.
33+
/// Specifies if the currently signed-in user is authenticated.
34+
/// If this property is null, it means that this state has not yet been determined.
3535
/// </summary>
3636
public bool? IsAuthenticated { get; }
3737

@@ -55,7 +55,7 @@ public UserState SetIsAuthenticated(bool isAuthenticated)
5555
/// <param name="other">A user state to compare with this user state.</param>
5656
/// <returns>
5757
/// <c>true</c> if the current user state is equal to the
58-
/// <paramref name="other">other user state</paramref> user state parameter;
58+
/// <paramref name="other">other user state</paramref> parameter;
5959
/// otherwise, <c>false</c>.
6060
/// </returns>
6161
public bool Equals(UserState? other)

src/HotChocolate/Core/src/Abstractions/WellKnownContextData.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ public static class WellKnownContextData
143143
/// </summary>
144144
public const string CacheControlConstraints = "HotChocolate.Caching.CacheControlConstraints";
145145

146-
/// <summary>
147-
/// The key to access the user state on the global context.
148-
/// </summary>
149-
public const string UserState = "HotChocolate.Authorization.UserState";
150-
151146
/// <summary>
152147
/// Type key to access the paging arguments in the local resolver state.
153148
/// </summary>

src/HotChocolate/Core/src/Authorization/AllowAnonymousDirectiveType.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ public void ApplyConfiguration(
3030
ITypeSystemConfiguration definition,
3131
Stack<ITypeSystemConfiguration> path)
3232
{
33-
((IDirectiveConfigurationProvider)definition).Directives.Add(new(directiveNode));
33+
((IDirectiveConfigurationProvider)definition).Directives.Add(new DirectiveConfiguration(directiveNode));
3434

3535
if (definition is ObjectFieldConfiguration fieldDef)
3636
{
37-
fieldDef.AllowAnonymous();
37+
fieldDef.ModifyAuthorizationFieldOptions(o => o with { AllowAnonymous = true });
3838
}
3939
}
4040

src/HotChocolate/Core/src/Authorization/AuthorizationContext.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
using HotChocolate.Execution;
2+
using HotChocolate.Features;
23
using HotChocolate.Language;
34

45
namespace HotChocolate.Authorization;
56

67
/// <summary>
7-
/// Represents the state that is used to execute authorization policies.
8+
/// Represents the state used to execute authorization policies.
89
/// </summary>
9-
public sealed class AuthorizationContext
10+
public sealed class AuthorizationContext : IFeatureProvider
1011
{
1112
/// <summary>
1213
/// Initializes a new <see cref="AuthorizationContext"/>.
1314
/// </summary>
1415
/// <param name="schema">The GraphQL schema.</param>
1516
/// <param name="services">The application services.</param>
1617
/// <param name="contextData">The request context data.</param>
18+
/// <param name="features">The request feature collection.</param>
1719
/// <param name="document">The GraphQL request document.</param>
1820
/// <param name="documentId">A unique string identifying the GraphQL document</param>
1921
public AuthorizationContext(
2022
Schema schema,
2123
IServiceProvider services,
2224
IDictionary<string, object?> contextData,
25+
IFeatureCollection features,
2326
DocumentNode document,
2427
OperationDocumentId documentId)
2528
{
2629
Schema = schema;
2730
Services = services;
2831
ContextData = contextData;
32+
Features = features;
2933
Document = document;
3034
DocumentId = documentId;
3135
}
@@ -45,6 +49,11 @@ public AuthorizationContext(
4549
/// </summary>
4650
public IDictionary<string, object?> ContextData { get; }
4751

52+
/// <summary>
53+
/// Gets the feature collection.
54+
/// </summary>
55+
public IFeatureCollection Features { get; }
56+
4857
/// <summary>
4958
/// Gets the GraphQL request document.
5059
/// </summary>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace HotChocolate.Authorization;
2+
3+
internal sealed record AuthorizationFieldOptions
4+
{
5+
public bool AuthorizeAtRequestLevel { get; init; }
6+
7+
public bool AllowAnonymous { get; init; }
8+
}

src/HotChocolate/Core/src/Authorization/AuthorizationRequestInfo.cs renamed to src/HotChocolate/Core/src/Authorization/AuthorizationRequestContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace HotChocolate.Authorization;
44

5-
public class AuthorizationRequestData
5+
internal class AuthorizationRequestContext
66
{
77
public IAuthorizationHandler? Handler { get; set; }
88

0 commit comments

Comments
 (0)