20240311
This commit is contained in:
parent
bb29af7cff
commit
2a66cf7b61
@ -8,7 +8,7 @@
|
|||||||
<RootNamespace>anbs_cp.Database</RootNamespace>
|
<RootNamespace>anbs_cp.Database</RootNamespace>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<PackageId>ANBSoftware.ComponentsPack.Database</PackageId>
|
<PackageId>ANBSoftware.ComponentsPack.Database</PackageId>
|
||||||
<Version>2024.2.6.0</Version>
|
<Version>2024.3.11.0</Version>
|
||||||
<Company>Александр Бабаев</Company>
|
<Company>Александр Бабаев</Company>
|
||||||
<Product>Набор компонентов ANB Software для работы с БД</Product>
|
<Product>Набор компонентов ANB Software для работы с БД</Product>
|
||||||
<Description>Библиотека полезных методов языка C# для работы с базами данных</Description>
|
<Description>Библиотека полезных методов языка C# для работы с базами данных</Description>
|
||||||
@ -16,10 +16,11 @@
|
|||||||
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
|
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
|
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<Authors>Александр Бабаев</Authors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Dapper" Version="2.1.28" />
|
<PackageReference Include="Dapper" Version="2.1.35" />
|
||||||
<PackageReference Include="MySqlConnector" Version="2.3.5" />
|
<PackageReference Include="MySqlConnector" Version="2.3.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using anbs_cp.ForNet.Enums;
|
using anbs_cp.ForNet.Enums;
|
||||||
|
|
||||||
using Ganss.Xss;
|
using Ganss.Xss;
|
||||||
|
|
||||||
namespace anbs_cp.ForNet.Classes;
|
namespace anbs_cp.ForNet.Classes;
|
||||||
@ -9,47 +8,53 @@ namespace anbs_cp.ForNet.Classes;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Sanitizer
|
public static class Sanitizer
|
||||||
{
|
{
|
||||||
|
#region Свойства
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Очистка текста по уровню очистки
|
/// Все теги запрещены
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="html">Текст</param>
|
public static SanitizerAllowedHtml AllowedNone => GetNone();
|
||||||
/// <param name="level">Уровень очистка</param>
|
|
||||||
/// <returns>Очищенный текст</returns>
|
/// <summary>
|
||||||
public static string SanitizeHtml (string html, ESanitizerLevel level)
|
/// Все теги разрешены
|
||||||
|
/// </summary>
|
||||||
|
public static SanitizerAllowedHtml AllowedAll => GetAll();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Оставлены только текстовые теги
|
||||||
|
/// </summary>
|
||||||
|
public static SanitizerAllowedHtml AllowedTextOnly => GetTextFormatOnly();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Оставлены только текстовые теги, а также img и a
|
||||||
|
/// </summary>
|
||||||
|
public static SanitizerAllowedHtml AllowedImageAndLinks => GetImageAndLinks();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Применяются все теги, кроме iframe
|
||||||
|
/// </summary>
|
||||||
|
public static SanitizerAllowedHtml AllowedAllExceptIFrame => GetAllExceptIFrame();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Методы
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Очистка html-кода <paramref name="html"/> согласно параметрам <paramref name="allowedHtml"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="html">HTML-код</param>
|
||||||
|
/// <param name="allowedHtml">Параметры очистки</param>
|
||||||
|
/// <returns>Очищенный html-кода</returns>
|
||||||
|
private static string SanitizeHtml(string html, SanitizerAllowedHtml allowedHtml)
|
||||||
{
|
{
|
||||||
|
// Создаю очиститель
|
||||||
HtmlSanitizer sanitizer = new()
|
HtmlSanitizer sanitizer = new()
|
||||||
{
|
{
|
||||||
|
// - сохраняю дочерние удалённых
|
||||||
KeepChildNodes = true
|
KeepChildNodes = true
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (level)
|
// Выключаю все параметры HTML
|
||||||
{
|
|
||||||
case ESanitizerLevel.NoTags:
|
|
||||||
PrepareForNone(ref sanitizer);
|
|
||||||
break;
|
|
||||||
case ESanitizerLevel.TextFormatOnly:
|
|
||||||
PrepareForTextFormatOnly(ref sanitizer);
|
|
||||||
break;
|
|
||||||
case ESanitizerLevel.ImageAndLinks:
|
|
||||||
PrepareForImageAndLinks(ref sanitizer);
|
|
||||||
break;
|
|
||||||
case ESanitizerLevel.AllExceptIFrame:
|
|
||||||
PrepareForAllExceptIFrame(ref sanitizer);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PrepareForNone(ref sanitizer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return level != ESanitizerLevel.All ? sanitizer.Sanitize(html) : html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Очистка всех тегов
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sanitizer"><see cref="HtmlSanitizer"/></param>
|
|
||||||
private static void PrepareForNone (ref HtmlSanitizer sanitizer)
|
|
||||||
{
|
|
||||||
sanitizer.AllowedTags.Clear();
|
sanitizer.AllowedTags.Clear();
|
||||||
sanitizer.AllowedSchemes.Clear();
|
sanitizer.AllowedSchemes.Clear();
|
||||||
sanitizer.AllowedCssProperties.Clear();
|
sanitizer.AllowedCssProperties.Clear();
|
||||||
@ -57,66 +62,146 @@ public static class Sanitizer
|
|||||||
sanitizer.AllowedAttributes.Clear();
|
sanitizer.AllowedAttributes.Clear();
|
||||||
sanitizer.AllowedAtRules.Clear();
|
sanitizer.AllowedAtRules.Clear();
|
||||||
sanitizer.AllowDataAttributes = false;
|
sanitizer.AllowDataAttributes = false;
|
||||||
|
|
||||||
|
// Загружаю параметры
|
||||||
|
sanitizer.AllowedTags.UnionWith(allowedHtml.AllowedTags);
|
||||||
|
sanitizer.AllowedSchemes.UnionWith(allowedHtml.AllowedSchemes);
|
||||||
|
sanitizer.AllowedCssProperties.UnionWith(allowedHtml.AllowedCssProperties);
|
||||||
|
sanitizer.AllowedClasses.UnionWith(allowedHtml.AllowedClasses);
|
||||||
|
sanitizer.AllowedAttributes.UnionWith(allowedHtml.AllowedAttributes);
|
||||||
|
sanitizer.AllowDataAttributes = allowedHtml.AllowDataAttributes;
|
||||||
|
|
||||||
|
// Очищаю html согласно правилам
|
||||||
|
return sanitizer.Sanitize(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Остаются только текстовые теги
|
/// Очистка html-кода по уровню очистки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sanitizer"><see cref="HtmlSanitizer"/></param>
|
/// <param name="html">HTML-код</param>
|
||||||
private static void PrepareForTextFormatOnly (ref HtmlSanitizer sanitizer)
|
/// <param name="level">Уровень очистка</param>
|
||||||
|
/// <returns>Очищенный html-код</returns>
|
||||||
|
public static string SanitizeHtml(string html, ESanitizerLevel level)
|
||||||
{
|
{
|
||||||
string[] allowedTags =
|
// Получаю параметры очистки
|
||||||
|
SanitizerAllowedHtml allowedHtml = level switch
|
||||||
{
|
{
|
||||||
"strong", "b", "em", "i", "u", "hr", "strike", "div", "ol", "ul", "li", "p", "span", "h1", "h2", "h3", "h4"
|
ESanitizerLevel.NoTags => AllowedNone,
|
||||||
};
|
ESanitizerLevel.TextFormatOnly => AllowedTextOnly,
|
||||||
string[] allowedAttributes =
|
ESanitizerLevel.ImageAndLinks => AllowedImageAndLinks,
|
||||||
{
|
ESanitizerLevel.AllExceptIFrame => AllowedAllExceptIFrame,
|
||||||
"align", "bgcolor", "border", "cellpadding", "cellspacing", "charset", "checked", "class", "clear", "color", "cols", "colspan",
|
ESanitizerLevel.All => AllowedAll,
|
||||||
"datetime", "disabled", "headers", "height", "high", "hspace", "label", "lang", "list", "low", "max", "maxlength", "min", "name",
|
var _ => AllowedAll
|
||||||
"nowrap", "placeholder", "required", "rev", "rows", "rowspan", "rules", "selected", "size", "span", "spellcheck", "style", "summary",
|
|
||||||
"tabindex", "title", "type", "valign", "value", "vspace", "width", "wrap"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sanitizer.AllowedTags.Clear();
|
// Очищаю код и возвращаю результат очистки
|
||||||
|
return SanitizeHtml(html, allowedHtml);
|
||||||
|
}
|
||||||
|
|
||||||
sanitizer.AllowedTags.UnionWith(allowedTags);
|
#endregion
|
||||||
|
|
||||||
sanitizer.AllowedAtRules.Clear();
|
#region Вспомогателдьные методы
|
||||||
sanitizer.AllowDataAttributes = false;
|
|
||||||
|
|
||||||
sanitizer.AllowedAttributes.Clear();
|
/// <summary>
|
||||||
sanitizer.AllowedAttributes.UnionWith(allowedAttributes);
|
/// Получаю параметры, удаляющие все теги
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Параметры очистки</returns>
|
||||||
|
private static SanitizerAllowedHtml GetNone() =>
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
AllowedTags = [],
|
||||||
|
AllowedAttributes = [],
|
||||||
|
AllowedCssProperties = [],
|
||||||
|
AllowedClasses = [],
|
||||||
|
AllowedSchemes = [],
|
||||||
|
AllowDataAttributes = false
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получаю параметры по умолчанию (разрешающие все теги)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Параметры очистки</returns>
|
||||||
|
private static SanitizerAllowedHtml GetAll()
|
||||||
|
{
|
||||||
|
// Создаю очиститель
|
||||||
|
HtmlSanitizer sanitizer = new();
|
||||||
|
|
||||||
|
// Создаю модель
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
AllowedTags = sanitizer.AllowedTags.ToList(),
|
||||||
|
AllowedAttributes = sanitizer.AllowedAttributes.ToList(),
|
||||||
|
AllowedCssProperties = sanitizer.AllowedCssProperties.ToList(),
|
||||||
|
AllowedClasses = sanitizer.AllowedClasses.ToList(),
|
||||||
|
AllowedSchemes = sanitizer.AllowedSchemes.ToList(),
|
||||||
|
AllowDataAttributes = true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Остаются текстовые теги + изображения и ссылки
|
/// Параметры, оставляющие только текстовые теги
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sanitizer"><see cref="HtmlSanitizer"/></param>
|
/// <returns>Параметры очистки</returns>
|
||||||
private static void PrepareForImageAndLinks (ref HtmlSanitizer sanitizer)
|
private static SanitizerAllowedHtml GetTextFormatOnly() =>
|
||||||
|
new()
|
||||||
{
|
{
|
||||||
PrepareForTextFormatOnly(ref sanitizer);
|
AllowedTags =
|
||||||
string[] allowedTags =
|
[
|
||||||
{
|
"strong", "b", "em", "i", "u", "hr", "strike", "div", "ol", "ul", "li", "p", "span", "h1", "h2", "h3",
|
||||||
"a", "img"
|
"h4"
|
||||||
|
],
|
||||||
|
|
||||||
|
// ReSharper disable StringLiteralTypo
|
||||||
|
AllowedAttributes =
|
||||||
|
[
|
||||||
|
"align", "bgcolor", "border", "cellpadding", "cellspacing", "charset", "checked", "class", "clear",
|
||||||
|
"color",
|
||||||
|
"cols", "colspan", "datetime", "disabled", "headers", "height", "high", "hspace", "label", "lang",
|
||||||
|
"list",
|
||||||
|
"low", "max", "maxlength", "min", "name", "nowrap", "placeholder", "required", "rev", "rows", "rowspan",
|
||||||
|
"rules", "selected", "size", "span", "spellcheck", "style", "summary", "tabindex", "title", "type",
|
||||||
|
"valign",
|
||||||
|
"value", "vspace", "width", "wrap"
|
||||||
|
]
|
||||||
|
// ReSharper restore StringLiteralTypo
|
||||||
};
|
};
|
||||||
|
|
||||||
string[] allowedAttributes =
|
/// <summary>
|
||||||
|
/// Параметры, оставляющие только текстовые теги, а также img и a
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Параметры очистки</returns>
|
||||||
|
private static SanitizerAllowedHtml GetImageAndLinks()
|
||||||
{
|
{
|
||||||
"alt", "href", "hreflang", "nohref", "rel", "src", "target"
|
// Получаю текстовые параметры
|
||||||
};
|
SanitizerAllowedHtml result = AllowedTextOnly;
|
||||||
|
|
||||||
sanitizer.AllowedTags.UnionWith(allowedTags);
|
// Добавляю теги
|
||||||
|
result.AllowedTags.AddRange(["a", "img"]);
|
||||||
|
|
||||||
sanitizer.AllowedAttributes.UnionWith(allowedAttributes);
|
// Добавляю параметры
|
||||||
|
// ReSharper disable StringLiteralTypo
|
||||||
|
result.AllowedAttributes.AddRange(["alt", "href", "hreflang", "nohref", "rel", "src", "target"]);
|
||||||
|
// ReSharper restore StringLiteralTypo
|
||||||
|
|
||||||
|
// Возвращаю результат
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Остаются все теги, за исключением IFRAME
|
/// Применяются все теги, кроме iframe
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sanitizer"><see cref="HtmlSanitizer"/></param>
|
/// <returns>Параметры очистки</returns>
|
||||||
private static void PrepareForAllExceptIFrame (ref HtmlSanitizer sanitizer)
|
private static SanitizerAllowedHtml GetAllExceptIFrame()
|
||||||
{
|
{
|
||||||
sanitizer.AllowedTags.Remove("iframe");
|
// Получаю все параметры
|
||||||
|
SanitizerAllowedHtml result = AllowedAll;
|
||||||
|
|
||||||
|
// Удаляю iframe
|
||||||
|
result.AllowedTags.Remove("iframe");
|
||||||
|
|
||||||
|
// Возвращаю результат
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
37
anbs_cpfn/Classes/SanitizerAllowedHtml.cs
Normal file
37
anbs_cpfn/Classes/SanitizerAllowedHtml.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
namespace anbs_cp.ForNet.Classes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимые параметры для очистки HTML
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SanitizerAllowedHtml
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимые теги
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AllowedTags { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимые аттрибуты
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AllowedAttributes { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимые параметры css
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AllowedCssProperties { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимые классы
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AllowedClasses { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимые схемы
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AllowedSchemes { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Допустимы ли data-атрибуты
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowDataAttributes { get; set; } = false;
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<PackageId>ANBSoftware.ComponentsPackForNet</PackageId>
|
<PackageId>ANBSoftware.ComponentsPackForNet</PackageId>
|
||||||
<Version>2024.2.24.0</Version>
|
<Version>2024.3.11.0</Version>
|
||||||
<Authors>Александр Бабаев</Authors>
|
<Authors>Александр Бабаев</Authors>
|
||||||
<Product>Набор компонентов ANB Software для ASP.NET Core</Product>
|
<Product>Набор компонентов ANB Software для ASP.NET Core</Product>
|
||||||
<Description>Библиотека полезных методов языка C# для ASP.NET Core</Description>
|
<Description>Библиотека полезных методов языка C# для ASP.NET Core</Description>
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
|
||||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>
|
|
Loading…
x
Reference in New Issue
Block a user