Sanitizers in Liferay 6

A new functionallity in Liferay 6 are the so called "Sanitizers". 

What are sanitizers? Sanitizers are a filtering element that "sanitize" web content (usually HTML or javascript code) so that it doesn't contain unappropiate content like javascript malicious code or swearwords, for example.
 
The portal.properties file has been updated with this entry:
 
sanitizer.impl=com.liferay.portal.sanitizer.DummySanitizerImpl
 
so that we can use our custom sanitizer.
 
For the moment it's being used in Blogs portlet out-of-the-box, just before entering the contents in the database, but this can be applied to whatever entity we need using plugins. For example you can use it in a Model Wrapper Hook for Wiki pages or a Model Wrapper Hook for web content.
 
There's already an antisamy hook in plugins repository that is ready to be used and it can be used as an starting point for you developers that are interested in implementing your custom sanitizers. (Read more about the antisamy project here)
 
To use this in core entities the best way is to use model wrapper hooks (read more about this kind of plugins here), so that you include this filtering before creating the entity and its related objects (like tags, categories and so on)
 
To create this hook, the fastest way is using Liferay IDE 
 
Create a hook plugin project ("Liferay hook plug-in project") and create a new hook portlet ("new hook plugin") that overrides Services (mark "Services" checkbox) and then select the class you want to extend. 
 
In this blog entry, I'll extend WikiPage creation, so my class is like this:
 
package com.test.hooks;
 
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portlet.wiki.model.WikiPage;
import com.liferay.portlet.wiki.service.WikiPageLocalService;
import com.liferay.portlet.wiki.service.WikiPageLocalServiceWrapper;

public class ExtWikiPageLocalService extends WikiPageLocalServiceWrapper {

public ExtWikiPageLocalService(WikiPageLocalService wikiPageLocalService) {
super(wikiPageLocalService);
}
public WikiPage addPage(
long userId, long nodeId, String title, double version,
String content, String summary, boolean minorEdit, String format,
boolean head, String parentTitle, String redirectTitle,
ServiceContext serviceContext)
throws PortalException, SystemException {

// My Custom Code: sanitize the content

String sanitizedContent = SanitizerUtil.sanitize(
serviceContext.getCompanyId(), serviceContext.getScopeGroupId(),
userId, WikiPage.class.getName(), 0, ContentTypes.TEXT_HTML, content);

// Then launch Liferay method code

return super.addPage(userId, nodeId, title, version,
sanitizedContent, summary, minorEdit, format,
head, parentTitle, redirectTitle,
serviceContext);
}
}
 
And my liferay-hook.xml is like this:
 
<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd">

<hook>
<service>
<service-type> com.liferay.portlet.wiki.service.WikiPageLocalService </service-type>
<service-impl> com.test.hooks.ExtWikiPageLocalService </service-impl>
</service>
</hook>
 
 
After deploying antisamy hook, when you deploy your custom wrapper, the wiki content is verified in creation time so that it filters wiki page's content the way the antisamy does.
 
I hope it's been useful
 
Regards!
Juan Fernández
 
Credits:
thanks to Zsolt Balogh for his help & patience with sanitizers :D
 image from Flickr: http://www.flickr.com/photos/loush555/2322773699/ (by El Tekolote)
Blogues
It seems it is not working in Latest Enterprise version of liferay. Always keeps giving me ClassNotFoundException.
Does anybody know why the antisamy-hook get removed from SVN?
svn://svn.liferay.com/repos/public/plugins/trunk/hooks/antisamy-hook
The source was removed on 2012.03.03.
We use this hook in our solution to sanitize blogs created by external users.