Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
4f482ebad1 Bump commons-net:commons-net from 3.11.1 to 3.12.0
Bumps [commons-net:commons-net](https://github.com/apache/commons-net) from 3.11.1 to 3.12.0.
- [Changelog](https://github.com/apache/commons-net/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/apache/commons-net/compare/rel/commons-net-3.11.1...rel/commons-net-3.12.0)

---
updated-dependencies:
- dependency-name: commons-net:commons-net
  dependency-version: 3.12.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 22:22:43 +00:00
95 changed files with 270 additions and 1977 deletions

View File

@@ -38,7 +38,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
@@ -61,7 +61,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -84,7 +84,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -104,7 +104,7 @@ jobs:
mkdir temp-dir-for-sast
bash ./scripts/ci/remove-sast-exclusions.sh ./packaging/war/target/alfresco.war temp-dir-for-sast/reduced.war
- name: "Run SAST Scan"
uses: veracode/Veracode-pipeline-scan-action@v1.0.20
uses: veracode/Veracode-pipeline-scan-action@v1.0.16
with:
vid: ${{ secrets.VERACODE_API_ID }}
vkey: ${{ secrets.VERACODE_API_KEY }}
@@ -173,7 +173,7 @@ jobs:
testModule: mmt
testAttributes: "-Dtest=AllMmtUnitTestSuite"
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -210,7 +210,7 @@ jobs:
env:
REQUIRES_INSTALLED_ARTIFACTS: true
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -245,7 +245,7 @@ jobs:
matrix:
version: ['10.5', '10.6']
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -272,7 +272,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -299,7 +299,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -325,7 +325,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -351,7 +351,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -377,7 +377,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -401,7 +401,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -457,7 +457,7 @@ jobs:
disabledHostnameVerification: false
mvn-options: '-Dencryption.ssl.keystore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.keystore -Dencryption.ssl.truststore.location=${CI_WORKSPACE}/keystores/alfresco/alfresco.truststore'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -527,7 +527,7 @@ jobs:
env:
REQUIRES_LOCAL_IMAGES: true
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -566,7 +566,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -596,7 +596,7 @@ jobs:
env:
REQUIRES_INSTALLED_ARTIFACTS: true
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -628,7 +628,7 @@ jobs:
env:
REQUIRES_INSTALLED_ARTIFACTS: true
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -656,7 +656,7 @@ jobs:
env:
REQUIRES_LOCAL_IMAGES: true
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
@@ -702,7 +702,7 @@ jobs:
!contains(github.event.head_commit.message, '[skip tests]') &&
!contains(github.event.head_commit.message, '[force]')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1

View File

@@ -31,7 +31,7 @@ jobs:
!contains(github.event.head_commit.message, '[no release]') &&
github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
@@ -60,7 +60,7 @@ jobs:
!contains(github.event.head_commit.message, '[no downstream]') &&
github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
if: contains(github.event.head_commit.message, '[reformat code]')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:

View File

@@ -1242,7 +1242,7 @@
"filename": "repository/src/main/resources/alfresco/repository.properties",
"hashed_secret": "1459a56410378e4d3ab470eff570e5eae1742762",
"is_verified": false,
"line_number": 314,
"line_number": 312,
"is_secret": false
},
{
@@ -1250,7 +1250,7 @@
"filename": "repository/src/main/resources/alfresco/repository.properties",
"hashed_secret": "84551ae5442affc9f1a2d3b4c86ae8b24860149d",
"is_verified": false,
"line_number": 773,
"line_number": 771,
"is_secret": false
}
],
@@ -1845,5 +1845,5 @@
}
]
},
"generated_at": "2025-07-23T08:25:11Z"
"generated_at": "2025-06-09T16:43:14Z"
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<build>

View File

@@ -43,7 +43,7 @@ import com.github.dockerjava.core.command.LogContainerResultCallback;
import com.github.dockerjava.netty.NettyDockerCmdExecFactory;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -37,7 +37,7 @@ import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPr
import java.util.Collections;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
@@ -56,7 +56,7 @@ import org.alfresco.test.AlfrescoTest;
/**
* Add Relationship tests
*
*
* @author Kavit Shah
*/
public class AddRelationshipTests extends BaseRMRestTest

View File

@@ -45,7 +45,7 @@ import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -15,13 +15,6 @@
<parameter property="end" jdbcType="BIGINT" javaType="java.lang.Long"/>
</parameterMap>
<parameterMap id="parameter_NodeIdsWhichReferenceContentUrl" type="map">
<parameter property="contentUrlShort" jdbcType="VARCHAR" javaType="java.lang.String"/>
<parameter property="contentUrlCrc" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="localName" jdbcType="VARCHAR" javaType="java.lang.String"/>
<parameter property="uri" jdbcType="VARCHAR" javaType="java.lang.String"/>
</parameterMap>
<resultMap id="result_NodeRefEntity" type="org.alfresco.module.org_alfresco_module_rm.query.NodeRefEntity">
<result property="row" column="row" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="protocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
@@ -62,21 +55,18 @@
<!-- Get list of node ids which reference given content url -->
<select id="select_NodeIdsWhichReferenceContentUrl"
parameterMap="parameter_NodeIdsWhichReferenceContentUrl"
parameterType="ContentUrl"
resultMap="result_NodeIds">
select
p.node_id
from
alf_content_url cu
left outer join alf_content_data cd ON (cd.content_url_id = cu.id)
left outer join alf_node_properties p ON (p.long_value = cd.id)
left outer join alf_qname q ON (q.id = p.qname_id)
left outer join alf_namespace n ON (n.id = q.ns_id)
where
cu.content_url_short = ? and
cu.content_url_crc = ? and
q.local_name = ? and
n.uri = ?
LEFT OUTER JOIN alf_content_data cd ON (cd.content_url_id = cu.id)
LEFT OUTER JOIN alf_node_properties p ON (p.long_value = cd.id)
WHERE
content_url_short = #{contentUrlShort} and
content_url_crc = #{contentUrlCrc}
</select>
<select id="select_RecordFoldersWithSchedules"

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -39,7 +39,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.domain.contentdata.ContentUrlEntity;
import org.alfresco.repo.domain.node.NodeDAO;
@@ -192,19 +191,13 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
ContentUrlEntity contentUrlEntity = new ContentUrlEntity();
contentUrlEntity.setContentUrl(contentUrl.toLowerCase());
Map<String, Object> params = new HashMap<>(4);
params.put("contentUrlShort", contentUrlEntity.getContentUrlShort());
params.put("contentUrlCrc", contentUrlEntity.getContentUrlCrc());
params.put("localName", ContentModel.PROP_CONTENT.getLocalName());
params.put("uri", ContentModel.PROP_CONTENT.getNamespaceURI());
if (logger.isDebugEnabled())
{
logger.debug("Executing query " + SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL);
}
// Get all the node ids which reference the given content url
List<Long> nodeIds = template.selectList(SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL, params);
List<Long> nodeIds = template.selectList(SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL, contentUrlEntity);
if (logger.isDebugEnabled())
{

View File

@@ -31,13 +31,11 @@ import static org.alfresco.service.cmr.security.PermissionService.GROUP_PREFIX;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.extensions.webscripts.ui.common.StringUtils;
import org.alfresco.model.ContentModel;
@@ -248,7 +246,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
*/
private Set<String> getAuthorities(String group)
{
Set<String> result = new LinkedHashSet<>();
Set<String> result = new HashSet<>();
result.addAll(authorityService.getContainedAuthorities(null, group, true));
return result;
}
@@ -373,18 +371,12 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
{
String group = null;
// If enabled, the authorities are forced to match the correct casing of the usernames in case they were set
// with the incorrect casing.
// If not, it will just use the authorities as they are.
// In normal circumstances, the authorities are in the correct casing, so this is disabled by default.
Set<String> authoritySet = normalizeAuthorities(authorities);
// find group or determine what the next index is if no group exists or there is a clash
Pair<String, Integer> groupResult = findIPRGroup(groupPrefix, authoritySet);
Pair<String, Integer> groupResult = findIPRGroup(groupPrefix, authorities);
if (groupResult.getFirst() == null)
{
group = createIPRGroup(groupPrefix, authoritySet, groupResult.getSecond());
group = createIPRGroup(groupPrefix, authorities, groupResult.getSecond());
}
else
{
@@ -412,8 +404,13 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
boolean hasMoreItems = true;
int pageCount = 0;
// If enabled, the authorities are forced to match the correct casing of the usernames in case they were set with the incorrect casing.
// If not, it will just use the authorities as they are.
// In normal circumstances, the authorities are in the correct casing, so this is disabled by default.
Set<String> authoritySet = normalizeAuthorities(authorities);
// determine the short name prefix
String groupShortNamePrefix = getIPRGroupPrefixShortName(groupPrefix, authorities);
String groupShortNamePrefix = getIPRGroupPrefixShortName(groupPrefix, authoritySet);
// iterate over the authorities to find a match
while (hasMoreItems == true)
@@ -434,7 +431,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
for (String group : results.getPage())
{
// if exists and matches we have found our group
if (isIPRGroupTrueMatch(group, authorities))
if (isIPRGroupTrueMatch(group, authoritySet))
{
return new Pair<String, Integer>(group, nextGroupIndex);
}
@@ -651,8 +648,8 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
}
catch (DuplicateChildNodeNameException ex)
{
// Rethrow as ConcurrencyFailureException so that is can be retried and linked to the group created by the concurrent transaction
throw new ConcurrencyFailureException("IPR group creation failed due to concurrent duplicate group name creation: " + groupShortName);
// the group was concurrently created
group = authorityService.getName(AuthorityType.GROUP, groupShortName);
}
return group;

View File

@@ -33,7 +33,6 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -326,8 +325,8 @@ public class ExtendedPermissionServiceImpl extends PermissionServiceImpl impleme
return aclReaders;
}
Set<String> assigned = new LinkedHashSet<>();
Set<String> readers = new LinkedHashSet<>();
HashSet<String> assigned = new HashSet<>();
HashSet<String> readers = new HashSet<>();
for (AccessControlEntry ace : acl.getEntries())
{
@@ -413,8 +412,8 @@ public class ExtendedPermissionServiceImpl extends PermissionServiceImpl impleme
return aclWriters;
}
Set<String> assigned = new LinkedHashSet<>();
Set<String> readers = new LinkedHashSet<>();
HashSet<String> assigned = new HashSet<>();
HashSet<String> readers = new HashSet<>();
for (AccessControlEntry ace : acl.getEntries())
{
@@ -486,7 +485,7 @@ public class ExtendedPermissionServiceImpl extends PermissionServiceImpl impleme
Set<String> writers = getWriters(aclId);
// add the current owner to the list of extended writers
Set<String> modifiedWrtiers = new LinkedHashSet<>(writers);
Set<String> modifiedWrtiers = new HashSet<>(writers);
String owner = ownableService.getOwner(nodeRef);
if (StringUtils.isNotBlank(owner) &&
!owner.equals(OwnableService.NO_OWNER) &&

View File

@@ -29,23 +29,14 @@ package org.alfresco.module.org_alfresco_module_rm.test.legacy.service;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.junit.Assert;
import org.springframework.dao.ConcurrencyFailureException;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.util.GUID;
@@ -215,8 +206,7 @@ public class ExtendedSecurityServiceImplTest extends BaseRMTestCase
final NodeRef record = doTestInTransaction(new Test<NodeRef>() {
public NodeRef run() throws Exception
{
NodeRef record = fileFolderService.create(documentLibrary, GUID.generate(), ContentModel.TYPE_CONTENT)
.getNodeRef();
NodeRef record = fileFolderService.create(documentLibrary, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
recordService.createRecord(filePlan, record);
return record;
}
@@ -289,238 +279,4 @@ public class ExtendedSecurityServiceImplTest extends BaseRMTestCase
}
});
}
public void testConcurrentSetWithRetry()
{
Set<String> extendedReaders = new HashSet<>(2);
Set<String> extendedWriters = new HashSet<>(2);
Set<NodeRef> documents = setupConcurrentTestCase(10, extendedReaders, extendedWriters);
// For each record created previously, spawn a thread to set extended security so we cause concurrency
// failure trying to create IPR groups with the same name
fireParallelExecutionOfSetExtendedSecurity(documents, extendedReaders, extendedWriters, true);
// Look for duplicated IPR groups and verify all documents have the same groups assigned
verifyCreatedGroups(documents, false);
AuthenticationUtil.clearCurrentSecurityContext();
}
public void testConcurrentSetWithoutRetry()
{
Set<String> extendedReaders = new HashSet<>(2);
Set<String> extendedWriters = new HashSet<>(2);
Set<NodeRef> documents = setupConcurrentTestCase(10, extendedReaders, extendedWriters);
// For each record created previously, spawn a thread to set extended security so we cause concurrency
// failure trying to create IPR groups with the same name.
// Since there is no retry, we expect to get a ConcurrencyFailureException
Assert.assertThrows(ConcurrencyFailureException.class, () -> {
fireParallelExecutionOfSetExtendedSecurity(documents, extendedReaders, extendedWriters, false);
});
// Look for duplicated IPR groups and verify all documents have the same groups assigned
// Since there was a ConcurrencyFailureException some threads failed to set extended security so some
// documents may not have IPR groups created.
verifyCreatedGroups(documents, true);
AuthenticationUtil.clearCurrentSecurityContext();
}
private Set<NodeRef> setupConcurrentTestCase(int concurrentThreads, Set<String> extendedReaders, Set<String> extendedWriters)
{
final String usera = createTestUser();
final String userb = createTestUser();
final String owner = createTestUser();
extendedReaders.add(usera);
extendedReaders.add(userb);
extendedWriters.add(usera);
extendedWriters.add(userb);
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
// Create a site
NodeRef documentLib = createSite(new HashSet<>(), new HashSet<>());
// Create records in the site document library
return createRecords(concurrentThreads, documentLib, owner);
}
private NodeRef createSite(Set<String> readers, Set<String> writers)
{
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>() {
@Override
public NodeRef execute() throws Throwable
{
final String siteShortName = GUID.generate();
siteService.createSite(null, siteShortName, "test", "test", SiteVisibility.PRIVATE);
readers.forEach(reader -> siteService.setMembership(siteShortName, reader, SiteModel.SITE_CONSUMER));
writers.forEach(writer -> siteService.setMembership(siteShortName, writer, SiteModel.SITE_COLLABORATOR));
return siteService.createContainer(siteShortName, SiteService.DOCUMENT_LIBRARY, null, null);
}
}, false, true);
}
private Set<NodeRef> createRecords(int numRecords, NodeRef parent, String owner)
{
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Set<NodeRef>>() {
@Override
public Set<NodeRef> execute() throws Throwable
{
int createdRecords = 0;
Set<NodeRef> documents = new HashSet<>();
while (createdRecords < numRecords)
{
final NodeRef doc = fileFolderService.create(parent, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef();
ownableService.setOwner(doc, owner);
recordService.createRecord(filePlan, doc, rmFolder, true);
recordService.file(doc);
recordService.complete(doc);
documents.add(doc);
createdRecords++;
}
return documents;
}
}, false, true);
}
private void setExtendedSecurity(NodeRef doc, Set<String> readers, Set<String> writers, boolean useRetry)
{
if (!useRetry)
{
setExtendedSecurity(doc, readers, writers);
return;
}
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
setExtendedSecurity(doc, readers, writers);
return null;
}
}, false, true);
}
private void setExtendedSecurity(NodeRef doc, Set<String> readers, Set<String> writers)
{
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
extendedSecurityService.set(doc, readers, writers);
}
private void fireParallelExecutionOfSetExtendedSecurity(Set<NodeRef> documents, Set<String> extendedReaders, Set<String> extendedWriters, boolean useRetry)
{
CompletableFuture<?>[] futures = documents.stream()
.map(doc -> CompletableFuture.runAsync(() -> setExtendedSecurity(doc, extendedReaders, extendedWriters, useRetry)))
.toArray(CompletableFuture[]::new);
try
{
CompletableFuture.allOf(futures).join();
}
catch (Exception e)
{
Throwable cause = e.getCause();
if (cause instanceof ConcurrencyFailureException)
{
throw (ConcurrencyFailureException) cause;
}
throw new RuntimeException("Error during parallel execution", e);
}
}
private void verifyCreatedGroups(Set<NodeRef> documents, boolean onlyDuplicatesValidation)
{
retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Void>() {
@Override
public Void execute() throws Throwable
{
Set<String> expectedAuthorities = null;
Set<Set<String>> errors = new HashSet<>();
for (NodeRef doc : documents)
{
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(doc);
Set<String> authorities = getDocumentAuthorities(permissions);
Set<String> authoritiesById = getAuthorityIds(authorities);
verifyIPRGroups(authorities, onlyDuplicatesValidation);
if (onlyDuplicatesValidation)
{
// Some documents may not have IPR groups created if there was a ConcurrencyFailureException
continue;
}
// All documents should have the same exact set of groups assigned
if (expectedAuthorities == null)
{
expectedAuthorities = authoritiesById;
}
if (!expectedAuthorities.equals(authoritiesById))
{
errors.add(authoritiesById);
}
}
assertTrue("Unexpected authorities linked to document", errors.isEmpty());
return null;
}
}, false, true);
}
private Set<String> getDocumentAuthorities(Set<AccessPermission> permissions)
{
Set<String> authorities = new HashSet<>();
for (AccessPermission accessPermission : permissions)
{
String authority = accessPermission.getAuthority();
String authName = authorityService.getName(AuthorityType.GROUP, authority);
authorities.add(authName);
}
return authorities;
}
private Set<String> getAuthorityIds(Set<String> authorities)
{
Set<String> authorityIds = new HashSet<>();
for (String authority : authorities)
{
String authId = authorityService.getAuthorityNodeRef(authority) != null
? authorityService.getAuthorityNodeRef(authority).getId()
: null;
authorityIds.add(authId);
}
return authorityIds;
}
private void verifyIPRGroups(Set<String> authorities, boolean onlyDuplicatesValidation)
{
boolean hasGroupIPR = false;
for (String authorityName : authorities)
{
String shortName = authorityService.getShortName(authorityName);
if (authorityName.startsWith("GROUP_IPR"))
{
hasGroupIPR = true;
PagingResults<String> results = authorityService.getAuthorities(AuthorityType.GROUP, null, shortName, false,
false, new PagingRequest(0, 10));
assertEquals("No duplicated IPR group expected", 1, results.getPage().size());
}
}
if (!onlyDuplicatesValidation)
{
assertTrue("No IPR Groups created", hasGroupIPR);
}
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<build>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<properties>
@@ -51,8 +51,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<scope>provided</scope>
</dependency>

View File

@@ -28,7 +28,7 @@ import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.json.simple.JSONObject;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
@@ -92,7 +92,7 @@ public class WikiPageGet extends AbstractWikiWebScript
{
links.add(link);
// build the list of available pages
WikiPageInfo wikiPage = wikiService.getWikiPage(site.getShortName(), StringEscapeUtils.unescapeHtml4(link));
WikiPageInfo wikiPage = wikiService.getWikiPage(site.getShortName(), StringEscapeUtils.unescapeHtml(link));
if (wikiPage != null)
{
pageTitles.add(wikiPage.getTitle());

View File

@@ -91,15 +91,6 @@ function doclist_getAllNodes(parsedArgs, filterParams, query, totalItemCount)
};
}
function sanitizeJunkFavouriteKeys(favourites){
for (var key in favourites) {
if (!key || key.trim() === "") {
delete favourites[key];
}
}
return favourites;
}
/**
* Main entry point: Create collection of documents and folders in the given space
*
@@ -132,47 +123,6 @@ function doclist_main()
if (logger.isLoggingEnabled())
logger.log("doclist.lib.js - NodeRef: " + parsedArgs.nodeRef + " Query: " + query);
favourites = sanitizeJunkFavouriteKeys(favourites);
if(query === null)
{
return {
luceneQuery: "",
paging: {
totalRecords: 0,
startIndex: 0
},
container: parsedArgs.rootNode,
parent: null,
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
itemCount: {
folders: 0,
documents: 0
},
items: [],
customJSON: slingshotDocLib.getJSON()
};
}
if(Object.keys(favourites).length === 0 && query === null)
{
return {
luceneQuery: "",
paging: {
totalRecords: 0,
startIndex: 0
},
container: parsedArgs.rootNode,
parent: null,
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
itemCount: {
folders: 0,
documents: 0
},
items: [],
customJSON: slingshotDocLib.getJSON()
};
}
var totalItemCount = filterParams.limitResults ? parseInt(filterParams.limitResults, 10) : -1;
// For all sites documentLibrary query we pull in all available results and post filter

View File

@@ -182,14 +182,11 @@ var Filters =
case "favourites":
for (var favourite in favourites)
{
if (favourite && favourite.trim() !== "")
if (filterQuery)
{
if (filterQuery)
{
filterQuery += " OR ";
}
filterQuery += "ID:\"" + favourite + "\"";
filterQuery += " OR ";
}
filterQuery += "ID:\"" + favourite + "\"";
}
if (filterQuery.length !== 0)
@@ -204,13 +201,7 @@ var Filters =
else
{
// empty favourites query
logger.warn("No favourites found for user: " + person.properties.userName);
return {
query: null,
limitResults: 0,
sort: [],
language: "lucene"
};
filterQuery = "+ID:\"\"";
}
filterParams.query = filterQuery;
@@ -233,15 +224,15 @@ var Filters =
filterParams.query = "+ID:\"" + parsedArgs.nodeRef + "\"";
break;
case "tag":
// Remove any trailing "/" character
if (filterData.charAt(filterData.length - 1) == "/")
{
filterData = filterData.slice(0, -1);
}
filterQuery = this.constructPathQuery(parsedArgs);
filterParams.query = filterQuery + " +TAG:\"" + search.ISO9075Encode(filterData) + "\"";
break;
case "tag":
// Remove any trailing "/" character
if (filterData.charAt(filterData.length - 1) == "/")
{
filterData = filterData.slice(0, -1);
}
filterQuery = this.constructPathQuery(parsedArgs);
filterParams.query = filterQuery + " +PATH:\"/cm:taggable/cm:" + search.ISO9075Encode(filterData) + "/member\"";
break;
case "category":
// Remove any trailing "/" character
@@ -249,15 +240,8 @@ var Filters =
{
filterData = filterData.slice(0, -1);
}
var categoryNodeRef = this.getCategoryNodeRef(filterData);
if (categoryNodeRef && search.findNode(categoryNodeRef) != null) {
filterParams.query = filterQuery + ' +@cm\\:categories:"' + categoryNodeRef + '"';
} else {
logger.warn("category filter: skipping invalid category node : " + categoryNodeRef);
}
filterParams.language = "fts-alfresco";
filterQuery = this.constructPathQuery(parsedArgs);
filterParams.query = filterQuery + " +PATH:\"/cm:categoryRoot/cm:generalclassifiable" + Filters.iso9075EncodePath(filterData) + "/member\"";
break;
case "aspect":
@@ -278,24 +262,11 @@ var Filters =
{
filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || "");
}
logger.warn("Final Query : " + filterParams.query);
return filterParams;
},
getCategoryNodeRef: function(categoryName) {
var results = search.luceneSearch(
'PATH:"/cm:categoryRoot/cm:generalclassifiable//*" AND @cm\\:name:"' + categoryName + '"'
);
if (results && results.length > 0) {
return results[0].nodeRef.toString();
}
logger.warn("Category not found: " + categoryName);
return null;
},
constructPathQuery: function(parsedArgs)
constructPathQuery: function constructPathQuery(parsedArgs)
{
var pathQuery = "";
if (parsedArgs.libraryRoot != companyhome || parsedArgs.nodeRef != "alfresco://company/home")

View File

@@ -25,7 +25,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jakarta.transaction.UserTransaction;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
@@ -958,7 +958,7 @@ public class WikiRestApiTest extends BaseWebScriptTest
String link = m.group(1);
link += "?title=<script>alert('xss');</script>";
WikiPageInfo wikiPage2 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, link);
WikiPageInfo wikiPage1 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, StringEscapeUtils.unescapeHtml4(link));
WikiPageInfo wikiPage1 = this.wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, StringEscapeUtils.unescapeHtml(link));
assertEquals(wikiPage2, wikiPage1);
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -9,6 +9,6 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
</project>

View File

@@ -37,7 +37,8 @@ commons-fileupload http://jakarta.apache.org/commons/
commons-httpclient http://jakarta.apache.org/commons/
commons-io http://jakarta.apache.org/commons/
commons-jxpath http://jakarta.apache.org/commons/
commons-lang3 http://jakarta.apache.org/commons/
commons-lang http://jakarta.apache.org/commons/
commons-lang3 http://jakarta.apache.org/commons/
commons-logging http://jakarta.apache.org/commons/
commons-net http://jakarta.apache.org/commons/
commons-pool http://jakarta.apache.org/commons/

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<modules>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<organization>

View File

@@ -5,7 +5,7 @@ import java.util.Date;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang.time.DateUtils;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<properties>

View File

@@ -675,11 +675,6 @@ public class RestWrapper extends DSLWrapper<RestWrapper>
{
returnedResponse = onRequest().get(restRequest.getPath(), restRequest.getPathParams()).andReturn();
}
else if (HttpMethod.PATCH.equals(httpMethod))
{
returnedResponse = onRequest().body(restRequest.getBody())
.patch(restRequest.getPath(), restRequest.getPathParams()).andReturn();
}
else
{
returnedResponse = onRequest().get(restRequest.getPath(), restRequest.getPathParams()).andReturn();

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<developers>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<properties>

40
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -51,14 +51,14 @@
<dependency.alfresco-server-root.version>7.0.2</dependency.alfresco-server-root.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.2.3-A.2</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.2.3-A.2</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>5.2.0-A.3</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.2.0</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>1.0.11</dependency.acs-event-model.version>
<dependency.acs-event-model.version>1.0.5</dependency.acs-event-model.version>
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
<dependency.spring.version>6.2.11</dependency.spring.version>
<dependency.spring-security.version>6.4.11</dependency.spring-security.version>
<dependency.spring.version>6.2.8</dependency.spring.version>
<dependency.spring-security.version>6.3.9</dependency.spring-security.version>
<dependency.antlr.version>3.5.3</dependency.antlr.version>
<dependency.jackson.version>2.17.2</dependency.jackson.version>
<dependency.cxf.version>4.1.2</dependency.cxf.version>
@@ -82,7 +82,7 @@
<dependency.slf4j.version>2.0.16</dependency.slf4j.version>
<dependency.log4j.version>2.25.1</dependency.log4j.version>
<dependency.groovy.version>3.0.25</dependency.groovy.version>
<dependency.tika.version>3.2.3</dependency.tika.version>
<dependency.tika.version>2.9.2</dependency.tika.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version>
<dependency.poi.version>5.4.0</dependency.poi.version>
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
@@ -115,7 +115,7 @@
<dependency.jakarta-json-path.version>2.9.0</dependency.jakarta-json-path.version>
<dependency.json-smart.version>2.5.2</dependency.json-smart.version>
<alfresco.googledrive.version>4.1.0</alfresco.googledrive.version>
<alfresco.aos-module.version>3.4.0</alfresco.aos-module.version>
<alfresco.aos-module.version>3.3.0</alfresco.aos-module.version>
<alfresco.api-explorer.version>25.2.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
@@ -154,7 +154,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>25.3.0.65</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>
@@ -170,12 +170,6 @@
<dependencyManagement>
<dependencies>
<!-- v1.10 has 0BSD license it must be consulted with Legal -->
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.9</version>
</dependency>
<!-- Jakarta... -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
@@ -428,9 +422,9 @@
<version>1.18.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.18.0</version>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
@@ -456,7 +450,7 @@
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.11.1</version>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
@@ -1131,10 +1125,16 @@
<exclude>jakarta.xml.soap:jakarta.xml.soap-api:(, 2.0.1)</exclude>
<exclude>jakarta.jws:jakarta.jws-api:(, 3.0.0)</exclude>
<!-- Enforce ban bouncycastle dependencies other than specified under <includes> section-->
<exclude>org.bouncycastle:(,1.81)</exclude>
<exclude>org.bouncycastle</exclude>
<!-- Enforce one version of Jaxb-->
<exclude>com.sun.xml.bind</exclude>
</excludes>
<includes>
<include>org.bouncycastle:bcprov-jdk18on:[1.78.1,)</include>
<include>org.bouncycastle:bcmail-jdk18on:[1.78.1,)</include>
<include>org.bouncycastle:bcpkix-jdk18on:[1.78.1,)</include>
<include>org.bouncycastle:bcutil-jdk18on:[1.78.1,)</include>
</includes>
</bannedDependencies>
</rules>
<fail>true</fail>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<dependencies>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -31,10 +31,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.json.simple.JSONObject;
import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
@@ -70,29 +67,6 @@ public class CommentsPost extends AbstractCommentsWebScript
// get json object from request
JSONObject json = parseJSON(req);
// Validating and Sanitizing comment content to prevent XSS
String commentContent = getOrNull(json, "content");
if (StringUtils.isBlank(commentContent))
{
throw new IllegalArgumentException("Comment content must not be empty");
}
else
{
// Allowed HTML elements and attributes in comment content e.g. Text formatting ,Lists and Structure & Styling
String[] allowedElements = {"b", "i", "u", "strong", "em", "ul", "ol", "li", "p", "br", "span", "div"};
PolicyFactory policy = new HtmlPolicyBuilder()
.allowElements(allowedElements)
.allowAttributes("style")
.onElements("span", "div", "p", "ul")
.allowStyling()
.allowStandardUrlProtocols()
.toFactory();
String safeContent = policy.sanitize(commentContent);
json.replace("content", safeContent);
}
/* MNT-10231, MNT-9771 fix */
this.behaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_AUDITABLE);

View File

@@ -27,6 +27,7 @@ package org.alfresco.rest.framework.resource.parameters;
import java.util.List;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
@@ -68,7 +69,7 @@ public interface Parameters
* @return The Parameter value
* @throws InvalidArgumentException
*/
<T> T getParameter(String parameterName, Class<T> clazz) throws InvalidArgumentException;
T getParameter(String parameterName, Class<T> clazz) throws InvalidArgumentException;
/**
* Returns a representation of the Paging of collections of resources, with skip count and max items. See {@link Paging} Specified by the "skipCount" and "maxItems" request parameters.

View File

@@ -31,6 +31,7 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.content.MimetypeMap;
@@ -230,7 +231,7 @@ public class Params implements Parameters
}
@Override
public <T> T getParameter(String parameterName, Class<T> clazz) throws InvalidArgumentException
public T getParameter(String parameterName, Class<T> clazz) throws InvalidArgumentException
{
String param = getParameter(parameterName);
if (param == null)
@@ -238,7 +239,7 @@ public class Params implements Parameters
Object obj = ConvertUtils.convert(param, clazz);
if (obj != null && obj.getClass().equals(clazz))
{
return clazz.cast(obj);
return (T) obj;
}
throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, new Object[]{parameterName});
}

View File

@@ -51,14 +51,6 @@ function main()
}
}
var contentChanged = false;
if (itemKind === "node") {
contentChanged = metadataExtractAction.isContentChanged(itemId,repoFormData);
}
if(logger.isLoggingEnabled() && contentChanged) {
logger.log("Content has been changed");
}
var persistedObject = null;
try
{
@@ -91,50 +83,9 @@ function main()
return;
}
if (itemKind === "node") {
checkAndExtractNodeMetadata(persistedObject, itemId, contentChanged);
}
model.persistedObject = persistedObject.toString();
model.message = "Successfully persisted form for item [" + itemKind + "]" + itemId;
}
function checkAndExtractNodeMetadata(persistedObject, itemId, isContentChanged) {
var nodeRefStr = toNodeRefString(persistedObject, itemId);
var node = search.findNode(nodeRefStr);
if (node == null) {
if (logger.isLoggingEnabled()) {
logger.log("Node not found: " + nodeRefStr);
}
} else if(isContentChanged) {
extractMetadata(node, isContentChanged);
} else {
if (logger.isLoggingEnabled()) {
logger.log("Content not changed, skipping metadata extraction for node: " + nodeRefStr);
}
}
}
function extractMetadata(file, isContentChanged) {
var emAction = metadataExtractAction.create(isContentChanged);
if (emAction) {
// readOnly=false, newTransaction=false
emAction.execute(file, false, false);
}
}
function toNodeRefString(persistedObject, itemId) {
// Prefer the NodeRef returned by saveForm (when kind=node).
if (persistedObject instanceof Packages.org.alfresco.service.cmr.repository.NodeRef) {
return persistedObject.toString();
}
// If the client passed a full noderef, keep it.
if (itemId && itemId.indexOf("://") !== -1) {
return itemId;
}
// Otherwise assume SpacesStore UUID.
return "workspace://SpacesStore/" + itemId;
}
main();

View File

@@ -2,7 +2,7 @@ function extractMetadata(file)
{
// Extract metadata - via repository action for now.
// This should use the MetadataExtracter API to fetch properties, allowing for possible failures.
var emAction = metadataExtractAction.create(true);
var emAction = actions.create("extract-metadata");
if (emAction != null)
{
// Call using readOnly = false, newTransaction = false

View File

@@ -25,8 +25,6 @@
*/
package org.alfresco.rest.api.tests;
import java.util.Arrays;
import org.alfresco.repo.web.util.JettyComponent;
public class EnterprisePublicApiTestFixture extends EnterpriseTestFixture
@@ -42,53 +40,32 @@ public class EnterprisePublicApiTestFixture extends EnterpriseTestFixture
public final static String[] CLASS_LOCATIONS = new String[]{"classpath*:/publicapi/lucene/"};
private static EnterprisePublicApiTestFixture instance;
private String[] customConfigLocations;
/* Note: synchronized for multi-threaded test access */
public synchronized static EnterprisePublicApiTestFixture getInstance(boolean createTestData, String... customConfigLocations)
public synchronized static EnterprisePublicApiTestFixture getInstance(boolean createTestData) throws Exception
{
if (instance == null)
{
instance = new EnterprisePublicApiTestFixture(customConfigLocations);
try
{
instance.setup(createTestData);
}
catch (Exception e)
{
String errorMessage = "Exception was thrown during setup EnterprisePublicApiTestFixture: " + e.getClass() + " - " + e.getMessage();
throw new RuntimeException(errorMessage, e);
}
instance = new EnterprisePublicApiTestFixture();
instance.setup(createTestData);
}
return instance;
}
public static EnterprisePublicApiTestFixture getInstance(String... customConfigLocations)
public static EnterprisePublicApiTestFixture getInstance() throws Exception
{
return getInstance(true, customConfigLocations);
return getInstance(true);
}
public static EnterprisePublicApiTestFixture getInstance()
{
return getInstance(true, null);
}
public static EnterprisePublicApiTestFixture getInstance(boolean createTestData)
{
return getInstance(createTestData, null);
}
private EnterprisePublicApiTestFixture(String... customConfigLocations)
private EnterprisePublicApiTestFixture()
{
super(CONFIG_LOCATIONS, CLASS_LOCATIONS, PORT, CONTEXT_PATH, PUBLIC_API_SERVLET_NAME, DEFAULT_NUM_MEMBERS_PER_SITE, false);
this.customConfigLocations = customConfigLocations;
}
@Override
protected JettyComponent makeJettyComponent()
{
String[] configLocations = mergeLocations(getConfigLocations(), this.customConfigLocations);
JettyComponent jettyComponent = new EnterpriseJettyComponent(getPort(), getContextPath(), configLocations, getClassLocations());
JettyComponent jettyComponent = new EnterpriseJettyComponent(getPort(), getContextPath(), getConfigLocations(), getClassLocations());
return jettyComponent;
}
@@ -97,19 +74,4 @@ public class EnterprisePublicApiTestFixture extends EnterpriseTestFixture
{
return new RepoService(applicationContext);
}
private String[] mergeLocations(String[]... locations)
{
String[] mergedLocations = new String[0];
for (String[] location : locations)
{
if (location == null || location.length == 0)
{
continue;
}
mergedLocations = Arrays.copyOf(mergedLocations, mergedLocations.length + location.length);
System.arraycopy(location, 0, mergedLocations, mergedLocations.length - location.length, location.length);
}
return mergedLocations;
}
}

View File

@@ -36,21 +36,15 @@ public class EnterpriseTestApi extends AbstractTestApi
getTestFixture().getRandomNetwork();
}
protected String[] getCustomConfigLocations()
{
return new String[]{};
}
@Override
protected TestFixture getTestFixture() throws Exception
{
return EnterprisePublicApiTestFixture.getInstance(getCustomConfigLocations());
return EnterprisePublicApiTestFixture.getInstance();
}
@Override
protected TestFixture getTestFixture(boolean createTestData) throws Exception
{
return EnterprisePublicApiTestFixture.getInstance(createTestData, getCustomConfigLocations());
return EnterprisePublicApiTestFixture.getInstance(createTestData);
}
}

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.65</version>
<version>25.3.0.15-SNAPSHOT</version>
</parent>
<dependencies>
@@ -94,6 +94,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.18.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -736,6 +737,10 @@
<artifactId>reflections</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies>
<build>

View File

@@ -1,67 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 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.action.evaluator;
import java.util.List;
import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Content change condition evaluator implementation. Required only in Scripted Actions to allow determination if content has changed. <br>
* Usage in {@link org.alfresco.repo.jscript.MetaDataExtractAction#create(boolean)}
*
* @author Sayan Bhattacharya
*/
public class CompareContentConditionEvaluator extends ActionConditionEvaluatorAbstractBase
{
/**
* Evaluator constants
*/
public static final String NAME = "compare-content";
public static final String PARAM_IS_CONTENT_CHANGED = "isContentChanged";
/**
* @see ActionConditionEvaluatorAbstractBase#evaluateImpl(ActionCondition, NodeRef)
*/
@Override
public boolean evaluateImpl(ActionCondition ruleCondition, NodeRef actionedUponNodeRef)
{
return true;
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(List)
*/
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
// No parameters to add
}
}

View File

@@ -51,14 +51,12 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.evaluator.CompareContentConditionEvaluator;
import org.alfresco.repo.content.metadata.AbstractMappingMetadataExtracter;
import org.alfresco.repo.content.metadata.AsynchronousExtractor;
import org.alfresco.repo.content.metadata.MetadataExtracter;
@@ -405,7 +403,6 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
((AbstractMappingMetadataExtracter) extracter).setEnableStringTagging(enableStringTagging);
}
MetadataExtracter.OverwritePolicy overwritePolicy = determineOverwritePolicy(ruleAction);
// Get all the node's properties
Map<QName, Serializable> nodeProperties = nodeService.getProperties(actionedUponNodeRef);
@@ -418,7 +415,7 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
modifiedProperties = extracter.extract(
actionedUponNodeRef,
reader,
overwritePolicy,
/* OverwritePolicy.PRAGMATIC, */
nodeProperties);
}
catch (Throwable e)
@@ -459,21 +456,6 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
stringTaggingSeparators);
}
private MetadataExtracter.OverwritePolicy determineOverwritePolicy(Action ruleAction)
{
return Optional.ofNullable(ruleAction.getActionConditions())
.flatMap(conditions -> conditions.stream()
.filter(e -> CompareContentConditionEvaluator.NAME.equals(e.getActionConditionDefinitionName()))
.findAny()
.map(e -> {
Serializable contentChanged = e.getParameterValue(CompareContentConditionEvaluator.PARAM_IS_CONTENT_CHANGED);
return Boolean.TRUE.equals(contentChanged)
? MetadataExtracter.OverwritePolicy.EAGER
: MetadataExtracter.OverwritePolicy.PRAGMATIC;
}))
.orElse(MetadataExtracter.OverwritePolicy.PRAGMATIC);
}
public static void addExtractedMetadataToNode(NodeRef actionedUponNodeRef, Map<QName, Serializable> nodeProperties,
Map<QName, Serializable> modifiedProperties,
NodeService nodeService, DictionaryService dictionaryService,

View File

@@ -70,13 +70,6 @@ public interface AuditComponent
*/
public void setUserAuditFilter(UserAuditFilter userAuditFilter);
/**
* @param auditRecordReporter
* AuditRecordReporter
* @since 25.3
*/
public void setAuditRecordReporter(AuditRecordReporter auditRecordReporter);
/**
* Get all registered audit applications, whether active or not.
*

View File

@@ -48,6 +48,7 @@ import org.alfresco.repo.audit.model.AuditModelRegistryImpl;
import org.alfresco.repo.domain.audit.AuditDAO;
import org.alfresco.repo.domain.propval.PropertyValueDAO;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
@@ -72,8 +73,8 @@ public class AuditComponentImpl implements AuditComponent
{
private static final String INBOUND_LOGGER = "org.alfresco.repo.audit.inbound";
private static final Log logger = LogFactory.getLog(AuditComponentImpl.class);
private static final Log loggerInbound = LogFactory.getLog(INBOUND_LOGGER);
private static Log logger = LogFactory.getLog(AuditComponentImpl.class);
private static Log loggerInbound = LogFactory.getLog(INBOUND_LOGGER);
private AuditModelRegistryImpl auditModelRegistry;
private PropertyValueDAO propertyValueDAO;
@@ -81,7 +82,6 @@ public class AuditComponentImpl implements AuditComponent
private TransactionService transactionService;
private AuditFilter auditFilter;
private UserAuditFilter userAuditFilter;
private AuditRecordReporter auditRecordReporter;
/**
* Default constructor
@@ -140,11 +140,6 @@ public class AuditComponentImpl implements AuditComponent
this.userAuditFilter = userAuditFilter;
}
public void setAuditRecordReporter(AuditRecordReporter auditRecordReporter)
{
this.auditRecordReporter = auditRecordReporter;
}
/**
* {@inheritDoc}
*
@@ -220,7 +215,7 @@ public class AuditComponentImpl implements AuditComponent
public int deleteAuditEntries(List<Long> auditEntryIds)
{
// Shortcut, if necessary
if (auditEntryIds.isEmpty())
if (auditEntryIds.size() == 0)
{
return 0;
}
@@ -239,7 +234,7 @@ public class AuditComponentImpl implements AuditComponent
{
Long disabledPathsId = application.getDisabledPathsId();
Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
return new HashSet<>(disabledPaths);
return new HashSet<String>(disabledPaths);
}
catch (Throwable e)
{
@@ -259,16 +254,6 @@ public class AuditComponentImpl implements AuditComponent
return auditModelRegistry.isAuditEnabled();
}
public boolean isAuditingToDatabaseEnabled()
{
return auditModelRegistry.isAuditingToDatabaseEnabled();
}
public boolean isAuditingToAuditStorageEnabled()
{
return auditModelRegistry.isAuditingToAuditStorageEnabled();
}
/**
* {@inheritDoc}
*
@@ -324,7 +309,7 @@ public class AuditComponentImpl implements AuditComponent
{
PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
Set<String> mappedPaths = pathMapper.getMappedPathsWithPartialMatch(path);
return loggerInbound.isDebugEnabled() || !mappedPaths.isEmpty();
return loggerInbound.isDebugEnabled() || mappedPaths.size() > 0;
}
/**
@@ -361,7 +346,7 @@ public class AuditComponentImpl implements AuditComponent
// Check if there are any entries that match or supercede the given path
String disablingPath = null;
;
for (String disabledPath : disabledPaths)
{
if (path.startsWith(disabledPath))
@@ -588,7 +573,7 @@ public class AuditComponentImpl implements AuditComponent
}
// Build the key paths using the session root path
Map<String, Serializable> pathedValues = new HashMap<>(values.size() * 2);
Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
for (Map.Entry<String, Serializable> entry : values.entrySet())
{
String pathElement = entry.getKey();
@@ -611,7 +596,12 @@ public class AuditComponentImpl implements AuditComponent
case TXN_NONE:
case TXN_READ_ONLY:
// New transaction
RetryingTransactionCallback<Map<String, Serializable>> callback = () -> recordAuditValuesImpl(mappedValues);
RetryingTransactionCallback<Map<String, Serializable>> callback = new RetryingTransactionCallback<Map<String, Serializable>>() {
public Map<String, Serializable> execute() throws Throwable
{
return recordAuditValuesImpl(mappedValues);
}
};
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
txnHelper.setForceWritable(true);
return txnHelper.doInTransaction(callback, false, true);
@@ -628,16 +618,21 @@ public class AuditComponentImpl implements AuditComponent
public Map<String, Serializable> recordAuditValuesImpl(Map<String, Serializable> mappedValues)
{
// Group the values by root path
Map<String, Map<String, Serializable>> mappedValuesByRootKey = new HashMap<>();
Map<String, Map<String, Serializable>> mappedValuesByRootKey = new HashMap<String, Map<String, Serializable>>();
for (Map.Entry<String, Serializable> entry : mappedValues.entrySet())
{
String path = entry.getKey();
String rootKey = AuditApplication.getRootKey(path);
Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.computeIfAbsent(rootKey, k -> new HashMap<>(7));
Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.get(rootKey);
if (rootKeyMappedValues == null)
{
rootKeyMappedValues = new HashMap<String, Serializable>(7);
mappedValuesByRootKey.put(rootKey, rootKeyMappedValues);
}
rootKeyMappedValues.put(path, entry.getValue());
}
Map<String, Serializable> allAuditedValues = new HashMap<>(mappedValues.size() * 2 + 1);
Map<String, Serializable> allAuditedValues = new HashMap<String, Serializable>(mappedValues.size() * 2 + 1);
// Now audit for each of the root keys
for (Map.Entry<String, Map<String, Serializable>> entry : mappedValuesByRootKey.entrySet())
{
@@ -699,7 +694,7 @@ public class AuditComponentImpl implements AuditComponent
}
// Check if there is anything to audit
if (values.isEmpty())
if (values.size() == 0)
{
if (logger.isDebugEnabled())
{
@@ -732,7 +727,12 @@ public class AuditComponentImpl implements AuditComponent
Map<String, Serializable> auditData = generateData(generators);
// Now extract values
Map<String, Serializable> extractedData = AuthenticationUtil.runAs(() -> extractData(application, values), AuthenticationUtil.getSystemUserName());
Map<String, Serializable> extractedData = AuthenticationUtil.runAs(new RunAsWork<Map<String, Serializable>>() {
public Map<String, Serializable> doWork() throws Exception
{
return extractData(application, values);
}
}, AuthenticationUtil.getSystemUserName());
// Combine extracted and generated values (extracted data takes precedence)
auditData.putAll(extractedData);
@@ -743,8 +743,8 @@ public class AuditComponentImpl implements AuditComponent
{
String root = value.getKey();
int index = root.lastIndexOf("/");
Map<String, Serializable> argc = new HashMap<>(1);
argc.put(root.substring(index).substring(1), value.getValue());
Map<String, Serializable> argc = new HashMap<String, Serializable>(1);
argc.put(root.substring(index, root.length()).substring(1), value.getValue());
if (!auditFilter.accept(root.substring(0, index), argc))
{
return Collections.emptyMap();
@@ -760,15 +760,10 @@ public class AuditComponentImpl implements AuditComponent
{
// Persist the values (if not just gathering data in a pre call for use in a post call)
boolean justGatherPreCallData = application.isApplicationJustGeneratingPreCallData();
if (!justGatherPreCallData && isAuditingToDatabaseEnabled())
if (!justGatherPreCallData)
{
entryId = auditDAO.createAuditEntry(applicationId, time, username, auditData);
}
if (isAuditingToAuditStorageEnabled())
{
auditRecordReporter.reportAuditRecord(createAuditRecord(auditData, true, username, entryId, application.getApplicationName()));
}
// Done
if (logger.isDebugEnabled())
{
@@ -827,7 +822,7 @@ public class AuditComponentImpl implements AuditComponent
AuditApplication application,
Map<String, Serializable> values)
{
Map<String, Serializable> newData = new HashMap<>(values.size());
Map<String, Serializable> newData = new HashMap<String, Serializable>(values.size());
List<DataExtractorDefinition> extractors = application.getDataExtractors();
for (DataExtractorDefinition extractorDef : extractors)
@@ -905,7 +900,7 @@ public class AuditComponentImpl implements AuditComponent
*/
private Map<String, Serializable> generateData(Map<String, DataGenerator> generators)
{
Map<String, Serializable> newData = new HashMap<>(generators.size() + 5);
Map<String, Serializable> newData = new HashMap<String, Serializable>(generators.size() + 5);
for (Map.Entry<String, DataGenerator> entry : generators.entrySet())
{
String path = entry.getKey();
@@ -930,20 +925,6 @@ public class AuditComponentImpl implements AuditComponent
return newData;
}
/**
* Creates an AuditRecord from the provided audit data.
*/
private AuditRecord createAuditRecord(Map<String, Serializable> auditData, boolean inTransaction, String username, Long entryId, String applicationName)
{
int rootSize = applicationName.length() + 2; // Root is constructed like this -> '/' + auditedApplicationName + '/'.
AuditRecord.Builder builder = AuditRecordUtils.generateAuditRecordBuilder(auditData, rootSize);
builder.setAuditRecordType(applicationName);
builder.setInTransaction(inTransaction);
builder.setUsername(username);
builder.setEntryDBId(entryId);
return builder.build();
}
/**
* {@inheritDoc}
*/

View File

@@ -1,130 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2025 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.audit;
import java.io.Serializable;
import java.time.ZonedDateTime;
import java.util.Map;
public class AuditRecord
{
private final boolean inTransaction;
private final String auditApplicationId;
private final ZonedDateTime createdAt;
private final String username;
private final Long entryDBId;
private final Map<String, Serializable> auditData;
public AuditRecord(Builder builder)
{
this.auditApplicationId = builder.auditRecordType;
this.inTransaction = builder.inTransaction;
this.auditData = builder.auditRecordData;
this.createdAt = ZonedDateTime.now();
this.username = builder.username;
this.entryDBId = builder.entryDBId;
}
public String getAuditApplicationId()
{
return auditApplicationId;
}
public boolean isInTransaction()
{
return inTransaction;
}
public ZonedDateTime getCreatedAt()
{
return createdAt;
}
public String getUsername()
{
return username;
}
public Long getEntryDBId()
{
return entryDBId;
}
public Map<String, Serializable> getAuditData()
{
return auditData;
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String auditRecordType;
private boolean inTransaction;
private Map<String, Serializable> auditRecordData;
private String username;
private Long entryDBId;
public Builder setAuditRecordType(String auditRecordType)
{
this.auditRecordType = auditRecordType;
return this;
}
public Builder setInTransaction(boolean inTransaction)
{
this.inTransaction = inTransaction;
return this;
}
public Builder setAuditRecordData(Map<String, Serializable> auditRecordData)
{
this.auditRecordData = auditRecordData;
return this;
}
public Builder setUsername(String username)
{
this.username = username;
return this;
}
public Builder setEntryDBId(Long entryDBId)
{
this.entryDBId = entryDBId;
return this;
}
public AuditRecord build()
{
return new AuditRecord(this);
}
}
}

View File

@@ -1,37 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2025 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.audit;
public interface AuditRecordReporter
{
/**
* This method will report AuditRecord to Audit Storage using RepoEvent2
*
* @param auditRecord
* represent data that will be reported.
*/
void reportAuditRecord(AuditRecord auditRecord);
}

View File

@@ -1,40 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2025 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.audit;
public class AuditRecordReporterImpl implements AuditRecordReporter
{
/**
* This method intentionally has an empty implementation.
* <p>
* This class provides a no-op implementation of {@link AuditRecordReporter}.
*/
@Override
public void reportAuditRecord(AuditRecord auditRecord)
{
// No operation performed.
}
}

View File

@@ -1,104 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2025 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.audit;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.repository.NodeRef;
public final class AuditRecordUtils
{
private AuditRecordUtils()
{
// This is a utility class and cannot be instantiated.
}
/**
* Generates an {@link AuditRecord.Builder} from flat audit data.
* <p>
* This method:
* <ul>
* <li>Translates flat {@code key-value} pairs into a nested JSON structure.</li>
* <li>Preloads the builder with the provided arguments.</li>
* <li>Splits keys by {@code /} to build the nested structure.</li>
* <li>Uses the root key as the application ID.</li>
* <li>Assumes each key starts with the same root, constructed as {@code '/' + auditedApplicationName + '/'}, which is removed before splitting.</li>
* </ul>
*
* @param data
* a map containing flat audit data as `key-value` pairs
* @param keyRootLength
* is a length of key root.
* @return a preloaded {@link AuditRecord.Builder}
*/
public static AuditRecord.Builder generateAuditRecordBuilder(Map<String, Serializable> data, int keyRootLength)
{
var auditRecordBuilder = AuditRecord.builder();
var rootNode = createRootNode(data, keyRootLength);
auditRecordBuilder.setAuditRecordData(rootNode);
return auditRecordBuilder;
}
@SuppressWarnings("unchecked")
private static HashMap<String, Serializable> createRootNode(Map<String, Serializable> data, int keyRootLength)
{
var rootNode = new HashMap<String, Serializable>();
data.forEach((k, v) -> {
var keys = k.substring(keyRootLength).split("/");
var current = rootNode;
for (int i = 0; i < keys.length - 1; i++)
{
current = (HashMap<String, Serializable>) current.computeIfAbsent(keys[i], newMap -> new HashMap<String, Serializable>());
}
current.put(keys[keys.length - 1], decodeValueByInstance(v));
});
return rootNode;
}
@SuppressWarnings("unchecked")
private static Serializable decodeValueByInstance(Serializable value)
{
if (value instanceof HashMap<?, ?>)
{
return createRootNode((HashMap<String, Serializable>) value, 0);
}
else if (value instanceof NodeRef)
{
return ((NodeRef) value).getId();
}
else
{
return value;
}
}
}

View File

@@ -58,21 +58,6 @@ public interface AuditModelRegistry
*/
public boolean isAuditEnabled();
/**
* Determines whether audit values should be stored in database. <code>True</code> by default if not changed by property.
*
* @return <code>true</code> if audit is enabled.
*/
boolean isAuditingToDatabaseEnabled();
/**
* Determines whether audit values should be stored in audit storage.
*
* @return <code>true</code> if auditing to Audit Storage is enabled.
*
*/
boolean isAuditingToAuditStorageEnabled();
/**
* Get a map of all audit applications key by name
*

View File

@@ -85,9 +85,6 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
{
/** The name of the global enablement property. */
public static final String PROPERTY_AUDIT_ENABLED = "audit.enabled";
private static final String AUDITING_TO_DATABASE = ".auditingToDatabase";
private static final String AUDITING_TO_AUDIT_STORAGE = ".auditingToAuditStorage";
/** The name of the strict loading flag. */
public static final String PROPERTY_AUDIT_CONFIG_STRICT = "audit.config.strict";
/** The XSD classpath location. */
@@ -252,26 +249,6 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
return value != null && value.equalsIgnoreCase("true");
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAuditingToDatabaseEnabled()
{
String value = getProperty(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_DATABASE);
return value == null || value.equalsIgnoreCase("true");
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAuditingToAuditStorageEnabled()
{
String value = getProperty(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_AUDIT_STORAGE);
return value != null && value.equalsIgnoreCase("true");
}
/**
* Enables audit and registers an audit model at a given URL. Does not register across the cluster and should only be used for unit test purposes.
*
@@ -319,8 +296,6 @@ public class AuditModelRegistryImpl extends AbstractPropertyBackedBean implement
// Default value for global enabled property
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED, false);
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_DATABASE, true);
properties.put(AUDIT_PROPERTY_AUDIT_ENABLED + AUDITING_TO_AUDIT_STORAGE, false);
// Let's search for config files in the appropriate places. The individual applications they contain can still
// be enabled/disabled by the bean properties

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -102,7 +102,6 @@ import org.alfresco.service.namespace.QName;
* @author Jesper Steen Møller
* @author Derek Hulley
*/
@SuppressWarnings("PMD.CyclomaticComplexity")
@AlfrescoPublicApi
abstract public class AbstractMappingMetadataExtracter implements MetadataExtracter, MetadataEmbedder, BeanNameAware, ApplicationContextAware
{
@@ -1119,15 +1118,6 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
return extract(nodeRef, reader, overwritePolicy, destination, mapping);
}
/**
* {@inheritDoc}
*/
@Override
public Map<QName, Serializable> extract(NodeRef nodeRef, ContentReader reader, OverwritePolicy overwritePolicy, Map<QName, Serializable> destination)
{
return extract(nodeRef, reader, overwritePolicy, destination, mapping);
}
/**
* {@inheritDoc}
*/
@@ -1164,7 +1154,7 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
// Check that the content has some meat
if (reader.getSize() > 0 && reader.exists())
{
rawMetadata = extractRaw(nodeRef, reader, getLimits(reader.getMimetype()), overwritePolicy);
rawMetadata = extractRaw(nodeRef, reader, getLimits(reader.getMimetype()));
}
else
{
@@ -2012,7 +2002,7 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
}
/**
* Exception wrapper to handle exceeded limits imposed by {@link MetadataExtracterLimits} {@link AbstractMappingMetadataExtracter#extractRaw(NodeRef, ContentReader, MetadataExtracterLimits,OverwritePolicy)}
* Exception wrapper to handle exceeded limits imposed by {@link MetadataExtracterLimits} {@link AbstractMappingMetadataExtracter#extractRaw(NodeRef, ContentReader, MetadataExtracterLimits)}
*/
private class LimitExceededException extends Exception
{
@@ -2042,7 +2032,7 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
* All exception conditions can be handled.
*/
private Map<String, Serializable> extractRaw(NodeRef nodeRef,
ContentReader reader, MetadataExtracterLimits limits, OverwritePolicy overwritePolicy) throws Throwable
ContentReader reader, MetadataExtracterLimits limits) throws Throwable
{
if (reader.getSize() > limits.getMaxDocumentSizeMB() * MEGABYTE_SIZE)
{
@@ -2069,12 +2059,6 @@ abstract public class AbstractMappingMetadataExtracter implements MetadataExtrac
}
}
return extractRawInThread(nodeRef, reader, limits, overwritePolicy);
}
protected Map<String, Serializable> extractRawInThread(NodeRef nodeRef, ContentReader reader, MetadataExtracterLimits limits, OverwritePolicy policy)
throws Throwable
{
return extractRawInThread(nodeRef, reader, limits);
}

View File

@@ -93,9 +93,6 @@ public class AsynchronousExtractor extends AbstractMappingMetadataExtracter
private static final String METADATA = "metadata";
private static final Map<String, Serializable> EMPTY_METADATA = Collections.emptyMap();
private static final OverwritePolicy DEFAULT_OVERWRITE_POLICY = OverwritePolicy.PRAGMATIC;
private OverwritePolicy extractOverwritePolicy = DEFAULT_OVERWRITE_POLICY;
private final ObjectMapper jsonObjectMapper = new ObjectMapper();
private NodeService nodeService;
@@ -263,9 +260,9 @@ public class AsynchronousExtractor extends AbstractMappingMetadataExtracter
}
@Override
protected Map<String, Serializable> extractRawInThread(NodeRef nodeRef, ContentReader reader, MetadataExtracterLimits limits, OverwritePolicy overwritePolicy) throws Throwable
protected Map<String, Serializable> extractRawInThread(NodeRef nodeRef, ContentReader reader, MetadataExtracterLimits limits)
throws Throwable
{
this.extractOverwritePolicy = overwritePolicy != null ? overwritePolicy : DEFAULT_OVERWRITE_POLICY;
Map<String, String> options = getExtractOptions(nodeRef, reader, limits);
transformInBackground(nodeRef, reader, MIMETYPE_METADATA_EXTRACT, EXTRACT, options);
return EMPTY_METADATA;
@@ -464,7 +461,7 @@ public class AsynchronousExtractor extends AbstractMappingMetadataExtracter
}
// Remove well know entries from the map that drive how the real metadata is applied.
OverwritePolicy overwritePolicy = removeOverwritePolicy(metadata, "sys:overwritePolicy", extractOverwritePolicy);
OverwritePolicy overwritePolicy = removeOverwritePolicy(metadata, "sys:overwritePolicy", OverwritePolicy.PRAGMATIC);
Boolean enableStringTagging = removeBoolean(metadata, "sys:enableStringTagging", false);
Boolean carryAspectProperties = removeBoolean(metadata, "sys:carryAspectProperties", true);
List<String> stringTaggingSeparators = removeTaggingSeparators(metadata, "sys:stringTaggingSeparators",

View File

@@ -404,24 +404,6 @@ public interface MetadataExtracter extends ContentWorker
return extract(reader, destination);
}
/**
* Identical to {@link #extract(ContentReader, OverwritePolicy ,Map)} but with the addition of the {@code NodeRef} being acted on. By default, the method without the {@code NodeRef} is called.
*
* @param nodeRef
* the node being acted on.
* @param reader
* the source of the content
* @param destination
* the map of properties to populate (essentially a return value)
* @return Returns a map of all properties on the destination map that were added or modified. If the return map is empty, then no properties were modified.
* @throws ContentIOException
* if a detectable error occurs
*/
default Map<QName, Serializable> extract(NodeRef nodeRef, ContentReader reader, OverwritePolicy overwritePolicy, Map<QName, Serializable> destination)
{
return extract(reader, overwritePolicy, destination);
}
/**
* Identical to {@link #extract(ContentReader, OverwritePolicy, Map, Map)} but with the addition of the {@code NodeRef} being acted on. By default, the method without the {@code NodeRef} is called.
*

View File

@@ -2066,7 +2066,7 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
Node node = getNodeNotNull(nodeId, false);
// Handle sys:referenceable
ReferenceablePropertiesEntity.addReferenceableProperties(node.getId(), node.getNodeRef(), props);
ReferenceablePropertiesEntity.addReferenceableProperties(node, props);
// Handle sys:localized
LocalizedPropertiesEntity.addLocalizedProperties(localeDAO, node, props);
// Handle cm:auditable

View File

@@ -86,8 +86,10 @@ public class ReferenceablePropertiesEntity
/**
* Adds all {@link ContentModel#ASPECT_REFERENCEABLE referencable} properties.
*/
public static void addReferenceableProperties(Long nodeId, NodeRef nodeRef, Map<QName, Serializable> properties)
public static void addReferenceableProperties(Node node, Map<QName, Serializable> properties)
{
Long nodeId = node.getId();
NodeRef nodeRef = node.getNodeRef();
properties.put(ContentModel.PROP_STORE_PROTOCOL, nodeRef.getStoreRef().getProtocol());
properties.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
properties.put(ContentModel.PROP_NODE_UUID, nodeRef.getId());

View File

@@ -116,7 +116,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
private static final String SELECT_NODE_MAX_ID = "alfresco.node.select_NodeMaxId";
private static final String SELECT_NODE_INTERVAL_BY_TYPE = "alfresco.node.select_MinMaxNodeIdForNodeType";
private static final String SELECT_NODES_WITH_ASPECT_IDS = "alfresco.node.select_NodesWithAspectIds";
private static final String SELECT_NODES_WITH_ASPECT_IDS_LIMITED = "alfresco.node.select.select_NodesWithAspectIds_Limited";
private static final String SELECT_NODES_WITH_ASPECT_IDS_LIMITED = "alfresco.node.select_NodesWithAspectIds_Limited";
private static final String INSERT_NODE_ASSOC = "alfresco.node.insert.insert_NodeAssoc";
private static final String UPDATE_NODE_ASSOC = "alfresco.node.update_NodeAssoc";
private static final String DELETE_NODE_ASSOC = "alfresco.node.delete_NodeAssoc";

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -97,26 +97,19 @@ public abstract class EventConsolidator<REF extends EntityRef, RES extends Resou
* @return the {@link RepoEvent} instance
*/
public RepoEvent<DataAttributes<RES>> getRepoEvent(EventInfo eventInfo)
{
final RepoEvent.Builder<DataAttributes<RES>> builder = RepoEvent.builder();
configureRepoEventBuilder(builder, eventInfo);
return builder.build();
}
protected void configureRepoEventBuilder(RepoEvent.Builder<DataAttributes<RES>> builder, EventInfo eventInfo)
{
EventType eventType = getDerivedEvent();
DataAttributes<RES> eventData = buildEventData(eventInfo, resource, eventType);
builder.setId(eventInfo.getId())
return RepoEvent.<DataAttributes<RES>> builder()
.setId(eventInfo.getId())
.setSource(eventInfo.getSource())
.setTime(eventInfo.getTimestamp())
.setType(eventType.getType())
.setData(eventData)
.setDataschema(EventJSONSchema.getSchemaV1(eventType));
.setDataschema(EventJSONSchema.getSchemaV1(eventType))
.build();
}
/**

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -38,7 +38,7 @@ import org.alfresco.util.Pair;
*/
public enum EventJSONSchema
{
NODE_CREATED_V1("nodeCreated", 1, EventType.NODE_CREATED), NODE_UPDATED_V1("nodeUpdated", 1, EventType.NODE_UPDATED), NODE_DELETED_V1("nodeDeleted", 1, EventType.NODE_DELETED), CHILD_ASSOC_CREATED_V1("childAssocCreated", 1, EventType.CHILD_ASSOC_CREATED), CHILD_ASSOC_DELETED_V1("childAssocDeleted", 1, EventType.CHILD_ASSOC_DELETED), PEER_ASSOC_CREATED_V1("peerAssocCreated", 1, EventType.PEER_ASSOC_CREATED), PEER_ASSOC_DELETED_V1("peerAssocDeleted", 1, EventType.PEER_ASSOC_DELETED), PERMISSION_UPDATED_V1("permissionUpdated", 1, EventType.PERMISSION_UPDATED), AUDIT_ENTRY_CREATED_V1("auditEntryCreated", 1, EventType.AUDIT_ENTRY_CREATED);
NODE_CREATED_V1("nodeCreated", 1, EventType.NODE_CREATED), NODE_UPDATED_V1("nodeUpdated", 1, EventType.NODE_UPDATED), NODE_DELETED_V1("nodeDeleted", 1, EventType.NODE_DELETED), CHILD_ASSOC_CREATED_V1("childAssocCreated", 1, EventType.CHILD_ASSOC_CREATED), CHILD_ASSOC_DELETED_V1("childAssocDeleted", 1, EventType.CHILD_ASSOC_DELETED), PEER_ASSOC_CREATED_V1("peerAssocCreated", 1, EventType.PEER_ASSOC_CREATED), PEER_ASSOC_DELETED_V1("peerAssocDeleted", 1, EventType.PEER_ASSOC_DELETED), PERMISSION_UPDATED_V1("permissionUpdated", 1, EventType.PERMISSION_UPDATED);
private static final String PREFIX = "https://api.alfresco.com/schema/event/repo/v";

View File

@@ -4,21 +4,21 @@
* %%
* Copyright (C) 2005 - 2016 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
* 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%
@@ -34,7 +34,7 @@ import org.alfresco.service.cmr.action.ActionService;
/**
* Scripted Action service for describing and executing actions against Nodes.
*
*
* @author davidc
*/
public final class Actions extends BaseScopableProcessorExtension
@@ -44,7 +44,7 @@ public final class Actions extends BaseScopableProcessorExtension
/**
* Set the service registry
*
*
* @param serviceRegistry
* the service registry
*/
@@ -55,7 +55,7 @@ public final class Actions extends BaseScopableProcessorExtension
/**
* Gets the list of registered action names
*
*
* @return the registered action names
*/
public String[] getRegistered()
@@ -73,7 +73,7 @@ public final class Actions extends BaseScopableProcessorExtension
/**
* Create an Action
*
*
* @param actionName
* the action name
* @return the action

View File

@@ -1,171 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2020 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%
*/
/*
* Copyright (C) 2005 - 2025 Alfresco Software Limited
*
* This file is part of Alfresco
*
* 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/>.
*/
package org.alfresco.repo.jscript;
import org.apache.commons.lang3.Strings;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.evaluator.CompareContentConditionEvaluator;
import org.alfresco.repo.forms.FormData;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* JavaScript wrapper for the "extract-metadata" action.
* <p>
* This class provides a scriptable interface to trigger metadata extraction actions within the Alfresco repository.</br>
* It is similar to {@link Actions} class but is dedicated to metadata extraction functionality.
*
* </br>
*
* @author Sayan Bhattacharya
*/
public final class MetaDataExtractAction extends BaseScopableProcessorExtension
{
private static final Log LOG = LogFactory.getLog(MetaDataExtractAction.class);
private final static String ACTION_NAME = "extract-metadata";
private ContentService contentService;
private ServiceRegistry services;
/**
* Set the service registry
*
* @param serviceRegistry
* the service registry
*/
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.services = serviceRegistry;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* Create a new metadata extraction action instance
*
* @param setActionContext
* if true, sets the action context to "scriptaction".
* @return the newly created action
*/
public ScriptAction create(boolean isContentChanged)
{
ScriptAction scriptAction = null;
ActionService actionService = services.getActionService();
ActionDefinition actionDef = actionService.getActionDefinition(ACTION_NAME);
if (actionDef != null)
{
Action action = actionService.createAction(ACTION_NAME);
ActionCondition actionCondition = actionService.createActionCondition(CompareContentConditionEvaluator.NAME);
actionCondition.setParameterValue(CompareContentConditionEvaluator.PARAM_IS_CONTENT_CHANGED, isContentChanged);
action.addActionCondition(actionCondition);
scriptAction = new ScriptAction(this.services, action, actionDef);
scriptAction.setScope(getScope());
}
return scriptAction;
}
/**
* Check if the content has been updated in the form data compared to the existing content of the node.
*
* @param itemId
* @param formData
* @return true if content has changed, false otherwise
*/
public boolean isContentChanged(String itemId, FormData formData)
{
try
{
NodeRef nodeRef = NodeRef.isNodeRef(itemId) ? new NodeRef(itemId) : parseNodeRef(itemId);
if (nodeRef == null)
{
return false;
}
ContentReader reader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
String contentString = reader.getContentString();
FormData.FieldData fieldData = formData.getFieldData("prop_cm_content");
if (fieldData == null || fieldData.getValue() == null)
{
return false;
}
String propCmContent = String.valueOf(fieldData.getValue());
return !Strings.CS.equals(contentString, propCmContent);
}
catch (Exception e)
{
if (LOG.isDebugEnabled())
{
LOG.debug("Unable to determine if content has changed for node: " + itemId, e);
}
return false;
}
}
private NodeRef parseNodeRef(String itemId)
{
String[] parts = itemId.split("/");
return (parts.length == 3) ? new NodeRef(parts[0], parts[1], parts[2]) : null;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -124,9 +124,6 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
/** Number of (bytecode) instructions that will trigger the observer */
private int observerInstructionCount = 100;
/** Flag to enable or disable scope cleaning at the end of each script execution */
private boolean cleanScope = true;
/** Custom context factory */
public static AlfrescoContextFactory contextFactory;
@@ -213,15 +210,6 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
this.observerInstructionCount = observerInstructionCount;
}
/**
* @param cleanScope
* true to enable scope cleaning at the end of each script execution - set to false to disable this feature.
*/
public void setCleanScope(boolean cleanScope)
{
this.cleanScope = cleanScope;
}
/**
* @see org.alfresco.service.cmr.repository.ScriptProcessor#reset()
*/
@@ -631,7 +619,7 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
}
finally
{
if (!secure && cleanScope)
if (!secure)
{
unsetScope(model, scope);
}

View File

@@ -1130,10 +1130,7 @@ public class Search extends BaseScopableProcessorExtension implements Initializi
// for example the key could be: {!afts}@{http://www.alfresco.org/model/content/1.0}created:[NOW/DAY-1DAY TO NOW/DAY+1DAY]
// qName => @{http://www.alfresco.org/model/content/1.0}created
// 7 => {!afts}
if (key.startsWith("{!afts}"))
{
key = key.substring(7);
}
key = key.substring(7);
String qName = key.substring(0, key.lastIndexOf(':'));
// Retrieve the previous facet queries

View File

@@ -862,18 +862,9 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl implements Extens
if (aspectDef != null)
{
// Remove default properties
Map<QName, Serializable> propsBefore = nodeDAO.getNodeProperties(nodeId);
Map<QName, PropertyDefinition> propertyDefs = aspectDef.getProperties();
Set<QName> propertyToRemoveQNames = propertyDefs.keySet();
boolean propertiesRemoved = nodeDAO.removeNodeProperties(nodeId, propertyToRemoveQNames);
if (propertiesRemoved)
{
invokeOnUpdateProperties(
nodeRef,
propsBefore, // before
nodeDAO.getNodeProperties(nodeId)); // after
}
nodeDAO.removeNodeProperties(nodeId, propertyToRemoveQNames);
// Remove child associations
// We have to iterate over the associations and remove all those between the parent and child

View File

@@ -28,10 +28,8 @@ package org.alfresco.repo.node.getchildren;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.node.AuditablePropertiesEntity;
import org.alfresco.repo.domain.node.NodeEntity;
import org.alfresco.repo.domain.node.NodePropertyEntity;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* Filterable/Sortable Node Entity
@@ -44,17 +42,12 @@ import org.alfresco.service.cmr.repository.StoreRef;
public class FilterSortNodeEntity
{
private Long id; // node id
private String nodeUuid;
private Long typeQNameId;
private AuditablePropertiesEntity auditablePropertiesEntity;
private NodeEntity node;
private NodePropertyEntity prop1;
private NodePropertyEntity prop2;
private NodePropertyEntity prop3;
private String storeProtocol;
private String storeIdentifier;
// Supplemental query-related parameters
private Long parentNodeId;
private Long prop1qnameId;
@@ -87,26 +80,6 @@ public class FilterSortNodeEntity
this.id = id;
}
public String getNodeUuid()
{
return nodeUuid;
}
public void setNodeUuid(String nodeUuid)
{
this.nodeUuid = nodeUuid;
}
public Long getTypeQNameId()
{
return typeQNameId;
}
public void setTypeQNameId(Long typeQNameId)
{
this.typeQNameId = typeQNameId;
}
public String getPattern()
{
return pattern;
@@ -163,16 +136,6 @@ public class FilterSortNodeEntity
this.namePropertyQNameId = namePropertyQNameId;
}
public AuditablePropertiesEntity getAuditablePropertiesEntity()
{
return auditablePropertiesEntity;
}
public void setAuditablePropertiesEntity(AuditablePropertiesEntity auditablePropertiesEntity)
{
this.auditablePropertiesEntity = auditablePropertiesEntity;
}
public NodePropertyEntity getProp1()
{
return prop1;
@@ -203,24 +166,14 @@ public class FilterSortNodeEntity
this.prop3 = prop3;
}
public String getStoreProtocol()
public NodeEntity getNode()
{
return storeProtocol;
return node;
}
public void setStoreProtocol(String storeProtocol)
public void setNode(NodeEntity childNode)
{
this.storeProtocol = storeProtocol;
}
public String getStoreIdentifier()
{
return storeIdentifier;
}
public void setStoreIdentifier(String storeIdentifier)
{
this.storeIdentifier = storeIdentifier;
this.node = childNode;
}
// Supplemental query-related parameters
@@ -304,9 +257,4 @@ public class FilterSortNodeEntity
{
this.isPrimary = isPrimary;
}
public NodeRef createNodeRef()
{
return new NodeRef(new StoreRef(storeProtocol, storeIdentifier), nodeUuid);
}
}

View File

@@ -48,6 +48,7 @@ import org.alfresco.query.CannedQueryParameters;
import org.alfresco.query.CannedQuerySortDetails;
import org.alfresco.query.CannedQuerySortDetails.SortOrder;
import org.alfresco.repo.domain.node.AuditablePropertiesEntity;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.node.NodeEntity;
import org.alfresco.repo.domain.node.NodePropertyEntity;
@@ -774,8 +775,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (results.size() >= BATCH_SIZE)
{
// batch
preloadNodes();
filterSort();
preloadFilterSort();
}
results.add(result);
@@ -788,27 +788,24 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (results.size() >= 0)
{
// finish batch
preloadNodes();
filterSort();
preloadFilterSort();
}
}
private void preloadNodes()
private void preloadFilterSort()
{
List<NodeRef> nodeRefs = new ArrayList<>(results.size());
for (FilterSortNodeEntity result : results)
{
nodeRefs.add(result.createNodeRef());
nodeRefs.add(result.getNode().getNodeRef());
}
preload(nodeRefs);
}
private void filterSort()
{
for (FilterSortNodeEntity result : results)
{
NodeRef nodeRef = result.createNodeRef();
Node node = result.getNode();
NodeRef nodeRef = node.getNodeRef();
Map<NodePropertyKey, NodePropertyValue> propertyValues = new HashMap<NodePropertyKey, NodePropertyValue>(3);
@@ -833,7 +830,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
Map<QName, Serializable> propVals = nodePropertyHelper.convertToPublicProperties(propertyValues);
// Add referenceable / spoofed properties (including spoofed name if null)
ReferenceablePropertiesEntity.addReferenceableProperties(result.getId(), nodeRef, propVals);
ReferenceablePropertiesEntity.addReferenceableProperties(node, propVals);
// special cases
@@ -855,7 +852,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
}
// Auditable props (eg. cm:creator, cm:created, cm:modifier, cm:modified, ...)
AuditablePropertiesEntity auditableProps = result.getAuditablePropertiesEntity();
AuditablePropertiesEntity auditableProps = node.getAuditableProperties();
if (auditableProps != null)
{
for (Map.Entry<QName, Serializable> entry : auditableProps.getAuditableProperties().entrySet())
@@ -865,7 +862,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
}
// Node type
Long nodeTypeQNameId = result.getTypeQNameId();
Long nodeTypeQNameId = node.getTypeQNameId();
if (nodeTypeQNameId != null)
{
Pair<Long, QName> pair = qnameDAO.getQName(nodeTypeQNameId);

View File

@@ -81,19 +81,11 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
public static final QName DEFAULT_RENDITION_CONTENT_PROP = ContentModel.PROP_CONTENT;
public static final String DEFAULT_MIMETYPE = MimetypeMap.MIMETYPE_TEXT_PLAIN;
public static final String MIMETYPE_METADATA_EXTRACT = "alfresco-metadata-extract";
public static final String MIMETYPE_METADATA_EMBED = "alfresco-metadata-embed";
public static final String DEFAULT_ENCODING = "UTF-8";
public static final int SOURCE_HAS_NO_CONTENT = -1;
public static final int RENDITION2_DOES_NOT_EXIST = -2;
// Allowed mimetypes to support text or metadata extract transforms when thumbnails are disabled.
private static final Set<String> ALLOWED_MIMETYPES = Set.of(
MimetypeMap.MIMETYPE_TEXT_PLAIN,
MIMETYPE_METADATA_EXTRACT,
MIMETYPE_METADATA_EMBED);
private static Log logger = LogFactory.getLog(RenditionService2Impl.class);
// As Async transforms and renditions are so similar, this class provides a way to provide the code that is different.
@@ -296,7 +288,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
{
try
{
if (!isAsyncAllowed(renderOrTransform))
if (!isEnabled())
{
throw new RenditionService2Exception("Async transforms and renditions are disabled " +
"(system.thumbnail.generate=false or renditionService2.enabled=false).");
@@ -975,24 +967,4 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
}
}
}
// Checks if the given transform callback is a text extract transform for content indexing or metadata extract/embed.
private boolean isTextOrMetadataExtractTransform(RenderOrTransformCallBack renderOrTransform)
{
RenditionDefinition2 renditionDefinition = renderOrTransform.getRenditionDefinition();
return renditionDefinition != null && ALLOWED_MIMETYPES.contains(renditionDefinition.getTargetMimetype());
}
private boolean isAsyncAllowed(RenderOrTransformCallBack renderOrTransform)
{
// If enabled is false, all async transforms/renditions must be blocked
if (!enabled)
{
return false;
}
// If thumbnails are disabled, allow only text extract or metadata extract/embed transforms
return thumbnailsEnabled || isTextOrMetadataExtractTransform(renderOrTransform);
}
}

View File

@@ -74,7 +74,7 @@ import com.nimbusds.oauth2.sdk.id.Identifier;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.openid.connect.sdk.claims.PersonClaims;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hc.client5.http.classic.HttpClient;

View File

@@ -42,7 +42,7 @@ import jakarta.servlet.http.HttpServletResponse;
import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.oauth2.sdk.id.Identifier;
import com.nimbusds.oauth2.sdk.id.State;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.oauth2.client.registration.ClientRegistration;

View File

@@ -237,12 +237,6 @@
<bean id="no-condition" class="org.alfresco.repo.action.evaluator.NoConditionEvaluator" parent="action-condition-evaluator">
</bean>
<bean id="compare-content" class="org.alfresco.repo.action.evaluator.CompareContentConditionEvaluator" parent="action-condition-evaluator">
<property name="publicCondition">
<value>false</value>
</property>
</bean>
<bean id="compare-property-value" class="org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator" parent="action-condition-evaluator">
<property name="nodeService">
<ref bean="nodeService" />

View File

@@ -37,9 +37,8 @@
<property name="properties" ref="global-properties" />
</bean>
</property>
<property name="auditRecordReporter" ref="auditRecordReporter"/>
</bean>
<!-- User Audit Filter -->
<bean id="userAuditFilter" class="org.alfresco.repo.audit.UserAuditFilter">
@@ -109,8 +108,5 @@
<!-- Reference in the audit registry managed bean -->
<alias name="Audit" alias="auditModel.modelRegistry"/>
<!-- Audit Record Reported -->
<bean id="auditRecordReporter" class="org.alfresco.repo.audit.AuditRecordReporterImpl"/>
</beans>
</beans>

View File

@@ -133,15 +133,7 @@
<resultMap id="result_FilterSortNode" type="FilterSortNode">
<id property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="nodeUuid" column="uuid" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="typeQNameId" column="type_qname_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="auditablePropertiesEntity.auditCreator" column="audit_creator" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditCreated" column="audit_created" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditModifier" column="audit_modifier" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditModified" column="audit_modified" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditAccessed" column="audit_accessed" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="prop1.nodeId" column="prop1_node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="prop1.key.qnameId" column="prop1_qname_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="prop1.key.localeId" column="prop1_locale_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
@@ -177,9 +169,9 @@
<result property="prop3.value.floatValue" column="prop3_float_value" jdbcType="FLOAT" javaType="java.lang.Float"/>
<result property="prop3.value.doubleValue" column="prop3_double_value" jdbcType="FLOAT" javaType="java.lang.Double"/>
<result property="prop3.value.stringValue" column="prop3_string_value" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="storeProtocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="storeIdentifier" column="identifier" jdbcType="VARCHAR" javaType="java.lang.String"/>
<association property="node" resultMap="alfresco.node.result_Node"/>
</resultMap>
<resultMap id="result_ArchivedNodes" type="ArchivedNodes">
@@ -790,6 +782,25 @@
<if test="ordered == true">order by node.id ASC</if>
</select>
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="result_NodeRef" >
select
node.id as id,
store.protocol as protocol,
store.identifier as identifier,
node.uuid as uuid
from
alf_node_aspects na
join alf_node node on (na.node_id = node.id)
left join alf_store store on (store.id = node.store_id)
where
<![CDATA[na.node_id >= #{idOne}]]>
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
and na.qname_id in
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
<if test="ordered == true">order by node.id ASC</if>
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
</select>
<!-- Common results for result_NodeAssoc -->
<sql id="select_NodeAssoc_Results">
select
@@ -980,8 +991,8 @@
</select>
<!-- GetChildren - with explicit prop filtering and/or sorting -->
<select id="select_GetChildrenCannedQueryWithProps" parameterType="FilterSortNode" resultMap="result_FilterSortNode" flushCache="true">
select distinct
<select id="select_GetChildrenCannedQueryWithProps" parameterType="FilterSortNode" resultMap="result_FilterSortNode">
select
childNode.id as id,
childNode.version as version,
childStore.id as store_id,
@@ -997,7 +1008,7 @@
childNode.audit_created as audit_created,
childNode.audit_modifier as audit_modifier,
childNode.audit_modified as audit_modified,
childNode.audit_accessed as audit_accessed
childNode.audit_accessed as audit_accessed
<if test="prop1qnameId != null">
, prop1.node_id as prop1_node_id,
prop1.qname_id as prop1_qname_id,
@@ -1075,6 +1086,9 @@
#{item}
</foreach>
</if>
<if test="prop1qnameId == null and auditableProps == false">
<include refid="alfresco.node.select_ChildAssoc_OrderBy"/>
</if>
</select>
<!-- GetChildren - with no explicit sorting (or prop filtering) - note: still filtered by child type (and optionally primary or secondary) -->
@@ -1552,4 +1566,4 @@
</foreach>
</delete>
</mapper>
</mapper>

View File

@@ -30,23 +30,4 @@
<![CDATA[and commit_time_ms <= #{maxCommitTime}]]>
</select>
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="alfresco.node.result_NodeRef" >
select
node.id as id,
store.protocol as protocol,
store.identifier as identifier,
node.uuid as uuid
from
alf_node_aspects na
join alf_node node on (na.node_id = node.id)
left join alf_store store on (store.id = node.store_id)
where
<![CDATA[na.node_id >= #{idOne}]]>
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
and na.qname_id in
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
<if test="ordered == true">order by node.id ASC</if>
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
</select>
</mapper>
</mapper>

View File

@@ -30,23 +30,4 @@
<![CDATA[and commit_time_ms <= #{maxCommitTime}]]>
</select>
<select id="select_NodesWithAspectIds_Limited" parameterType="Ids" resultMap="alfresco.node.result_NodeRef" >
select
node.id as id,
store.protocol as protocol,
store.identifier as identifier,
node.uuid as uuid
from
alf_node_aspects na
join alf_node node on (na.node_id = node.id)
left join alf_store store on (store.id = node.store_id)
where
<![CDATA[na.node_id >= #{idOne}]]>
<if test="idTwo != null"><![CDATA[and na.node_id < #{idTwo}]]></if>
and na.qname_id in
<foreach item="item" index="i" collection="ids" open="(" separator="," close=")">#{item}</foreach>
<if test="ordered == true">order by node.id ASC</if>
<if test="maxResults != null"><![CDATA[limit #{maxResults}]]></if>
</select>
</mapper>
</mapper>

View File

@@ -286,8 +286,6 @@ audit.alfresco-access.enabled=false
audit.alfresco-access.sub-actions.enabled=false
audit.cmischangelog.enabled=false
audit.dod5015.enabled=false
audit.enabled.auditingToAuditStorage=false
audit.enabled.auditingToDatabase=true
# Setting this flag to true will force startup failure when invalid audit configurations are detected
audit.config.strict=false
# Audit map filter for AccessAuditor - restricts recorded events to user driven events
@@ -1396,9 +1394,6 @@ scripts.execution.maxMemoryUsedInBytes=-1
# Number of instructions that will trigger the observer
scripts.execution.observerInstructionCount=5000
# Flag to control if the scope is cleaned at the end of script execution
scripts.execution.clean.scope=true
# Default value being used in POST/size-details endpoint to partition a huge folder into smaller chunks
# so that we can compute more efficiently and consolidate all sizes into a single unit.
default.async.folder.items=1000

View File

@@ -60,9 +60,6 @@
<property name="observerInstructionCount">
<value>${scripts.execution.observerInstructionCount}</value>
</property>
<property name="cleanScope">
<value>${scripts.execution.clean.scope}</value>
</property>
</bean>
<!-- base config implementation that script extension beans extend from - for auto registration
@@ -104,17 +101,6 @@
</property>
</bean>
<bean id="metadataExtractServiceScript" parent="baseJavaScriptExtension"
class="org.alfresco.repo.jscript.MetaDataExtractAction">
<property name="extensionName">
<value>metadataExtractAction</value>
</property>
<property name="contentService" ref="ContentService" />
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
</bean>
<bean id="imapScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.Imap">
<property name="extensionName">
<value>imap</value>

View File

@@ -48,7 +48,6 @@ import org.alfresco.util.testing.category.NonBuildTests;
org.alfresco.repo.audit.UserAuditFilterTest.class,
org.alfresco.repo.audit.AuditMethodInterceptorTest.class,
org.alfresco.repo.audit.access.AccessAuditorTest.class,
org.alfresco.repo.audit.AuditRecordUtilsTest.class,
// the following test will lock up the DB if run in the applicationContext_01 test suite
org.alfresco.repo.activities.feed.FeedNotifierTest.class,

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -66,7 +66,6 @@ import org.alfresco.util.testing.category.NonBuildTests;
org.alfresco.repo.importer.FileImporterTest.class,
org.alfresco.repo.importer.ImporterComponentTest.class,
org.alfresco.repo.jscript.PeopleTest.class,
org.alfresco.repo.jscript.MetaDataExtractActionTest.class,
org.alfresco.repo.jscript.RhinoScriptTest.class,
// needs a clean DB to run

View File

@@ -28,7 +28,6 @@ package org.alfresco.repo.action.executer;
import static org.awaitility.Awaitility.await;
import java.io.Serializable;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -47,8 +46,6 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.metadata.AbstractMappingMetadataExtracter;
import org.alfresco.repo.content.metadata.MetadataExtracterRegistry;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.jscript.MetaDataExtractAction;
import org.alfresco.repo.jscript.ScriptAction;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -77,10 +74,6 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
protected static final String QUICK_DESCRIPTION = "Pangram, fox, dog, Gym class featuring a brown fox and lazy dog";
protected static final String QUICK_CREATOR = "Nevin Nollop";
protected static final String QUICK_UPDATED_TITLE = "The hot dog is eaten by the city fox";
protected static final String QUICK_UPDATED_DESCRIPTION = "Pangram, fox, dog, Gym class featuring only brown fox";
protected static final String QUICK_UPDATED_CREATOR = "Friday";
private NodeService nodeService;
private ContentService contentService;
private MetadataExtracterRegistry registry;
@@ -91,8 +84,6 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
private ContentMetadataExtracter executer;
private MetaDataExtractAction extractAction;
private final static String ID = GUID.generate();
@Before
@@ -125,9 +116,6 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
// Get the executer instance
this.executer = (ContentMetadataExtracter) this.applicationContext.getBean("extract-metadata");
// get the js script action
this.extractAction = (MetaDataExtractAction) this.applicationContext.getBean("metadataExtractServiceScript");
}
/**
@@ -363,45 +351,4 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
}
});
}
@Test
public void testUsingScriptAction_WhenContentChanged() throws Exception
{
// update the content
ContentWriter cw = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
cw.setMimetype(MimetypeMap.MIMETYPE_PDF);
cw.putContent(AbstractContentTransformerTest.loadNamedQuickTestFile("quickupdated.pdf"));
// Make the nodeRef visible to other transactions as it will need to be in async requests
TestTransaction.flagForCommit();
TestTransaction.end();
// Execute the action
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
ScriptAction action = extractAction.create(true);
action.execute(nodeRef, false, false);
return null;
}
});
// Need to wait for the async extract
await().pollInSameThread()
.atMost(Duration.ofSeconds(100))
.until(() -> nodeService.getProperty(nodeRef, ContentModel.PROP_DESCRIPTION), Objects::nonNull);
// Check that the properties have been preserved, but that description has been set
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable
{
assertEquals(QUICK_UPDATED_TITLE, nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE));
assertEquals(QUICK_UPDATED_CREATOR, nodeService.getProperty(nodeRef, ContentModel.PROP_AUTHOR));
assertEquals(QUICK_UPDATED_DESCRIPTION, nodeService.getProperty(nodeRef, ContentModel.PROP_DESCRIPTION));
return null;
}
});
}
}

View File

@@ -877,7 +877,6 @@ public class AuditComponentTest extends TestCase
auditModelRegistry.loadAuditModels();
auditModelRegistry.setProperty("audit.enabled", "true");
auditModelRegistry.setProperty("audit.enabled.auditingToDatabase", "true");
auditModelRegistry.setProperty("audit.app1.enabled", "true");
auditModelRegistry.setProperty("audit.filter.app1.default.enabled", "true");

View File

@@ -1,123 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2025 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.audit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.Serializable;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
public class AuditRecordUtilsTest
{
@SuppressWarnings("unchecked")
@Test
public void testGenerateAuditRecordBuilderTest()
{
var testData = new HashMap<String, Serializable>();
testData.put("/alfresco-access/transaction/path", "/app:company_home");
testData.put("/alfresco-access/transaction/user", "admin");
testData.put("/alfresco-access/transaction/sub-actions", "updateNodeProperties");
var now = Instant.now();
testData.put("/alfresco-access/transaction/properties/from", (Serializable) Map.of(QName.createQName("modified"), Date.from(now)));
testData.put("/alfresco-access/transaction/properties/to", (Serializable) Map.of(QName.createQName("modified"), Date.from(now)));
var builder = AuditRecordUtils.generateAuditRecordBuilder(testData, "/alfresco-access/".length());
builder.setAuditRecordType("alfresco-access");
var auditRecord = builder.build();
assertNotNull(auditRecord);
assertEquals("alfresco-access", auditRecord.getAuditApplicationId());
var auditData = auditRecord.getAuditData();
assertEquals(1, auditData.size());
var transaction = (HashMap<String, ?>) auditData.get("transaction");
assertNotNull(transaction);
assertEquals(4, transaction.size());
assertEquals(testData.get("/alfresco-access/transaction/path"), transaction.get("path"));
assertEquals(testData.get("/alfresco-access/transaction/user"), transaction.get("user"));
assertEquals(testData.get("/alfresco-access/transaction/sub-actions"), transaction.get("sub-actions"));
var properties = (HashMap<String, Object>) transaction.get("properties");
assertNotNull(properties);
assertEquals(2, properties.size());
assertEquals(testData.get("/alfresco-access/transaction/properties/from"), properties.get("from"));
assertEquals(testData.get("/alfresco-access/transaction/properties/to"), properties.get("to"));
}
@SuppressWarnings("unchecked")
@Test
public void testGenerateAuditRecordBuilderTestNodeRef()
{
var testData = new HashMap<String, Serializable>();
var expectedValue = new HashMap<String, Serializable>();
expectedValue.put("nodeRef", new NodeRef("workspace://SpacesStore/bfa612e6-1a02-46a0-a612-e61a02e6a036"));
expectedValue.put("objectId", "bfa612e6-1a02-46a0-a612-e61a02e6a036;1.0");
testData.put("/CMISChangeLog/CREATED/result/value", expectedValue);
var builder = AuditRecordUtils.generateAuditRecordBuilder(testData, "/CMISChangeLog/".length());
builder.setAuditRecordType("CMISChangeLog");
var auditRecord = builder.build();
assertNotNull(auditRecord);
assertEquals("CMISChangeLog", auditRecord.getAuditApplicationId());
var auditData = auditRecord.getAuditData();
assertEquals(1, auditData.size());
var created = (HashMap<String, ?>) auditData.get("CREATED");
assertNotNull(created);
assertEquals(1, created.size());
var result = (HashMap<String, Object>) created.get("result");
assertNotNull(result);
assertEquals(1, result.size());
var resultValue = (HashMap<String, Object>) result.get("value");
assertNotNull(resultValue);
assertEquals(2, resultValue.size());
var expectedNodeRef = (NodeRef) expectedValue.get("nodeRef");
assertEquals(expectedNodeRef.getId(), resultValue.get("nodeRef"));
assertEquals(expectedValue.get("objectId"), resultValue.get("objectId"));
}
}

View File

@@ -50,7 +50,6 @@ public class AuditTestSuite extends TestSuite
suite.addTestSuite(UserAuditFilterTest.class);
suite.addTestSuite(AuditMethodInterceptorTest.class);
suite.addTest(new JUnit4TestAdapter(AuditRecordUtilsTest.class));
suite.addTest(new JUnit4TestAdapter(PropertyAuditFilterTest.class));
suite.addTest(new JUnit4TestAdapter(AccessAuditorTest.class));

View File

@@ -26,12 +26,6 @@
package org.alfresco.repo.event2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.alfresco.model.ContentModel.PROP_DESCRIPTION;
import java.io.Serializable;
@@ -551,49 +545,6 @@ public class UpdateRepoEventIT extends AbstractContextAwareRepoEvent
assertEquals(aspectsBeforeRemove, resourceBefore.getAspectNames());
}
@Test
public void testRemoveAspectPropertiesTest()
{
final NodeRef nodeRef = createNode(ContentModel.TYPE_CONTENT);
NodeResource resource = getNodeResource(1);
final Set<String> originalAspects = resource.getAspectNames();
assertNotNull(originalAspects);
// Add cm:geographic aspect with properties
retryingTransactionHelper.doInTransaction(() -> {
Map<QName, Serializable> aspectProperties = new HashMap<>();
aspectProperties.put(ContentModel.PROP_LATITUDE, "12.345678");
aspectProperties.put(ContentModel.PROP_LONGITUDE, "12.345678");
nodeService.addAspect(nodeRef, ContentModel.ASPECT_GEOGRAPHIC, aspectProperties);
return null;
});
resource = getNodeResource(2);
Set<String> aspectsBeforeRemove = resource.getAspectNames();
assertNotNull(aspectsBeforeRemove);
assertTrue(aspectsBeforeRemove.contains("cm:geographic"));
// Remove cm:geographic aspect - this automatically removes the properties from the node
retryingTransactionHelper.doInTransaction(() -> {
nodeService.removeAspect(nodeRef, ContentModel.ASPECT_GEOGRAPHIC);
return null;
});
resource = getNodeResource(3);
assertEquals(originalAspects, resource.getAspectNames());
NodeResource resourceBefore = getNodeResourceBefore(3);
assertNotNull(resourceBefore.getAspectNames());
assertEquals(aspectsBeforeRemove, resourceBefore.getAspectNames());
// Resource before should contain cm:latitude and cm:longitude properties
assertNotNull(resourceBefore.getProperties());
assertTrue(resourceBefore.getProperties().containsKey("cm:latitude"));
assertTrue(resourceBefore.getProperties().containsKey("cm:longitude"));
// Resource after should NOT contain cm:latitude and cm:longitude properties
assertNotNull(resource.getProperties());
assertFalse(resource.getProperties().containsKey("cm:latitude"));
assertFalse(resource.getProperties().containsKey("cm:longitude"));
}
@Test
public void testCreateAndUpdateInTheSameTransaction()
{

View File

@@ -1,128 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 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%
*/
/*
* Copyright (C) 2005 Jesper Steen Møller
*
* This file is part of Alfresco
*
* 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/>.
*/
package org.alfresco.repo.jscript;
import static org.junit.Assert.*;
import org.junit.Test;
import org.mockito.Mockito;
import org.alfresco.repo.forms.FormData;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
public class MetaDataExtractActionTest
{
@Test
public void testIsContentChangedReturnsTrue()
{
MetaDataExtractAction action = new MetaDataExtractAction();
ContentService contentService = Mockito.mock(ContentService.class);
ContentReader reader = Mockito.mock(ContentReader.class);
FormData formData = Mockito.mock(FormData.class);
FormData.FieldData fieldData = Mockito.mock(FormData.FieldData.class);
String nodeRefStr = "workspace://SpacesStore/abc/def";
Mockito.when(contentService.getReader(Mockito.any(), Mockito.any())).thenReturn(reader);
Mockito.when(reader.getContentString()).thenReturn("oldContent");
Mockito.when(formData.getFieldData("prop_cm_content")).thenReturn(fieldData);
Mockito.when(fieldData.getValue()).thenReturn("newContent");
action.setContentService(contentService);
boolean result = action.isContentChanged(nodeRefStr, formData);
assertTrue(result);
}
@Test
public void testIsContentChangedReturnsFalse()
{
MetaDataExtractAction action = new MetaDataExtractAction();
ContentService contentService = Mockito.mock(ContentService.class);
ContentReader reader = Mockito.mock(ContentReader.class);
FormData formData = Mockito.mock(FormData.class);
FormData.FieldData fieldData = Mockito.mock(FormData.FieldData.class);
String nodeRefStr = "workspace://SpacesStore/abc/def";
Mockito.when(contentService.getReader(Mockito.any(), Mockito.any())).thenReturn(reader);
Mockito.when(reader.getContentString()).thenReturn("sameContent");
Mockito.when(formData.getFieldData("prop_cm_content")).thenReturn(fieldData);
Mockito.when(fieldData.getValue()).thenReturn("sameContent");
action.setContentService(contentService);
boolean result = action.isContentChanged(nodeRefStr, formData);
assertFalse(result);
}
@Test
public void testCreateWhenContentChangedReturnsScriptAction()
{
MetaDataExtractAction action = new MetaDataExtractAction();
ServiceRegistry serviceRegistry = Mockito.mock(ServiceRegistry.class);
ActionService actionService = Mockito.mock(ActionService.class);
ActionDefinition actionDefinition = Mockito.mock(ActionDefinition.class);
Action alfrescoAction = Mockito.mock(Action.class);
ActionCondition actionCondition = Mockito.mock(ActionCondition.class);
Mockito.when(serviceRegistry.getActionService()).thenReturn(actionService);
Mockito.when(actionService.getActionDefinition(Mockito.anyString())).thenReturn(actionDefinition);
Mockito.when(actionService.createAction(Mockito.anyString())).thenReturn(alfrescoAction);
Mockito.when(actionService.createActionCondition(Mockito.anyString())).thenReturn(actionCondition);
action.setServiceRegistry(serviceRegistry);
ScriptAction result = action.create(true);
assertNotNull("ScriptAction should not be null when content has changed", result);
}
}

View File

@@ -39,7 +39,6 @@ import org.junit.Test;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -777,58 +776,4 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
}
}
@Test
public void testTextExtractTransformAllowedWhenThumbnailDisabled()
{
// create a source node
NodeRef sourceNodeRef = createSource(ADMIN, "quick.pdf");
assertNotNull("Node not generated", sourceNodeRef);
String replyQueue = "org.test.queue";
String targetMimetype = MimetypeMap.MIMETYPE_TEXT_PLAIN;
TransformDefinition textExtractTransform = new TransformDefinition(
targetMimetype,
java.util.Collections.emptyMap(),
"clientData",
replyQueue,
"requestId");
renditionService2.setThumbnailsEnabled(false);
try
{
// Should NOT throw, as this is a text extract transform
AuthenticationUtil.runAs(() -> {
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
renditionService2.transform(sourceNodeRef, textExtractTransform);
return null;
});
return null;
}, ADMIN);
}
finally
{
renditionService2.setThumbnailsEnabled(true);
}
}
@Test
public void testMetadataExtractTransformAllowedWhenThumbnailDisabled()
{
// create a source node
NodeRef sourceNodeRef = createSource(ADMIN, "quick.pdf");
assertNotNull("Node not generated", sourceNodeRef);
renditionService2.setThumbnailsEnabled(false);
try
{
// Should NOT throw, as this is a metadata extract transform
extract(ADMIN, sourceNodeRef);
waitForExtract(ADMIN, sourceNodeRef, true);
}
finally
{
renditionService2.setThumbnailsEnabled(true);
}
}
}