-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from redbridge-uk/webapicore
WebApi Core Port
- Loading branch information
Showing
12 changed files
with
341 additions
and
3 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
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
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,15 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Redbridge.ApiManagement; | ||
|
||
namespace Redbridge.WebApiCore.Controllers | ||
{ | ||
public abstract class ApiFactoryController : ControllerBase | ||
{ | ||
protected ApiFactoryController(IApiFactory apiFactory) | ||
{ | ||
ApiFactory = apiFactory ?? throw new ArgumentNullException(nameof(apiFactory)); | ||
} | ||
|
||
protected IApiFactory ApiFactory { get; } | ||
} | ||
} |
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,63 @@ | ||
using System.IO.Compression; | ||
using System.Net; | ||
using System.Net.Http.Headers; | ||
using Redbridge.Data; | ||
using Redbridge.IO; | ||
|
||
namespace Redbridge.WebApiCore | ||
{ | ||
public static class FileDownloadDataExtensions | ||
{ | ||
public static HttpResponseMessage AsFileResult(this FileDownloadData downloadData) | ||
{ | ||
var result = new HttpResponseMessage(HttpStatusCode.OK) | ||
{ | ||
Content = new StreamContent(downloadData.FileStream) | ||
}; | ||
|
||
result.Content.Headers.ContentType = new MediaTypeHeaderValue(downloadData.ContentType); | ||
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") | ||
{ | ||
FileName = downloadData.FileName | ||
}; | ||
|
||
return result; | ||
} | ||
|
||
public static HttpResponseMessage AsZippedFileResult(this FileDownloadsData downloadData) | ||
{ | ||
using (var archiveStream = new MemoryStream()) | ||
{ | ||
using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true)) | ||
{ | ||
foreach (var download in downloadData.Files) | ||
{ | ||
var zipArchiveEntry = archive.CreateEntry(download.FileName, CompressionLevel.Fastest); | ||
using var zipStream = zipArchiveEntry.Open(); | ||
zipStream.Write(download.FileStream.ToByteArray(), 0, (int)download.FileStream.Length); | ||
} | ||
} | ||
|
||
var archiveFile = archiveStream.ToArray(); | ||
return ZipContentResult(archiveFile, downloadData.FileName); | ||
} | ||
} | ||
|
||
private static HttpResponseMessage ZipContentResult( byte[] archiveFile, string filename) | ||
{ | ||
var pushStreamContent = new PushStreamContent((stream, content, context) => | ||
{ | ||
stream.Write(archiveFile); | ||
stream.Close(); // After save we close the stream to signal that we are done writing. | ||
}, "application/zip"); | ||
|
||
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent }; | ||
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); | ||
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") | ||
{ | ||
FileName = filename | ||
}; | ||
return response; | ||
} | ||
} | ||
} |
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,20 @@ | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Redbridge.WebApiCore.Filters | ||
{ | ||
public class LoggingExceptionFilter : ExceptionFilterAttribute | ||
{ | ||
private readonly ILogger _logger; | ||
|
||
public LoggingExceptionFilter(ILogger<LoggingExceptionFilter> logger) | ||
{ | ||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
public override void OnException(ExceptionContext actionExecutedContext) | ||
{ | ||
_logger.LogError(actionExecutedContext.Exception, actionExecutedContext.Exception.Message); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
Redbridge.WebApiCore/Filters/UnknownEntityExceptionFilter.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,27 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.Extensions.Logging; | ||
using Redbridge.Data; | ||
|
||
namespace Redbridge.WebApiCore.Filters | ||
{ | ||
public class UnknownEntityExceptionFilter : ExceptionFilterAttribute | ||
{ | ||
private readonly ILogger _logger; | ||
|
||
public UnknownEntityExceptionFilter(ILogger<UnknownEntityExceptionFilter> logger) | ||
{ | ||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
public override void OnException(ExceptionContext actionExecutedContext) | ||
{ | ||
if (actionExecutedContext.Exception is UnknownEntityException unknownEntityException) | ||
{ | ||
_logger.LogInformation($"Unknown entity exception processing with message {unknownEntityException.Message}"); | ||
var errorMessageError = new { error = unknownEntityException.Message}; | ||
actionExecutedContext.Result = new JsonResult(errorMessageError) { StatusCode = 422 }; | ||
} | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
Redbridge.WebApiCore/Filters/UserNotAuthenticatedExceptionFilter.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,27 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.Extensions.Logging; | ||
using Redbridge.Exceptions; | ||
|
||
namespace Redbridge.WebApiCore.Filters | ||
{ | ||
public class UserNotAuthenticatedExceptionFilter : ExceptionFilterAttribute | ||
{ | ||
readonly ILogger _logger; | ||
|
||
public UserNotAuthenticatedExceptionFilter(ILogger<UserNotAuthenticatedExceptionFilter> logger) | ||
{ | ||
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
public override void OnException(ExceptionContext actionExecutedContext) | ||
{ | ||
if (actionExecutedContext.Exception is UserNotAuthenticatedException exception) | ||
{ | ||
_logger.LogDebug("Processing user not authenticated exception filtering."); | ||
actionExecutedContext.Result = new UnauthorizedResult(); | ||
actionExecutedContext.ExceptionHandled = true; | ||
} | ||
} | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
Redbridge.WebApiCore/Filters/UserNotAuthorizedExceptionFilter.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,29 @@ | ||
using System.Net; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.Extensions.Logging; | ||
using Redbridge.Exceptions; | ||
|
||
namespace Redbridge.WebApiCore.Filters | ||
{ | ||
public class UserNotAuthorizedExceptionFilter : ExceptionFilterAttribute | ||
{ | ||
readonly ILogger _logger; | ||
|
||
public UserNotAuthorizedExceptionFilter(ILogger<UserNotAuthorizedExceptionFilter> logger) | ||
{ | ||
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
public override void OnException(ExceptionContext actionExecutedContext) | ||
{ | ||
_logger.LogInformation("Checking exception for user not authorized exception filtering...."); | ||
|
||
if (actionExecutedContext.Exception is UserNotAuthorizedException exception) | ||
{ | ||
actionExecutedContext.ExceptionHandled = true; | ||
actionExecutedContext.Result = new JsonResult(null) { StatusCode = 403 }; | ||
} | ||
} | ||
} | ||
} |
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,57 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Serialization; | ||
using Redbridge.Exceptions; | ||
using Redbridge.Validation; | ||
|
||
namespace Redbridge.WebApiCore.Filters | ||
{ | ||
public class ValidationExceptionFilter : ExceptionFilterAttribute | ||
{ | ||
readonly ILogger _logger; | ||
|
||
public ValidationExceptionFilter(ILogger<ValidationExceptionFilter> logger) | ||
{ | ||
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); | ||
} | ||
|
||
public override void OnException(ExceptionContext actionExecutedContext) | ||
{ | ||
// Convert ValidationResultsException results or a ValidationException into ValidationResults | ||
_logger.LogInformation("Checking exception for validation exception filtering...."); | ||
|
||
if (actionExecutedContext.Exception is ValidationResultsException || | ||
actionExecutedContext.Exception is ValidationException) | ||
{ | ||
ValidationResult[] results = Array.Empty<ValidationResult>(); | ||
|
||
if (actionExecutedContext.Exception is ValidationResultsException validationResultsException) | ||
{ | ||
_logger.LogInformation( | ||
"Validation exception filtering being applied to a multi-results exception..."); | ||
results = validationResultsException.Results?.Results != null | ||
? validationResultsException.Results.Results.ToArray() | ||
: new[] { new ValidationResult(false, validationResultsException.Message) }; | ||
} | ||
else if (actionExecutedContext.Exception is ValidationException validationException) | ||
{ | ||
_logger.LogInformation( | ||
"Validation exception filtering being applied to a single result validation exception..."); | ||
results = new[] { new ValidationResult(false, validationException.Message) }; | ||
} | ||
|
||
_logger.LogInformation("Serializing results into JSON for transmission..."); | ||
var rawJson = JsonConvert.SerializeObject(results, new JsonSerializerSettings() | ||
{ | ||
ContractResolver = new CamelCasePropertyNamesContractResolver() | ||
}); | ||
|
||
actionExecutedContext.Result = new JsonResult(rawJson) { StatusCode = 422 }; | ||
actionExecutedContext.ExceptionHandled = true; | ||
} | ||
} | ||
|
||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
Redbridge.WebApiCore/QueryStringAuthenticationExtension.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,45 @@ | ||
using Microsoft.AspNetCore.Builder; | ||
using Redbridge.Web; | ||
using Redbridge.Web.Messaging; | ||
|
||
namespace Redbridge.WebApiCore | ||
{ | ||
public static class QueryStringAuthenticationExtension | ||
{ | ||
public static void UseQueryStringAuthentication(this IApplicationBuilder app) | ||
{ | ||
app.Use(async (context, next) => | ||
{ | ||
if (context.Request.QueryString.HasValue) | ||
{ | ||
if (context.Request.Headers.TryGetValue(HeaderNames.Authorization, out var authorizationHeader)) | ||
{ | ||
if (string.IsNullOrWhiteSpace(authorizationHeader)) | ||
{ | ||
var queryString = HttpUtility.ParseQueryString(context.Request.QueryString.Value); | ||
if (queryString.ContainsKey(QueryStringParts.Authentication)) | ||
{ | ||
var token = queryString[QueryStringParts.Authentication]; | ||
|
||
if (!string.IsNullOrWhiteSpace(token)) | ||
{ | ||
context.Request.Headers.Add(HeaderNames.Authorization, | ||
new[] { BearerTokenFormatter.CreateToken(token) }); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
try | ||
{ | ||
await next.Invoke(); | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
// Do not propagate this exception. | ||
} | ||
}); | ||
} | ||
} | ||
} |
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,18 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<IsPackable>true</IsPackable> | ||
<PackageIconUrl>https://github.com/redbridge-uk/resources/blob/master/redbridge_32.png</PackageIconUrl> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="6.0.10" /> | ||
<PackageReference Include="Redbridge.ApiManagement" Version="2.2.1" /> | ||
<PackageReference Include="Redbridge.SDK" Version="2.2.1" /> | ||
</ItemGroup> | ||
|
||
</Project> |
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