Skip to content

Commit ca865df

Browse files
committed
Initial authorization behavior PoC and simplfication of parameter resolution and action invocation
1 parent 0dabfe9 commit ca865df

51 files changed

Lines changed: 1350 additions & 720 deletions

File tree

Some content is hidden

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

src/Dibix.Http.Server/Model/HttpActionDefinition.cs

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,22 @@
22

33
namespace Dibix.Http.Server
44
{
5-
public sealed class HttpActionDefinition : HttpParameterSourceSelector
5+
public sealed class HttpActionDefinition : IHttpActionExecutionDefinition
66
{
7-
private Uri _computedUri;
8-
9-
public HttpControllerDefinition Controller { get; }
10-
public IHttpActionTarget Target { get; }
7+
public HttpControllerDefinition Controller { get; internal set; }
8+
public Uri Uri { get; set; }
9+
public IHttpActionExecutionMethod Executor { get; set; }
10+
public IHttpParameterResolutionMethod ParameterResolver { get; set; }
1111
public HttpApiMethod Method { get; set; }
1212
public string ChildRoute { get; set; }
13-
public Type BodyContract { get; set; }
14-
public Type BodyBinder { get; set; }
1513
public HttpRequestBody Body { get; set; }
1614
public bool IsAnonymous { get; set; }
1715
public HttpFileResponseDefinition FileResponse { get; set; }
1816
public string Description { get; set; }
19-
public Uri ComputedUri => this._computedUri ?? (this._computedUri = this.BuildUri());
20-
21-
internal HttpActionDefinition(HttpControllerDefinition controller, IHttpActionTarget target)
22-
{
23-
this.Controller = controller;
24-
this.Target = target;
25-
}
26-
27-
public void ResolveParameterFromBody(string targetParameterName, string bodyConverterName)
28-
{
29-
base.ResolveParameter(targetParameterName, new HttpParameterBodySource(bodyConverterName));
30-
}
31-
public void ResolveParameterFromSource(string targetParameterName, string sourceName, string sourcePropertyName, Action<IHttpParameterSourceSelector> itemSources)
32-
{
33-
HttpParameterPropertySource source = base.ResolveParameterFromSourceCore(targetParameterName, sourceName, sourcePropertyName, null);
34-
if (itemSources == null)
35-
return;
36-
37-
HttpParameterSourceSelector sourceSelector = new HttpParameterSourceSelector();
38-
itemSources.Invoke(sourceSelector);
39-
source.ItemSources.AddRange(sourceSelector.ParameterSources);
40-
}
17+
public HttpAuthorizationDefinition Authorization { get; set; }
4118

42-
private Uri BuildUri()
19+
internal HttpActionDefinition()
4320
{
44-
return new Uri(RouteBuilder.BuildRoute(this.Controller.AreaName, this.Controller.ControllerName, this.ChildRoute), UriKind.Relative);
4521
}
4622
}
4723
}

src/Dibix.Http.Server/Model/HttpApiDescriptor.cs

Lines changed: 204 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
4+
using System.Linq;
45
using System.Reflection;
56

67
namespace Dibix.Http.Server
@@ -12,15 +13,15 @@ public abstract class HttpApiDescriptor
1213
#endregion
1314

1415
#region Properties
15-
public string AreaName => this._areaNameAccessor.Value;
16+
public string AreaName => _areaNameAccessor.Value;
1617
public ICollection<HttpControllerDefinition> Controllers { get; }
1718
#endregion
1819

1920
#region Constructor
2021
protected HttpApiDescriptor()
2122
{
22-
this.Controllers = new Collection<HttpControllerDefinition>();
23-
this._areaNameAccessor = new Lazy<string>(this.ResolveAreaName);
23+
Controllers = new Collection<HttpControllerDefinition>();
24+
_areaNameAccessor = new Lazy<string>(ResolveAreaName);
2425
}
2526
#endregion
2627

@@ -37,25 +38,218 @@ protected virtual string ResolveAreaName(Assembly assembly)
3738

3839
if (String.IsNullOrEmpty(attribute.AreaName))
3940
throw new InvalidOperationException($@"Area name cannot be empty
40-
{assembly.GetName().Name} -> {this.GetType()}");
41+
{assembly.GetName().Name} -> {GetType()}");
4142

4243
return attribute.AreaName;
4344
}
4445

45-
protected void RegisterController(string controllerName, Action<HttpControllerDefinition> setupAction)
46+
protected void RegisterController(string controllerName, Action<IHttpControllerDefinitionBuilder> setupAction)
4647
{
4748
Guard.IsNotNullOrEmpty(controllerName, nameof(controllerName));
48-
HttpControllerDefinition controller = new HttpControllerDefinition(this.AreaName, controllerName);
49-
setupAction(controller);
50-
this.Controllers.Add(controller);
49+
HttpControllerDefinitionBuilder builder = new HttpControllerDefinitionBuilder(AreaName, controllerName);
50+
setupAction(builder);
51+
HttpControllerDefinition controller = builder.Build();
52+
Controllers.Add(controller);
5153
}
5254
#endregion
5355

5456
#region Private Methods
5557
private string ResolveAreaName()
5658
{
57-
Assembly assembly = this.GetType().Assembly;
58-
return this.ResolveAreaName(assembly);
59+
Assembly assembly = GetType().Assembly;
60+
return ResolveAreaName(assembly);
61+
}
62+
#endregion
63+
64+
#region Nested Types
65+
private sealed class HttpControllerDefinitionBuilder : IHttpControllerDefinitionBuilder
66+
{
67+
private readonly string _areaName;
68+
private readonly string _controllerName;
69+
private readonly IList<HttpActionDefinitionBuilder> _actions;
70+
private readonly IList<string> _controllerImports;
71+
72+
internal HttpControllerDefinitionBuilder(string areaName, string controllerName)
73+
{
74+
_areaName = areaName;
75+
_controllerName = controllerName;
76+
_actions = new Collection<HttpActionDefinitionBuilder>();
77+
_controllerImports = new Collection<string>();
78+
}
79+
80+
public void AddAction(IHttpActionTarget target, Action<IHttpActionDefinitionBuilder> setupAction)
81+
{
82+
Guard.IsNotNull(setupAction, nameof(setupAction));
83+
HttpActionDefinitionBuilder builder = new HttpActionDefinitionBuilder(_areaName, _controllerName, target);
84+
setupAction(builder);
85+
_actions.Add(builder);
86+
}
87+
88+
public void Import(string fullControllerTypeName) => _controllerImports.Add(fullControllerTypeName);
89+
90+
public HttpControllerDefinition Build()
91+
{
92+
IList<HttpActionDefinition> actions = _actions.Select(x => x.Build()).ToArray();
93+
HttpControllerDefinition controller = new HttpControllerDefinition(_areaName, _controllerName, actions, _controllerImports);
94+
foreach (HttpActionDefinition action in actions)
95+
{
96+
action.Controller = controller;
97+
}
98+
return controller;
99+
}
100+
}
101+
102+
private sealed class HttpActionDefinitionBuilder : HttpActionBuilderBase, IHttpActionDefinitionBuilder, IHttpActionBuilderBase, IHttpParameterSourceSelector, IHttpActionDescriptor
103+
{
104+
private readonly string _areaName;
105+
private readonly string _controllerName;
106+
private HttpAuthorizationBuilder _authorization;
107+
private Uri _uri;
108+
109+
public MethodInfo Target { get; }
110+
public HttpApiMethod Method { get; set; }
111+
public Uri Uri => _uri ??= new Uri(RouteBuilder.BuildRoute(_areaName, _controllerName, ChildRoute), UriKind.Relative);
112+
public string ChildRoute { get; set; }
113+
public Type BodyContract { get; set; }
114+
public Type BodyBinder { get; set; }
115+
public bool IsAnonymous { get; set; }
116+
public HttpFileResponseDefinition FileResponse { get; set; }
117+
public string Description { get; set; }
118+
119+
public HttpActionDefinitionBuilder(string areaName, string controllerName, IHttpActionTarget target)
120+
{
121+
_areaName = areaName;
122+
_controllerName = controllerName;
123+
Target = target.Build();
124+
}
125+
126+
public void WithAuthorization(IHttpActionTarget target, Action<IHttpAuthorizationBuilder> setupAction)
127+
{
128+
HttpAuthorizationBuilder builder = new HttpAuthorizationBuilder(this, target);
129+
Guard.IsNotNull(setupAction, nameof(setupAction));
130+
setupAction(builder);
131+
_authorization = builder;
132+
}
133+
134+
bool IHttpActionDescriptor.TryGetParameter(string parameterName, out HttpParameterSource value) => ParameterSources.TryGetValue(parameterName, out value);
135+
136+
public HttpActionDefinition Build()
137+
{
138+
IHttpActionExecutionMethod executor = HttpActionExecutorResolver.Compile(this);
139+
IHttpParameterResolutionMethod parameterResolver = HttpParameterResolver.Compile(this);
140+
HttpActionDefinition action = new HttpActionDefinition
141+
{
142+
Uri = Uri,
143+
Executor = executor,
144+
ParameterResolver = parameterResolver,
145+
Method = Method,
146+
ChildRoute = ChildRoute,
147+
Body = BodyContract != null ? new HttpRequestBody(BodyContract, BodyBinder) : null,
148+
IsAnonymous = IsAnonymous,
149+
FileResponse = FileResponse,
150+
Description = Description,
151+
Authorization = _authorization?.Build()
152+
};
153+
return action;
154+
}
155+
}
156+
157+
private sealed class HttpAuthorizationBuilder : HttpActionBuilderBase, IHttpAuthorizationBuilder, IHttpActionDescriptor, IHttpActionBuilderBase, IHttpParameterSourceSelector
158+
{
159+
private readonly IHttpActionDescriptor _parent;
160+
161+
public MethodInfo Target { get; }
162+
public HttpApiMethod Method => _parent.Method;
163+
public Uri Uri => _parent.Uri;
164+
public string ChildRoute => _parent.ChildRoute;
165+
public Type BodyContract => _parent.BodyContract;
166+
public Type BodyBinder => _parent.BodyBinder;
167+
168+
public HttpAuthorizationBuilder(IHttpActionDescriptor parent, IHttpActionTarget target)
169+
{
170+
_parent = parent;
171+
Target = target.Build();
172+
}
173+
174+
public HttpAuthorizationDefinition Build()
175+
{
176+
IHttpActionExecutionMethod executor = HttpActionExecutorResolver.Compile(this);
177+
IHttpParameterResolutionMethod parameterResolver = HttpParameterResolver.Compile(this);
178+
HttpAuthorizationDefinition authorization = new HttpAuthorizationDefinition
179+
{
180+
Executor = executor,
181+
ParameterResolver = parameterResolver,
182+
};
183+
return authorization;
184+
}
185+
186+
bool IHttpActionDescriptor.TryGetParameter(string parameterName, out HttpParameterSource value) => ParameterSources.TryGetValue(parameterName, out value);
187+
}
188+
189+
private abstract class HttpActionBuilderBase : HttpParameterSourceSelector, IHttpActionBuilderBase, IHttpParameterSourceSelector
190+
{
191+
public void ResolveParameterFromBody(string targetParameterName, string bodyConverterName)
192+
{
193+
base.ResolveParameter(targetParameterName, new HttpParameterBodySource(bodyConverterName));
194+
}
195+
196+
public void ResolveParameterFromSource(string targetParameterName, string sourceName, string sourcePropertyName, Action<IHttpParameterSourceSelector> itemSources)
197+
{
198+
HttpParameterPropertySource source = base.ResolveParameterFromSourceCore(targetParameterName, sourceName, sourcePropertyName, null);
199+
if (itemSources == null)
200+
return;
201+
202+
HttpParameterSourceSelector sourceSelector = new HttpParameterSourceSelector();
203+
itemSources.Invoke(sourceSelector);
204+
source.ItemSources.AddRange(sourceSelector.ParameterSources);
205+
}
206+
}
207+
208+
private class HttpParameterSourceSelector : IHttpParameterSourceSelector
209+
{
210+
internal IDictionary<string, HttpParameterSource> ParameterSources { get; }
211+
212+
public HttpParameterSourceSelector()
213+
{
214+
ParameterSources = new Dictionary<string, HttpParameterSource>(StringComparer.OrdinalIgnoreCase);
215+
}
216+
217+
public void ResolveParameterFromConstant(string targetParameterName, bool value)
218+
{
219+
ResolveParameter(targetParameterName, new HttpParameterConstantSource(value));
220+
}
221+
public void ResolveParameterFromConstant(string targetParameterName, int value)
222+
{
223+
ResolveParameter(targetParameterName, new HttpParameterConstantSource(value));
224+
}
225+
public void ResolveParameterFromConstant(string targetParameterName, string value)
226+
{
227+
ResolveParameter(targetParameterName, new HttpParameterConstantSource(value));
228+
}
229+
public void ResolveParameterFromNull(string targetParameterName)
230+
{
231+
ResolveParameter(targetParameterName, new HttpParameterConstantSource(null));
232+
}
233+
public void ResolveParameterFromSource(string targetParameterName, string sourceName, string sourcePropertyPath)
234+
{
235+
ResolveParameterFromSourceCore(targetParameterName, sourceName, sourcePropertyPath, null);
236+
}
237+
public void ResolveParameterFromSource(string targetParameterName, string sourceName, string sourcePropertyPath, string converterName)
238+
{
239+
ResolveParameterFromSourceCore(targetParameterName, sourceName, sourcePropertyPath, converterName);
240+
}
241+
242+
protected HttpParameterPropertySource ResolveParameterFromSourceCore(string targetParameterName, string sourceName, string sourcePropertyPath, string converterName)
243+
{
244+
HttpParameterPropertySource source = new HttpParameterPropertySource(sourceName, sourcePropertyPath, converterName);
245+
ResolveParameter(targetParameterName, source);
246+
return source;
247+
}
248+
249+
protected void ResolveParameter(string targetParameterName, HttpParameterSource source)
250+
{
251+
ParameterSources.Add(targetParameterName, source);
252+
}
59253
}
60254
#endregion
61255
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Dibix.Http.Server
2+
{
3+
public sealed class HttpAuthorizationDefinition : IHttpActionExecutionDefinition
4+
{
5+
public IHttpActionExecutionMethod Executor { get; set; }
6+
public IHttpParameterResolutionMethod ParameterResolver { get; set; }
7+
}
8+
}
Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using System.Collections.ObjectModel;
43

54
namespace Dibix.Http.Server
@@ -8,24 +7,15 @@ public sealed class HttpControllerDefinition
87
{
98
public string AreaName { get; }
109
public string ControllerName { get; }
10+
public IReadOnlyCollection<HttpActionDefinition> Actions { get; }
11+
public IReadOnlyCollection<string> ControllerImports { get; }
1112

12-
public ICollection<HttpActionDefinition> Actions { get; }
13-
public ICollection<string> ControllerImports { get; }
14-
15-
internal HttpControllerDefinition(string areaName, string controllerName)
16-
{
17-
this.AreaName = areaName;
18-
this.ControllerName = controllerName;
19-
this.Actions = new Collection<HttpActionDefinition>();
20-
this.ControllerImports = new Collection<string>();
21-
}
22-
23-
public void AddAction(IHttpActionTarget target, Action<HttpActionDefinition> setupAction)
13+
internal HttpControllerDefinition(string areaName, string controllerName, IList<HttpActionDefinition> actions, IList<string> imports)
2414
{
25-
HttpActionDefinition action = new HttpActionDefinition(this, target);
26-
Guard.IsNotNull(setupAction, nameof(setupAction));
27-
setupAction(action);
28-
this.Actions.Add(action);
15+
AreaName = areaName;
16+
ControllerName = controllerName;
17+
Actions = new ReadOnlyCollection<HttpActionDefinition>(actions);
18+
ControllerImports = new ReadOnlyCollection<string>(imports);
2919
}
3020
}
3121
}

0 commit comments

Comments
 (0)