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

Favourite Pages Macro queries all available labels and causes inefficient permission checks

XMLWordPrintable

      Issue Summary

      Apart from displaying all favourited (Saved for Later) pages, the Favourite Pages Macro will display all pages that have been labelled with "favourite".
      If an anonymous user visits a page with the Favourite Pages Macro, the macro will trigger a query to all favourite pages and check permissions on all pages.

      Fixed in 9.2.10

      Steps to Reproduce

      1. Assuming several hundred pages have been labelled with the "favourite" label
      2. Create a page with the "Favourite Pages Macro"
      3. Visit the page with the Favourite Pages Macro as an anonymous user

      Expected Results

      The "Favourite Pages Macro" displays normally, and pagination is applied in the background to accommodate a large number of favourite pages.

      Actual Results

      The "Favourite Pages Macro" tries to query all favourite pages, checks their permissions, and only limits the results at the very end.

      FavouritePagesMacro.java & favpages.vm
      contents.addAll(labelManager.getContentForLabel(LabelManagerInternal.NO_OFFSET, LabelManagerInternal.NO_MAX_RESULTS, label).getList()); 
      ...
      contents = permissionManager.getPermittedEntities(AuthenticatedUserThreadLocal.get(), Permission.VIEW, contents);
      ...
      #set ($contentSublist = $generalUtil.safeSubList($contents, $maxResults))
      

      There is a high chance of stuck threads building up, such as the one below:

      "http-nio-8090-exec-120 url: /pages/viewpage.action" #30615 [426048] daemon prio=5 os_prio=0 cpu=449066.11ms elapsed=54782.61s tid=0x00007f4380344e80 nid=426048 runnable  [0x00007f42374f1000]
         java.lang.Thread.State: RUNNABLE
      	at org.hibernate.internal.util.collections.IdentityMap.get(IdentityMap.java:104)
      	at org.hibernate.engine.internal.StatefulPersistenceContext.getCollectionEntry(StatefulPersistenceContext.java:484)
      	at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:151)
      	at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:53)
      	at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
      	at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
      	at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
      	at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:187)
      	at org.hibernate.event.internal.AbstractFlushingEventListener$$Lambda/0x00007f444a26ed58.accept(Unknown Source)
      	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
      	at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:229)
      	at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93)
      	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50)
      	at org.hibernate.internal.SessionImpl$$Lambda/0x00007f4449bcfb78.accept(Unknown Source)
      	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
      	at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1372)
      	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1452)
      	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
      	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
      	at com.atlassian.confluence.security.persistence.dao.hibernate.HibernateContentPermissionSetDao.lambda$getInheritedContentPermissionSets$2(HibernateContentPermissionSetDao.java:133)
      	at com.atlassian.confluence.security.persistence.dao.hibernate.HibernateContentPermissionSetDao$$Lambda/0x00007f444bd1fdc0.doInHibernate(Unknown Source)
      	at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:366)
      	at org.springframework.orm.hibernate5.HibernateTemplate.execute(HibernateTemplate.java:319)
      	at com.atlassian.confluence.security.persistence.dao.hibernate.HibernateContentPermissionSetDao.getInheritedContentPermissionSets(HibernateContentPermissionSetDao.java:104)
      	at com.atlassian.confluence.core.DefaultInheritedContentPermissionManager.getInheritedContentPermissionSets(DefaultInheritedContentPermissionManager.java:44)
      	at com.atlassian.confluence.core.DefaultInheritedContentPermissionManager.getInheritedContentPermissionSetsIncludeEdit(DefaultInheritedContentPermissionManager.java:37)
      	at com.atlassian.confluence.impl.security.CachingInheritedContentPermissionManager.lambda$getInheritedContentPermissionSets$2(CachingInheritedContentPermissionManager.java:96)
      	at com.atlassian.confluence.impl.security.CachingInheritedContentPermissionManager$$Lambda/0x00007f444bce73e0.get(Unknown Source)
      	at com.atlassian.confluence.impl.security.ContentPermissionSetCache.lambda$getOrLoad$0(ContentPermissionSetCache.java:41)
      	at com.atlassian.confluence.impl.security.ContentPermissionSetCache$$Lambda/0x00007f444bce77e8.get(Unknown Source)
      	at com.atlassian.confluence.cache.CacheOperations.lambda$get$0(CacheOperations.java:172)
      	at com.atlassian.confluence.cache.CacheOperations$$Lambda/0x00007f4449bc9d80.apply(Unknown Source)
      	at java.util.HashMap.computeIfAbsent(java.base@21.0.7/HashMap.java:1228)
      	at com.atlassian.confluence.cache.CacheOperations.get(CacheOperations.java:172)
      	at com.atlassian.confluence.cache.DeferredOperationsCache.getOrLoad(DeferredOperationsCache.java:92)
      	at com.atlassian.confluence.cache.DeferredOperationsCache.get(DeferredOperationsCache.java:56)
      	at com.atlassian.confluence.cache.TransactionalCacheFactory$TransactionalCache.get(TransactionalCacheFactory.java:327)
      	at com.atlassian.confluence.impl.cache.tx.TransactionAwareCache$1.get(TransactionAwareCache.java:43)
      	at com.atlassian.confluence.impl.security.ContentPermissionSetCache.getOrLoad(ContentPermissionSetCache.java:39)
      	at com.atlassian.confluence.impl.security.CachingInheritedContentPermissionManager.getInheritedContentPermissionSets(CachingInheritedContentPermissionManager.java:96)
      	at com.atlassian.confluence.impl.security.CachingInheritedContentPermissionManager.getInheritedContentPermissionSetsIncludeEdit(CachingInheritedContentPermissionManager.java:87)
      	at com.atlassian.confluence.core.DefaultContentPermissionManager.getInheritedContentPermissionSets(DefaultContentPermissionManager.java:175)
      	at com.atlassian.confluence.core.DefaultContentPermissionManager.hasInheritedContentLevelViewPermissions(DefaultContentPermissionManager.java:310)
      	at com.atlassian.confluence.core.DefaultContentPermissionManager.hasContentLevelPermission(DefaultContentPermissionManager.java:212)
      	at java.lang.invoke.LambdaForm$DMH/0x00007f444bcd4000.invokeInterface(java.base@21.0.7/LambdaForm$DMH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f444bfb4800.invoke(java.base@21.0.7/LambdaForm$MH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4448004800.invokeExact_MT(java.base@21.0.7/LambdaForm$MH)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.7/DirectMethodHandleAccessor.java:156)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.7/DirectMethodHandleAccessor.java:103)
      	at java.lang.reflect.Method.invoke(java.base@21.0.7/Method.java:580)
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
      	at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda/0x00007f4449a1c3c8.proceedWithInvocation(Unknown Source)
      	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
      	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
      	at jdk.proxy4.$Proxy250.hasContentLevelPermission(jdk.proxy4/Unknown Source)
      	at com.atlassian.confluence.security.delegate.PagePermissionsDelegate.hasContentLevelViewPermission(PagePermissionsDelegate.java:132)
      	at com.atlassian.confluence.security.delegate.PagePermissionsDelegate.canView(PagePermissionsDelegate.java:24)
      	at com.atlassian.confluence.security.delegate.PagePermissionsDelegate.canView(PagePermissionsDelegate.java:13)
      	at com.atlassian.confluence.security.delegate.TargetToLatestVersionDecorator.canView(TargetToLatestVersionDecorator.java:24)
      	at com.atlassian.confluence.security.delegate.SharedAccessInterceptor$$Lambda/0x00007f444bcd9060.test(Unknown Source)
      	at com.atlassian.confluence.security.delegate.SharedAccessInterceptor.checkAccess(SharedAccessInterceptor.java:88)
      	at com.atlassian.confluence.security.delegate.SharedAccessInterceptor.canView(SharedAccessInterceptor.java:26)
      	at com.atlassian.confluence.security.Permission$1.checkAgainst(Permission.java:19)
      	at com.atlassian.confluence.security.DefaultPermissionManager.hasPermissionNoExemptions(DefaultPermissionManager.java:116)
      	at com.atlassian.confluence.security.DefaultPermissionManager.hasPermission(DefaultPermissionManager.java:57)
      	at com.atlassian.confluence.security.DefaultPermissionManager.getPermittedEntities(DefaultPermissionManager.java:177)
      	at java.lang.invoke.LambdaForm$DMH/0x00007f4449590000.invokeInterface(java.base@21.0.7/LambdaForm$DMH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4449739400.invoke(java.base@21.0.7/LambdaForm$MH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4448004800.invokeExact_MT(java.base@21.0.7/LambdaForm$MH)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.7/DirectMethodHandleAccessor.java:156)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.7/DirectMethodHandleAccessor.java:103)
      	at java.lang.reflect.Method.invoke(java.base@21.0.7/Method.java:580)
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
      	at com.atlassian.spring.interceptors.SpringProfilingInterceptor.invoke(SpringProfilingInterceptor.java:16)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
      	at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda/0x00007f4449a1c3c8.proceedWithInvocation(Unknown Source)
      	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
      	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
      	at jdk.proxy4.$Proxy240.getPermittedEntities(jdk.proxy4/Unknown Source)
      	at java.lang.invoke.LambdaForm$DMH/0x00007f4449590000.invokeInterface(java.base@21.0.7/LambdaForm$DMH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4449739400.invoke(java.base@21.0.7/LambdaForm$MH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4448004800.invokeExact_MT(java.base@21.0.7/LambdaForm$MH)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.7/DirectMethodHandleAccessor.java:156)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.7/DirectMethodHandleAccessor.java:103)
      	at java.lang.reflect.Method.invoke(java.base@21.0.7/Method.java:580)
      	at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
      	at jdk.proxy4.$Proxy375.getPermittedEntities(jdk.proxy4/Unknown Source)
      	at java.lang.invoke.LambdaForm$DMH/0x00007f4449590000.invokeInterface(java.base@21.0.7/LambdaForm$DMH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4449739400.invoke(java.base@21.0.7/LambdaForm$MH)
      	at java.lang.invoke.LambdaForm$MH/0x00007f4448004800.invokeExact_MT(java.base@21.0.7/LambdaForm$MH)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.base@21.0.7/DirectMethodHandleAccessor.java:156)
      	at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.base@21.0.7/DirectMethodHandleAccessor.java:103)
      	at java.lang.reflect.Method.invoke(java.base@21.0.7/Method.java:580)
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
      	at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
      	at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      	at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:70)
      	at org.eclipse.gemini.blueprint.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:53)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      	at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137)
      	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
      	at jdk.proxy10.$Proxy1017.getPermittedEntities(jdk.proxy10/Unknown Source)
      	at com.atlassian.confluence.plugins.macros.advanced.FavouritePagesMacro.execute(FavouritePagesMacro.java:68)
      	at com.atlassian.renderer.v2.macro.ResourceAwareMacroDecorator.execute(ResourceAwareMacroDecorator.java:51)
      	at com.atlassian.confluence.macro.V2CompatibilityMacro.execute(V2CompatibilityMacro.java:35)
      	at com.atlassian.confluence.macro.LazyLoadingMacroWrapper.execute(LazyLoadingMacroWrapper.java:27)
      	at com.atlassian.confluence.content.render.xhtml.view.macro.ViewMacroMarshaller.executeMacro(ViewMacroMarshaller.java:244)
      	at com.atlassian.confluence.content.render.xhtml.view.macro.ViewMacroMarshaller.marshalInternal(ViewMacroMarshaller.java:159)
      	at com.atlassian.confluence.content.render.xhtml.view.macro.ViewMacroMarshaller.lambda$marshal$0(ViewMacroMarshaller.java:116)
      	at com.atlassian.confluence.content.render.xhtml.view.macro.ViewMacroMarshaller$$Lambda/0x00007f444be6cfc8.marshal(Unknown Source)
      	at com.atlassian.confluence.impl.content.render.xhtml.analytics.MetricsCollectingMarshaller.marshal(MetricsCollectingMarshaller.java:49)
      	at com.atlassian.confluence.content.render.xhtml.view.macro.ViewMacroMarshaller.marshal(ViewMacroMarshaller.java:120)
      	at com.atlassian.confluence.content.render.xhtml.view.macro.ViewMacroMarshaller.marshal(ViewMacroMarshaller.java:52)
      	at com.atlassian.confluence.content.render.xhtml.UnmarshalMarshalFragmentTransformer.transform(UnmarshalMarshalFragmentTransformer.java:29)
      	at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer.transformFragment(DefaultFragmentTransformer.java:141)
      	at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer.transform(DefaultFragmentTransformer.java:123)
      	at com.atlassian.confluence.content.render.xhtml.view.ViewTableWrappingFragmentTransformer.transform(ViewTableWrappingFragmentTransformer.java:62)
      	at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer.transformFragment(DefaultFragmentTransformer.java:141)
      	at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer.transform(DefaultFragmentTransformer.java:123)
      	at com.atlassian.confluence.content.render.xhtml.storage.StorageXhtmlTransformer.transform(StorageXhtmlTransformer.java:41)
      	at com.atlassian.confluence.content.render.xhtml.TransformerChain.transform(TransformerChain.java:38)
      	at com.atlassian.confluence.content.render.xhtml.TransformerChain.transform(TransformerChain.java:38)
      	at com.atlassian.confluence.content.render.xhtml.PluggableTransformerChain.transform(PluggableTransformerChain.java:42)
      	at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.renderWithoutMetrics(DefaultRenderer.java:190)
      	at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.renderWithResult(DefaultRenderer.java:151)
      	at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.render(DefaultRenderer.java:135)
      	at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.render(DefaultRenderer.java:118)
      	at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.render(DefaultRenderer.java:112)
      	at com.atlassian.confluence.content.render.xhtml.DeviceTypeAwareRenderer.render(DeviceTypeAwareRenderer.java:43)
      	at com.atlassian.confluence.pages.actions.ViewPageAction.execute(ViewPageAction.java:208)
      

      Workaround

      Temporarily replace "Favourite Pages Macro with the "List Labels Macro" as the "List Labels Macro" has a pagination service that would avoid querying all pages at once.

              d5dce7b13926 agawron
              jwaihou Jonathan Soo
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: