Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrated authorization directives back into the ASP.NET Core packages. (
- Loading branch information
1 parent
93f21fa
commit a069057
Showing
42 changed files
with
2,383 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/HotChocolate/AspNetCore/src/AspNetCore.Authorization/ApplyPolicy.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace HotChocolate.AspNetCore.Authorization | ||
{ | ||
public enum ApplyPolicy | ||
{ | ||
BeforeResolver = 0, | ||
AfterResolver = 1 | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/HotChocolate/AspNetCore/src/AspNetCore.Authorization/ApplyPolicyType.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using HotChocolate.Types; | ||
|
||
namespace HotChocolate.AspNetCore.Authorization | ||
{ | ||
public sealed class ApplyPolicyType | ||
: EnumType<ApplyPolicy> | ||
{ | ||
protected override void Configure( | ||
IEnumTypeDescriptor<ApplyPolicy> descriptor) | ||
{ | ||
descriptor | ||
.Name("ApplyPolicy") | ||
.BindValuesExplicitly(); | ||
|
||
descriptor | ||
.Value(ApplyPolicy.BeforeResolver) | ||
.Name("BEFORE_RESOLVER"); | ||
|
||
descriptor | ||
.Value(ApplyPolicy.AfterResolver) | ||
.Name("AFTER_RESOLVER"); | ||
} | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
src/HotChocolate/AspNetCore/src/AspNetCore.Authorization/AuthorizeAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using System; | ||
using System.Reflection; | ||
using HotChocolate.Types; | ||
using HotChocolate.Types.Descriptors; | ||
|
||
namespace HotChocolate.AspNetCore.Authorization | ||
{ | ||
[AttributeUsage( | ||
AttributeTargets.Class | ||
| AttributeTargets.Struct | ||
| AttributeTargets.Property | ||
| AttributeTargets.Method, | ||
Inherited = true, | ||
AllowMultiple = true)] | ||
public class AuthorizeAttribute : DescriptorAttribute | ||
{ | ||
public string? Policy { get; set; } | ||
|
||
public string[]? Roles { get; set; } | ||
|
||
public ApplyPolicy Apply { get; set; } = ApplyPolicy.BeforeResolver; | ||
|
||
protected override void TryConfigure( | ||
IDescriptorContext context, | ||
IDescriptor descriptor, | ||
ICustomAttributeProvider element) | ||
{ | ||
if (descriptor is IObjectTypeDescriptor type) | ||
{ | ||
type.Directive(CreateDirective()); | ||
} | ||
else if (descriptor is IObjectFieldDescriptor field) | ||
{ | ||
field.Directive(CreateDirective()); | ||
} | ||
} | ||
|
||
private AuthorizeDirective CreateDirective() | ||
{ | ||
if (Policy is { }) | ||
{ | ||
return new AuthorizeDirective( | ||
Policy, | ||
apply: Apply); | ||
} | ||
else if (Roles is { }) | ||
{ | ||
return new AuthorizeDirective( | ||
Roles, | ||
apply: Apply); | ||
} | ||
else | ||
{ | ||
return new AuthorizeDirective( | ||
apply: Apply); | ||
} | ||
} | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
src/HotChocolate/AspNetCore/src/AspNetCore.Authorization/AuthorizeDirective.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Runtime.Serialization; | ||
using HotChocolate.Language; | ||
|
||
namespace HotChocolate.AspNetCore.Authorization | ||
{ | ||
public sealed class AuthorizeDirective | ||
: ISerializable | ||
{ | ||
public AuthorizeDirective( | ||
IReadOnlyList<string> roles, | ||
ApplyPolicy apply = ApplyPolicy.BeforeResolver) | ||
: this(null, roles, apply) | ||
{ } | ||
|
||
public AuthorizeDirective( | ||
string? policy = null, | ||
IReadOnlyList<string>? roles = null, | ||
ApplyPolicy apply = ApplyPolicy.BeforeResolver) | ||
{ | ||
Policy = policy; | ||
Roles = roles; | ||
Apply = apply; | ||
} | ||
|
||
public AuthorizeDirective(SerializationInfo info, StreamingContext context) | ||
{ | ||
var node = info.GetValue( | ||
nameof(DirectiveNode), | ||
typeof(DirectiveNode)) | ||
as DirectiveNode; | ||
|
||
if (node == null) | ||
{ | ||
Policy = info.GetString(nameof(Policy)); | ||
Roles = info.GetValue(nameof(Roles), typeof(List<string>)) as List<string>; | ||
Apply = (ApplyPolicy)info.GetInt16(nameof(Apply)); | ||
} | ||
else | ||
{ | ||
ArgumentNode policyArgument = node.Arguments | ||
.FirstOrDefault(t => t.Name.Value == "policy"); | ||
ArgumentNode rolesArgument = node.Arguments | ||
.FirstOrDefault(t => t.Name.Value == "roles"); | ||
ArgumentNode resolverArgument = node.Arguments | ||
.FirstOrDefault(t => t.Name.Value == "apply"); | ||
|
||
Policy = (policyArgument is { } | ||
&& policyArgument.Value is StringValueNode sv) | ||
? sv.Value | ||
: null; | ||
|
||
if (rolesArgument is { }) | ||
{ | ||
if (rolesArgument.Value is ListValueNode lv) | ||
{ | ||
Roles = lv.Items.OfType<StringValueNode>() | ||
.Select(t => t.Value?.Trim()) | ||
.Where(s => !string.IsNullOrEmpty(s)) | ||
.ToArray()!; | ||
} | ||
else if (rolesArgument.Value is StringValueNode svn) | ||
{ | ||
Roles = new[] { svn.Value }; | ||
} | ||
} | ||
|
||
Apply = ApplyPolicy.BeforeResolver; | ||
if (resolverArgument is { } | ||
&& resolverArgument.Value.Value is string s | ||
&& s == "AFTER_RESOLVER") | ||
{ | ||
Apply = ApplyPolicy.AfterResolver; | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets the policy name that determines access to the resource. | ||
/// </summary> | ||
public string? Policy { get; } | ||
|
||
/// <summary> | ||
/// Gets of roles that are allowed to access the resource. | ||
/// </summary> | ||
public IReadOnlyList<string>? Roles { get; } | ||
|
||
/// <summary> | ||
/// Gets a value indicating if the resolver has to be executed | ||
/// before the policy is run or after the policy is run. | ||
/// | ||
/// The before policy option is good if the actual object is needed | ||
/// for the policy to be evaluated. | ||
/// | ||
/// The default is BeforeResolver. | ||
/// </summary> | ||
public ApplyPolicy Apply { get; } | ||
|
||
public void GetObjectData(SerializationInfo info, StreamingContext context) | ||
{ | ||
info.AddValue(nameof(Policy), Policy); | ||
info.AddValue(nameof(Roles), Roles?.ToList()); | ||
info.AddValue(nameof(Apply), (int)Apply); | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/HotChocolate/AspNetCore/src/AspNetCore.Authorization/AuthorizeDirectiveType.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using HotChocolate.Types; | ||
|
||
namespace HotChocolate.AspNetCore.Authorization | ||
{ | ||
public sealed class AuthorizeDirectiveType | ||
: DirectiveType<AuthorizeDirective> | ||
{ | ||
protected override void Configure( | ||
IDirectiveTypeDescriptor<AuthorizeDirective> descriptor) | ||
{ | ||
descriptor | ||
.Name("authorize") | ||
.Location(DirectiveLocation.Schema) | ||
.Location(DirectiveLocation.Object) | ||
.Location(DirectiveLocation.FieldDefinition) | ||
.Repeatable(); | ||
|
||
descriptor.Argument(t => t.Policy) | ||
.Description( | ||
"The name of the authorization policy that determines " + | ||
"access to the annotated resource.") | ||
.Type<StringType>(); | ||
|
||
descriptor.Argument(t => t.Roles) | ||
.Description( | ||
"Roles that are allowed to access the " + | ||
"annotated resource.") | ||
.Type<ListType<NonNullType<StringType>>>(); | ||
|
||
descriptor.Argument(t => t.Apply) | ||
.Description( | ||
"Defines when when the resolver shall be executed." + | ||
"By default the resolver is executed after the policy " + | ||
"has determined that the current user is allowed to access " + | ||
"the field.") | ||
.Type<NonNullType<ApplyPolicyType>>() | ||
.DefaultValue(ApplyPolicy.BeforeResolver); | ||
|
||
descriptor.Use<AuthorizeMiddleware>(); | ||
} | ||
} | ||
} |
Oops, something went wrong.