Setting document library folder permissions in Liferay can be a tedious task, especially if you have a complicated structure of shards and organizations. Using a script can be the faster way than doing it manually. In this post I will show you how I manage this task in production servers and will provide you with the Beanshell script. If you are unsure about how to run Beanshell scripts in Liferay you can also check out my post about Liferay Beanshell Scripts for Sharded Environments.
Document library folder permissions
Liferay’s document library one of the core functionality that the Liferay portal offers. It is the document management function. It provides the users means to store and share documents in a structured way. As any document management solution it provides means for protecting folders and documents based on permissions. The permissions model is the same for all items in Liferay, so you can set various permissions for the portal’s user roles. Users can have one or more roles, and these will decide which folders / documents they will have access to and what kind of access (edit rights, delete rights, etc)
One important aspect to keep in mind regarding the Document Library is that it’s a portlet and by default it has as scope the community or organization on which page it is deployed. So, all folders and documents with their permissions refer to the scope of the portlet. You can set the scope of the portlet other than the default scope, but I won’t go into the details of that setup in this post.
The main document library permissions refer to viewing the document, editing the document and deleting the document. There are some other permissions which you can view if you go to the Document Library and click the Actions button > Permissions on one of the folders or documents.
One important thing to note regarding the document library folder permissions is that setting permissions on the folder will also have effect on the files and folders underneath. So, if a user does not have view permissions for one folder he will not see any of the files or folders underneath either.
Beanshell script for setting folder permissions in a sharded environment
Enough theory, let’s get into writing the script that will set the document library folder permissions for all organizations in a specific shard. I have created the script functions that will allow you to do just that. Please note, that in my case I use in production a server on which we have multiple shards and each shard has it’s own structure of organizations. For each organization, I have a mechanism that replicates exactly the same structure of root folders, so I know exactly the names of the folders in the root. Probably in your case this won’t be so, but the script function I made allows you to go through all organizations in a shard and set the document library folder permissions for a specific folder name.
import com.liferay.portal.*;
import com.liferay.portal.model.*;
import com.liferay.portal.service.*;
import com.liferay.portal.kernel.dao.orm.*;
import com.liferay.portlet.documentlibrary.model.*;
import com.liferay.portlet.documentlibrary.service.*;
import com.liferay.portal.model.PortletConstants;
import com.liferay.portal.security.auth.*;
import com.liferay.portal.security.permission.*;
import com.liferay.portal.service.*;
import com.liferay.portal.kernel.dao.shard.*;
//function for getting the shard id from the shard name
long getCompanyIdByShardName(String shardName){
List allShards = ShardLocalServiceUtil.getShards(QueryUtil.ALL_POS, QueryUtil.ALL_POS);
long result = 0;
if (allShards!=null){
for (i=0;i<allShards.size();i++){
if (allShards.get(i).getName().equals(shardName)){
return allShards.get(i).getClassPK();
}
}
}
return result;
}
//get the default user id from a shard
long getDefaultUserId(companyId){
long userId = 0;
try{
ShardUtil.pushCompanyService(companyId);
try{
userId = UserLocalServiceUtil.getUserByEmailAddress(companyId,"[email protected]").getUserId();
}catch (Exception e){
userId = UserLocalServiceUtil.getUserByEmailAddress(companyId,"[email protected]").getUserId();
}
}catch (Exception e){ e.printStackTrace(); }
finally { ShardUtil.popCompanyService();}
if (userId==0){
throw new Exception("Role [email protected] or [email protected] not found on shard "+companyId);
}
return userId;
}
//get the role id starting from the role name
long getRoleId(companyId,String roleName){
long roleId = 0;
try{
ShardUtil.pushCompanyService(companyId);
try{
roleId = RoleLocalServiceUtil.getRole(companyId,roleName).getRoleId();
}catch (Exception e){
roleId = RoleLocalServiceUtil.getRole(companyId,roleName).getRoleId();
}
}catch (Exception e){ e.printStackTrace(); }
finally { ShardUtil.popCompanyService();}
if (roleId==0){
throw new Exception("Role "+roleName+ " not found on shard "+companyId);
}
return roleId;
}
//function to set folder permissions for a certain role
setFolderPermissions(String shardName, String folderName, String roleName, String[] permissions){
long companyId = getCompanyIdByShardName(shardName);
long userId = getDefaultUserId(companyId);
long roleId = getRoleId(companyId, roleName);
ServiceContext ctx = new ServiceContext();
ctx.setCompanyId(companyId);
try{
//selecting the right shard
ShardUtil.pushCompanyService(companyId);
//performing operation as the default user of this shard
User user = UserLocalServiceUtil.getUser(userId);
PrincipalThreadLocal.setName(user.getUserId());
PermissionChecker permissionChecker = PermissionCheckerFactoryUtil.create(user, false);
PermissionThreadLocal.setPermissionChecker(permissionChecker);
//enumerate all organizations on this shard
List organizations = OrganizationLocalServiceUtil.search(companyId, -1, null, null, null, null, null, QueryUtil.ALL_POS,QueryUtil.ALL_POS);
for (Organization org : organizations){
long groupId = org.getGroup().getGroupId();
List folders = DLFolderLocalServiceUtil.getFolders(groupId,0);
System.out.println(org.getName());
//for each folder in this organization set the permissions
//for the folder which matches the name
for (DLFolder folder: folders) {
if (folder.getName().equalsIgnoreCase(folderName)) {
ResourcePermissionLocalServiceUtil.setResourcePermissions(companyId,DLFolder.class.getName(),ResourceConstants.SCOPE_INDIVIDUAL,""+folder.getFolderId(), roleId, permissions);
}
}
}
}catch (Exception e){ e.printStackTrace(); }
finally { ShardUtil.popCompanyService();}
}
//permissions for full access
String[] fullAccess = {"ACCESS", "ADD_DOCUMENT","ADD_SHORTCUT","ADD_SUBFOLDER","UPDATE","VIEW","PERMISSIONS"};
//view only permissions
String[] viewAccess = {"ACCESS","VIEW"};
//the shard name on which you want to do the operations
String shard = "two";
String folder = "Public folder";
String role = "Guest";
//grant Guest role view only permissions for "Public folder" folder
setFolderPermissions(shard,folder,role,viewAccess);
hope you found this post useful and please feel free to contact me in the comments section for any questions.