20240311-1

This commit is contained in:
Александр Бабаев 2024-03-11 23:44:26 +03:00
parent 2a66cf7b61
commit 66b5f5741b
2 changed files with 172 additions and 171 deletions

View File

@ -1,207 +1,208 @@
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;
/// <summary> /// <summary>
/// Очистка текста от лишних HTML-тегов /// Очистка текста от лишних HTML-тегов
/// </summary> /// </summary>
public static class Sanitizer public static class Sanitizer
{ {
#region Свойства #region Свойства
/// <summary> /// <summary>
/// Все теги запрещены /// Все теги запрещены
/// </summary> /// </summary>
public static SanitizerAllowedHtml AllowedNone => GetNone(); public static SanitizerAllowedHtml AllowedNone => GetNone();
/// <summary> /// <summary>
/// Все теги разрешены /// Все теги разрешены
/// </summary> /// </summary>
public static SanitizerAllowedHtml AllowedAll => GetAll(); public static SanitizerAllowedHtml AllowedAll => GetAll();
/// <summary> /// <summary>
/// Оставлены только текстовые теги /// Оставлены только текстовые теги
/// </summary> /// </summary>
public static SanitizerAllowedHtml AllowedTextOnly => GetTextFormatOnly(); public static SanitizerAllowedHtml AllowedTextOnly => GetTextFormatOnly();
/// <summary> /// <summary>
/// Оставлены только текстовые теги, а также img и a /// Оставлены только текстовые теги, а также img и a
/// </summary> /// </summary>
public static SanitizerAllowedHtml AllowedImageAndLinks => GetImageAndLinks(); public static SanitizerAllowedHtml AllowedImageAndLinks => GetImageAndLinks();
/// <summary> /// <summary>
/// Применяются все теги, кроме iframe /// Применяются все теги, кроме iframe
/// </summary> /// </summary>
public static SanitizerAllowedHtml AllowedAllExceptIFrame => GetAllExceptIFrame(); public static SanitizerAllowedHtml AllowedAllExceptIFrame => GetAllExceptIFrame();
#endregion #endregion
#region Методы #region Методы
/// <summary> /// <summary>
/// Очистка html-кода <paramref name="html"/> согласно параметрам <paramref name="allowedHtml"/> /// Очистка html-кода <paramref name="html" /> согласно параметрам <paramref name="allowedHtml" />
/// </summary> /// </summary>
/// <param name="html">HTML-код</param> /// <param name="html">HTML-код</param>
/// <param name="allowedHtml">Параметры очистки</param> /// <param name="allowedHtml">Параметры очистки</param>
/// <returns>Очищенный html-кода</returns> /// <returns>Очищенный html-кода</returns>
private static string SanitizeHtml(string html, SanitizerAllowedHtml allowedHtml) public static string SanitizeHtml (string html, SanitizerAllowedHtml allowedHtml)
{
// Создаю очиститель
HtmlSanitizer sanitizer = new()
{ {
// Создаю очиститель // - сохраняю дочерние удалённых
HtmlSanitizer sanitizer = new() KeepChildNodes = true
{ };
// - сохраняю дочерние удалённых
KeepChildNodes = true
};
// Выключаю все параметры HTML // Выключаю все параметры HTML
sanitizer.AllowedTags.Clear(); sanitizer.AllowedTags.Clear();
sanitizer.AllowedSchemes.Clear(); sanitizer.AllowedSchemes.Clear();
sanitizer.AllowedCssProperties.Clear(); sanitizer.AllowedCssProperties.Clear();
sanitizer.AllowedClasses.Clear(); sanitizer.AllowedClasses.Clear();
sanitizer.AllowedAttributes.Clear(); sanitizer.AllowedAttributes.Clear();
sanitizer.AllowedAtRules.Clear(); sanitizer.AllowedAtRules.Clear();
sanitizer.AllowDataAttributes = false; sanitizer.AllowDataAttributes = false;
// Загружаю параметры // Загружаю параметры
sanitizer.AllowedTags.UnionWith(allowedHtml.AllowedTags); sanitizer.AllowedTags.UnionWith(allowedHtml.AllowedTags);
sanitizer.AllowedSchemes.UnionWith(allowedHtml.AllowedSchemes); sanitizer.AllowedSchemes.UnionWith(allowedHtml.AllowedSchemes);
sanitizer.AllowedCssProperties.UnionWith(allowedHtml.AllowedCssProperties); sanitizer.AllowedCssProperties.UnionWith(allowedHtml.AllowedCssProperties);
sanitizer.AllowedClasses.UnionWith(allowedHtml.AllowedClasses); sanitizer.AllowedClasses.UnionWith(allowedHtml.AllowedClasses);
sanitizer.AllowedAttributes.UnionWith(allowedHtml.AllowedAttributes); sanitizer.AllowedAttributes.UnionWith(allowedHtml.AllowedAttributes);
sanitizer.AllowDataAttributes = allowedHtml.AllowDataAttributes; sanitizer.AllowDataAttributes = allowedHtml.AllowDataAttributes;
// Очищаю html согласно правилам // Очищаю html согласно правилам
return sanitizer.Sanitize(html); return sanitizer.Sanitize(html);
} }
/// <summary> /// <summary>
/// Очистка html-кода по уровню очистки /// Очистка html-кода по уровню очистки
/// </summary> /// </summary>
/// <param name="html">HTML-код</param> /// <param name="html">HTML-код</param>
/// <param name="level">Уровень очистка</param> /// <param name="level">Уровень очистка</param>
/// <returns>Очищенный html-код</returns> /// <returns>Очищенный html-код</returns>
public static string SanitizeHtml(string html, ESanitizerLevel level) public static string SanitizeHtml (string html, ESanitizerLevel level)
{
// Получаю параметры очистки
SanitizerAllowedHtml allowedHtml = level switch
{ {
// Получаю параметры очистки ESanitizerLevel.NoTags => AllowedNone,
SanitizerAllowedHtml allowedHtml = level switch ESanitizerLevel.TextFormatOnly => AllowedTextOnly,
{ ESanitizerLevel.ImageAndLinks => AllowedImageAndLinks,
ESanitizerLevel.NoTags => AllowedNone, ESanitizerLevel.AllExceptIFrame => AllowedAllExceptIFrame,
ESanitizerLevel.TextFormatOnly => AllowedTextOnly, ESanitizerLevel.All => AllowedAll,
ESanitizerLevel.ImageAndLinks => AllowedImageAndLinks, var _ => AllowedAll
ESanitizerLevel.AllExceptIFrame => AllowedAllExceptIFrame, };
ESanitizerLevel.All => AllowedAll,
var _ => AllowedAll
};
// Очищаю код и возвращаю результат очистки // Очищаю код и возвращаю результат очистки
return SanitizeHtml(html, allowedHtml); return SanitizeHtml(html, allowedHtml);
} }
#endregion #endregion
#region Вспомогателдьные методы #region Вспомогателдьные методы
/// <summary> /// <summary>
/// Получаю параметры, удаляющие все теги /// Получаю параметры, удаляющие все теги
/// </summary> /// </summary>
/// <returns>Параметры очистки</returns> /// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetNone() => private static SanitizerAllowedHtml GetNone () =>
new() new()
{
AllowedTags = [],
AllowedAttributes = [],
AllowedCssProperties = [],
AllowedClasses = [],
AllowedSchemes = [],
AllowDataAttributes = false
};
/// <summary>
/// Получаю параметры по умолчанию (разрешающие все теги)
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetAll()
{ {
// Создаю очиститель AllowedTags = [],
HtmlSanitizer sanitizer = new(); AllowedAttributes = [],
AllowedCssProperties = [],
AllowedClasses = [],
AllowedSchemes = [],
AllowDataAttributes = false
};
// Создаю модель /// <summary>
return new() /// Получаю параметры по умолчанию (разрешающие все теги)
{ /// </summary>
AllowedTags = sanitizer.AllowedTags.ToList(), /// <returns>Параметры очистки</returns>
AllowedAttributes = sanitizer.AllowedAttributes.ToList(), private static SanitizerAllowedHtml GetAll ()
AllowedCssProperties = sanitizer.AllowedCssProperties.ToList(), {
AllowedClasses = sanitizer.AllowedClasses.ToList(), // Создаю очиститель
AllowedSchemes = sanitizer.AllowedSchemes.ToList(), HtmlSanitizer sanitizer = new();
AllowDataAttributes = true
};
}
/// <summary> // Создаю модель
/// Параметры, оставляющие только текстовые теги return new()
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetTextFormatOnly() =>
new()
{
AllowedTags =
[
"strong", "b", "em", "i", "u", "hr", "strike", "div", "ol", "ul", "li", "p", "span", "h1", "h2", "h3",
"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
};
/// <summary>
/// Параметры, оставляющие только текстовые теги, а также img и a
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetImageAndLinks()
{ {
// Получаю текстовые параметры AllowedTags = sanitizer.AllowedTags.ToList(),
SanitizerAllowedHtml result = AllowedTextOnly; AllowedAttributes = sanitizer.AllowedAttributes.ToList(),
AllowedCssProperties = sanitizer.AllowedCssProperties.ToList(),
AllowedClasses = sanitizer.AllowedClasses.ToList(),
AllowedSchemes = sanitizer.AllowedSchemes.ToList(),
AllowDataAttributes = true
};
}
// Добавляю теги /// <summary>
result.AllowedTags.AddRange(["a", "img"]); /// Параметры, оставляющие только текстовые теги
/// </summary>
// Добавляю параметры /// <returns>Параметры очистки</returns>
// ReSharper disable StringLiteralTypo private static SanitizerAllowedHtml GetTextFormatOnly () =>
result.AllowedAttributes.AddRange(["alt", "href", "hreflang", "nohref", "rel", "src", "target"]); new()
// ReSharper restore StringLiteralTypo
// Возвращаю результат
return result;
}
/// <summary>
/// Применяются все теги, кроме iframe
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetAllExceptIFrame()
{ {
// Получаю все параметры AllowedTags =
SanitizerAllowedHtml result = AllowedAll; [
"strong", "b", "em", "i", "u", "hr", "strike", "div", "ol", "ul", "li", "p", "span", "h1", "h2", "h3",
"h4"
],
// Удаляю iframe // ReSharper disable StringLiteralTypo
result.AllowedTags.Remove("iframe"); 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
};
// Возвращаю результат /// <summary>
return result; /// Параметры, оставляющие только текстовые теги, а также img и a
} /// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetImageAndLinks ()
{
// Получаю текстовые параметры
SanitizerAllowedHtml result = AllowedTextOnly;
#endregion // Добавляю теги
result.AllowedTags.AddRange(["a", "img"]);
// Добавляю параметры
// ReSharper disable StringLiteralTypo
result.AllowedAttributes.AddRange(["alt", "href", "hreflang", "nohref", "rel", "src", "target"]);
// ReSharper restore StringLiteralTypo
// Возвращаю результат
return result;
}
/// <summary>
/// Применяются все теги, кроме iframe
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetAllExceptIFrame ()
{
// Получаю все параметры
SanitizerAllowedHtml result = AllowedAll;
// Удаляю iframe
result.AllowedTags.Remove("iframe");
// Возвращаю результат
return result;
}
#endregion
} }

View File

@ -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.3.11.0</Version> <Version>2024.3.11.1</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>