Browse Source

Readonly middleware.

pull/285/head
Sebastian 8 years ago
parent
commit
02946f790e
  1. 35
      src/Squidex.Infrastructure/Commands/ReadonlyCommandMiddleware.cs
  2. 14
      src/Squidex.Infrastructure/Commands/ReadonlyOptions.cs
  3. 3
      src/Squidex/AppServices.cs
  4. 3
      src/Squidex/Config/Domain/EntitiesServices.cs
  5. 7
      src/Squidex/appsettings.json
  6. 62
      tests/Squidex.Infrastructure.Tests/Commands/ReadonlyCommandMiddlewareTests.cs
  7. 16
      tests/Squidex.Tests/Pipeline/EnforceHttpsMiddlewareTests.cs

35
src/Squidex.Infrastructure/Commands/ReadonlyCommandMiddleware.cs

@ -0,0 +1,35 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace Squidex.Infrastructure.Commands
{
public sealed class ReadonlyCommandMiddleware : ICommandMiddleware
{
private readonly IOptions<ReadonlyOptions> options;
public ReadonlyCommandMiddleware(IOptions<ReadonlyOptions> options)
{
Guard.NotNull(options, nameof(options));
this.options = options;
}
public Task HandleAsync(CommandContext context, Func<Task> next)
{
if (options.Value.IsReadonly)
{
throw new DomainException("Application is in readonly mode at the moment.");
}
return next();
}
}
}

14
src/Squidex.Infrastructure/Commands/ReadonlyOptions.cs

@ -0,0 +1,14 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Commands
{
public sealed class ReadonlyOptions
{
public bool IsReadonly { get; set; }
}
}

3
src/Squidex/AppServices.cs

@ -13,6 +13,7 @@ using Squidex.Config;
using Squidex.Config.Authentication;
using Squidex.Config.Domain;
using Squidex.Config.Web;
using Squidex.Infrastructure.Commands;
namespace Squidex
{
@ -40,6 +41,8 @@ namespace Squidex
services.AddMySwaggerSettings();
services.AddMySubscriptionServices(config);
services.Configure<ReadonlyOptions>(
config.GetSection("mode"));
services.Configure<MyUrlsOptions>(
config.GetSection("urls"));
services.Configure<MyIdentityOptions>(

3
src/Squidex/Config/Domain/EntitiesServices.cs

@ -83,6 +83,9 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<InMemoryCommandBus>()
.As<ICommandBus>();
services.AddSingletonAs<ReadonlyCommandMiddleware>()
.As<ICommandMiddleware>();
services.AddSingletonAs<ETagCommandMiddleware>()
.As<ICommandMiddleware>();

7
src/Squidex/appsettings.json

@ -1,4 +1,11 @@
{
"mode": {
/*
* Use this flag to set Squidex to readonly, e.g. when you deploy a second instance for migration.
*/
"isReadonly": false
},
"urls": {
/*
* Set the base url of your application, to generate correct urls in background process.

62
tests/Squidex.Infrastructure.Tests/Commands/ReadonlyCommandMiddlewareTests.cs

@ -0,0 +1,62 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Options;
using Squidex.Infrastructure.Tasks;
using Xunit;
namespace Squidex.Infrastructure.Commands
{
public class ReadonlyCommandMiddlewareTests
{
private readonly ICommand command = A.Dummy<ICommand>();
private readonly ICommandBus commandBus = A.Dummy<ICommandBus>();
private readonly ReadonlyOptions options = new ReadonlyOptions();
private readonly ReadonlyCommandMiddleware sut;
public ReadonlyCommandMiddlewareTests()
{
sut = new ReadonlyCommandMiddleware(Options.Create(options));
}
[Fact]
public async Task Should_throw_exception_if_readonly()
{
var context = new CommandContext(command, commandBus);
options.IsReadonly = true;
await Assert.ThrowsAsync<DomainException>(() => MakeCallAsync(context));
Assert.False(context.IsCompleted);
}
[Fact]
public async Task Should_not_throw_exception_if_not_readonly()
{
var context = new CommandContext(command, commandBus);
options.IsReadonly = false;
await MakeCallAsync(context);
Assert.True(context.IsCompleted);
}
private async Task MakeCallAsync(CommandContext context)
{
await sut.HandleAsync(context, () =>
{
context.Complete(true);
return TaskHelper.Done;
});
}
}
}

16
tests/Squidex.Tests/Pipeline/EnforceHttpsMiddlewareTests.cs

@ -17,6 +17,8 @@ namespace Squidex.Pipeline
public class EnforceHttpsMiddlewareTests
{
private readonly RequestDelegate next;
private readonly MyUrlsOptions options = new MyUrlsOptions();
private readonly EnforceHttpsMiddleware sut;
private bool isNextCalled;
public EnforceHttpsMiddlewareTests()
@ -27,6 +29,8 @@ namespace Squidex.Pipeline
return TaskHelper.Done;
};
sut = new EnforceHttpsMiddleware(Options.Create(options));
}
[Fact]
@ -34,9 +38,9 @@ namespace Squidex.Pipeline
{
var httpContext = CreateHttpContext();
var sut = new EnforceHttpsMiddleware(next, Options.Create(new MyUrlsOptions { EnforceHTTPS = true }));
options.EnforceHTTPS = true;
await sut.Invoke(httpContext);
await sut.InvokeAsync(httpContext, next);
Assert.False(isNextCalled);
Assert.Equal("https://squidex.local/path?query=1", httpContext.Response.Headers["Location"]);
@ -47,9 +51,9 @@ namespace Squidex.Pipeline
{
var httpContext = CreateHttpContext("https");
var sut = new EnforceHttpsMiddleware(next, Options.Create(new MyUrlsOptions { EnforceHTTPS = true }));
options.EnforceHTTPS = true;
await sut.Invoke(httpContext);
await sut.InvokeAsync(httpContext, next);
Assert.True(isNextCalled);
Assert.Null((string)httpContext.Response.Headers["Location"]);
@ -60,9 +64,9 @@ namespace Squidex.Pipeline
{
var httpContext = CreateHttpContext("http");
var sut = new EnforceHttpsMiddleware(next, Options.Create(new MyUrlsOptions { EnforceHTTPS = false }));
options.EnforceHTTPS = false;
await sut.Invoke(httpContext);
await sut.InvokeAsync(httpContext, next);
Assert.True(isNextCalled);
Assert.Null((string)httpContext.Response.Headers["Location"]);

Loading…
Cancel
Save