1

I have been trying to propagate the View permission for a layout for a custom role, for which no entry exists in resourcepermission table for that layout and that custom role. As in below code, layout permission should be ideally set using

ResourcePermissionServiceUtil.setIndividualResourcePermissions(groupId, companyId, layout.getModelClassName(),
                "primkey", roleIdsToActionIds);

However, here first call works but second call to set current layout's parent layout permission, it gives error as shown in the error log. Can someone please guide me how to achieve this?

    // Propagete VIEW access to Page, on which Portlet is added - START
long plid = LayoutLocalServiceUtil.getDefaultPlid(groupId, false, portletId);
if(plid!=0){
Layout layout = LayoutLocalServiceUtil.getLayout(plid); 
if(layout!=null){
    _log.info("Adding permission for layout: "+layout+", layout model class name:"+layout.getModelClassName()+", scope:"+ResourceConstants.SCOPE_INDIVIDUAL
            +", primkey:"+String.valueOf(plid)+", roleid:"+customRoleId+", actionid:"+ ActionKeys.VIEW);

    Map<Long, String[]> roleIdsToActionIds = new HashMap<Long, String[]>();
    List<String> actionIds = new ArrayList<String>();
    actionIds.add(ActionKeys.VIEW);

    roleIdsToActionIds.put(customRoleId, actionIds.toArray(new String[actionIds.size()]));

    ResourcePermissionServiceUtil.setIndividualResourcePermissions(groupId, companyId, layout.getModelClassName(),
            String.valueOf(plid), roleIdsToActionIds);


    // TODO: give view permission to all its parent layouts as well
    while(layout.getParentLayoutId()!=0){
        layout = LayoutLocalServiceUtil.getParentLayout(layout);
        _log.info("Adding permission for parent layout: "+layout+", layout model class name:"+layout.getModelClassName()+", scope:"+ResourceConstants.SCOPE_INDIVIDUAL
                +", primkey:"+String.valueOf(layout.getPlid())+", roleid:"+customRoleId+", actionid:"+ ActionKeys.VIEW);

        ResourcePermissionServiceUtil.setIndividualResourcePermissions(groupId, companyId, layout.getModelClassName(),
                String.valueOf(layout.getPlid()), roleIdsToActionIds);
    }

    _log.debug("Added view permission for page of portlet:"+portletId);

    }   
} // Propagete VIEW access to Page, on which Portlet is added - END

Error log:

    ...


Adding permission for layout: {uuid=e3d30768-8025-494b-b651-aa12e34baa45, plid=100207, groupId=AAA, companyId=XXX, userId=20199, userName=Liferay Admin, createDate=Sat Jan 14 00:56:55 GMT 2017, modifiedDate=Sat Jan 14 00:58:48 GMT 2017, privateLayout=false, layoutId=89, parentLayoutId=30, name=<?xml version='1.0' encoding='UTF-8'?><root available-locales="en_US" default-locale="en_US"><Name language-id="en_US">Notifications</Name></root>, title=, description=, keywords=, robots=, type=portlet, typeSettings=column-1=XXX_WAR_YYY,
    column-2=XXXZZZ_WAR_XXXWWW
    layout-template-id=my_custom_layout
    , hidden=false, friendlyURL=/notifications, iconImage=false, iconImageId=0, themeId=, colorSchemeId=, wapThemeId=, wapColorSchemeId=, css=, priority=4, layoutPrototypeUuid=, layoutPrototypeLinkEnabled=false, sourcePrototypeLayoutUuid=}, layout model class name:com.liferay.portal.model.Layout, scope:4, primkey:100207, roleid:73933, actionid:VIEW
    02:01:14,465 INFO  [http-bio-443-exec-46][setupServiceImpl:955] layout.getParentLayoutId():30
    02:01:14,466 INFO  [http-bio-443-exec-46][setupServiceImpl:958] Adding permission for parent layout: {uuid=f7202f94-3660-426f-bd18-7e083668d5ac, plid=26752, groupId=AAA, companyId=XXX, userId=XXX, userName=XXX Admin, createDate=Thu Apr 14 15:59:06 GMT 2016, modifiedDate=Wed Dec 07 20:33:22 GMT 2016, privateLayout=false, layoutId=30, parentLayoutId=3, name=<?xml version='1.0' encoding='UTF-8'?><root available-locales="en_US" default-locale="en_US"><Name language-id="en_US">Users</Name></root>, title=, description=, keywords=, robots=, type=link_to_layout, typeSettings=column-1-customizable=false
    column-2-customizable=false
    groupId=AAA
    layout-template-id=my_custom_layout
    layoutUpdateable=true
    linkToLayoutId=31
    privateLayout=false
    sitemap-changefreq=daily
    sitemap-include=1
    , hidden=false, friendlyURL=/users, iconImage=false, iconImageId=0, themeId=classic, colorSchemeId=, wapThemeId=, wapColorSchemeId=, css=, priority=9, layoutPrototypeUuid=, layoutPrototypeLinkEnabled=false, sourcePrototypeLayoutUuid=}, layout model class name:com.liferay.portal.model.Layout, scope:4, primkey:26752, roleid:73933, actionid:VIEW
    java.lang.NullPointerException
            at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.doUpdateResourcePermission(ResourcePermissionLocalServiceImpl.java:1200)
            at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.doUpdateResourcePermission(ResourcePermissionLocalServiceImpl.java:1253)
            at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.updateResourcePermission(ResourcePermissionLocalServiceImpl.java:1407)
            at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.setResourcePermissions(ResourcePermissionLocalServiceImpl.java:1134)
            at sun.reflect.GeneratedMethodAccessor1164.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
            at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
            at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
            at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
            at com.sun.proxy.$Proxy152.setResourcePermissions(Unknown Source)
            at com.liferay.portal.service.impl.ResourcePermissionServiceImpl.setIndividualResourcePermissions(ResourcePermissionServiceImpl.java:238)
            at sun.reflect.GeneratedMethodAccessor1163.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
            at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
            at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
            at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
            at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
            at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
            at com.sun.proxy.$Proxy153.setIndividualResourcePermissions(Unknown Source)
            at com.liferay.portal.service.ResourcePermissionServiceUtil.setIndividualResourcePermissions(ResourcePermissionServiceUtil.java:245)
shuchi
  • 33
  • 9
  • What results does debugging throw?At what level does layout goes null,can you try loooping layout ids to check before setting in permissions? – Shivam Aggarwal Feb 03 '17 at 06:17
  • @shivam, I've added the loggers in code and updated the error log accordingly. – shuchi Feb 03 '17 at 18:33
  • as per my understanding, the problem here is that method setIndividualResourcePermissions of ResourcePermissionServiceUtil only does update of existing entries in resourcepermission table. so, if the permission entry for layout for that role does not already exists, then it fails with this exception. – shuchi Feb 03 '17 at 18:35

1 Answers1

1

So finally it looks like this API call has fixed my issue.

ResourcePermissionLocalServiceUtil.setResourcePermissions(
                                                companyId, Layout.class.getName(),
                                                ResourceConstants.SCOPE_INDIVIDUAL,
                                                String.valueOf(layout.getPlid()), customRoleId,
                                                new String[] {
                                                    ActionKeys.VIEW
                                                });

Before trying out this, I also tried below two other Liferay APIs without success.

ResourcePermissionLocalServiceUtil.setResourcePermissions(companyId, layout.getModelClassName(), ResourceConstants.SCOPE_INDIVIDUAL, String.valueOf(layout.getPlid()), roleIdsToActionIds);

and

ResourcePermissionServiceUtil.addResourcePermission(groupId, companyId, layout.getModelClassName(), ResourceConstants.SCOPE_INDIVIDUAL, String.valueOf(layout.getPlid()), customRoleId, ActionKeys.VIEW);

Both failed with exception.

java.lang.NullPointerException
    at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.doUpdateResourcePermission(ResourcePermissionLocalServiceImpl.java:1200)
    at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.doUpdateResourcePermission(ResourcePermissionLocalServiceImpl.java:1253)
    at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.updateResourcePermission(ResourcePermissionLocalServiceImpl.java:1407)
    at com.liferay.portal.service.impl.ResourcePermissionLocalServiceImpl.setResourcePermissions(ResourcePermissionLocalServiceImpl.java:1134)
shuchi
  • 33
  • 9
  • I found the same solution, but I'm thinking to how can we disable ( delete) a permission for VIEW Layout ( actually I can only add Ressource permission for a action Keys..) – wikimix Jul 10 '17 at 09:35
  • If you give empty ActionKeys, the permissions will get removed. new String[] {} – Vrishank Feb 10 '22 at 22:55