-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Register SQL/Redis Health Checks (#1422)
* Removed view and unused "using" statements * Map healthchecks to /health * Add Redis to Health Check * Add DbContextChecks to Health Checks This will ensure that the healthcheck endpoint correctly reports the status of the service if a database connection faults * Moved package into Api project * Remove unnecessary call to AddHealthChecks() * This bit isn't necessary as we are already registering it on the Sql and Redis servers * Register /health endpoint on App and API
- Loading branch information
1 parent
ff2acc6
commit 1e73390
Showing
11 changed files
with
368 additions
and
417 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,53 @@ | ||
using ConcernsCaseWork.API.Extensions; | ||
using ConcernsCaseWork.API.Middleware; | ||
using ConcernsCaseWork.API.StartupConfiguration; | ||
using ConcernsCaseWork.Middleware; | ||
using Microsoft.AspNetCore.Mvc.ApiExplorer; | ||
|
||
namespace ConcernsCaseWork.API | ||
{ | ||
/// <summary> | ||
/// THIS STARTUP ISN'T USED WHEN API IS HOSTED THROUGH WEBSITE. It is used when running API tests | ||
/// </summary> | ||
public class Startup | ||
{ | ||
public Startup(IConfiguration configuration) | ||
{ | ||
Configuration = configuration; | ||
} | ||
|
||
public IConfiguration Configuration { get; } | ||
|
||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
services.AddConcernsApiProject(Configuration); | ||
} | ||
|
||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider) | ||
{ | ||
app.UseConcernsCaseworkSwagger(provider); | ||
|
||
if (env.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
} | ||
|
||
app.UseMiddleware<ExceptionHandlerMiddleware>(); | ||
app.UseMiddleware<ApiKeyMiddleware>(); | ||
app.UseMiddleware<UrlDecoderMiddleware>(); | ||
app.UseMiddleware<CorrelationIdMiddleware>(); | ||
app.UseMiddleware<UserContextReceiverMiddleware>(); | ||
|
||
app.UseHttpsRedirection(); | ||
|
||
app.UseRouting(); | ||
|
||
app.UseAuthorization(); | ||
|
||
app.UseConcernsCaseworkEndpoints(); | ||
} | ||
} | ||
} | ||
using ConcernsCaseWork.API.Extensions; | ||
using ConcernsCaseWork.API.Middleware; | ||
using ConcernsCaseWork.API.StartupConfiguration; | ||
using ConcernsCaseWork.Middleware; | ||
using Microsoft.AspNetCore.Mvc.ApiExplorer; | ||
|
||
namespace ConcernsCaseWork.API | ||
{ | ||
/// <summary> | ||
/// THIS STARTUP ISN'T USED WHEN API IS HOSTED THROUGH WEBSITE. It is used when running API tests | ||
/// </summary> | ||
public class Startup | ||
{ | ||
public Startup(IConfiguration configuration) | ||
{ | ||
Configuration = configuration; | ||
} | ||
|
||
public IConfiguration Configuration { get; } | ||
|
||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
services.AddConcernsApiProject(Configuration); | ||
} | ||
|
||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider) | ||
{ | ||
app.UseConcernsCaseworkSwagger(provider); | ||
|
||
if (env.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
} | ||
|
||
app.UseMiddleware<ExceptionHandlerMiddleware>(); | ||
app.UseMiddleware<ApiKeyMiddleware>(); | ||
app.UseMiddleware<UrlDecoderMiddleware>(); | ||
app.UseMiddleware<CorrelationIdMiddleware>(); | ||
app.UseMiddleware<UserContextReceiverMiddleware>(); | ||
|
||
app.UseHttpsRedirection(); | ||
|
||
app.UseRouting(); | ||
|
||
app.UseAuthorization(); | ||
|
||
app.UseConcernsCaseworkEndpoints(); | ||
|
||
// Add Health Checks | ||
app.UseHealthChecks("/health"); | ||
} | ||
} | ||
} |
34 changes: 18 additions & 16 deletions
34
...ernsCaseWork/ConcernsCaseWork.API/StartupConfiguration/DatabaseConfigurationExtensions.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 |
---|---|---|
@@ -1,16 +1,18 @@ | ||
using ConcernsCaseWork.Data; | ||
|
||
namespace ConcernsCaseWork.API.StartupConfiguration; | ||
|
||
public static class DatabaseConfigurationExtensions | ||
{ | ||
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration) | ||
{ | ||
var connectionString = configuration.GetConnectionString("DefaultConnection"); | ||
services.AddDbContext<ConcernsDbContext>(options => | ||
options.UseConcernsSqlServer(connectionString) | ||
); | ||
|
||
return services; | ||
} | ||
} | ||
using ConcernsCaseWork.Data; | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
namespace ConcernsCaseWork.API.StartupConfiguration; | ||
|
||
public static class DatabaseConfigurationExtensions | ||
{ | ||
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration) | ||
{ | ||
var connectionString = configuration.GetConnectionString("DefaultConnection"); | ||
services.AddDbContext<ConcernsDbContext>(options => | ||
options.UseConcernsSqlServer(connectionString) | ||
); | ||
services.AddHealthChecks() | ||
.AddDbContextCheck<ConcernsDbContext>("Concerns Database"); | ||
|
||
return services; | ||
} | ||
} |
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
132 changes: 55 additions & 77 deletions
132
ConcernsCaseWork/ConcernsCaseWork.Tests/Security/AuthorizeAttributeTests.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 |
---|---|---|
@@ -1,77 +1,55 @@ | ||
using ConcernsCaseWork.Pages; | ||
using ConcernsCaseWork.Pages.Base; | ||
using FluentAssertions; | ||
using FluentAssertions.Execution; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using NUnit.Framework; | ||
using System; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
namespace ConcernsCaseWork.Tests.Security | ||
{ | ||
public class AuthorizeAttributeTests | ||
{ | ||
public AuthorizeAttributeTests() | ||
{ | ||
this.UnauthorizedPages = new Type[] | ||
{ | ||
typeof(HealthModel), | ||
typeof(ErrorPageModel), | ||
}; | ||
} | ||
|
||
public Type[] UnauthorizedPages { get; } | ||
|
||
[Test] | ||
public void All_Pages_Include_Authorize_Attribute() | ||
{ | ||
var pages = this.GetAllPagesExceptUnauthorizedPages(); | ||
|
||
pages.Length.Should().BeGreaterThan(0); | ||
|
||
using (var scope = new AssertionScope()) | ||
{ | ||
foreach (Type page in pages) | ||
{ | ||
var authAttributes = page.GetCustomAttributes<AuthorizeAttribute>(); | ||
if (authAttributes == null || !authAttributes.Any()) | ||
{ | ||
scope.AddPreFormattedFailure($"Could not find [Authorize] attribute and no exemption for the following page type: {page.Name} ({page.FullName})"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
[Test] | ||
public void Open_Pages_Do_Not_Require_Authorization() | ||
{ | ||
Type[] UnauthorizedPages = new[] | ||
{ | ||
typeof(HealthModel), | ||
}; | ||
|
||
using (var scope = new AssertionScope()) | ||
{ | ||
foreach (Type page in this.UnauthorizedPages) | ||
{ | ||
var authAttribute = page.GetCustomAttribute<AuthorizeAttribute>(); | ||
if (authAttribute != null) | ||
{ | ||
scope.AddPreFormattedFailure($"Expected page to be open and not require authorisation. But found [Authorize] attribute on the following page type: {page.Name} ({page.FullName})"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private Type[] GetAllPagesExceptUnauthorizedPages() | ||
{ | ||
return Assembly | ||
.GetAssembly(typeof(AbstractPageModel)) | ||
.GetTypes() | ||
.Where(x => x.IsAssignableTo(typeof(PageModel)) && !this.UnauthorizedPages.Contains(x)) | ||
.ToArray(); | ||
} | ||
} | ||
} | ||
using ConcernsCaseWork.Pages; | ||
using ConcernsCaseWork.Pages.Base; | ||
using FluentAssertions; | ||
using FluentAssertions.Execution; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using NUnit.Framework; | ||
using System; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
namespace ConcernsCaseWork.Tests.Security | ||
{ | ||
public class AuthorizeAttributeTests | ||
{ | ||
public AuthorizeAttributeTests() | ||
{ | ||
this.UnauthorizedPages = new Type[] | ||
{ | ||
typeof(ErrorPageModel), | ||
}; | ||
} | ||
|
||
public Type[] UnauthorizedPages { get; } | ||
|
||
[Test] | ||
public void All_Pages_Include_Authorize_Attribute() | ||
{ | ||
var pages = this.GetAllPagesExceptUnauthorizedPages(); | ||
|
||
pages.Length.Should().BeGreaterThan(0); | ||
|
||
using (var scope = new AssertionScope()) | ||
{ | ||
foreach (Type page in pages) | ||
{ | ||
var authAttributes = page.GetCustomAttributes<AuthorizeAttribute>(); | ||
if (authAttributes == null || !authAttributes.Any()) | ||
{ | ||
scope.AddPreFormattedFailure($"Could not find [Authorize] attribute and no exemption for the following page type: {page.Name} ({page.FullName})"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private Type[] GetAllPagesExceptUnauthorizedPages() | ||
{ | ||
return Assembly | ||
.GetAssembly(typeof(AbstractPageModel)) | ||
.GetTypes() | ||
.Where(x => x.IsAssignableTo(typeof(PageModel)) && !this.UnauthorizedPages.Contains(x)) | ||
.ToArray(); | ||
} | ||
} | ||
} |
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 was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,24 +1,23 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
|
||
namespace ConcernsCaseWork | ||
{ | ||
public class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
|
||
CreateHostBuilder(args).Build().Run(); | ||
} | ||
|
||
private static IHostBuilder CreateHostBuilder(string[] args) => | ||
Host.CreateDefaultBuilder(args) | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder | ||
.ConfigureKestrel(options => options.AddServerHeader = false) | ||
.UseStartup<Startup>(); | ||
}); | ||
} | ||
} | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
|
||
namespace ConcernsCaseWork | ||
{ | ||
public class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
CreateHostBuilder(args).Build().Run(); | ||
} | ||
|
||
private static IHostBuilder CreateHostBuilder(string[] args) => | ||
Host.CreateDefaultBuilder(args) | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder | ||
.ConfigureKestrel(options => options.AddServerHeader = false) | ||
.UseStartup<Startup>(); | ||
}); | ||
} | ||
} |
Oops, something went wrong.