mirror of https://github.com/Squidex/squidex.git
11 changed files with 188 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||||
|
p41pr8YRXXiqrW5DrLpCxbsyTZwZ9ONcdFjYaHorvCuvPeMiBgl+WOFKkzLENEnJdh22tkh7FKjfSMW1S1jtZg== |
||||
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> |
||||
|
<metadata> |
||||
|
<id>Jurassic</id> |
||||
|
<version>4.0.0</version> |
||||
|
<authors>Paul Bartrum</authors> |
||||
|
<owners>Paul Bartrum</owners> |
||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
||||
|
<description>A .NET library to parse and execute JavaScript code.</description> |
||||
|
<dependencies> |
||||
|
<group targetFramework=".NETStandard2.0"> |
||||
|
<dependency id="System.Reflection.Emit.Lightweight" version="4.3.0" exclude="Build,Analyzers" /> |
||||
|
</group> |
||||
|
</dependencies> |
||||
|
</metadata> |
||||
|
</package> |
||||
@ -0,0 +1,20 @@ |
|||||
|
// ==========================================================================
|
||||
|
// IScriptEngine.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public interface IScriptEngine |
||||
|
{ |
||||
|
Task ExecuteAsync(ScriptContext context, string operationName, string script); |
||||
|
|
||||
|
Task<NamedContentData> ExecuteAndTransformAsync(ScriptContext context, string operationName, string script); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,103 @@ |
|||||
|
// ==========================================================================
|
||||
|
// JurassicScriptEngine.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Security; |
||||
|
using System.Threading.Tasks; |
||||
|
using Jurassic; |
||||
|
using Jurassic.Library; |
||||
|
using Newtonsoft.Json; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Tasks; |
||||
|
|
||||
|
// ReSharper disable ConvertToLambdaExpression
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class JurassicScriptEngine : IScriptEngine |
||||
|
{ |
||||
|
private readonly JsonSerializerSettings serializerSettings; |
||||
|
|
||||
|
public JurassicScriptEngine(JsonSerializerSettings serializerSettings) |
||||
|
{ |
||||
|
Guard.NotNull(serializerSettings, nameof(serializerSettings)); |
||||
|
|
||||
|
this.serializerSettings = serializerSettings; |
||||
|
} |
||||
|
|
||||
|
public Task ExecuteAsync(ScriptContext context, string operationName, string script) |
||||
|
{ |
||||
|
Guard.NotNull(context, nameof(context)); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(script)) |
||||
|
{ |
||||
|
return TaskHelper.False; |
||||
|
} |
||||
|
|
||||
|
var engine = CreateScriptEngine(context, operationName); |
||||
|
|
||||
|
engine.Execute(script); |
||||
|
|
||||
|
return TaskHelper.False; |
||||
|
} |
||||
|
|
||||
|
public Task<NamedContentData> ExecuteAndTransformAsync(ScriptContext context, string operationName, string script) |
||||
|
{ |
||||
|
Guard.NotNull(context, nameof(context)); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(script)) |
||||
|
{ |
||||
|
return Task.FromResult(context.Data); |
||||
|
} |
||||
|
|
||||
|
var result = context.Data; |
||||
|
|
||||
|
var engine = CreateScriptEngine(context, operationName); |
||||
|
|
||||
|
engine.SetGlobalFunction("replace", new Action<ObjectInstance>(data => |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
result = JsonConvert.DeserializeObject<NamedContentData>(JSONObject.Stringify(engine, data)); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
result = new NamedContentData(); |
||||
|
} |
||||
|
})); |
||||
|
|
||||
|
engine.Execute(script); |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
|
||||
|
private ScriptEngine CreateScriptEngine(ScriptContext context, string operationName) |
||||
|
{ |
||||
|
Guard.NotNullOrEmpty(operationName, nameof(operationName)); |
||||
|
|
||||
|
var engine = new ScriptEngine(); |
||||
|
|
||||
|
engine.SetGlobalFunction("disallow", new Action<string>(message => |
||||
|
{ |
||||
|
throw new SecurityException(message); |
||||
|
})); |
||||
|
|
||||
|
engine.SetGlobalFunction("reject", new Action<string>(message => |
||||
|
{ |
||||
|
throw new ValidationException($"Failed to '{operationName}", !string.IsNullOrWhiteSpace(message) ? new[] { new ValidationError(message) } : null); |
||||
|
})); |
||||
|
|
||||
|
var json = JsonConvert.SerializeObject(context, serializerSettings); |
||||
|
|
||||
|
engine.SetGlobalValue("ctx", JSONObject.Parse(engine, json)); |
||||
|
|
||||
|
return engine; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
// ==========================================================================
|
||||
|
// ScriptContext.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class ScriptContext |
||||
|
{ |
||||
|
public ScriptUser User { get; set; } |
||||
|
|
||||
|
public Guid ContentId { get; set; } |
||||
|
|
||||
|
public NamedContentData Data { get; set; } |
||||
|
|
||||
|
public NamedContentData OldData { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Security.Claims; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class ScriptUser |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public string Email { get; set; } |
||||
|
|
||||
|
public bool IsClient { get; set; } |
||||
|
|
||||
|
public Dictionary<string, string[]> Scopes { get; } = new Dictionary<string, string[]>(); |
||||
|
|
||||
|
public static ScriptUser Create(ClaimsPrincipal principal) |
||||
|
{ |
||||
|
return new ScriptUser(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue