new API project

This commit is contained in:
2021-11-29 18:25:50 +01:00
parent 192a0d795a
commit 346a674306
85 changed files with 940 additions and 410 deletions
@@ -1,26 +0,0 @@
using Microsoft.AspNetCore.Mvc.Filters;
namespace zero.Backoffice.Controllers;
public class BackofficeFilterAttribute : IActionFilter
{
const string SCOPE_KEY = "scope";
public void OnActionExecuting(ActionExecutingContext context)
{
Type type = context.Controller.GetType();
if (typeof(ZeroBackofficeController).IsAssignableFrom(type))
{
if (context.HttpContext.Request.Query.TryGetValue(SCOPE_KEY, out var scope))
{
//(context.Controller as ZeroBackofficeController).OnScopeChanged(scope.ToString());
}
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
@@ -1,38 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace zero.Backoffice.Controllers;
public class CanEditAttribute : TypeFilterAttribute
{
public CanEditAttribute() : base(typeof(CanEditAttributeImpl)) { }
private class CanEditAttributeImpl : IAsyncResultFilter
{
//IToken token;
public CanEditAttributeImpl()//IToken token)
{
//this.token = token;
}
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
if (context.Result is JsonResult)
{
JsonResult result = context.Result as JsonResult;
//if (result.Value is ObsoleteEditModel)
//{
// ObsoleteEditModel model = result.Value as ObsoleteEditModel;
// model.CanEdit = true; // TODO query authorize attrs to get permissions
//}
}
await next();
}
}
}
@@ -1,33 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Net.Http.Headers;
namespace zero.Backoffice.Controllers;
/// <summary>
/// Ensures that the request is not cached by the browser
/// </summary>
public class DisableBrowserCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
base.OnResultExecuting(context);
var httpResponse = context.HttpContext.Response;
if (httpResponse.StatusCode != 200) return;
httpResponse.GetTypedHeaders().CacheControl =
new CacheControlHeaderValue()
{
NoCache = true,
MaxAge = TimeSpan.Zero,
MustRevalidate = true,
NoStore = true
};
httpResponse.Headers[HeaderNames.LastModified] = DateTime.Now.ToString("R"); // Format RFC1123
httpResponse.Headers[HeaderNames.Pragma] = "no-cache";
httpResponse.Headers[HeaderNames.Expires] = new DateTime(1990, 1, 1, 0, 0, 0).ToString("R");
}
}
@@ -1,19 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace zero.Backoffice.Controllers;
public class ModelStateValidationFilterAttribute : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
@@ -1,56 +0,0 @@
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.Mvc.Filters;
//using System;
//using System.Threading.Tasks;
//using zero.Core.Api;
//using zero.Web.Models;
//namespace zero.Web.Controllers
//{
// public class VerifyTokenAttribute : TypeFilterAttribute
// {
// public VerifyTokenAttribute(string key = "model") : base(typeof(VerifyTokenAttributeImpl))
// {
// Arguments = new object[] { key };
// }
// private class VerifyTokenAttributeImpl : IAsyncActionFilter
// {
// IToken token;
// string key;
// public VerifyTokenAttributeImpl(IToken token, string key)
// {
// this.token = token;
// this.key = key;
// }
// public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
// {
// if (context.ActionArguments.ContainsKey(key))
// {
// object argument = context.ActionArguments[key];
// if (argument is ObsoleteEditModel)
// {
// ObsoleteEditModel model = (argument as ObsoleteEditModel);
// string tokenId = model.Meta?.Token;
// bool isVerified = await token.Verify(model.Id, tokenId);
// if (!isVerified)
// {
// context.Result = new StatusCodeResult(409);
// return;
// }
// }
// }
// await next();
// }
// }
// }
//}
@@ -1,60 +0,0 @@
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.Mvc.Filters;
//using System;
//using System.Threading.Tasks;
//using zero.Core.Api;
//using zero.Core.Entities;
//using zero.Web.Models;
//namespace zero.Web.Controllers
//{
// public class ZeroBackofficeAttribute : TypeFilterAttribute
// {
// public bool IsTyped { get; set; }
// public ZeroBackofficeAttribute(bool isTyped = true) : base(typeof(ZeroBackofficeAttributeImpl))
// {
// IsTyped = isTyped;
// }
// private class ZeroBackofficeAttributeImpl : IAsyncResultFilter
// {
// IToken token;
// public ZeroBackofficeAttributeImpl(IToken token)
// {
// this.token = token;
// }
// public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
// {
// JsonResult result = context.Result as JsonResult;
// if (result != null)
// {
// ZeroEntity model = result.Value as ZeroEntity;
// if (model != null)
// {
// Type type = result.Value.GetType();
// EditModel editModel = new EditModel()
// {
// Entity = result.Value,
// Token = await token.Get(model),
// IsAppAware = typeof(IAppAwareEntity).IsAssignableFrom(type),
// CanBeShared = typeof(IAppAwareShareableEntity).IsAssignableFrom(type),
// CanDelete = false, // TODO
// };
// }
// }
// await next();
// }
// }
// }
//}
@@ -1,12 +0,0 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
namespace zero.Backoffice.Controllers;
[ApiController]
//[ServiceFilter(typeof(ModelStateValidationFilterAttribute))]
//[ServiceFilter(typeof(BackofficeFilterAttribute))]
public abstract class ZeroBackofficeApiController : ZeroBackofficeController
{
protected IMapper Mapper { get; private set; }
}
@@ -1,10 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace zero.Backoffice.Controllers;
[ZeroAuthorize]
[DisableBrowserCache]
public abstract class ZeroBackofficeController : ControllerBase
{
}
@@ -1,81 +1,16 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using System.IO;
using zero.Api.Controllers;
namespace zero.Backoffice.Controllers;
public static class ZeroBackofficeControllerExtensions
{
/// <summary>
/// Transform entities to a preview list
/// </summary>
public static List<PickerPreviewModel> TransformToPreviewModels<T>(this ZeroBackofficeController controller, Dictionary<string, T> items, Action<T, PickerPreviewModel> transform = null) where T : ZeroIdEntity
{
List<PickerPreviewModel> previews = new();
foreach (var item in items)
{
if (item.Value == null)
{
previews.Add(new PickerPreviewModel()
{
HasError = true,
Icon = "fth-alert-circle color-red",
Id = item.Key,
Name = "@errors.preview.notfound",
Text = "@errors.preview.notfound_text"
});
continue;
}
PickerPreviewModel model = new() { Id = item.Value.Id };
if (item.Value is ZeroEntity)
{
model.Name = (item.Value as ZeroEntity).Name;
}
transform?.Invoke(item.Value, model);
previews.Add(model);
}
return previews;
}
/// <summary>
/// Transform entities to a select list
/// </summary>
public static List<PickerModel> TransformToSelectModels<T>(this ZeroBackofficeController controller, IEnumerable<T> enumerable, Action<T, PickerModel> transform = null) where T : ZeroIdEntity
{
List<PickerModel> items = new();
foreach (T item in enumerable)
{
PickerModel model = new()
{
Id = item.Id
};
if (item is ZeroEntity)
{
model.Name = (item as ZeroEntity).Name;
model.IsActive = (item as ZeroEntity).IsActive;
}
transform?.Invoke(item, model);
items.Add(model);
}
return items;
}
/// <summary>
/// Provides a file stream for download in the browser
/// </summary>
public static IActionResult DownloadFile(this ZeroBackofficeController controller, Stream stream, string filename)
public static IActionResult DownloadFile(this ZeroApiController controller, Stream stream, string filename)
{
if (stream == null)
{
@@ -102,7 +37,7 @@ public static class ZeroBackofficeControllerExtensions
/// <summary>
/// Provides a file stream to the browser
/// </summary>
public static IActionResult File(this ZeroBackofficeController controller, FileStorage.FileResult file)
public static IActionResult File(this ZeroApiController controller, FileStorage.FileResult file)
{
if (file == null)
{
@@ -1,34 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace zero.Backoffice.Controllers;
public class ZeroBackofficeControllerModelConvention : IApplicationModelConvention
{
readonly AttributeRouteModel RouteModel;
readonly Type BaseClass = typeof(ZeroBackofficeController);
public ZeroBackofficeControllerModelConvention(string backofficePath)
{
RouteModel = new AttributeRouteModel(new RouteAttribute(backofficePath.TrimEnd('/') + "/api/[controller]"));
}
/// <summary>
/// Configure routing model for all backoffice controllers
/// </summary>
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
bool hasAttributeRouteModels = controller.Selectors.Any(selector => selector.AttributeRouteModel != null);
if (controller.ControllerType.IsSubclassOf(BaseClass))
{
controller.Selectors[0].AttributeRouteModel = RouteModel;
}
}
}
}
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using zero.Api.Controllers;
namespace zero.Backoffice.Controllers;