Uploaded image for project: 'Bitbucket Data Center'
  1. Bitbucket Data Center
  2. BSERV-11865

Initial attachments on pull requests cannot be seen by reviewers that have no access to source forked repository

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Low
    • 6.6.0
    • 5.16.0, 6.4.0
    • Pull Requests

    Description

      Issue Summary

      Attaching files on the initial submission of a pull request from a forked repository to the main repository, and then setting a reviewer that only has access to the main repository (and not the forked one), results in the reviewer not being able to see the attached files.

      Steps to Reproduce

      1. Create repository A in project 1
        • Grant access to repository A for a user
      2. Push an initial commit to repository A
      3. Create a forked repository B in project 1 off of repository A
        •  Do NOT grant access to repository B for the user mentioned in step 1
      4. In repository B, push up a second commit
      5. In repository B, go to 'Pull requests' and choose to create a new pull request.
        • Set Source to be Project1/RepositoryB > master
        • Set Destination to be Project1/RepositoryA > master
        • Add an attachment of any type to the description:
      6. Add the user mentioned in step 1 as a reviewer for the pull request
      7. Proceed with creating the pull request

      Expected Results

      The user mentioned in step 1 above is able to view and access the attached file with no issues.

      Actual Results

      The file is unable to be viewed or opened.

      • In the case of text files, the text is shown and looks clickable - but there is no actual hyperlink associated with the text.
      • In the case of images, they are not rendered at all.

      In addition, the following warning message is thrown within the atlassian-bitbucket.log file:

      2019-07-20 02:58:27,999 WARN  [http-nio-7990-exec-12] bcrusher @15A9NR1x178x14754x0 1n9td3f 192.168.5.1,192.168.5.2 "GET /projects/PROJB/repos/test-attachment/pull-requests/1/overview HTTP/1.1" c.a.s.i.m.r.MarkupRendererImpl com.atlassian.bitbucket.server.bitbucket-markup-renderers:attachmentMarkupRenderer failed to transform markup due to an unexpected exception. Skipping transformation.
      com.atlassian.bitbucket.AuthorisationException: You are not permitted to access this resource
              at com.atlassian.stash.internal.aop.ExceptionRewriteAdvice.afterThrowing(ExceptionRewriteAdvice.java:37)
              at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
              at com.atlassian.stash.internal.web.markup.AttachmentMarkupRenderer.process(AttachmentMarkupRenderer.java:48)
              at com.atlassian.stash.internal.markup.renderer.MarkupRendererImpl.lambda$transform$0(MarkupRendererImpl.java:67)
              at com.google.common.collect.Iterators$6.transform(Iterators.java:785)
              at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
              at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
              at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
              at com.google.common.collect.Iterators$ConcatenatedIterator.hasNext(Iterators.java:1332)
              at com.google.common.collect.Iterators.addAll(Iterators.java:357)
              at com.google.common.collect.Lists.newArrayList(Lists.java:147)
              at com.google.common.collect.Iterables.castOrCopyToCollection(Iterables.java:306)
              at com.google.common.collect.Iterables.toArray(Iterables.java:295)
              at com.google.common.collect.Ordering.sortedCopy(Ordering.java:851)
              at com.atlassian.stash.internal.markup.renderer.TransformUtils.getReplacements(TransformUtils.java:83)
              at com.atlassian.stash.internal.markup.renderer.TransformUtils.tokenReplace(TransformUtils.java:56)
              at com.atlassian.stash.internal.markup.renderer.MarkupRendererImpl.transform(MarkupRendererImpl.java:65)
              at com.atlassian.stash.internal.markup.renderer.MarkupRendererImpl.renderReplace(MarkupRendererImpl.java:59)
              at com.atlassian.stash.internal.markup.renderer.MarkupRendererImpl.render(MarkupRendererImpl.java:38)
              at com.atlassian.stash.internal.markup.DefaultMarkupService.render(DefaultMarkupService.java:73)
              at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
              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.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.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
              at com.atlassian.stash.internal.rest.enrich.DefaultMarkupEnricher.render(DefaultMarkupEnricher.java:61)
              at com.atlassian.stash.internal.rest.enrich.DefaultMarkupEnricher.access$100(DefaultMarkupEnricher.java:16)
              at com.atlassian.stash.internal.rest.enrich.DefaultMarkupEnricher$1.apply(DefaultMarkupEnricher.java:37)
              at com.atlassian.bitbucket.rest.util.RestUtils.processEntities(RestUtils.java:285)
              at com.atlassian.stash.internal.rest.enrich.DefaultMarkupEnricher.enrich(DefaultMarkupEnricher.java:29)
              at com.atlassian.stash.internal.rest.renderer.BaseSurrogateJsonRenderer.enrich(BaseSurrogateJsonRenderer.java:91)
              at com.atlassian.stash.internal.rest.renderer.BaseSurrogateJsonRenderer.render(BaseSurrogateJsonRenderer.java:61)
              at com.atlassian.stash.internal.json.PluginJsonRenderer.render(PluginJsonRenderer.java:45)
              at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
              at com.atlassian.stash.internal.web.soy.functions.ToJsonFunction.apply(ToJsonFunction.java:51)
              at com.atlassian.stash.internal.web.soy.functions.ToJsonFunction.apply(ToJsonFunction.java:14)
              at com.atlassian.soy.impl.modules.SoyJavaFunctionAdapter.computeForJava(SoyJavaFunctionAdapter.java:34)
              at com.atlassian.soy.impl.modules.CompositeFunctionAdaptor.computeForJava(CompositeFunctionAdaptor.java:38)
              at com.google.template.soy.sharedpasses.render.EvalVisitor.computeFunctionHelper(EvalVisitor.java:670)
              at com.google.template.soy.sharedpasses.render.EvalVisitor.visitFunctionNode(EvalVisitor.java:653)
              at com.google.template.soy.sharedpasses.render.EvalVisitor.visitFunctionNode(EvalVisitor.java:87)
              at com.google.template.soy.exprtree.AbstractReturningExprNodeVisitor.visit(AbstractReturningExprNodeVisitor.java:118)
              at com.google.template.soy.sharedpasses.render.EvalVisitor.visitExprRootNode(EvalVisitor.java:148)
              at com.google.template.soy.sharedpasses.render.EvalVisitor.visitExprRootNode(EvalVisitor.java:87)
              at com.google.template.soy.exprtree.AbstractReturningExprNodeVisitor.visit(AbstractReturningExprNodeVisitor.java:81)
              at com.google.template.soy.exprtree.AbstractReturningExprNodeVisitor.visit(AbstractReturningExprNodeVisitor.java:73)
              at com.google.template.soy.basetree.AbstractReturningNodeVisitor.exec(AbstractReturningNodeVisitor.java:43)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.eval(RenderVisitor.java:739)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitPrintNode(RenderVisitor.java:248)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:87)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:56)
              at com.google.template.soy.basetree.AbstractNodeVisitor.visitChildren(AbstractNodeVisitor.java:59)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visitChildren(AbstractSoyNodeVisitor.java:129)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitBlockHelper(RenderVisitor.java:702)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.renderBlock(RenderVisitor.java:716)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitCallNodeHelper(RenderVisitor.java:564)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitCallBasicNode(RenderVisitor.java:457)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:110)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:56)
              at com.google.template.soy.basetree.AbstractNodeVisitor.visitChildren(AbstractNodeVisitor.java:59)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visitChildren(AbstractSoyNodeVisitor.java:129)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitBlockHelper(RenderVisitor.java:698)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitTemplateNode(RenderVisitor.java:220)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visitTemplateBasicNode(AbstractSoyNodeVisitor.java:160)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:66)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:56)
              at com.google.template.soy.basetree.AbstractNodeVisitor.exec(AbstractNodeVisitor.java:40)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitCallNodeHelper(RenderVisitor.java:590)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitCallBasicNode(RenderVisitor.java:457)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:110)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:56)
              at com.google.template.soy.basetree.AbstractNodeVisitor.visitChildren(AbstractNodeVisitor.java:59)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visitChildren(AbstractSoyNodeVisitor.java:129)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitBlockHelper(RenderVisitor.java:702)
              at com.google.template.soy.sharedpasses.render.RenderVisitor.visitTemplateNode(RenderVisitor.java:220)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visitTemplateBasicNode(AbstractSoyNodeVisitor.java:160)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:66)
              at com.google.template.soy.soytree.AbstractSoyNodeVisitor.visit(AbstractSoyNodeVisitor.java:56)
              at com.google.template.soy.basetree.AbstractNodeVisitor.exec(AbstractNodeVisitor.java:40)
              at com.google.template.soy.tofu.internal.BaseTofu.renderMainHelper(BaseTofu.java:366)
              at com.google.template.soy.tofu.internal.BaseTofu.renderMain(BaseTofu.java:322)
              at com.google.template.soy.tofu.internal.BaseTofu.access$100(BaseTofu.java:66)
              at com.google.template.soy.tofu.internal.BaseTofu$RendererImpl.render(BaseTofu.java:476)
              at com.atlassian.soy.impl.DefaultSoyManager.render(DefaultSoyManager.java:154)
              at com.atlassian.soy.impl.DefaultSoyTemplateRenderer.render(DefaultSoyTemplateRenderer.java:45)
              at com.atlassian.stash.internal.plugin.OsgiServiceProxyFactoryImpl$DynamicServiceInvocationHandler.invoke(OsgiServiceProxyFactoryImpl.java:105)
              at com.atlassian.soy.springmvc.SoyView.render(SoyView.java:50)
              at com.atlassian.stash.internal.web.soy.StashSoyViewResolver$1.render(StashSoyViewResolver.java:34)
              at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
              at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
              at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
              at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
              at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
              at com.atlassian.bitbucket.internal.importer.web.RepositoryImportFilter.doFilter(RepositoryImportFilter.java:64)
              at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
              at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
              at com.atlassian.stash.internal.spring.security.StashAuthenticationFilter.doFilter(StashAuthenticationFilter.java:85)
              at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doInsideSpringSecurityChain(BeforeLoginPluginAuthenticationFilter.java:112)
              at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doFilter(BeforeLoginPluginAuthenticationFilter.java:75)
              at com.atlassian.security.auth.trustedapps.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:94)
              at com.atlassian.oauth.serviceprovider.internal.servlet.OAuthFilter.doFilter(OAuthFilter.java:67)
              at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
              at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
              at com.atlassian.security.auth.trustedapps.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:94)
              at com.atlassian.oauth.serviceprovider.internal.servlet.OAuthFilter.doFilter(OAuthFilter.java:67)
              at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
              at com.atlassian.plugin.connect.plugin.auth.oauth2.DefaultSalAuthenticationFilter.doFilter(DefaultSalAuthenticationFilter.java:69)
              at com.atlassian.plugin.connect.plugin.auth.user.ThreeLeggedAuthFilter.doFilter(ThreeLeggedAuthFilter.java:109)
              at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:37)
              at com.atlassian.analytics.client.filter.DefaultAnalyticsFilter.doFilter(DefaultAnalyticsFilter.java:38)
              at com.atlassian.analytics.client.filter.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:39)
              at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
              at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doBeforeBeforeLoginFilters(BeforeLoginPluginAuthenticationFilter.java:90)
              at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doFilter(BeforeLoginPluginAuthenticationFilter.java:73)
              at com.atlassian.stash.internal.request.DefaultRequestManager.doAsRequest(DefaultRequestManager.java:87)
              at com.atlassian.stash.internal.hazelcast.ConfigurableWebFilter.doFilter(ConfigurableWebFilter.java:38)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
              at java.lang.Thread.run(Thread.java:748)
              ... 334 frames trimmed
      Caused by: org.springframework.security.access.AccessDeniedException: Access is denied
              at org.springframework.security.access.expression.method.ExpressionBasedPostInvocationAdvice.after(ExpressionBasedPostInvocationAdvice.java:77)
              ... 119 common frames omitted
      

      Notes

      Files attached in any subsequent comments have no permissions issues, and can be viewed as expected. This is presumably because they are associated with the main repository, and not the forked one.

      All other aspects of the pull request, such as the commit data and so on, all render without issue for the reviewer that only has access to the main/destination repository.

       In step 5 above, if you create the pull request by navigating to Pull Requests from Repository A, and not Repository B - the issue does not occur.

      Workaround

      The creator of the pull request that has access to both repositories will need to do one of the following options:

      • Remove and add the attachment in the pull request.
      • Allow the reviewer to have read access to the source forked repository
      • Create the pull request by navigating to the 'Pull Requests' section of the main repository, and not the forked repository

      Attachments

        Issue Links

          Activity

            People

              khughes@atlassian.com Kristy
              eslaughter@atlassian.com Evan Slaughter
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: