|
| 1 | +using Fluid.Utils; |
1 | 2 | using Fluid.Values;
|
2 | 3 | using System.Buffers;
|
3 | 4 | using System.Globalization;
|
4 | 5 | using System.Net;
|
5 | 6 | using System.Reflection;
|
| 7 | +using System.Security.Cryptography; |
6 | 8 | using System.Text;
|
7 | 9 | using System.Text.Json;
|
8 | 10 | using TimeZoneConverter;
|
@@ -41,6 +43,8 @@ public static FilterCollection WithMiscFilters(this FilterCollection filters)
|
41 | 43 | filters.AddFilter("md5", MD5);
|
42 | 44 | filters.AddFilter("sha1", Sha1);
|
43 | 45 | filters.AddFilter("sha256", Sha256);
|
| 46 | + filters.AddFilter("hmac_sha1", HmacSha1); |
| 47 | + filters.AddFilter("hmac_sha256", HmacSha256); |
44 | 48 |
|
45 | 49 | return filters;
|
46 | 50 | }
|
@@ -931,5 +935,46 @@ public static ValueTask<FluidValue> Sha256(FluidValue input, FilterArguments arg
|
931 | 935 | return new StringValue(builder.ToString());
|
932 | 936 | #endif
|
933 | 937 | }
|
| 938 | + |
| 939 | + public static ValueTask<FluidValue> HmacSha1(FluidValue input, FilterArguments arguments, TemplateContext context) => ComputeHmac("HMACSHA1", input, arguments); |
| 940 | + |
| 941 | + public static ValueTask<FluidValue> HmacSha256(FluidValue input, FilterArguments arguments, TemplateContext context) => ComputeHmac("HMACSHA256", input, arguments); |
| 942 | + |
| 943 | + private static ValueTask<FluidValue> ComputeHmac(string algorithm, FluidValue input, FilterArguments arguments) |
| 944 | + { |
| 945 | + var key = arguments.At(0); |
| 946 | + if (key.IsNil() || input.IsNil()) |
| 947 | + { |
| 948 | + return StringValue.Empty; |
| 949 | + } |
| 950 | + |
| 951 | + var value = input.ToStringValue(); |
| 952 | + var keyBytes = Encoding.UTF8.GetBytes(key.ToStringValue()); |
| 953 | + |
| 954 | +#if NET6_0_OR_GREATER |
| 955 | +#pragma warning disable CA5350 |
| 956 | + var hash = algorithm switch |
| 957 | + { |
| 958 | + "HMACSHA1" => HMACSHA1.HashData(keyBytes, Encoding.UTF8.GetBytes(value)), |
| 959 | + "HMACSHA256" => HMACSHA256.HashData(keyBytes, Encoding.UTF8.GetBytes(value)), |
| 960 | + _ => throw new ArgumentException("Unsupported HMAC algorithm", nameof(algorithm)) |
| 961 | + }; |
| 962 | +#pragma warning restore CA5350 |
| 963 | + |
| 964 | + return new StringValue(HexUtilities.ToHexLower(hash)); |
| 965 | +#else |
| 966 | + using var provider = HMAC.Create(algorithm); |
| 967 | + provider.Key = keyBytes; |
| 968 | + var builder = new StringBuilder(64); |
| 969 | +#pragma warning disable CA1850 |
| 970 | + foreach (var b in provider.ComputeHash(Encoding.UTF8.GetBytes(value))) |
| 971 | +#pragma warning restore CA1850 |
| 972 | + { |
| 973 | + builder.Append(b.ToString("x2")); |
| 974 | + } |
| 975 | + |
| 976 | + return new StringValue(builder.ToString()); |
| 977 | +#endif |
| 978 | + } |
934 | 979 | }
|
935 | 980 | }
|
0 commit comments