How to limit search result based on the user's permission

Updated on 11/4/2008

Liferay has role based access control on any item created by different portlet, but the search result doesn't honor the permission but returned all matched item. Only till you clicked on the link then portlet indicated that you don't have permission to view it. In some cases, the summary of search result has already broken the permission if it gave the sensitive information.

If the search engine doesn't have the function of role base permission, we could mark up item with ACL prepared for indexing then do the same on the search query to match the user's permission.

There are few requirement for any given search engine to fullfil this idea.

  • The search engine must have boolean operation, for example: query1 AND query2
  • The search engine must have none tokenized field index and search capibility. For example:  field1 = "abc"
  • The search engine must have multiple value filed support for indexing , For example:  index field1 with values {"member", "guest"}

 

In Lifaray, the default Lucene search engine has all above requirement, so I could use my idea to implement the role base search.

Indexing

The document for indexing has already used the "groupId" to restrict the result in the portlet, so we could use the "roleId" in the field for acl. To determine the values of "viewacl" will be using resourceId and permission service.

For example: (using json syntax)

a document with guest view permission prepared for indexing.

{doc:{portletId:"wiki", groupId:12345, viewacl: {"guest"}, ........}}

another document without guest view permission

{doc:{portletId:"wiki", groupId:12345, viewacl:{"10315", "10318"}, ........}}

 

Search

The SearchEngineUtil will add extra field search of "viewacl" based on the user's role in current community, so the search api need to inculde a user object as an argument.

For example:

The query of search on "java"

+(+(+portletId:19) +(userName:java title:java content:java tagsEntries:java)) +(VIEWACL:guest)

The query fo a logined user.

+(+(+portletId:19) +(userName:java title:java content:java tagsEntries:java)) +(VIEWACL:guest VIEWACL:10315 VIEWACL:10130)

 

Implementation

https://lportal.svn.sourceforge.net/svnroot/lportal/portal/shelves/allenchiang/

  • Only implemented in Messageboards portlet for the initial check in.
  • need to catch the action of portleconfiguration EditPermissionAction then reindex the item with new permission. current workaround is edit the message and save after the permission changed, it will reindex the document with new permission.
  • Only indexed with viewacl = groupId or guest. need to take care of all defined role permission. For example, an item with owner view permission only.
  • Need to implement the same for other applications.

 

 

Blogs
I think is a good feature, but i do not know what happen when a resource (like document uploaded to DocumentLibrary) update it's permissions.
It will be necessary that the search engine knows that?
My implementation was adding resourceId into the document for indexing, so the acl markup can be done in SearchEngineImpl not each Indexer.

Since the resourceId was indexed as a field, I was thinkging about to do a search on "resourceId=id_of_permission_modified_resource" to get the document from index then reindex it with new viewacl. This action will be added into PermissionLocalService when a resource permission got updated.
Hi Allen, Can you please provide us with an update on status of this?
I believe the implementation is already in 5.2.3 and trunk. However, the implementation is not done by me so it is not exact the same as stated in this blog.
Please use following LPS to track the implementation.

http://issues.liferay.com/browse/LPS-427
http://issues.liferay.com/browse/LPS-2242
Hi Everybody,
I want to customize the search portlet and remove the search option like This Site and EveryThink.
Kindly help on this.