mirror of https://github.com/Squidex/squidex.git
2 changed files with 205 additions and 11 deletions
@ -0,0 +1,197 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using System.Security.Principal; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Microsoft.AspNetCore.Mvc.Authorization; |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Squidex.Domain.Apps.Core.Apps; |
|||
using Squidex.Domain.Apps.Entities; |
|||
using Squidex.Domain.Apps.Entities.Apps; |
|||
using Squidex.Infrastructure.Security; |
|||
using Squidex.Shared; |
|||
using Squidex.Shared.Identity; |
|||
using Xunit; |
|||
|
|||
#pragma warning disable IDE0017 // Simplify object initialization
|
|||
|
|||
namespace Squidex.Web.Pipeline |
|||
{ |
|||
public class AppResolverTests |
|||
{ |
|||
private readonly IAppProvider appProvider = A.Fake<IAppProvider>(); |
|||
private readonly HttpContext httpContext = new DefaultHttpContext(); |
|||
private readonly ActionContext actionContext; |
|||
private readonly ActionExecutingContext actionExecutingContext; |
|||
private readonly ActionExecutionDelegate next; |
|||
private readonly ClaimsIdentity user = new ClaimsIdentity(); |
|||
private readonly string appName = "my-app"; |
|||
private readonly AppResolver sut; |
|||
private bool isNextCalled; |
|||
|
|||
public AppResolverTests() |
|||
{ |
|||
actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor |
|||
{ |
|||
FilterDescriptors = new List<FilterDescriptor>() |
|||
}); |
|||
|
|||
actionExecutingContext = new ActionExecutingContext(actionContext, new List<IFilterMetadata>(), new Dictionary<string, object>(), this); |
|||
actionExecutingContext.HttpContext = httpContext; |
|||
actionExecutingContext.HttpContext.User = new ClaimsPrincipal(user); |
|||
actionExecutingContext.RouteData.Values["app"] = appName; |
|||
|
|||
next = () => |
|||
{ |
|||
isNextCalled = true; |
|||
|
|||
return Task.FromResult<ActionExecutedContext>(null); |
|||
}; |
|||
|
|||
sut = new AppResolver(appProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_return_not_found_if_app_not_found() |
|||
{ |
|||
A.CallTo(() => appProvider.GetAppAsync(appName)) |
|||
.Returns(Task.FromResult<IAppEntity>(null)); |
|||
|
|||
await sut.OnActionExecutionAsync(actionExecutingContext, next); |
|||
|
|||
Assert.IsType<NotFoundResult>(actionExecutingContext.Result); |
|||
Assert.False(isNextCalled); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_resolve_app_from_user() |
|||
{ |
|||
var app = CreateApp(appName, appUser: "user1"); |
|||
|
|||
user.AddClaim(new Claim(OpenIdClaims.Subject, "user1")); |
|||
user.AddClaim(new Claim(SquidexClaimTypes.Permissions, "squidex.apps.my-app")); |
|||
|
|||
A.CallTo(() => appProvider.GetAppAsync(appName)) |
|||
.Returns(app); |
|||
|
|||
await sut.OnActionExecutionAsync(actionExecutingContext, next); |
|||
|
|||
Assert.Same(app, httpContext.Features.Get<IAppFeature>()?.App); |
|||
Assert.True(user.Claims.Count() > 2); |
|||
Assert.True(isNextCalled); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_resolve_app_from_client() |
|||
{ |
|||
var app = CreateApp(appName, appClient: "client1"); |
|||
|
|||
user.AddClaim(new Claim(OpenIdClaims.ClientId, "client1")); |
|||
user.AddClaim(new Claim(SquidexClaimTypes.Permissions, "squidex.apps.my-app")); |
|||
|
|||
A.CallTo(() => appProvider.GetAppAsync(appName)) |
|||
.Returns(app); |
|||
|
|||
await sut.OnActionExecutionAsync(actionExecutingContext, next); |
|||
|
|||
Assert.Same(app, httpContext.Features.Get<IAppFeature>()?.App); |
|||
Assert.True(user.Claims.Count() > 2); |
|||
Assert.True(isNextCalled); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_resolve_app_if_anonymouse_but_not_permissions() |
|||
{ |
|||
var app = CreateApp(appName); |
|||
|
|||
user.AddClaim(new Claim(OpenIdClaims.ClientId, "client1")); |
|||
user.AddClaim(new Claim(SquidexClaimTypes.Permissions, "squidex.apps.other-app")); |
|||
|
|||
actionContext.ActionDescriptor.FilterDescriptors.Add(new FilterDescriptor(new AllowAnonymousFilter(), 1)); |
|||
|
|||
A.CallTo(() => appProvider.GetAppAsync(appName)) |
|||
.Returns(app); |
|||
|
|||
await sut.OnActionExecutionAsync(actionExecutingContext, next); |
|||
|
|||
Assert.Same(app, httpContext.Features.Get<IAppFeature>()?.App); |
|||
Assert.Equal(2, user.Claims.Count()); |
|||
Assert.True(isNextCalled); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_return_not_found_if_user_has_no_permissions() |
|||
{ |
|||
var app = CreateApp(appName); |
|||
|
|||
user.AddClaim(new Claim(OpenIdClaims.ClientId, "client1")); |
|||
user.AddClaim(new Claim(SquidexClaimTypes.Permissions, "squidex.apps.other-app")); |
|||
|
|||
A.CallTo(() => appProvider.GetAppAsync(appName)) |
|||
.Returns(app); |
|||
|
|||
await sut.OnActionExecutionAsync(actionExecutingContext, next); |
|||
|
|||
Assert.IsType<NotFoundResult>(actionExecutingContext.Result); |
|||
Assert.False(isNextCalled); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_do_nothing_if_parameter_not_set() |
|||
{ |
|||
actionExecutingContext.RouteData.Values.Remove("app"); |
|||
|
|||
await sut.OnActionExecutionAsync(actionExecutingContext, next); |
|||
|
|||
Assert.True(isNextCalled); |
|||
|
|||
A.CallTo(() => appProvider.GetAppAsync(A<string>.Ignored)) |
|||
.MustNotHaveHappened(); |
|||
} |
|||
|
|||
private static IAppEntity CreateApp(string name, string appUser = null, string appClient = null) |
|||
{ |
|||
var app = A.Fake<IAppEntity>(); |
|||
|
|||
if (appUser != null) |
|||
{ |
|||
A.CallTo(() => app.Contributors) |
|||
.Returns(AppContributors.Empty.Assign(appUser, Role.Owner)); |
|||
} |
|||
else |
|||
{ |
|||
A.CallTo(() => app.Contributors) |
|||
.Returns(AppContributors.Empty); |
|||
} |
|||
|
|||
if (appClient != null) |
|||
{ |
|||
A.CallTo(() => app.Clients) |
|||
.Returns(AppClients.Empty.Add(appClient, "secret")); |
|||
} |
|||
else |
|||
{ |
|||
A.CallTo(() => app.Clients) |
|||
.Returns(AppClients.Empty); |
|||
} |
|||
|
|||
A.CallTo(() => app.Roles) |
|||
.Returns(Roles.CreateDefaults(name)); |
|||
|
|||
return app; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue