null

Liferay 7.0 + Syntax Highlighter: вырезается атрибут class

Несмотря на наличие различных руководств по миграции портала со старой версии на новую, почти никогда не обходится без неожиданных проблем. И что-то, что отлично работало на старой версии, без видимых причин перестаёт работать на новой.

Одной из таких проблем была подсветка синтаксиса блоков кода в блогах, за которую отвечает библиотека Syntax Highlighter в связке с плагином для CKEeditor (о том, как это реализовано, можно почитать в отдельной статье).

Так выглядит фрагмент исходного кода статьи до сохранения.

<pre class="brush: js;">
  alert("Hello, world!");
</pre>

А так после.

<pre>
  alert("Hello, world!");
</pre>

Как видно из примера, классы Syntax Highlighter-а были кем-то вырезаны. Было не важно, вставлены классы плагином или вручную. Но в то же время классы вида class="brush-js", проставленные вручную, успешно сохранялись.

Дело в том, что Syntax Highlighter использует специфичный синтаксис для задания свойств. Как пишет сам автор, свойства задаются в атрибуте class, но формат при этом идентичен атрибуту style - свойства перечисляются через точку с запятой.

Получаемый в итоге код не является валидным именем CSS-класса, или во всяком случае не признаётся таковым большинством сторонних модулей, выполняющих проверку и фильтрацию HTML, что вызывает проблемы не только у пользователей Liferay (Drupal WYSIWYG Filter, HTML Purifier).

Очевидно, что и в нашем случае кто-то фильтрует код статьи. Кандидатов было два:

 

Advanced Content Filter (CKEditor 4)

Advanced Content Filter отключается через написание хука, который устанавливает параметр allowedContent в true. Подробнее об этом можно прочесть в документации в разделе Modifying an Editor’s Configuration или в этой статье. На нашем сайте такой хук реализован. Убедиться, что параметр установлен, можно в консоли браузера на странице, где есть текстовый редактор. Достаточно найти нужный инстанс и посмотреть config.

CKEDITOR.instances._com_liferay_blogs_web_portlet_BlogsPortlet_contentEditor.config.allowedContent

 

AntiSamy Sanitizer (Liferay 7.0)

Поскольку Advanced Content Filter уже был отключен, остаётся второй вариант.

Согласно Liferay 6.x Portal Enterprise Intranets Cookbook [стр. 236] в Liferay 6 пользователям предлагалось самостоятельно обеспечить защиту от вредоносного кода в контенте (статьях, wiki, сообщениях и т.д.) с помощью установки antisamy-hook. Встроенной защиты от XSS атак в 6-й версии портала не было.

В версии 7 в портал включён модуль AntiSamy, фильтрующий определенные фрагменты HTML/CSS и удаляющий из них подозрительный код JavaScript. В дефолтной конфигурации регулярное выражение для CSS-класса не допускает наличие двоеточия в имени класса.

<regexp name="htmlClass" value="[a-zA-Z0-9\s,\-_]+"/>

Настраивается AntiSamy в Control Panel -> System Settings -> Foundation -> AntiSamy Sanitizer. Там можно отключить фильтр совсем, загрузить собственный файл конфигурации и настроить белый и черный список. В нашем случае достаточно добавить в белый список, где по умолчанию есть JournalArticle, сущности портлета блогов (com.liferay.blogs.*).

После этого классы Syntax Highlighter остаются в неизменном виде и подсветка работает.