mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-11-12 15:39:46 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d933cedbd7 | ||
|
|
5e54f94c6a | ||
|
|
8484c3e022 | ||
|
|
eca25addff | ||
|
|
0ea417ed37 | ||
|
|
fb811cdb2d | ||
|
|
9c0ac89015 | ||
|
|
1028b5c44b | ||
|
|
39d209a6a1 | ||
|
|
d9adbd60e1 | ||
|
|
cb07b26653 | ||
|
|
327129f021 | ||
|
|
afbaf11ff9 | ||
|
|
e779057f23 | ||
|
|
49ee9f8f29 | ||
|
|
213886cedd | ||
|
|
1be9a43bcd | ||
|
|
eceb7c0eb3 | ||
|
|
8cd46d4585 | ||
|
|
11d71e1941 | ||
|
|
353d50a35c | ||
|
|
2daafc711d | ||
|
|
dfa94fbe21 | ||
|
|
4a93aec66b | ||
|
|
3f0bbc9844 | ||
|
|
cb9ad42101 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -107,7 +107,7 @@ jobs:
|
||||
bash ./scripts/ci/init.sh
|
||||
bash ./scripts/ci/build.sh
|
||||
- name: "Run SAST Scan"
|
||||
uses: veracode/Veracode-pipeline-scan-action@v1.0.16
|
||||
uses: veracode/Veracode-pipeline-scan-action@v1.0.20
|
||||
with:
|
||||
vid: ${{ secrets.VERACODE_API_ID }}
|
||||
vkey: ${{ secrets.VERACODE_API_KEY }}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -160,6 +160,7 @@
|
||||
<property name="nodesModelFactory" ref="nodesModelFactory" />
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
|
||||
<property name="dispositionService" ref="DispositionService"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rm.rest.api.recordfolders.RecordFolderEntityResource">
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -26,10 +26,25 @@
|
||||
*/
|
||||
package org.alfresco.rm.rest.api.retentionschedule;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionScheduleImpl;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
||||
@@ -50,18 +65,6 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
|
||||
/**
|
||||
* Retention schedule action relation is used to perform the retention schedule step operations.
|
||||
*/
|
||||
@@ -73,6 +76,7 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
|
||||
protected NodeService nodeService;
|
||||
private RecordsManagementServiceRegistry service;
|
||||
private ApiNodesModelFactory nodesModelFactory;
|
||||
private DispositionService dispositionService;
|
||||
|
||||
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
|
||||
{
|
||||
@@ -94,27 +98,41 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void setDispositionService(DispositionService dispositionService)
|
||||
{
|
||||
this.dispositionService = dispositionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@WebApiDescription(title="Create a retention schedule step for the particular retention schedule using the 'retentionScheduleId'")
|
||||
@WebApiDescription(title = "Create a retention schedule step for the particular retention schedule using the 'retentionScheduleId'")
|
||||
public List<RetentionScheduleActionDefinition> create(String retentionScheduleId, List<RetentionScheduleActionDefinition> nodeInfos, Parameters parameters)
|
||||
{
|
||||
checkNotBlank("retentionScheduleId", retentionScheduleId);
|
||||
mandatory("entity", nodeInfos);
|
||||
mandatory("parameters", parameters);
|
||||
NodeRef retentionScheduleNodeRef = apiUtils.lookupAndValidateNodeType(retentionScheduleId, RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
|
||||
|
||||
RetentionScheduleActionDefinition retentionScheduleActionDefinition = nodeInfos.get(0);
|
||||
|
||||
// validation for the order of the step
|
||||
retentionScheduleStepValidation(retentionScheduleNodeRef, nodeInfos.get(0));
|
||||
retentionScheduleStepValidation(retentionScheduleNodeRef, retentionScheduleActionDefinition);
|
||||
|
||||
DispositionSchedule dispositionSchedule = new DispositionScheduleImpl(service, nodeService, retentionScheduleNodeRef);
|
||||
boolean isRecordLevel = dispositionSchedule.isRecordLevelDisposition();
|
||||
|
||||
// request property validation
|
||||
retentionScheduleRequestValidation(nodeInfos.get(0));
|
||||
retentionScheduleRequestValidation(retentionScheduleActionDefinition, isRecordLevel);
|
||||
|
||||
// create the parameters for the action definition
|
||||
Map<QName, Serializable> actionDefinitionParams = nodesModelFactory.createRetentionActionDefinitionParams(nodeInfos.get(0));
|
||||
Map<QName, Serializable> actionDefinitionParams = nodesModelFactory.createRetentionActionDefinitionParams(retentionScheduleActionDefinition);
|
||||
|
||||
// create the child association from the schedule to the action definition
|
||||
NodeRef actionNodeRef = this.nodeService.createNode(retentionScheduleNodeRef,
|
||||
RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
|
||||
QName.createValidLocalName(nodeInfos.get(0).getName())),
|
||||
QName.createValidLocalName(retentionScheduleActionDefinition.getName())),
|
||||
RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef();
|
||||
DispositionSchedule dispositionSchedule = new DispositionScheduleImpl(service, nodeService, retentionScheduleNodeRef);
|
||||
|
||||
DispositionActionDefinition dispositionActionDefinition = dispositionSchedule.getDispositionActionDefinition(actionNodeRef.getId());
|
||||
List<RetentionScheduleActionDefinition> responseActions = new ArrayList<>();
|
||||
if (dispositionActionDefinition != null)
|
||||
@@ -141,8 +159,11 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
|
||||
|
||||
/**
|
||||
* this method is used to validate the order of the retention schedule step
|
||||
* @param retentionScheduleNodeRef nodeRef
|
||||
* @param retentionScheduleActionDefinition retention schedule action definition
|
||||
*
|
||||
* @param retentionScheduleNodeRef
|
||||
* nodeRef
|
||||
* @param retentionScheduleActionDefinition
|
||||
* retention schedule action definition
|
||||
*/
|
||||
private void retentionScheduleStepValidation(NodeRef retentionScheduleNodeRef, RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
||||
{
|
||||
@@ -188,17 +209,19 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
|
||||
|
||||
/**
|
||||
* this method is used to validate the request of the retention schedule
|
||||
* @param retentionScheduleActionDefinition retention schedule action definition
|
||||
*
|
||||
* @param retentionScheduleActionDefinition
|
||||
* retention schedule action definition
|
||||
*/
|
||||
private void retentionScheduleRequestValidation(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
||||
private void retentionScheduleRequestValidation(RetentionScheduleActionDefinition retentionScheduleActionDefinition, boolean isRecordLevel)
|
||||
{
|
||||
// step name validation
|
||||
if (invalidStepNameCheck(retentionScheduleActionDefinition.getName()))
|
||||
{
|
||||
throw new InvalidArgumentException("name value is invalid : " +retentionScheduleActionDefinition.getName());
|
||||
throw new InvalidArgumentException("name value is invalid : " + retentionScheduleActionDefinition.getName());
|
||||
}
|
||||
|
||||
validatePeriodAndPeriodProperty(retentionScheduleActionDefinition);
|
||||
validatePeriodAndPeriodProperty(retentionScheduleActionDefinition, isRecordLevel);
|
||||
|
||||
// event name validation
|
||||
if (invalidEventNameCheck(retentionScheduleActionDefinition.getEvents()))
|
||||
@@ -217,17 +240,17 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePeriodAndPeriodProperty(RetentionScheduleActionDefinition retentionScheduleActionDefinition)
|
||||
private void validatePeriodAndPeriodProperty(RetentionScheduleActionDefinition retentionScheduleActionDefinition, boolean isRecordLevel)
|
||||
{
|
||||
// period value validation
|
||||
if (invalidPeriodCheck(retentionScheduleActionDefinition.getPeriod()))
|
||||
{
|
||||
throw new InvalidArgumentException("period value is invalid : " +retentionScheduleActionDefinition.getPeriod());
|
||||
throw new InvalidArgumentException("period value is invalid : " + retentionScheduleActionDefinition.getPeriod());
|
||||
}
|
||||
|
||||
// periodProperty validation
|
||||
List<String> validPeriodProperties = Arrays.asList("cm:created", "rma:cutOffDate", "rma:dispositionAsOf");
|
||||
if (validPeriodProperties.stream().noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals))
|
||||
Collection<DispositionProperty> validPeriodProperties = dispositionService.getDispositionProperties(isRecordLevel, retentionScheduleActionDefinition.getName());
|
||||
if (validPeriodProperties.stream().map(dp -> dp.getQName().toPrefixString()).noneMatch(retentionScheduleActionDefinition.getPeriodProperty()::equals))
|
||||
{
|
||||
throw new InvalidArgumentException("periodProperty value is invalid: " + retentionScheduleActionDefinition.getPeriodProperty());
|
||||
}
|
||||
@@ -243,7 +266,7 @@ public class RetentionScheduleActionRelation implements RelationshipResourceActi
|
||||
{
|
||||
return retentionScheduleActionDefinition.getLocation() != null
|
||||
&& !retentionScheduleActionDefinition.getName().equals(RetentionSteps.TRANSFER.stepName)
|
||||
&& !retentionScheduleActionDefinition.getLocation().isEmpty();
|
||||
&& !retentionScheduleActionDefinition.getLocation().isEmpty();
|
||||
}
|
||||
|
||||
private boolean checkStepAlreadyExists(Set<String> completedActions, String stepName)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# Version label
|
||||
version.major=23
|
||||
version.minor=6
|
||||
version.minor=7
|
||||
version.revision=0
|
||||
version.label=
|
||||
|
||||
|
||||
@@ -27,22 +27,32 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.util;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.hold.HoldService;
|
||||
@@ -85,20 +95,11 @@ import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.collections.CollectionUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Base unit test.
|
||||
* <p>
|
||||
* Contains core and records management service mocks ready for injection. Helper methods
|
||||
* provide an easy way to build RM or Alfresco constructs for use in tests.
|
||||
* Contains core and records management service mocks ready for injection. Helper methods provide an easy way to build RM or Alfresco constructs for use in tests.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
@@ -112,47 +113,85 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
protected NodeRef record;
|
||||
|
||||
/** core service mocks */
|
||||
@Mock(name="nodeService") protected NodeService mockedNodeService;
|
||||
@Mock(name="dictionaryService") protected DictionaryService mockedDictionaryService;
|
||||
@Mock(name="namespaceService") protected NamespaceService mockedNamespaceService;
|
||||
@Mock(name="identifierService") protected IdentifierService mockedIdentifierService;
|
||||
@Mock(name="permissionService") protected PermissionService mockedPermissionService;
|
||||
@Mock(name="ownableService") protected OwnableService mockedOwnableService;
|
||||
@Mock(name="searchService") protected SearchService mockedSearchService;
|
||||
@Mock(name="retryingTransactionHelper") protected RetryingTransactionHelper mockedRetryingTransactionHelper;
|
||||
@Mock(name="authorityService") protected AuthorityService mockedAuthorityService;
|
||||
@Mock(name="policyComponent") protected PolicyComponent mockedPolicyComponent;
|
||||
@Mock(name="copyService") protected CopyService mockedCopyService;
|
||||
@Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService;
|
||||
@Mock(name="modelSecurityService") protected ModelSecurityService mockedModelSecurityService;
|
||||
@Mock(name="ruleService") protected RuleService mockedRuleService;
|
||||
@Mock(name="versionService") protected VersionService mockedVersionService;
|
||||
@Mock(name = "nodeService")
|
||||
protected NodeService mockedNodeService;
|
||||
@Mock(name = "dictionaryService")
|
||||
protected DictionaryService mockedDictionaryService;
|
||||
@Mock(name = "namespaceService")
|
||||
protected NamespaceService mockedNamespaceService;
|
||||
@Mock(name = "identifierService")
|
||||
protected IdentifierService mockedIdentifierService;
|
||||
@Mock(name = "permissionService")
|
||||
protected PermissionService mockedPermissionService;
|
||||
@Mock(name = "ownableService")
|
||||
protected OwnableService mockedOwnableService;
|
||||
@Mock(name = "searchService")
|
||||
protected SearchService mockedSearchService;
|
||||
@Mock(name = "retryingTransactionHelper")
|
||||
protected RetryingTransactionHelper mockedRetryingTransactionHelper;
|
||||
@Mock(name = "authorityService")
|
||||
protected AuthorityService mockedAuthorityService;
|
||||
@Mock(name = "policyComponent")
|
||||
protected PolicyComponent mockedPolicyComponent;
|
||||
@Mock(name = "copyService")
|
||||
protected CopyService mockedCopyService;
|
||||
@Mock(name = "fileFolderService")
|
||||
protected FileFolderService mockedFileFolderService;
|
||||
@Mock(name = "modelSecurityService")
|
||||
protected ModelSecurityService mockedModelSecurityService;
|
||||
@Mock(name = "ruleService")
|
||||
protected RuleService mockedRuleService;
|
||||
@Mock(name = "versionService")
|
||||
protected VersionService mockedVersionService;
|
||||
|
||||
/** rm service mocks */
|
||||
@Mock(name="filePlanService") protected FilePlanService mockedFilePlanService;
|
||||
@Mock(name="recordFolderService") protected RecordFolderService mockedRecordFolderService;
|
||||
@Mock(name="recordService") protected RecordService mockedRecordService;
|
||||
@Mock(name="holdService") protected HoldService mockedHoldService;
|
||||
@Mock(name="recordsManagementActionService") protected RecordsManagementActionService mockedRecordsManagementActionService;
|
||||
@Mock(name="reportService") protected ReportService mockedReportService;
|
||||
@Mock(name="filePlanRoleService") protected FilePlanRoleService mockedFilePlanRoleService;
|
||||
@Mock(name="recordsManagementAuditService") protected RecordsManagementAuditService mockedRecordsManagementAuditService;
|
||||
@Mock(name="policyBehaviourFilter") protected BehaviourFilter mockedBehaviourFilter;
|
||||
@Mock(name="authenticationUtil") protected AuthenticationUtil mockedAuthenticationUtil;
|
||||
@Mock(name="extendedPermissionService") protected ExtendedPermissionService mockedExtendedPermissionService;
|
||||
@Mock(name="extendedSecurityService") protected ExtendedSecurityService mockedExtendedSecurityService;
|
||||
@Mock(name="recordableVersionConfigService") protected RecordableVersionConfigService mockedRecordableVersionConfigService;
|
||||
@Mock(name="cmObjectType") protected CmObjectType mockedCmObjectType;
|
||||
@Mock(name="recordableVersionService") protected RecordableVersionService mockedRecordableVersionService;
|
||||
@Mock(name="transactionalResourceHelper") protected TransactionalResourceHelper mockedTransactionalResourceHelper;
|
||||
@Mock(name="alfrescoTransactionSupport") protected AlfrescoTransactionSupport mockedAlfrescoTransactionSupport;
|
||||
@Mock(name="freezeService") protected FreezeService mockedFreezeService;
|
||||
@Mock(name="dispositionService") protected DispositionService mockedDispositionService;
|
||||
@Mock(name = "filePlanService")
|
||||
protected FilePlanService mockedFilePlanService;
|
||||
@Mock(name = "recordFolderService")
|
||||
protected RecordFolderService mockedRecordFolderService;
|
||||
@Mock(name = "recordService")
|
||||
protected RecordService mockedRecordService;
|
||||
@Mock(name = "holdService")
|
||||
protected HoldService mockedHoldService;
|
||||
@Mock(name = "recordsManagementActionService")
|
||||
protected RecordsManagementActionService mockedRecordsManagementActionService;
|
||||
@Mock(name = "reportService")
|
||||
protected ReportService mockedReportService;
|
||||
@Mock(name = "filePlanRoleService")
|
||||
protected FilePlanRoleService mockedFilePlanRoleService;
|
||||
@Mock(name = "recordsManagementAuditService")
|
||||
protected RecordsManagementAuditService mockedRecordsManagementAuditService;
|
||||
@Mock(name = "policyBehaviourFilter")
|
||||
protected BehaviourFilter mockedBehaviourFilter;
|
||||
@Mock(name = "authenticationUtil")
|
||||
protected AuthenticationUtil mockedAuthenticationUtil;
|
||||
@Mock(name = "extendedPermissionService")
|
||||
protected ExtendedPermissionService mockedExtendedPermissionService;
|
||||
@Mock(name = "extendedSecurityService")
|
||||
protected ExtendedSecurityService mockedExtendedSecurityService;
|
||||
@Mock(name = "recordableVersionConfigService")
|
||||
protected RecordableVersionConfigService mockedRecordableVersionConfigService;
|
||||
@Mock(name = "cmObjectType")
|
||||
protected CmObjectType mockedCmObjectType;
|
||||
@Mock(name = "recordableVersionService")
|
||||
protected RecordableVersionService mockedRecordableVersionService;
|
||||
@Mock(name = "transactionalResourceHelper")
|
||||
protected TransactionalResourceHelper mockedTransactionalResourceHelper;
|
||||
@Mock(name = "alfrescoTransactionSupport")
|
||||
protected AlfrescoTransactionSupport mockedAlfrescoTransactionSupport;
|
||||
@Mock(name = "freezeService")
|
||||
protected FreezeService mockedFreezeService;
|
||||
@Mock(name = "dispositionService")
|
||||
protected DispositionService mockedDispositionService;
|
||||
@Mock(name = "recordsManagementEventService")
|
||||
protected RecordsManagementEventService mockedRecordsManagementEventService;
|
||||
|
||||
/** application context mock */
|
||||
@Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
|
||||
@Mock(name = "applicationContext")
|
||||
protected ApplicationContext mockedApplicationContext;
|
||||
|
||||
@Mock protected NodeTypeUtility mockedNodeTypeUtility;
|
||||
@Mock
|
||||
protected NodeTypeUtility mockedNodeTypeUtility;
|
||||
|
||||
/** expected exception rule */
|
||||
@Rule
|
||||
@@ -171,17 +210,16 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
lenient().doReturn(mockedNodeService).when(mockedApplicationContext).getBean("dbNodeService");
|
||||
|
||||
// setup retrying transaction helper
|
||||
Answer<Object> doInTransactionAnswer = new Answer<Object>()
|
||||
{
|
||||
Answer<Object> doInTransactionAnswer = new Answer<Object>() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
RetryingTransactionCallback callback = (RetryingTransactionCallback)invocation.getArguments()[0];
|
||||
RetryingTransactionCallback callback = (RetryingTransactionCallback) invocation.getArguments()[0];
|
||||
return callback.execute();
|
||||
}
|
||||
};
|
||||
lenient().doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).<Object>doInTransaction(any(RetryingTransactionCallback.class));
|
||||
lenient().doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).<Object> doInTransaction(any(RetryingTransactionCallback.class));
|
||||
|
||||
// setup mocked authentication util
|
||||
MockAuthenticationUtilHelper.setup(mockedAuthenticationUtil);
|
||||
@@ -215,8 +253,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate hold reference
|
||||
*
|
||||
* @param name hold name
|
||||
* @return {@link NodeRef} node reference that will behave like a hold
|
||||
* @param name
|
||||
* hold name
|
||||
* @return {@link NodeRef} node reference that will behave like a hold
|
||||
*/
|
||||
protected NodeRef generateHoldNodeRef(String name)
|
||||
{
|
||||
@@ -229,7 +268,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate record folder reference
|
||||
*
|
||||
* @return {@link NodeRef} node reference that will behave like a record folder
|
||||
* @return {@link NodeRef} node reference that will behave like a record folder
|
||||
*/
|
||||
protected NodeRef generateRecordFolder()
|
||||
{
|
||||
@@ -242,7 +281,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate a record node reference.
|
||||
*
|
||||
* @return {@link NodeRef} node reference that will behave like a record or type cm:content
|
||||
* @return {@link NodeRef} node reference that will behave like a record or type cm:content
|
||||
*/
|
||||
protected NodeRef generateRecord()
|
||||
{
|
||||
@@ -256,7 +295,8 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to setup a node reference as a file plan component.
|
||||
*
|
||||
* @param nodeRef {@link NodeRef} node reference that will now behave like a file plan component
|
||||
* @param nodeRef
|
||||
* {@link NodeRef} node reference that will now behave like a file plan component
|
||||
*/
|
||||
protected void setupAsFilePlanComponent(NodeRef nodeRef)
|
||||
{
|
||||
@@ -269,7 +309,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate a node reference.
|
||||
*
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store
|
||||
*/
|
||||
protected NodeRef generateNodeRef()
|
||||
{
|
||||
@@ -279,9 +319,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate a node reference of a particular type.
|
||||
*
|
||||
* @param type content type qualified name
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store with
|
||||
* the content type provided
|
||||
* @param type
|
||||
* content type qualified name
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store with the content type provided
|
||||
*/
|
||||
protected NodeRef generateNodeRef(QName type)
|
||||
{
|
||||
@@ -291,8 +331,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate a cm:content node reference with a given name.
|
||||
*
|
||||
* @param name content name
|
||||
* @return NodeRef node reference
|
||||
* @param name
|
||||
* content name
|
||||
* @return NodeRef node reference
|
||||
*/
|
||||
protected NodeRef generateCmContent(String name)
|
||||
{
|
||||
@@ -304,10 +345,11 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate a node reference of a particular type with a given existence characteristic.
|
||||
*
|
||||
* @param type content type qualified name
|
||||
* @param exists indicates whether this node should behave like a node that exists or not
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists (or not) in the spaces store with
|
||||
* the content type provided
|
||||
* @param type
|
||||
* content type qualified name
|
||||
* @param exists
|
||||
* indicates whether this node should behave like a node that exists or not
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists (or not) in the spaces store with the content type provided
|
||||
*/
|
||||
protected NodeRef generateNodeRef(QName type, boolean exists)
|
||||
{
|
||||
@@ -324,9 +366,11 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
/**
|
||||
* Helper method to generate a mocked child association reference.
|
||||
*
|
||||
* @param parent parent node (optional)
|
||||
* @param child child node (optional)
|
||||
* @return {@link ChildAssociationRef} mocked to return the parent and child nodes
|
||||
* @param parent
|
||||
* parent node (optional)
|
||||
* @param child
|
||||
* child node (optional)
|
||||
* @return {@link ChildAssociationRef} mocked to return the parent and child nodes
|
||||
*/
|
||||
protected ChildAssociationRef generateChildAssociationRef(NodeRef parent, NodeRef child)
|
||||
{
|
||||
@@ -357,17 +401,17 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
{
|
||||
makePrimaryParentOf(child, parent, ContentModel.ASSOC_CONTAINS, generateQName());
|
||||
}
|
||||
|
||||
|
||||
protected void makePrimaryParentOf(NodeRef child, NodeRef parent, QName assocType, QName assocName)
|
||||
{
|
||||
makePrimaryParentOf(child, parent, assocType, assocName, mockedNodeService);
|
||||
makePrimaryParentOf(child, parent, assocType, assocName, mockedNodeService);
|
||||
}
|
||||
|
||||
|
||||
protected void makePrimaryParentOf(NodeRef child, NodeRef parent, QName assocType, QName assocName, NodeService mockedNodeService)
|
||||
{
|
||||
doReturn(new ChildAssociationRef(assocType, parent, assocName, child))
|
||||
.when(mockedNodeService)
|
||||
.getPrimaryParent(child);
|
||||
.when(mockedNodeService)
|
||||
.getPrimaryParent(child);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,7 +422,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
* @param parent
|
||||
* @param children
|
||||
*/
|
||||
protected void makeChildrenOf(NodeRef parent, NodeRef ... children)
|
||||
protected void makeChildrenOf(NodeRef parent, NodeRef... children)
|
||||
{
|
||||
List<ChildAssociationRef> assocs = new ArrayList<>(children.length);
|
||||
for (NodeRef child : children)
|
||||
@@ -390,7 +434,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> List<T> buildList(T ... values)
|
||||
protected <T> List<T> buildList(T... values)
|
||||
{
|
||||
List<T> result = new ArrayList<>(values.length);
|
||||
for (T value : values)
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Records Management Module
|
||||
* %%
|
||||
* 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.rm.rest.api.retentionschedule;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinitionImpl;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionServiceImpl;
|
||||
import org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
|
||||
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
|
||||
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
|
||||
import org.alfresco.rm.rest.api.model.RetentionSteps;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Unit tests for RetentionScheduleActionRelation
|
||||
*/
|
||||
public class RetentionScheduleActionRelationUnitTest extends BaseUnitTest
|
||||
{
|
||||
|
||||
@Mock
|
||||
private FilePlanComponentsApiUtils apiUtils;
|
||||
|
||||
@Mock
|
||||
private ApiNodesModelFactory nodesModelFactory;
|
||||
|
||||
@Mock
|
||||
private Parameters parameters;
|
||||
|
||||
private RetentionScheduleActionRelation retentionScheduleActionRelation;
|
||||
|
||||
private NodeRef rsRecordLevelNodeRef = new NodeRef("workspace://SpacesStore/recordLevel");
|
||||
private NodeRef rsRecordFolderLevelNodeRef = new NodeRef("workspace://SpacesStore/recordFolderLevel");
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
|
||||
// Disposition Service
|
||||
DispositionService dispositionService = new DispositionServiceImpl();
|
||||
|
||||
// Disposition Properties
|
||||
DispositionProperty publicationDate = createDispositionProperty("dod:publicationDate", false, true, Set.of());
|
||||
DispositionProperty cutoffDate = createDispositionProperty("rma:cutOffDate", true, true, Set.of("cutoff"));
|
||||
DispositionProperty dispositionAsOf = createDispositionProperty("rma:dispositionAsOf", true, true, Set.of());
|
||||
DispositionProperty dateFiled = createDispositionProperty("rma:dateFiled", false, true, Set.of());
|
||||
DispositionProperty created = createDispositionProperty("cm:created", true, true, Set.of());
|
||||
|
||||
// Register Disposition Properties
|
||||
dispositionService.registerDispositionProperty(publicationDate);
|
||||
dispositionService.registerDispositionProperty(cutoffDate);
|
||||
dispositionService.registerDispositionProperty(dispositionAsOf);
|
||||
dispositionService.registerDispositionProperty(dateFiled);
|
||||
dispositionService.registerDispositionProperty(created);
|
||||
|
||||
// Retention Schedule Action Relation
|
||||
retentionScheduleActionRelation = new RetentionScheduleActionRelation();
|
||||
retentionScheduleActionRelation.setApiUtils(apiUtils);
|
||||
retentionScheduleActionRelation.setNodeService(mockedNodeService);
|
||||
retentionScheduleActionRelation.setNodesModelFactory(nodesModelFactory);
|
||||
retentionScheduleActionRelation.setDispositionService(dispositionService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "cutoff" retention step for a retention schedule with "record" level disposition supplying only VALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Valid: dod:publicationDate, rma:dispositionAsOf, rma:dateField and cm:created
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordLevel_Cutoff_Valid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(true, false);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.CUTOFF.stepName;
|
||||
|
||||
// Cutoff - dod:publicationDate
|
||||
executeValidStep(retentionScheduleId, actionName, "dod:publicationDate");
|
||||
|
||||
// Cutoff - rma:dispositionAsOf
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:dispositionAsOf");
|
||||
|
||||
// Cutoff - rma:dateFiled
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:dateFiled");
|
||||
|
||||
// Cutoff - cm:created
|
||||
executeValidStep(retentionScheduleId, actionName, "cm:created");
|
||||
|
||||
verify(mockedNodeService, times(4)).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "cutoff" retention step for a retention schedule with "record" level disposition supplying only INVALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Invalid: rma:cutOffDate
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordLevel_Cutoff_Invalid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(true, false);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.CUTOFF.stepName;
|
||||
|
||||
// Cutoff - rma:cutOffDate
|
||||
executeInvalidStep(retentionScheduleId, actionName, "rma:cutOffDate");
|
||||
|
||||
verify(mockedNodeService, never()).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "cutoff" retention step for a retention schedule with "record folder" level disposition supplying only VALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Valid: rma:dispositionAsOf and cm:created
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordFolderLevel_Cutoff_Valid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record folder" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(false, false);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.CUTOFF.stepName;
|
||||
|
||||
// Cutoff - rma:dispositionAsOf
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:dispositionAsOf");
|
||||
|
||||
// Cutoff - cm:created
|
||||
executeValidStep(retentionScheduleId, actionName, "cm:created");
|
||||
|
||||
verify(mockedNodeService, times(2)).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "cutoff" retention step for a retention schedule with "record folder" level disposition supplying only INVALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Invalid: dod:publicationDate, rma:cutOffDate and rma:dateFiled
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordFolderLevel_Cutoff_Invalid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record folder" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(false, false);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.CUTOFF.stepName;
|
||||
|
||||
// Cutoff - dod:publicationDate
|
||||
executeInvalidStep(retentionScheduleId, actionName, "dod:publicationDate");
|
||||
|
||||
// Cutoff - rma:cutOffDate
|
||||
executeInvalidStep(retentionScheduleId, actionName, "rma:cutOffDate");
|
||||
|
||||
// Cutoff - rma:dateFiled
|
||||
executeInvalidStep(retentionScheduleId, actionName, "rma:dateFiled");
|
||||
|
||||
verify(mockedNodeService, never()).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "transfer" retention step for a retention schedule with "record" level disposition supplying only VALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Valid: dod:publicationDate, rma:cutOffDate, rma:dispositionAsOf, rma:dateField and cm:created
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordLevel_Transfer_Valid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(true, true);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.TRANSFER.stepName;
|
||||
|
||||
// Transfer - dod:publicationDate
|
||||
executeValidStep(retentionScheduleId, actionName, "dod:publicationDate");
|
||||
|
||||
// Transfer - rma:cutOffDate
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:cutOffDate");
|
||||
|
||||
// Transfer - rma:dispositionAsOf
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:dispositionAsOf");
|
||||
|
||||
// Transfer - rma:dateFiled
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:dateFiled");
|
||||
|
||||
// Transfer - cm:created
|
||||
executeValidStep(retentionScheduleId, actionName, "cm:created");
|
||||
|
||||
verify(mockedNodeService, times(5)).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "transfer" retention step for a retention schedule with "record" level disposition supplying only INVALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Invalid: any other property that is not dod:publicationDate, rma:cutOffDate, rma:dispositionAsOf, rma:dateField and cm:created.
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordLevel_Transfer_Invalid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(true, true);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.TRANSFER.stepName;
|
||||
|
||||
// Transfer - bad:property
|
||||
executeInvalidStep(retentionScheduleId, actionName, "bad:property");
|
||||
|
||||
verify(mockedNodeService, never()).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "transfer" retention step for a retention schedule with "record folder" level disposition supplying only VALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Valid: rma:cutOffDate, rma:dispositionAsOf and cm:created
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordFolderLevel_Transfer_Valid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(false, true);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.TRANSFER.stepName;
|
||||
|
||||
// Transfer - rma:cutOffDate
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:cutOffDate");
|
||||
|
||||
// Transfer - rma:dispositionAsOf
|
||||
executeValidStep(retentionScheduleId, actionName, "rma:dispositionAsOf");
|
||||
|
||||
// Transfer - cm:created
|
||||
executeValidStep(retentionScheduleId, actionName, "cm:created");
|
||||
|
||||
verify(mockedNodeService, times(3)).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "transfer" retention step for a retention schedule with "record folder" level disposition supplying only INVALID disposition properties.
|
||||
*
|
||||
* <p>
|
||||
* Invalid: dod:publicationDate and rma:dateFiled
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_RetentionScheduleRecordFolderLevel_Transfer_Invalid() throws Exception
|
||||
{
|
||||
|
||||
// Retention schedule with "record" level disposition
|
||||
String retentionScheduleId = useRetentionScheduleWithRecordLevel(false, true);
|
||||
|
||||
// Retention step action
|
||||
String actionName = RetentionSteps.TRANSFER.stepName;
|
||||
|
||||
// Transfer - dod:publicationDate
|
||||
executeInvalidStep(retentionScheduleId, actionName, "dod:publicationDate");
|
||||
|
||||
// Transfer - rma:dateFiled
|
||||
executeInvalidStep(retentionScheduleId, actionName, "rma:dateFiled");
|
||||
|
||||
verify(mockedNodeService, never()).createNode(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
private void executeValidStep(String retentionScheduleId, String actionName, String periodProperty)
|
||||
{
|
||||
RetentionScheduleActionDefinition actionDef = createAction(actionName, periodProperty);
|
||||
retentionScheduleActionRelation.create(retentionScheduleId, Arrays.asList(actionDef), parameters);
|
||||
}
|
||||
|
||||
private void executeInvalidStep(String retentionScheduleId, String actionName, String periodProperty)
|
||||
{
|
||||
RetentionScheduleActionDefinition actionDef = createAction(actionName, periodProperty);
|
||||
try
|
||||
{
|
||||
retentionScheduleActionRelation.create(retentionScheduleId, Arrays.asList(actionDef), parameters);
|
||||
}
|
||||
catch (InvalidArgumentException e)
|
||||
{
|
||||
assertTrue(e.getMessage().contains("periodProperty value is invalid: " + periodProperty));
|
||||
}
|
||||
}
|
||||
|
||||
private String useRetentionScheduleWithRecordLevel(Boolean withRecordLevel, boolean hasCompletedActions)
|
||||
{
|
||||
|
||||
NodeRef retentionScheduleNodeRef = withRecordLevel ? rsRecordLevelNodeRef : rsRecordFolderLevelNodeRef;
|
||||
|
||||
String retentionScheduleId = retentionScheduleNodeRef.getId();
|
||||
|
||||
ChildAssociationRef retentionScheduleAssocRef = mock(ChildAssociationRef.class);
|
||||
|
||||
NodeRef cutOffActionNodeRef = mock(NodeRef.class);
|
||||
|
||||
DispositionActionDefinition cutoffAction = new DispositionActionDefinitionImpl(
|
||||
mockedRecordsManagementEventService, mockedRecordsManagementActionService, mockedNodeService,
|
||||
cutOffActionNodeRef, 0);
|
||||
|
||||
List<DispositionActionDefinition> completedActions = hasCompletedActions ? Arrays.asList(cutoffAction)
|
||||
: Collections.emptyList();
|
||||
|
||||
when(retentionScheduleAssocRef.getChildRef()).thenReturn(new NodeRef("workspace://SpacesStore/123"));
|
||||
when(apiUtils.lookupAndValidateNodeType(eq(retentionScheduleId), any(QName.class))).thenReturn(retentionScheduleNodeRef);
|
||||
when(mockedNodeService.getProperty(retentionScheduleNodeRef, RecordsManagementModel.PROP_RECORD_LEVEL_DISPOSITION)).thenReturn(withRecordLevel);
|
||||
when(nodesModelFactory.getRetentionActions(retentionScheduleNodeRef)).thenReturn(completedActions);
|
||||
when(mockedNodeService.createNode(any(), any(), any(), any(), any())).thenReturn(retentionScheduleAssocRef);
|
||||
|
||||
return retentionScheduleId;
|
||||
}
|
||||
|
||||
private RetentionScheduleActionDefinition createAction(String name, String periodProperty)
|
||||
{
|
||||
RetentionScheduleActionDefinition actionDef = mock(RetentionScheduleActionDefinition.class);
|
||||
when(actionDef.getName()).thenReturn(name);
|
||||
when(actionDef.getPeriodProperty()).thenReturn(periodProperty);
|
||||
when(actionDef.getPeriodAmount()).thenReturn(2);
|
||||
when(actionDef.getPeriod()).thenReturn("day");
|
||||
when(actionDef.getEvents()).thenReturn(Collections.singletonList("versioned"));
|
||||
when(actionDef.isCombineRetentionStepConditions()).thenReturn(false);
|
||||
return actionDef;
|
||||
}
|
||||
|
||||
private DispositionProperty createDispositionProperty(String name, Boolean appliesToFolderLevel,
|
||||
Boolean appliesToRecordLevel, Set<String> excludedActions) {
|
||||
when(mockedNamespaceService.getNamespaceURI(any())).thenReturn(name.split(":")[0]);
|
||||
DispositionProperty dp = new DispositionProperty();
|
||||
dp.setNamespaceService(mockedNamespaceService);
|
||||
dp.setName(name);
|
||||
dp.setAppliesToRecordLevel(appliesToRecordLevel);
|
||||
dp.setAppliesToFolderLevel(appliesToFolderLevel);
|
||||
dp.setExcludedDispositionActions(excludedActions);
|
||||
return dp;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -134,6 +134,25 @@ function doclist_main()
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -233,15 +233,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 + " +PATH:\"/cm:taggable/cm:" + search.ISO9075Encode(filterData) + "/member\"";
|
||||
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 "category":
|
||||
// Remove any trailing "/" character
|
||||
@@ -249,8 +249,15 @@ var Filters =
|
||||
{
|
||||
filterData = filterData.slice(0, -1);
|
||||
}
|
||||
filterQuery = this.constructPathQuery(parsedArgs);
|
||||
filterParams.query = filterQuery + " +PATH:\"/cm:categoryRoot/cm:generalclassifiable" + Filters.iso9075EncodePath(filterData) + "/member\"";
|
||||
|
||||
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";
|
||||
break;
|
||||
|
||||
case "aspect":
|
||||
@@ -271,11 +278,24 @@ var Filters =
|
||||
{
|
||||
filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || "");
|
||||
}
|
||||
|
||||
logger.warn("Final Query : " + filterParams.query);
|
||||
return filterParams;
|
||||
},
|
||||
|
||||
constructPathQuery: function constructPathQuery(parsedArgs)
|
||||
|
||||
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)
|
||||
{
|
||||
var pathQuery = "";
|
||||
if (parsedArgs.libraryRoot != companyhome || parsedArgs.nodeRef != "alfresco://company/home")
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<organization>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
12
pom.xml
12
pom.xml
@@ -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>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<properties>
|
||||
<acs.version.major>23</acs.version.major>
|
||||
<acs.version.minor>6</acs.version.minor>
|
||||
<acs.version.minor>7</acs.version.minor>
|
||||
<acs.version.revision>0</acs.version.revision>
|
||||
<acs.version.label />
|
||||
<amp.min.version>${acs.version.major}.0.0</amp.min.version>
|
||||
@@ -85,8 +85,8 @@
|
||||
<dependency.truezip.version>7.7.10</dependency.truezip.version>
|
||||
<dependency.poi.version>5.4.1</dependency.poi.version>
|
||||
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
|
||||
<dependency.camel.version>4.10.2</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
|
||||
<dependency.netty.version>4.1.118.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
|
||||
<dependency.camel.version>4.15.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
|
||||
<dependency.netty.version>4.1.127.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
|
||||
<dependency.activemq.version>5.18.3</dependency.activemq.version>
|
||||
<dependency.apache-compress.version>1.27.1</dependency.apache-compress.version>
|
||||
<dependency.awaitility.version>4.2.2</dependency.awaitility.version>
|
||||
@@ -104,7 +104,7 @@
|
||||
<dependency.jakarta-annotation-api.version>3.0.0</dependency.jakarta-annotation-api.version>
|
||||
<dependency.jakarta-transaction-api.version>2.0.1</dependency.jakarta-transaction-api.version>
|
||||
<dependency.jakarta-jws-api.version>3.0.0</dependency.jakarta-jws-api.version>
|
||||
<dependency.jakarta-ee-mail.version>2.0.1</dependency.jakarta-ee-mail.version>
|
||||
<dependency.jakarta-ee-mail.version>2.0.2</dependency.jakarta-ee-mail.version>
|
||||
<dependency.jakarta-ee-activation.version>2.0.1</dependency.jakarta-ee-activation.version>
|
||||
<dependency.jakarta-ee-jms.version>3.1.0</dependency.jakarta-ee-jms.version>
|
||||
<dependency.java-ee-activation.version>1.2.0</dependency.java-ee-activation.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>23.6.0.33</tag>
|
||||
<tag>23.7.0.7</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* 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
|
||||
@@ -31,6 +31,14 @@ 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;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ForumModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
@@ -44,10 +52,6 @@ import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.extensions.webscripts.Cache;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
|
||||
/**
|
||||
* This class is the controller for the comments.post web script.
|
||||
@@ -58,7 +62,7 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
public class CommentsPost extends AbstractCommentsWebScript
|
||||
{
|
||||
/**
|
||||
* Overrides AbstractCommentsWebScript to add comment
|
||||
* Overrides AbstractCommentsWebScript to add comment
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, Object> executeImpl(NodeRef nodeRef, WebScriptRequest req, Status status, Cache cache)
|
||||
@@ -66,6 +70,29 @@ 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);
|
||||
|
||||
@@ -99,32 +126,32 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
{
|
||||
// fetch the parent to add the node to
|
||||
NodeRef commentsFolder = getOrCreateCommentsFolder(nodeRef);
|
||||
|
||||
|
||||
// get a unique name
|
||||
String name = getUniqueChildName("comment");
|
||||
|
||||
|
||||
// create the comment
|
||||
NodeRef commentNodeRef = nodeService.createNode(commentsFolder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(name)),
|
||||
NodeRef commentNodeRef = nodeService.createNode(commentsFolder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(name)),
|
||||
ForumModel.TYPE_POST).getChildRef();
|
||||
|
||||
|
||||
// fetch the title required to create a comment
|
||||
String title = getOrNull(json, JSON_KEY_TITLE);
|
||||
HashMap<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
props.put(ContentModel.PROP_TITLE, title != null ? title : "");
|
||||
nodeService.addProperties(commentNodeRef, props);
|
||||
|
||||
|
||||
ContentWriter writer = contentService.getWriter(commentNodeRef, ContentModel.PROP_CONTENT, true);
|
||||
// fetch the content of a comment
|
||||
String contentString = getOrNull(json, JSON_KEY_CONTENT);
|
||||
|
||||
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_HTML);
|
||||
writer.putContent(contentString);
|
||||
|
||||
|
||||
return commentNodeRef;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generates an comment item value
|
||||
*
|
||||
@@ -134,34 +161,34 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
private Map<String, Object> generateItemValue(NodeRef commentNodeRef)
|
||||
{
|
||||
Map<String, Object> result = new HashMap<String, Object>(4, 1.0f);
|
||||
|
||||
String creator = (String)this.nodeService.getProperty(commentNodeRef, ContentModel.PROP_CREATOR);
|
||||
|
||||
|
||||
String creator = (String) this.nodeService.getProperty(commentNodeRef, ContentModel.PROP_CREATOR);
|
||||
|
||||
Serializable created = this.nodeService.getProperty(commentNodeRef, ContentModel.PROP_CREATED);
|
||||
Serializable modified = this.nodeService.getProperty(commentNodeRef, ContentModel.PROP_MODIFIED);
|
||||
|
||||
|
||||
boolean isUpdated = false;
|
||||
if (created instanceof Date && modified instanceof Date)
|
||||
{
|
||||
isUpdated = ((Date)modified).getTime() - ((Date)created).getTime() > 5000;
|
||||
isUpdated = ((Date) modified).getTime() - ((Date) created).getTime() > 5000;
|
||||
}
|
||||
|
||||
// TODO refactor v0 Comments API to use CommentService (see ACE-5437)
|
||||
Serializable owner = this.nodeService.getProperty(commentNodeRef, ContentModel.PROP_OWNER);
|
||||
String currentUser = this.serviceRegistry.getAuthenticationService().getCurrentUserName();
|
||||
|
||||
|
||||
boolean isSiteManager = this.permissionService.hasPermission(commentNodeRef, SiteModel.SITE_MANAGER) == (AccessStatus.ALLOWED);
|
||||
boolean isCoordinator = this.permissionService.hasPermission(commentNodeRef, PermissionService.COORDINATOR) == (AccessStatus.ALLOWED);
|
||||
boolean canEditComment = isSiteManager || isCoordinator || currentUser.equals(creator) || currentUser.equals(owner);
|
||||
|
||||
|
||||
result.put("node", commentNodeRef);
|
||||
result.put("author", this.personService.getPerson(creator));
|
||||
result.put("isUpdated", isUpdated);
|
||||
result.put("canEditComment", canEditComment);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generates the response model for adding a comment
|
||||
*
|
||||
@@ -194,7 +221,7 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
}
|
||||
return commentsFolder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the nodeRef of the existing one
|
||||
*
|
||||
@@ -207,7 +234,7 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
{
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, ForumModel.ASSOC_DISCUSSION, RegexQNamePattern.MATCH_ALL);
|
||||
ChildAssociationRef firstAssoc = assocs.get(0);
|
||||
|
||||
|
||||
return nodeService.getChildByName(firstAssoc.getChildRef(), ContentModel.ASSOC_CONTAINS, COMMENTS_TOPIC_NAME);
|
||||
}
|
||||
else
|
||||
@@ -220,7 +247,7 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
{
|
||||
return prefix + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creates the comments folder if it does not exists
|
||||
*
|
||||
@@ -229,35 +256,34 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
*/
|
||||
private NodeRef createCommentsFolder(final NodeRef nodeRef)
|
||||
{
|
||||
NodeRef commentsFolder = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
|
||||
{
|
||||
NodeRef commentsFolder = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>() {
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
NodeRef commentsFolder = null;
|
||||
AuthenticationUtil.pushAuthentication();
|
||||
|
||||
|
||||
// ALF-5240: turn off auditing round the discussion node creation to prevent
|
||||
// the source document from being modified by the first user leaving a comment
|
||||
behaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_AUDITABLE);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
// MNT-12082: set System user for creating forumFolder and commentsFolder nodes
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
|
||||
|
||||
|
||||
nodeService.addAspect(nodeRef, QName.createQName(NamespaceService.FORUMS_MODEL_1_0_URI, "discussable"), null);
|
||||
nodeService.addAspect(nodeRef, QName.createQName(NamespaceService.FORUMS_MODEL_1_0_URI, "commentsRollup"), null);
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, QName.createQName(NamespaceService.FORUMS_MODEL_1_0_URI, "discussion"), RegexQNamePattern.MATCH_ALL);
|
||||
if (assocs.size() != 0)
|
||||
{
|
||||
NodeRef forumFolder = assocs.get(0).getChildRef();
|
||||
|
||||
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f);
|
||||
props.put(ContentModel.PROP_NAME, COMMENTS_TOPIC_NAME);
|
||||
commentsFolder = nodeService.createNode(
|
||||
forumFolder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, COMMENTS_TOPIC_NAME),
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, COMMENTS_TOPIC_NAME),
|
||||
QName.createQName(NamespaceService.FORUMS_MODEL_1_0_URI, "topic"),
|
||||
props).getChildRef();
|
||||
}
|
||||
@@ -267,12 +293,12 @@ public class CommentsPost extends AbstractCommentsWebScript
|
||||
AuthenticationUtil.popAuthentication();
|
||||
behaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_AUDITABLE);
|
||||
}
|
||||
|
||||
|
||||
return commentsFolder;
|
||||
}
|
||||
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
return commentsFolder;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>23.6.0.33</version>
|
||||
<version>23.7.0.7</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
repository.name=Main Repository
|
||||
|
||||
# Schema number
|
||||
version.schema=19500
|
||||
version.schema=19600
|
||||
|
||||
# Directory configuration
|
||||
|
||||
|
||||
Reference in New Issue
Block a user