[MNT-25862] Fix AccessDeniedException for generating share url (#4358)

This commit is contained in:
tathagta15
2026-09-07 10:19:34 +05:30
committed by GitHub
parent e5bcdcf7b6
commit 72cd0b49e1
3 changed files with 105 additions and 1 deletions
@@ -658,7 +658,14 @@ public class TemplateNode extends BasePermissionsNode implements NamespacePrefix
// TODO URLs for the repo server.
// TODO URLs for folders
String siteShortName = services.getSiteService().getSiteShortName(getNodeRef());
// Run site lookup as system to avoid parent-folder permission issues.
String siteShortName = AuthenticationUtil.runAsSystem(new RunAsWork<>() {
@Override
public String doWork() throws Exception
{
return services.getSiteService().getSiteShortName(getNodeRef());
}
});
String baseUrl = UrlUtil.getShareUrl(services.getSysAdminParams());
@@ -679,6 +686,7 @@ public class TemplateNode extends BasePermissionsNode implements NamespacePrefix
// ------------------------------------------------------------------------------
// Inner classes
@Override
public NamespacePrefixResolver getNamespacePrefixResolver()
{
return this.services.getNamespaceService();
@@ -59,6 +59,7 @@ import org.alfresco.util.testing.category.NonBuildTests;
org.alfresco.repo.oauth1.OAuth1CredentialsStoreServiceTest.class,
org.alfresco.repo.oauth2.OAuth2CredentialsStoreServiceTest.class,
org.alfresco.repo.template.TemplateServiceImplTest.class,
org.alfresco.repo.template.TemplateNodeTest.class,
org.alfresco.repo.tenant.MultiTServiceImplTest.class,
org.alfresco.repo.search.SearcherComponentTest.class,
org.alfresco.repo.blog.BlogServiceImplTest.class,
@@ -0,0 +1,95 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2026 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.template;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.transaction.annotation.Transactional;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.test_category.BaseSpringTestsCategory;
import org.alfresco.util.BaseAlfrescoSpringTest;
import org.alfresco.util.GUID;
/**
* Test for {@link TemplateNode#getShareUrl()}.
* <p>
* A user with access to a child folder only (not its parent) must still be able to resolve a share URL for a node in that child folder, e.g. from a 'Send email' rule template.
*/
@Category(BaseSpringTestsCategory.class)
@Transactional
public class TemplateNodeTest extends BaseAlfrescoSpringTest
{
private PermissionService permissionService;
private ServiceRegistry serviceRegistry;
@Before
public void before() throws Exception
{
super.before();
this.permissionService = (PermissionService) this.applicationContext.getBean("permissionService");
this.serviceRegistry = (ServiceRegistry) this.applicationContext.getBean("ServiceRegistry");
}
@Test
public void testGetShareUrlWhenUserCannotReadParentFolder() throws Exception
{
String userName = "templateNodeTestUser" + GUID.generate();
createUser(userName);
// F1: not readable by userName
NodeRef f1 = createNode(this.rootNodeRef, "f1", ContentModel.TYPE_FOLDER);
this.permissionService.setInheritParentPermissions(f1, false);
// F2: userName only has access here, not on the parent F1
NodeRef f2 = createNode(f1, "f2", ContentModel.TYPE_FOLDER);
this.permissionService.setInheritParentPermissions(f2, false);
this.permissionService.setPermission(f2, userName, PermissionService.CONTRIBUTOR, true);
String shareUrl = AuthenticationUtil.runAs(() -> {
NodeRef doc = createNode(f2, "doc.txt", ContentModel.TYPE_CONTENT);
TemplateNode templateNode = new TemplateNode(doc, this.serviceRegistry, null);
try
{
return templateNode.getShareUrl();
}
catch (Exception e)
{
fail("getShareUrl() should not fail for a user without read access to a parent folder: " + e);
return null;
}
}, userName);
assertNotNull(shareUrl);
assertTrue(shareUrl.contains("document-details?nodeRef="));
}
}