update namespaces
refactor the name of the organisation
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OpenHarbor.CQRS.Abstractions;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
[Produces("application/json")]
|
||||
[ApiController, Route("api/command/[controller]")]
|
||||
public class CommandController<TCommand> : Controller
|
||||
where TCommand : class
|
||||
{
|
||||
[HttpPost, CommandControllerAuthorization]
|
||||
public async Task<IActionResult> Handle([FromServices] ICommandHandler<TCommand> handler,
|
||||
[FromBody] TCommand command)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
await handler.HandleAsync(command, this.Request.HttpContext.RequestAborted);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
||||
[Produces("application/json")]
|
||||
[ApiController, Route("api/command/[controller]")]
|
||||
public class CommandController<TCommand, TTCommandResult> : Controller
|
||||
where TCommand : class
|
||||
{
|
||||
[HttpPost, CommandControllerAuthorization]
|
||||
public async Task<ActionResult<TTCommandResult>> Handle([FromServices] ICommandHandler<TCommand, TTCommandResult> handler,
|
||||
[FromBody] TCommand command)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(await handler.HandleAsync(command, this.Request.HttpContext.RequestAborted));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Reflection;
|
||||
using OpenHarbor.CQRS.Abstractions.Security;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class CommandControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
|
||||
{
|
||||
private readonly ICommandAuthorizationService _authorizationService;
|
||||
|
||||
public CommandControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
|
||||
{
|
||||
_authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
|
||||
}
|
||||
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
if (_authorizationService == null)
|
||||
return;
|
||||
|
||||
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
|
||||
if (action == null)
|
||||
throw new Exception("Only Supports controller action descriptor");
|
||||
|
||||
var attribute = action.MethodInfo.GetCustomAttribute<CommandControllerAuthorizationAttribute>();
|
||||
Type commandType;
|
||||
if (attribute?.CommandType != null)
|
||||
commandType = attribute.CommandType;
|
||||
else
|
||||
commandType = action.ControllerTypeInfo.GenericTypeArguments.First();
|
||||
|
||||
var ar = await _authorizationService.IsAllowedAsync(commandType);
|
||||
if (ar == AuthorizationResult.Forbidden)
|
||||
context.Result = new StatusCodeResult(403);
|
||||
else if(ar == AuthorizationResult.Unauthorized)
|
||||
context.Result = new StatusCodeResult(401);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class CommandControllerAuthorizationAttribute : TypeFilterAttribute
|
||||
{
|
||||
public CommandControllerAuthorizationAttribute() : base(typeof(CommandControllerAsyncAuthorizationFilter))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public CommandControllerAuthorizationAttribute(Type commandType) : base(typeof(CommandControllerAsyncAuthorizationFilter))
|
||||
{
|
||||
CommandType = commandType;
|
||||
}
|
||||
|
||||
public Type CommandType { get; } = null;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenHarbor.CQRS.Abstractions.Discovery;
|
||||
using System;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class CommandControllerConvention : IControllerModelConvention
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public CommandControllerConvention(IServiceProvider serviceProvider)
|
||||
{
|
||||
this._serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public void Apply(ControllerModel controller)
|
||||
{
|
||||
if (!controller.ControllerType.IsGenericType)
|
||||
return;
|
||||
|
||||
if (!controller.ControllerType.Name.Contains("CommandController"))
|
||||
return;
|
||||
|
||||
if (controller.ControllerType.Assembly != typeof(CommandControllerConvention).Assembly)
|
||||
return;
|
||||
|
||||
var genericType = controller.ControllerType.GenericTypeArguments[0];
|
||||
var commandDiscovery = this._serviceProvider.GetRequiredService<ICommandDiscovery>();
|
||||
var command = commandDiscovery.FindCommand(genericType);
|
||||
controller.ControllerName = command.LowerCamelCaseName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenHarbor.CQRS.Abstractions.Discovery;
|
||||
using OpenHarbor.CQRS.AspNetCore.Abstractions.Attributes;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class CommandControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
|
||||
{
|
||||
private readonly ServiceProvider _serviceProvider;
|
||||
|
||||
public CommandControllerFeatureProvider(ServiceProvider serviceProvider)
|
||||
{
|
||||
this._serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
|
||||
{
|
||||
var commandDiscovery = this._serviceProvider.GetRequiredService<ICommandDiscovery>();
|
||||
foreach (var f in commandDiscovery.GetCommands())
|
||||
{
|
||||
var ignoreAttribute = f.CommandType.GetCustomAttribute<CommandControllerIgnoreAttribute>();
|
||||
if (ignoreAttribute != null)
|
||||
continue;
|
||||
|
||||
if (f.CommandResultType == null)
|
||||
{
|
||||
var controllerType = typeof(CommandController<>).MakeGenericType(f.CommandType);
|
||||
var controllerTypeInfo = controllerType.GetTypeInfo();
|
||||
feature.Controllers.Add(controllerTypeInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
var controllerType = typeof(CommandController<,>).MakeGenericType(f.CommandType, f.CommandResultType);
|
||||
var controllerTypeInfo = controllerType.GetTypeInfo();
|
||||
feature.Controllers.Add(controllerTypeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class CommandControllerOptions
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public static class MvcBuilderExtensions
|
||||
{
|
||||
public static IMvcBuilder AddPoweredSoftQueries(this IMvcBuilder builder, Action<QueryControllerOptions> configuration = null)
|
||||
{
|
||||
var options = new QueryControllerOptions();
|
||||
configuration?.Invoke(options);
|
||||
var services = builder.Services;
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
builder.AddMvcOptions(o => o.Conventions.Add(new QueryControllerConvention(serviceProvider)));
|
||||
builder.ConfigureApplicationPartManager(m => m.FeatureProviders.Add(new QueryControllerFeatureProvider(serviceProvider)));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IMvcBuilder AddPoweredSoftCommands(this IMvcBuilder builder)
|
||||
{
|
||||
var services = builder.Services;
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
builder.AddMvcOptions(o => o.Conventions.Add(new CommandControllerConvention(serviceProvider)));
|
||||
builder.ConfigureApplicationPartManager(m => m.FeatureProviders.Add(new CommandControllerFeatureProvider(serviceProvider)));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OpenHarbor.CQRS.Abstractions;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
[Produces("application/json")]
|
||||
[ApiController, Route("api/query/[controller]")]
|
||||
public class QueryController<TQuery, TQueryResult> : Controller
|
||||
where TQuery : class
|
||||
{
|
||||
[HttpPost, QueryControllerAuthorization]
|
||||
public async Task<ActionResult<TQueryResult>> Handle([FromServices] IQueryHandler<TQuery, TQueryResult> handler,
|
||||
[FromBody] TQuery query)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
|
||||
return Ok(await handler.HandleAsync(query, this.Request.HttpContext.RequestAborted));
|
||||
}
|
||||
|
||||
[HttpGet, QueryControllerAuthorization]
|
||||
public async Task<ActionResult<TQueryResult>> HandleGet([FromServices] IQueryHandler<TQuery, TQueryResult> handler,
|
||||
[FromQuery] TQuery query)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
|
||||
return Ok(await handler.HandleAsync(query, this.Request.HttpContext.RequestAborted));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Reflection;
|
||||
using OpenHarbor.CQRS.Abstractions.Security;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class QueryControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
|
||||
{
|
||||
private readonly IQueryAuthorizationService _authorizationService;
|
||||
|
||||
public QueryControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
|
||||
{
|
||||
_authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
|
||||
}
|
||||
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
if (_authorizationService == null)
|
||||
return;
|
||||
|
||||
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
|
||||
if (action == null)
|
||||
throw new Exception("Only Supports controller action descriptor");
|
||||
|
||||
var attribute = action.MethodInfo.GetCustomAttribute<QueryControllerAuthorizationAttribute>();
|
||||
Type queryType;
|
||||
if (attribute?.QueryType != null)
|
||||
queryType = attribute.QueryType;
|
||||
else
|
||||
queryType = action.ControllerTypeInfo.GenericTypeArguments.First();
|
||||
|
||||
var ar = await _authorizationService.IsAllowedAsync(queryType);
|
||||
if (ar == AuthorizationResult.Forbidden)
|
||||
context.Result = new StatusCodeResult(403);
|
||||
else if (ar == AuthorizationResult.Unauthorized)
|
||||
context.Result = new StatusCodeResult(401);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class QueryControllerAuthorizationAttribute : TypeFilterAttribute
|
||||
{
|
||||
public QueryControllerAuthorizationAttribute() : base(typeof(QueryControllerAsyncAuthorizationFilter))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public QueryControllerAuthorizationAttribute(Type queryType) : base(typeof(QueryControllerAsyncAuthorizationFilter))
|
||||
{
|
||||
QueryType = queryType;
|
||||
}
|
||||
|
||||
public Type QueryType { get; }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenHarbor.CQRS.Abstractions.Discovery;
|
||||
using System;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class QueryControllerConvention : IControllerModelConvention
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public QueryControllerConvention(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public void Apply(ControllerModel controller)
|
||||
{
|
||||
if (controller.ControllerType.IsGenericType && controller.ControllerType.Name.Contains("QueryController") && controller.ControllerType.Assembly == typeof(QueryControllerConvention).Assembly)
|
||||
{
|
||||
var genericType = controller.ControllerType.GenericTypeArguments[0];
|
||||
var queryDiscovery = _serviceProvider.GetRequiredService<IQueryDiscovery>();
|
||||
var query = queryDiscovery.FindQuery(genericType);
|
||||
controller.ControllerName = query.LowerCamelCaseName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenHarbor.CQRS.Abstractions.Discovery;
|
||||
using OpenHarbor.CQRS.AspNetCore.Abstractions.Attributes;
|
||||
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class QueryControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
|
||||
{
|
||||
private readonly ServiceProvider _serviceProvider;
|
||||
|
||||
public QueryControllerFeatureProvider(ServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
|
||||
{
|
||||
var queryDiscovery = this._serviceProvider.GetRequiredService<IQueryDiscovery>();
|
||||
foreach (var f in queryDiscovery.GetQueries())
|
||||
{
|
||||
var ignoreAttribute = f.QueryType.GetCustomAttribute<QueryControllerIgnoreAttribute>();
|
||||
if (ignoreAttribute != null)
|
||||
continue;
|
||||
|
||||
if (f.Category != "BasicQuery")
|
||||
continue;
|
||||
|
||||
var controllerType = typeof(QueryController<,>).MakeGenericType(f.QueryType, f.QueryResultType);
|
||||
var controllerTypeInfo = controllerType.GetTypeInfo();
|
||||
feature.Controllers.Add(controllerTypeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
|
||||
|
||||
public class QueryControllerOptions
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<PackageIconUrl>https://avatars.githubusercontent.com/u/52874619?v=4</PackageIconUrl>
|
||||
<Authors>David Lebee, Mathias Beaulieu-Duncan</Authors>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenHarbor.CQRS.Abstractions\OpenHarbor.CQRS.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\OpenHarbor.CQRS.AspNetCore.Abstractions\OpenHarbor.CQRS.AspNetCore.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user