Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-58536

Pages not visible to groups in PageTree when permission is set via ContentPermissionManager class after an update

      Issue Summary

      After upgrading our instance to version 6.15.1 (from 6.8.1) some of our users reported missing page hierarchies in the tree of a single space. All restrictions are looking fine, and the affected users can access the missing pages using direct links. However, they cannot see them on the tree on the navigation panel even when opening the page from a direct link.

      Scope: we've set up a page tree and need to set the restrictions on page level individually. Because there's a lot of pages and branches the restriction handling must be achieved by API calls. Performance is an issue, so processing these restrictions needs to be fast.

      Approach: We are using the following method: https://docs.atlassian.com/ConfluenceServer/javadoc/6.15.6/com/atlassian/confluence/core/ContentPermissionManager.html#setContentPermissions-java.util.Map-com.atlassian.confluence.core.ContentEntityObject-

      Consider the following snippet:

      Page page = pageManager.getPage("SPACE", "Some Page Title");
      
      Set<ContentPermission> viewPermissions = new HashSet<ContentPermission>();
      Set<ContentPermission> editPermissions = new HashSet<ContentPermission>();
      
      editPermissions.add(ContentPermission.createGroupPermission(ContentPermission.EDIT_PERMISSION, "Group A"));
      viewPermissions.add(ContentPermission.createGroupPermission(ContentPermission.VIEW_PERMISSION, "Group C"));
      
      Map<String, Collection<ContentPermission>> permissionMap = new HashMap<String, Collection<ContentPermission>>();
      permissionMap.put(ContentPermission.EDIT_PERMISSION, editPermissions);
      permissionMap.put(ContentPermission.VIEW_PERMISSION, viewPermissions);
      
      contentPermissionManager.setContentPermissions(permissionMap, page);
      

      The pages show all restrictions in place as provided by the map, however, some users within some groups have issues seeing the pages on the Page Tree.
      As far as we can tell the issue is not related to a single space.

      Steps to Reproduce

      1. Install addon that handles the space structure and restrictions in v6.8.1
      2. Update Confluence to v6.15.1

      Expected Results

      The pages should be both visible to people in groups within the map provided to the method, as well as viewable and/or editable.

      Actual Results

      In some circumstances, users cannot see pages on the Page Tree. They are able to access the pages missing in the Page Tree by using a direct link, however.

      Notes

      • This is a follow up on a service desk issue with key CSP-248197. See information there for a more wide view on the issue and what has been tried to resolve the issue already.
      • In order to isolate the issue, the following were done
        • We installed Confluence Server 6.8.1 and installed our addon that handles the space structure and restrictions. The space was set up, restrictions put in place as described below, and users within the groups affected could see everything on their Page Tree.
        • Now I proceeded to uninstall the addon to remove any customization, so the testing environment turned back to a standard installation. Users could still see everything in the Page Tree.
        • Then I proceeded to upgrade the Confluence instance from 6.8.1 to
          6.15.1, and when the users checked in on the Page Tree, they found the pages missing. This leads to the conclusion that somewhere along the line of the upgrade process the permissions got messed up. And it looks like they can't be brought back to work by using the same API calls.

      Workaround

      Currently, there is no known workaround for this behavior. A workaround will be added here when available

            [CONFSERVER-58536] Pages not visible to groups in PageTree when permission is set via ContentPermissionManager class after an update

            I found a workaround:

            You can send a HTTP POST request to "{your_confluence_link}/pages/setcontentpermissions.action?contentId={pageId}&viewPermissionsUserList={username1_or_userkey1}&viewPermissionsUserList={username*_or_userkey*}&editPermissionsUserList={username_or_userkey}&viewPermissionsGroupList={groupname}&editPermissionsGroupList={groupname}"

            You can list multiple users/groups in one URL by listing them directly behind each other like "viewPermissionsUserList={username1_or_userkey1}&viewPermissionsUserList={username*_or_userkey*}"

            Rainier Klopper added a comment - I found a workaround: You can send a HTTP POST request to "{your_confluence_link}/pages/setcontentpermissions.action?contentId={pageId}&viewPermissionsUserList={username1_or_userkey1}&viewPermissionsUserList={username*_or_userkey*}&editPermissionsUserList={username_or_userkey}&viewPermissionsGroupList={groupname}&editPermissionsGroupList={groupname}" You can list multiple users/groups in one URL by listing them directly behind each other like "viewPermissionsUserList={username1_or_userkey1}&viewPermissionsUserList={username*_or_userkey*}"

            h_grote added a comment -

            @mjoshi

            Sadly there is no solution afaik. This is really frustrating as we are completely ignored by Atlassian for over a year now.

            h_grote added a comment - @mjoshi Sadly there is no solution afaik. This is really frustrating as we are completely ignored by Atlassian for over a year now.

            Do we have any workaround or reason for getting NullPointerException? Our case is similar as @masopust mentioned 

            contentPermissionManager.addContentPermission(editPermission, page); result in NullPointerException

            2020-11-25 16:44:19,348 ERROR [http-nio-8090-exec-8] [confluence.ddic.restservice.ConfluencePageAPI] editPermissionUserTree java.lang.NullPointerException
            at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.updateModificationData(HibernateObjectDao.java:218)
            at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.save(HibernateObjectDao.java:197)
            at com.atlassian.confluence.core.DefaultContentPermissionManager.doAddContentPermission(DefaultContentPermissionManager.java:297)
            at com.atlassian.confluence.core.DefaultContentPermissionManager.addContentPermission(DefaultContentPermissionManager.java:285)
            at jdk.internal.reflect.GeneratedMethodAccessor3356.invoke(Unknown Source)
            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

            Manoj Joshi added a comment - Do we have any workaround or reason for getting NullPointerException? Our case is similar as @masopust mentioned  contentPermissionManager.addContentPermission(editPermission, page); result in NullPointerException 2020-11-25 16:44:19,348 ERROR [http-nio-8090-exec-8] [confluence.ddic.restservice.ConfluencePageAPI] editPermissionUserTree java.lang.NullPointerException at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.updateModificationData(HibernateObjectDao.java:218) at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.save(HibernateObjectDao.java:197) at com.atlassian.confluence.core.DefaultContentPermissionManager.doAddContentPermission(DefaultContentPermissionManager.java:297) at com.atlassian.confluence.core.DefaultContentPermissionManager.addContentPermission(DefaultContentPermissionManager.java:285) at jdk.internal.reflect.GeneratedMethodAccessor3356.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

            jsherry added a comment -

            We are experiencing the same issue.  We are using the Comala Workflow plugin version 6.6.0.  With Confluence 6.15.10.  The Comala Workflow plugin has macros that modify the permissions/restrictions of a page on triggered events.  I believe this is causing or contributing to this issue in our case.  The modification of restrictions at given stages also makes the page show in the Page Tree (during some restriction modifications). 

             

            It may be worth noting that the pages are also not showing in the Reorder Pages feature of Confluence and don't show in the Comala Workflow Report Macro.  However, they do show in the Child Display macro as noted above.

            jsherry added a comment - We are experiencing the same issue.  We are using the Comala Workflow plugin version 6.6.0.  With Confluence 6.15.10.  The Comala Workflow plugin has macros that modify the permissions/restrictions of a page on triggered events.  I believe this is causing or contributing to this issue in our case.  The modification of restrictions at given stages also makes the page show in the Page Tree (during some restriction modifications).    It may be worth noting that the pages are also not showing in the Reorder Pages feature of Confluence and don't show in the Comala Workflow Report Macro.  However, they do show in the Child Display macro as noted above.

            masopust added a comment -

            Update:

             

            By sheer accident one of my users noticed that using the Child macro, all pages are displayed correctly. So apprently the issue lies somewhere within the PageTree macro?

            masopust added a comment - Update:   By sheer accident one of my users noticed that using the Child macro, all pages are displayed correctly. So apprently the issue lies somewhere within the PageTree macro?

            masopust added a comment -

            Update:

             

            I've went ahead and tested two alternative ways of setting permissions using the ContentPermissionManager interface.

             

            Alternative 1

            Basically the same as the snippet in the opening post, but instead of using one single map, we're using two calls for each view and edit:

            Set<ContentPermission> viewPermissions = new HashSet<ContentPermission>();
            Set<ContentPermission> editPermissions = new HashSet<ContentPermission>();
            
            editPermissions.add(ContentPermission.createGroupPermission(ContentPermission.EDIT_PERMISSION, "Group A"));
            viewPermissions.add(ContentPermission.createGroupPermission(ContentPermission.VIEW_PERMISSION, "Group C"));
            
            contentPermissionManager.setContentPermissions(viewPermissions, page, ContentPermission.VIEW_PERMISSION);
            contentPermissionManager.setContentPermissions(editPermissions, page, ContentPermission.EDIT_PERMISSION)  

            The result is unchanged, not all pages are showing up for affected groups.

            Alternative 2

            Using the following snippet:

            ConfluenceUser adminUser = ... //get user by some means
            Page page = ... //get Page object by some means
            
            ContentPermission viewPermission = ContentPermission.createGroupPermission(ContentPermission.VIEW_PERMISSION, "Group A");
            viewPermission.setCreator(adminUser);
            viewPermission.setCreationDate(new Date());
            viewPermission.setLastModificationDate(new Date());
            viewPermission.setLastModifier(adminUser);
            contentPermissionManager.addContentPermission(viewPermission, page); 

            This code runs into a NullPointerException which is kind of surprising because I cannot find the reason:

            java.lang.NullPointerException
            	at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.updateModificationData(HibernateObjectDao.java:222)
            	at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.save(HibernateObjectDao.java:201)
            	at com.atlassian.confluence.core.DefaultContentPermissionManager.doAddContentPermission(DefaultContentPermissionManager.java:329)
            	at com.atlassian.confluence.core.DefaultContentPermissionManager.addContentPermission(DefaultContentPermissionManager.java:317)
            	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            	at java.lang.reflect.Method.invoke(Method.java:498)
            	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
            	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
            	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
            	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
            	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
            	at com.sun.proxy.$Proxy194.addContentPermission(Unknown Source)
            	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            	at java.lang.reflect.Method.invoke(Method.java:498)
            	at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
            	at com.sun.proxy.$Proxy574.addContentPermission(Unknown Source)
            	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            	at java.lang.reflect.Method.invoke(Method.java:498)
            	at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:136)
            	at com.sun.proxy.$Proxy574.addContentPermission(Unknown Source)
            	at at.sk_versicherung.core.security.PageRestrictionsWorker.commitPermissionsPerPage(PageRestrictionsWorker.java:110) 

            I guess that's some entirely different problem, however this also means this workaround also doesn't help.

             

            Is there any other way of setting content permissions via Java API that I'm missing?

            masopust added a comment - Update:   I've went ahead and tested two alternative ways of setting permissions using the ContentPermissionManager interface.   Alternative 1 Basically the same as the snippet in the opening post, but instead of using one single map, we're using two calls for each view and edit: Set<ContentPermission> viewPermissions = new HashSet<ContentPermission>(); Set<ContentPermission> editPermissions = new HashSet<ContentPermission>(); editPermissions.add(ContentPermission.createGroupPermission(ContentPermission.EDIT_PERMISSION, "Group A" )); viewPermissions.add(ContentPermission.createGroupPermission(ContentPermission.VIEW_PERMISSION, "Group C" )); contentPermissionManager.setContentPermissions(viewPermissions, page, ContentPermission.VIEW_PERMISSION); contentPermissionManager.setContentPermissions(editPermissions, page, ContentPermission.EDIT_PERMISSION) The result is unchanged, not all pages are showing up for affected groups. Alternative 2 Using the following snippet: ConfluenceUser adminUser = ... //get user by some means Page page = ... //get Page object by some means ContentPermission viewPermission = ContentPermission.createGroupPermission(ContentPermission.VIEW_PERMISSION, "Group A" ); viewPermission.setCreator(adminUser); viewPermission.setCreationDate( new Date()); viewPermission.setLastModificationDate( new Date()); viewPermission.setLastModifier(adminUser); contentPermissionManager.addContentPermission(viewPermission, page); This code runs into a NullPointerException which is kind of surprising because I cannot find the reason: java.lang.NullPointerException at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.updateModificationData(HibernateObjectDao.java:222) at com.atlassian.confluence.core.persistence.hibernate.HibernateObjectDao.save(HibernateObjectDao.java:201) at com.atlassian.confluence.core.DefaultContentPermissionManager.doAddContentPermission(DefaultContentPermissionManager.java:329) at com.atlassian.confluence.core.DefaultContentPermissionManager.addContentPermission(DefaultContentPermissionManager.java:317) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy194.addContentPermission(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26) at com.sun.proxy.$Proxy574.addContentPermission(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:136) at com.sun.proxy.$Proxy574.addContentPermission(Unknown Source) at at.sk_versicherung.core.security.PageRestrictionsWorker.commitPermissionsPerPage(PageRestrictionsWorker.java:110) I guess that's some entirely different problem, however this also means this workaround also doesn't help.   Is there any other way of setting content permissions via Java API that I'm missing?

            masopust added a comment -

            Update:

            • We've proceeded to create a fresh install of 6.15.1, installed the addon and let the addon set up the space and permissions
            • The issue still remains on the fresh install
            • We also tested the behavior on an instance that was upgraded from 6.8.1, this time in a newly created space
            • The issue remains in the new space
            • Setting the permissions manually via the UI on an affected page makes the page visible in the tree until the addon starts its permission handling job again, after execution the pages are hidden from the tree again

            The addon uses Java API version 6.15.1.

            Our next step is to try different approaches when setting the permissions via the addon. I will report my findings once I got the results.

            masopust added a comment - Update: We've proceeded to create a fresh install of 6.15.1, installed the addon and let the addon set up the space and permissions The issue still remains on the fresh install We also tested the behavior on an instance that was upgraded from 6.8.1, this time in a newly created space The issue remains in the new space Setting the permissions manually via the UI on an affected page makes the page visible in the tree until the addon starts its permission handling job again, after execution the pages are hidden from the tree again The addon uses Java API version 6.15.1. Our next step is to try different approaches when setting the permissions via the addon. I will report my findings once I got the results.

              Unassigned Unassigned
              23880cf3f2c2 masopust
              Affected customers:
              10 This affects my team
              Watchers:
              12 Start watching this issue

                Created:
                Updated: