Browse Source

Full compatibility.

pull/341/head
Sebastian 8 years ago
parent
commit
210d5ed8c4
  1. 55
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs
  2. 6
      src/Squidex.Domain.Apps.Core.Operations/Scripting/JintUser.cs
  3. 12
      src/Squidex.Domain.Apps.Entities/Rules/EventEnricher.cs
  4. 54
      src/Squidex.Shared/Users/ClientUser.cs
  5. 42
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs

55
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs

@ -22,7 +22,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
{
public class RuleEventFormatter
{
private const string Undefined = "null";
private const string Fallback = "null";
private const string ScriptSuffix = ")";
private const string ScriptPrefix = "Script(";
private static readonly char[] ContentPlaceholderStartOld = "CONTENT_DATA".ToCharArray();
@ -84,7 +84,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules
var customFunctions = new Dictionary<string, Func<string>>
{
["contentUrl"] = () => ContentUrl(@event)
["contentUrl"] = () => ContentUrl(@event),
["contentAction"] = () => ContentAction(@event)
};
return scriptEngine.Interpolate("event", @event, script, customFunctions);
@ -145,7 +146,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
}
else
{
sb.Append(Undefined);
sb.Append(Fallback);
}
current = current.Slice(match.Length + 1);
@ -187,7 +188,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return schemaEvent.SchemaId.Id.ToString();
}
return Undefined;
return Fallback;
}
private static string SchemaName(EnrichedEvent @event)
@ -197,7 +198,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return schemaEvent.SchemaId.Name;
}
return Undefined;
return Fallback;
}
private static string ContentAction(EnrichedEvent @event)
@ -207,7 +208,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return contentEvent.Type.ToString();
}
return Undefined;
return Fallback;
}
private string ContentUrl(EnrichedEvent @event)
@ -217,43 +218,17 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return urlGenerator.GenerateContentUIUrl(contentEvent.AppId, contentEvent.SchemaId, contentEvent.Id);
}
return Undefined;
return Fallback;
}
private static string UserName(EnrichedEvent @event)
{
if (@event.Actor != null)
{
if (@event.Actor.Type.Equals(RefTokenType.Client, StringComparison.OrdinalIgnoreCase))
{
return @event.Actor.ToString();
}
if (@event.User != null)
{
return @event.User.DisplayName();
}
}
return Undefined;
return @event.User?.DisplayName() ?? Fallback;
}
private static string UserEmail(EnrichedEvent @event)
{
if (@event.Actor != null)
{
if (@event.Actor.Type.Equals(RefTokenType.Client, StringComparison.OrdinalIgnoreCase))
{
return @event.Actor.ToString();
}
if (@event.User != null)
{
return @event.User.Email;
}
}
return Undefined;
return @event.User?.Email ?? Fallback;
}
private static string CalculateData(NamedContentData data, Match match)
@ -269,12 +244,12 @@ namespace Squidex.Domain.Apps.Core.HandleRules
if (!data.TryGetValue(path[0], out var field))
{
return Undefined;
return Fallback;
}
if (!field.TryGetValue(path[1], out var value))
{
return Undefined;
return Fallback;
}
for (var j = 2; j < path.Length; j++)
@ -290,16 +265,16 @@ namespace Squidex.Domain.Apps.Core.HandleRules
}
else
{
return Undefined;
return Fallback;
}
}
if (value == null || value.Type == JsonValueType.Null)
{
return Undefined;
return Fallback;
}
return value.ToString() ?? Undefined;
return value.ToString() ?? Fallback;
}
}
}

6
src/Squidex.Domain.Apps.Core.Operations/Scripting/JintUser.cs

@ -22,7 +22,11 @@ namespace Squidex.Domain.Apps.Core.Scripting
public static ObjectWrapper Create(Engine engine, IUser user)
{
return CreateUser(engine, user.Id, false, user.Email, user.DisplayName(), user.Claims);
var clientId = user.Claims.FirstOrDefault(x => x.Type == OpenIdClaims.ClientId)?.Value;
var isClient = !string.IsNullOrWhiteSpace(clientId);
return CreateUser(engine, user.Id, isClient, user.Email, user.DisplayName(), user.Claims);
}
public static ObjectWrapper Create(Engine engine, ClaimsPrincipal principal)

12
src/Squidex.Domain.Apps.Entities/Rules/EventEnricher.cs

@ -170,14 +170,22 @@ namespace Squidex.Domain.Apps.Entities.Rules
{
x.AbsoluteExpirationRelativeToNow = UserCacheDuration;
IUser user = null;
try
{
return await userResolver.FindByIdOrEmailAsync(actor.Identifier);
user = await userResolver.FindByIdOrEmailAsync(actor.Identifier);
}
catch
{
return null;
user = null;
}
if (user == null && actor.Type.Equals(RefTokenType.Client, StringComparison.OrdinalIgnoreCase))
{
user = new ClientUser(actor);
}
return user;
});
}
}

54
src/Squidex.Shared/Users/ClientUser.cs

@ -0,0 +1,54 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using System.Security.Claims;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Security;
using Squidex.Shared.Identity;
namespace Squidex.Shared.Users
{
public sealed class ClientUser : IUser
{
private readonly RefToken token;
private readonly List<Claim> claims;
public ClientUser(RefToken token)
{
Guard.NotNull(token, nameof(token));
this.token = token;
claims = new List<Claim>
{
new Claim(OpenIdClaims.ClientId, token.Identifier),
new Claim(SquidexClaimTypes.DisplayName, token.ToString())
};
}
public string Id
{
get { return token.Identifier; }
}
public string Email
{
get { return token.ToString(); }
}
public bool IsLocked
{
get { return false; }
}
public IReadOnlyList<Claim> Claims
{
get { return claims; }
}
}
}

42
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs

@ -137,7 +137,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Theory]
[InlineData("From $USER_NAME ($USER_EMAIL)")]
[InlineData("Script(`From ${event.user.name} (${event.user.email})`)", Skip = "Not Supported")]
[InlineData("Script(`From ${event.user.name} (${event.user.email})`)")]
public void Should_return_null_if_user_is_not_found_with_scripting(string script)
{
var @event = new EnrichedContentEvent { Actor = new RefToken(RefTokenType.Subject, "123") };
@ -147,6 +147,18 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
Assert.Equal("From null (null)", result);
}
[Theory]
[InlineData("From $USER_NAME ($USER_EMAIL)")]
[InlineData("Script(`From ${event.user.name} (${event.user.email})`)")]
public void Should_format_email_and_display_name_from_client(string script)
{
var @event = new EnrichedContentEvent { User = new ClientUser(new RefToken(RefTokenType.Client, "android")) };
var result = sut.Format(script, @event);
Assert.Equal("From client:android (client:android)", result);
}
[Theory]
[InlineData("Go to $CONTENT_URL")]
[InlineData("Script(`Go to ${contentUrl()}`)")]
@ -175,6 +187,14 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
Assert.Equal("Created", sut.Format(script, new EnrichedContentEvent { Type = EnrichedContentEventType.Created }));
}
[Theory]
[InlineData("$CONTENT_ACTION")]
[InlineData("Script(contentAction())")]
public void Should_null_when_content_action_not_found(string script)
{
Assert.Equal("null", sut.Format(script, new EnrichedAssetEvent()));
}
[Theory]
[InlineData("$CONTENT_DATA.country.iv")]
[InlineData("Script(`${event.data.country.iv}`)")]
@ -311,7 +331,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Theory]
[InlineData("$CONTENT_DATA.city.iv")]
[InlineData("Script(`${event.data.city.iv}`)", Skip = "Not Supported")]
[InlineData("Script(`${JSON.stringify(event.data.city.iv)}`)")]
public void Should_return_json_string_when_object(string script)
{
var @event = new EnrichedContentEvent
@ -327,23 +347,5 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
Assert.Equal("{\"name\":\"Berlin\"}", result);
}
[Theory]
[InlineData("$CONTENT_ACTION")]
public void Should_null_when_content_action_not_found(string script)
{
Assert.Equal("null", sut.Format(script, new EnrichedAssetEvent()));
}
[Theory]
[InlineData("From $USER_NAME ($USER_EMAIL)")]
public void Should_format_email_and_display_name_from_client(string script)
{
var @event = new EnrichedContentEvent { Actor = new RefToken(RefTokenType.Client, "android") };
var result = sut.Format(script, @event);
Assert.Equal("From client:android (client:android)", result);
}
}
}

Loading…
Cancel
Save