Browse Source

Feature/hash functions (#691)

* Hash function for scripts.

* Liquid hash functions.
release/5.7
Sebastian Stehle 5 years ago
committed by GitHub
parent
commit
d89849cc17
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs
  2. 28
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/StringJintExtension.cs
  3. 15
      backend/src/Squidex.Domain.Apps.Core.Operations/Templates/Extensions/StringFluidExtension.cs
  4. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs
  5. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/DomainObject/AssetCommandMiddleware.cs
  6. 45
      backend/src/Squidex.Infrastructure/RandomHash.cs
  7. 2
      backend/src/Squidex.Web/Constants.cs
  8. 2
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs
  9. 2
      backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs
  10. 34
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs
  11. 30
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Templates/FluidTemplateEngineTests.cs

2
backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs

@ -45,7 +45,7 @@ namespace Squidex.Extensions.Actions.Webhook
requestBody = ToEnvelopeJson(@event);
}
requestSignature = $"{requestBody}{action.SharedSecret}".Sha256Base64();
requestSignature = $"{requestBody}{action.SharedSecret}".ToSha256Base64();
}
var ruleDescription = $"Send event to webhook '{requestUrl}'";

28
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/StringJintExtension.cs

@ -8,6 +8,7 @@
using System;
using Jint;
using Jint.Native;
using Squidex.Infrastructure;
using Squidex.Text;
namespace Squidex.Domain.Apps.Core.Scripting.Extensions
@ -16,6 +17,30 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{
private delegate JsValue StringSlugifyDelegate(string text, bool single = false);
private readonly Func<string, JsValue> sha256 = (text) =>
{
try
{
return text.ToSha256();
}
catch
{
return JsValue.Undefined;
}
};
private readonly Func<string, JsValue> md5 = (text) =>
{
try
{
return text.ToMD5();
}
catch
{
return JsValue.Undefined;
}
};
private readonly StringSlugifyDelegate slugify = (text, single) =>
{
try
@ -82,6 +107,9 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{
engine.SetValue("slugify", slugify);
engine.SetValue("sha256", sha256);
engine.SetValue("md5", md5);
engine.SetValue("toCamelCase", toCamelCase);
engine.SetValue("toPascalCase", toPascalCase);

15
backend/src/Squidex.Domain.Apps.Core.Operations/Templates/Extensions/StringFluidExtension.cs

@ -8,6 +8,7 @@
using Fluid;
using Fluid.Values;
using Newtonsoft.Json;
using Squidex.Infrastructure;
using Squidex.Text;
namespace Squidex.Domain.Apps.Core.Templates.Extensions
@ -51,11 +52,23 @@ namespace Squidex.Domain.Apps.Core.Templates.Extensions
return FluidValue.Create(input.ToStringValue().Trim());
};
private static readonly FilterDelegate MD5 = (input, arguments, context) =>
{
return FluidValue.Create(input.ToStringValue().ToMD5());
};
private static readonly FilterDelegate Sha256 = (input, arguments, context) =>
{
return FluidValue.Create(input.ToStringValue().ToSha256());
};
public void RegisterGlobalTypes(IMemberAccessStrategy memberAccessStrategy)
{
TemplateContext.GlobalFilters.AddFilter("escape", Escape);
TemplateContext.GlobalFilters.AddFilter("html2text", Html2Text);
TemplateContext.GlobalFilters.AddFilter("markdown2text", Markdown2Text);
TemplateContext.GlobalFilters.AddFilter("escape", Escape);
TemplateContext.GlobalFilters.AddFilter("md5", MD5);
TemplateContext.GlobalFilters.AddFilter("sha256", Sha256);
TemplateContext.GlobalFilters.AddFilter("slugify", Slugify);
TemplateContext.GlobalFilters.AddFilter("trim", Trim);
}

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs

@ -139,7 +139,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas
sb.Append(';');
}
return sb.ToString().Sha256Base64();
return sb.ToString().ToSha256Base64();
}
finally
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/DomainObject/AssetCommandMiddleware.cs

@ -181,7 +181,7 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
{
var steamHash = hashStream.GetHashStringAndReset();
return $"{steamHash}{file.FileName}{file.FileSize}".Sha256Base64();
return $"{steamHash}{file.FileName}{file.FileSize}".ToSha256Base64();
}
private async Task EnrichWithMetadataAsync(UploadAssetCommand command)

45
backend/src/Squidex.Infrastructure/RandomHash.cs

@ -16,7 +16,7 @@ namespace Squidex.Infrastructure
public static string New()
{
return Guid.NewGuid()
.ToString().Sha256Base64()
.ToString().ToSha256Base64()
.ToLowerInvariant()
.Replace("+", "x")
.Replace("=", "x")
@ -28,12 +28,12 @@ namespace Squidex.Infrastructure
return Guid.NewGuid().ToString().Replace("-", string.Empty);
}
public static string Sha256Base64(this string value)
public static string ToSha256Base64(this string value)
{
return Sha256Base64(Encoding.UTF8.GetBytes(value));
return ToSha256Base64(Encoding.UTF8.GetBytes(value));
}
public static string Sha256Base64(this byte[] bytes)
public static string ToSha256Base64(this byte[] bytes)
{
using (var sha = SHA256.Create())
{
@ -44,5 +44,42 @@ namespace Squidex.Infrastructure
return result;
}
}
public static string ToSha256(this string value)
{
return value.ToHashed(SHA256.Create());
}
public static string ToSha256(this byte[] bytes)
{
return bytes.ToHashed(SHA256.Create());
}
public static string ToMD5(this string value)
{
return value.ToHashed(MD5.Create());
}
public static string ToMD5(this byte[] bytes)
{
return bytes.ToHashed(MD5.Create());
}
public static string ToHashed(this string value, HashAlgorithm algorithm)
{
return Encoding.UTF8.GetBytes(value).ToHashed(algorithm);
}
public static string ToHashed(this byte[] bytes, HashAlgorithm algorithm)
{
using (algorithm)
{
var bytesHash = algorithm.ComputeHash(bytes);
var result = Encoding.UTF8.GetString(bytesHash);
return result;
}
}
}
}

2
backend/src/Squidex.Web/Constants.cs

@ -38,7 +38,7 @@ namespace Squidex.Web
public static readonly string InternalClientId = "squidex-internal";
public static readonly string InternalClientSecret = "squidex-internal".Sha256Base64();
public static readonly string InternalClientSecret = "squidex-internal".ToSha256Base64();
public static readonly string IdentityServerPrefix = "/identity-server";
}

2
backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs

@ -78,7 +78,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
return permissionsProvider.GetPermissionsAsync(App);
});
Response.Headers[HeaderNames.ETag] = string.Concat(response).Sha256Base64();
Response.Headers[HeaderNames.ETag] = string.Concat(response).ToSha256Base64();
return Ok(response);
}

2
backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs

@ -70,7 +70,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ApiCosts(0)]
public IActionResult GetActions()
{
var etag = string.Concat(ruleRegistry.Actions.Select(x => x.Key)).Sha256Base64();
var etag = string.Concat(ruleRegistry.Actions.Select(x => x.Key)).ToSha256Base64();
var response = Deferred.Response(() =>
{

34
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs

@ -184,6 +184,40 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
Assert.Equal("4-hauser", result);
}
[Fact]
public void Should_compute_sha256_hash()
{
const string script = @"
return sha256(value);
";
var vars = new ScriptVars
{
["value"] = "HelloWorld"
};
var result = sut.Execute(vars, script).ToString();
Assert.Equal("HelloWorld".ToSha256(), result);
}
[Fact]
public void Should_compute_md5_hash()
{
const string script = @"
return md5(value);
";
var vars = new ScriptVars
{
["value"] = "HelloWorld"
};
var result = sut.Execute(vars, script).ToString();
Assert.Equal("HelloWorld".ToMD5(), result);
}
[Fact]
public async Task Should_throw_validation_exception_if_calling_reject()
{

30
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Templates/FluidTemplateEngineTests.cs

@ -190,6 +190,36 @@ namespace Squidex.Domain.Apps.Core.Operations.Templates
Assert.Equal("10", result);
}
[Fact]
public async Task Should_compute_md5_hash()
{
var template = "{{ e.text | md5 }}";
var value = new
{
text = "HelloWorld"
};
var result = await RenderAync(template, value);
Assert.Equal("HelloWorld".ToMD5(), result);
}
[Fact]
public async Task Should_compute_sha256_hash()
{
var template = "{{ e.text | sha256 }}";
var value = new
{
text = "HelloWorld"
};
var result = await RenderAync(template, value);
Assert.Equal("HelloWorld".ToSha256(), result);
}
[Fact]
public async Task Should_throw_exception_if_template_invalid()
{

Loading…
Cancel
Save