From ca236d981480fa8050dac32db803f977257a55ae Mon Sep 17 00:00:00 2001 From: SathishK-T <166369440+SathishK-T@users.noreply.github.com> Date: Tue, 25 Jun 2024 19:34:58 +0530 Subject: [PATCH 01/10] [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs (#2672) * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs * [APPS-2853] Swagger Documentation for Retention Schedule V1 APIs --------- Co-authored-by: Sathish Kumar --- .../main/webapp/definitions/gs-core-api.yaml | 424 ++++++++++++++++++ 1 file changed, 424 insertions(+) diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml b/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml index 41c728fc7e..6ab10c5079 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/gs-core-api.yaml @@ -40,6 +40,8 @@ tags: description: Retrieve and manage unfiled record folders - name: holds description: Retrieve and manage holds + - name: retention-schedules + description: Perform retention schedule specific operations paths: ## GS sites @@ -2634,7 +2636,194 @@ paths: description: Unexpected error schema: $ref: '#/definitions/Error' + ##retention-schedule + '/record-categories/{recordCategoryId}/retention-schedules': + post: + tags: + - retention-schedules + summary: Create a retention schedule + description: | + Create a retention schedule. + + For example, using the following JSON body will create a retention schedule: + ```JSON + { + "authority": "Retention Authority", + "instructions": "Retention Instructions", + "isRecordLevel": false + } + ``` + operationId: createRetentionSchedule + parameters: + - $ref: '#/parameters/recordCategoryIdParam' + - in: body + name: retentionNodeBodyCreate + description: | + The retention schedule information to create. + schema: + $ref: '#/definitions/RetentionNodeBodyCreate' + consumes: + - application/json + produces: + - application/json + responses: + '201': + description: Successful response + schema: + $ref: '#/definitions/RetentionScheduleResponse' + '400': + description: | + Invalid parameter: value of recordCategoryId is invalid + '401': + description: Authentication failed + '403': + description: Current user does not have permission to create retention schedule + '404': + description: recordCategoryId does not exist + '409': + description: Retention schedule already exist for the given recordCategoryId + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + get: + tags: + - retention-schedules + summary: Get the retention schedule for a record category + description: | + Get the retention schedule for a record category. + + You can use the **include** parameter (include=actions) to return additional information. + + operationId: getRetentionScheduleList + parameters: + - $ref: '#/parameters/recordCategoryIdParam' + - $ref: '#/parameters/retentionScheduleIncludeParam' + - $ref: '#/parameters/skipCountParam' + - $ref: '#/parameters/maxItemsParam' + consumes: + - application/json + produces: + - application/json + responses: + '200': + description: Successful response + schema: + $ref: '#/definitions/RetentionScheduleResponseList' + '400': + description: | + Invalid parameter: value of recordCategoryId is invalid + '401': + description: Authentication failed + '403': + description: Current user does not have permission to get retention schedule + '404': + description: recordCategoryId does not exist + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + '/retention-schedules/{retentionScheduleId}/retention-steps': + post: + tags: + - retention-schedules + summary: Create a step in the retention schedule + description: | + Create a step in the retention schedule. + + Order of steps: + * "**retain**" or "**cutoff**" should be first + * can't use "**cutoff**" after "**transfer**" or "**accession**" + * only the "**transfer**" action is allowed multiple times + * no steps are allowed after "**destroy**" + + For example, the following JSON body will create a step in the retention schedule: + ```JSON + { + "name":"accession", + "periodAmount": 2, + "period":"month", + "periodProperty":"cm:created", + "combineDispositionStepConditions": false, + "events":["versioned"], + "eligibleOnFirstCompleteEvent": true, + "description":"Step Description" + } + ``` + operationId: createRetentionScheduleAction + parameters: + - $ref: '#/parameters/retentionScheduleIdParam' + - in: body + name: nodeBodyCreate + description: | + The retention schedule steps information to create. + required: true + schema: + $ref: '#/definitions/RetentionStepNodeBodyCreate' + consumes: + - application/json + produces: + - application/json + responses: + '201': + description: Successful response + schema: + $ref: '#/definitions/RetentionStepNodeBodyResponse' + '400': + description: | + Invalid parameter: value of retentionScheduleId is invalid + Invalid parameter (e.g. event, period, periodProperty) + '401': + description: Authentication failed + '403': + description: Current user does not have permission to create retention schedule step + '404': + description: retentionScheduleId does not exist + '409': + description: | + * Invalid Step - Can't use Cut Off after Transfer or Accession + * Invalid Step - Destroy action already completed. Can't do any other Action + * Invalid Step - This step already exists. You can’t create this step [Transfer action is allowed many times] + '422': + description: Cut Off or Retain should be the first step + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + get: + tags: + - retention-schedules + summary: Get the list of steps in the retention schedule + description: | + Get the list of steps in the retention schedule. + operationId: getRetentionScheduleActionList + parameters: + - $ref: '#/parameters/retentionScheduleIdParam' + - $ref: '#/parameters/skipCountParam' + - $ref: '#/parameters/maxItemsParam' + consumes: + - application/json + produces: + - application/json + responses: + '200': + description: Successful response + schema: + $ref: '#/definitions/RetentionStepsNodeBodyResponse' + '400': + description: | + Invalid parameter: value of retentionScheduleId is invalid + '401': + description: Authentication failed + '403': + description: Current user does not have permission to get retention schedule steps + '404': + description: retentionScheduleId does not exist + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' parameters: ## File plans filePlanEntryIncludeParam: @@ -3100,6 +3289,22 @@ parameters: If true, then a name clash will cause an attempt to auto rename by finding a unique name using an integer suffix. required: false type: boolean + ## RetentionSchedule + retentionScheduleIdParam: + name: retentionScheduleId + in: path + description: + The identifier of a retention schedule. + required: true + type: string + retentionScheduleIncludeParam: + name: include + in: query + description: | + Returns additional information about the retention schedule actions. Any optional field from the response model can be requested. For example: + * actions + required: false + type: string definitions: FilePlanComponentBodyUpdate: type: object @@ -4258,6 +4463,225 @@ definitions: type: array items: $ref: '#/definitions/HoldBulkStatusEntry' + RetentionNodeBodyCreate: + type: object + properties: + authority: + type: string + description: | + Authority name for the retention schedule. + instructions: + type: string + description: | + Required instructions for the retention schedule. + isRecordLevel: + type: boolean + default: false + description: | + This field is used to specify whether the retention schedule needs to be applied in the folder level or record level. + True will cause the the retention schedule to apply to records and false will cause the retention schedule to apply to record folders. + This cannot be changed once items start being managed by the retention schedule. + RetentionScheduleResponse: + type: object + properties: + id: + type: string + parentId: + type: string + authority: + type: string + instructions: + type: string + isRecordLevel: + type: boolean + unpublishedUpdates: + type: boolean + RetentionScheduleResponseList: + type: object + properties: + list: + type: object + properties: + pagination: + $ref: '#/definitions/Pagination' + entries: + type: array + items: + $ref: '#/definitions/FullRetentionScheduleResponse' + FullRetentionScheduleResponse: + type: object + properties: + id: + type: string + parentId: + type: string + authority: + type: string + instructions: + type: string + isRecordLevel: + type: boolean + unpublishedUpdates: + type: boolean + actions: + type: array + items: + $ref: '#/definitions/Actions' + Actions: + type: object + properties: + id: + type: string + name: + type: string + periodAmount: + type: integer + period: + type: string + periodProperty: + type: string + combineDispositionStepConditions: + type: boolean + default: false + eligibleOnFirstCompleteEvent: + type: boolean + default: true + description: + type: string + retainRecordMetadataAfterDestruction: + type: boolean + location: + type: string + events: + type: array + items: + type: string + index: + type: integer + RetentionStepNodeBodyCreate: + type: object + properties: + name: + type: string + description: | + The valid names are: + * retain + * cutoff + * accession + * transfer + * destroy + periodAmount: + type: integer + description: | + This property is only applicable for the following period values. + * day + * month + * quarter + * week + * duration + * year + period: + type: string + description: | + Valid values for the period. + * day = Day + * fmend = End Of Financial Month + * fqend = End Of Financial Quarter + * fyend = End Of Financial Year + * immediately = Immediately + * monthend = End Of Month + * quarterend = End Of Quarter + * yearend = End Of Year + * month = Month + * none = None + * quarter = Quarter + * week = Week + * duration = XML Duration + * year = Year + + If you provide XML Duration for the period value, you need to specify a time interval using XML syntax. + The syntax should take the form of: + P = Period (required) + nY = Number of years + nM = Number of months + nD = Number of days + T = Start time of a time section (required if specifying hours, minutes, or seconds) + nH = Number of hours + nM = Number of minutes + nS = Number of seconds + For example, ‘P2M10D’ represents two months and ten days. + periodProperty: + type: string + default: cm:created + description: | + Valid values for the periodProperty property + * cm:created = Created Date (defult value) + * rma:cutOffDate = Cut Off Date + * rma:dispositionAsOf = Retention Action + combineDispositionStepConditions: + type: boolean + description: | + This property is only valid for **accession** step. + This is used to specify whether to combine the period condition and events for the step execution or only consider one of them. + For example: + **periodCondition**: After a period of 2 months + **eventsCondition**: Case Closed event + This flag can be used to consider only (**periodCondition** or **eventsCondition**) or both of them at once. + events: + type: array + items: + type: string + description: | + Valid values for the events property + * case_closed = Case Closed + * abolished = Abolished + * re_designated = Redesignated + * no_longer_needed = No Longer Needed + * superseded = Superseded + * versioned = Versioned + * study_complete = Study Complete + * training_complete = Training Complete + * related_record_trasfered_inactive_storage = Related Record Transferred to Inactive Storage + * obsolete = Obsolete + * all_allowances_granted_are_terminated = All Allowances Granted are Terminated + * WGI_action_complete = WGI Action Complete + * separation = Separation + * case_complete = Case Complete + * declassification_review = Declassification Review + eligibleOnFirstCompleteEvent: + type: boolean + description: | + * false = When all events have happened + * true = Whichever event is earlier + description: + type: string + description: | + This property is used to provide the step description. + retainRecordMetadataAfterDestruction: + type: boolean + description: | + This property is used to retain the metadata after record destruction. + location: + type: string + description: | + This property is only valid for transfer step + RetentionStepNodeBodyResponse: + type: object + properties: + actions: + $ref: '#/definitions/Actions' + RetentionStepsNodeBodyResponse: + type: object + properties: + list: + type: object + properties: + pagination: + $ref: '#/definitions/Pagination' + entries: + type: array + items: + $ref: '#/definitions/RetentionStepNodeBodyResponse' ## RequestBodyFile: type: object From d13da0cdfa81dc697eb5a46d2934d30dc3d26d75 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:45:07 +0000 Subject: [PATCH 02/10] [maven-release-plugin][skip ci] prepare release 23.3.0.58 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 4cd032a00d..8a6762831d 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 8fb2984e5e..ec6268f2dd 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 8a1c88b4ee..c07415e61e 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index f241bcf6ea..30097edad5 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index ac473e89de..db1fb2242a 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index ea537b28dd..a962e259fd 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/pom.xml b/amps/pom.xml index 03cb9a4617..ffcdc5ec39 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index ccd28bf2db..001282a45a 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/core/pom.xml b/core/pom.xml index c7d0428605..c2d0afd17c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/data-model/pom.xml b/data-model/pom.xml index b5e884dc48..bc4b1b4d5a 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/mmt/pom.xml b/mmt/pom.xml index 203a25b4d3..87c28a4fc5 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index c815b26189..7fcd75908d 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 3b868bce08..3ee0e53f50 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/pom.xml b/packaging/pom.xml index b5de6e9f0d..f0cf16edfd 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index dadcc89c80..eb3e87b067 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 0a63121a52..ac865624c1 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 995fa9abcc..0a9a604c73 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 58a8f0d567..6199c9044c 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index f351f59f64..87e1d06e7a 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 5192b8fa43..cb0dbef057 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index d990f883bd..1b1f3d1a00 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/pom.xml b/pom.xml index 8b961fe41d..0c19777ad3 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 23.3.0.58 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 0150864b82..1acefefa35 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 diff --git a/repository/pom.xml b/repository/pom.xml index 7a0ac1881c..71def7f728 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58-SNAPSHOT + 23.3.0.58 From b580a52459a184178460d9917bc9ff94bc39a790 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:45:09 +0000 Subject: [PATCH 03/10] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 8a6762831d..6051b2469b 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index ec6268f2dd..c45e764903 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index c07415e61e..93923f5a41 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 30097edad5..59c5da0fc2 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index db1fb2242a..9d75c3d154 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index a962e259fd..7317a46013 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index ffcdc5ec39..23a57cbc6e 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 001282a45a..2612b85b6f 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index c2d0afd17c..7e92b4ac9a 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index bc4b1b4d5a..579d040c35 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index 87c28a4fc5..a9c9b6d6c6 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 7fcd75908d..df507d4663 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 3ee0e53f50..0b042cc8de 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index f0cf16edfd..80806bf878 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index eb3e87b067..7917e19983 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index ac865624c1..531c34f7f4 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 0a9a604c73..21a2364e59 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 6199c9044c..2cacd91bf6 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 87e1d06e7a..31719248c8 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index cb0dbef057..36169d6923 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 1b1f3d1a00..5b14540802 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/pom.xml b/pom.xml index 0c19777ad3..17670275f6 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 23.3.0.58 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 1acefefa35..82842eac22 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index 71def7f728..e1635b662c 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.58 + 23.3.0.59-SNAPSHOT From f1fdf72c5bba9ed31ef38b349184dc7dd5089162 Mon Sep 17 00:00:00 2001 From: SathishK-T <166369440+SathishK-T@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:48:25 +0530 Subject: [PATCH 04/10] [APPS-2836][APPS-2837] Retention Schedule POST and GET API (#2704) * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule * [APPS-2836][APPS-2837] POST and GET API for Retention Schedule --------- Co-authored-by: Sathish Kumar --- .../alfresco/rest/core/RestAPIFactory.java | 11 + .../retentionschedule/RetentionSchedule.java | 49 ++++ .../RetentionScheduleActionDefinition.java | 50 ++++ .../RetentionScheduleCollection.java | 32 +++ .../RetentionScheduleEntry.java | 37 +++ .../community/requests/gscore/GSCoreAPI.java | 6 + .../gscore/api/RetentionScheduleAPI.java | 125 ++++++++ .../RetentionScheduleTests.java | 270 ++++++++++++++++++ .../rm-public-rest-context.xml | 7 + .../disposition/DispositionServiceImpl.java | 187 ++++++------ .../rest/api/impl/ApiNodesModelFactory.java | 144 +++++++++- .../rm/rest/api/model/RetentionSchedule.java | 45 +++ .../RetentionScheduleActionDefinition.java | 51 ++++ .../RetentionScheduleRelation.java | 108 +++++++ .../api/retentionschedule/package-info.java | 34 +++ .../service/DispositionServiceImplTest.java | 36 +-- .../RetentionScheduleModelUnitTest.java | 110 +++++++ 17 files changed, 1175 insertions(+), 127 deletions(-) create mode 100644 amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java create mode 100644 amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java create mode 100644 amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleCollection.java create mode 100644 amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleEntry.java create mode 100644 amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java create mode 100644 amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java create mode 100644 amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java create mode 100644 amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java create mode 100644 amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java create mode 100644 amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/package-info.java create mode 100644 amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java index b07ec559b5..d034690d8a 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/core/RestAPIFactory.java @@ -49,6 +49,7 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI; import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI; import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI; import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI; +import org.alfresco.rest.rm.community.requests.gscore.api.RetentionScheduleAPI; import org.alfresco.utility.data.DataUserAIS; import org.alfresco.utility.model.RepoTestModel; import org.alfresco.utility.model.UserModel; @@ -254,4 +255,14 @@ public class RestAPIFactory { return getGSCoreAPI(userModel).usingHoldsAPI(); } + + public RetentionScheduleAPI getRetentionScheduleAPI() + { + return getGSCoreAPI(null).usingRetentionScheduleAPI(); + } + + public RetentionScheduleAPI getRetentionScheduleAPI(UserModel userModel) + { + return getGSCoreAPI(userModel).usingRetentionScheduleAPI(); + } } diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java new file mode 100644 index 0000000000..63ba5045a8 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionSchedule.java @@ -0,0 +1,49 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rest.rm.community.model.retentionschedule; + +import lombok.EqualsAndHashCode; +import org.alfresco.utility.model.TestModel; +import lombok.Data; + +import java.util.List; + +/** + * retention schedule + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class RetentionSchedule extends TestModel +{ + private String id ; + private String parentId; + private String authority; + private String instructions; + private boolean isRecordLevel; + private boolean isUnpublishedUpdates; + private List actions; +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java new file mode 100644 index 0000000000..0c79e9f543 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleActionDefinition.java @@ -0,0 +1,50 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rest.rm.community.model.retentionschedule; + +import java.util.List; +import lombok.Data; + +/** + * retention schedule action definition + */ +@Data +public class RetentionScheduleActionDefinition +{ + private String id; + private String name; + private int periodAmount; + private String period; + private String periodProperty; + private boolean combineDispositionStepConditions; + private List events; + private boolean eligibleOnFirstCompleteEvent; + private String description; + private boolean retainRecordMetadataAfterDestruction; + private String location; + private int index; +} \ No newline at end of file diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleCollection.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleCollection.java new file mode 100644 index 0000000000..878a48ff09 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleCollection.java @@ -0,0 +1,32 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rest.rm.community.model.retentionschedule; + +import org.alfresco.rest.core.RestModels; +public class RetentionScheduleCollection extends RestModels +{ +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleEntry.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleEntry.java new file mode 100644 index 0000000000..74a95dcf19 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/retentionschedule/RetentionScheduleEntry.java @@ -0,0 +1,37 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rest.rm.community.model.retentionschedule; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.alfresco.rest.core.RestModels; +@Data +public class RetentionScheduleEntry extends RestModels +{ + @JsonProperty + private RetentionSchedule entry; +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java index d1c6a6c2c7..84333a5c73 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/GSCoreAPI.java @@ -47,6 +47,7 @@ import org.alfresco.rest.rm.community.requests.gscore.api.TransferAPI; import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI; import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI; import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI; +import org.alfresco.rest.rm.community.requests.gscore.api.RetentionScheduleAPI; /** * Defines the entire GS Core API @@ -193,4 +194,9 @@ public class GSCoreAPI extends RMModelRequest } public HoldsAPI usingHoldsAPI() { return new HoldsAPI(getRmRestWrapper()); } + + public RetentionScheduleAPI usingRetentionScheduleAPI() + { + return new RetentionScheduleAPI(getRmRestWrapper()); + } } diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java new file mode 100644 index 0000000000..83a2a142d4 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/gscore/api/RetentionScheduleAPI.java @@ -0,0 +1,125 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rest.rm.community.requests.gscore.api; + +import org.alfresco.rest.core.RMRestWrapper; +import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule; +import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleCollection; +import org.alfresco.rest.rm.community.requests.RMModelRequest; + +import static org.alfresco.rest.core.RestRequest.requestWithBody; +import static org.alfresco.rest.core.RestRequest.simpleRequest; +import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject; +import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString; +import static org.alfresco.rest.rm.community.util.PojoUtility.toJson; +import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; + +public class RetentionScheduleAPI extends RMModelRequest +{ + + /** + * @param rmRestWrapper + */ + public RetentionScheduleAPI(RMRestWrapper rmRestWrapper) + { + super(rmRestWrapper); + } + + + /** + * Creates a retention schedule. + * + * @param retentionScheduleModel The retentionSchedule model + * @param recordCategoryId The identifier of a record category + * @param parameters The URL parameters to add + * @return The created {@link RetentionSchedule} + * @throws RuntimeException for the following cases: + *
    + *
  • {@code recordCategoryId} is not a valid format or {@code recordCategoryId} is invalid
  • + *
  • authentication fails
  • + *
  • current user does not have permission to add children to {@code recordCategoryId}
  • + *
  • {@code recordCategoryId} does not exist
  • + *
  • new name clashes with an existing node in the current parent container
  • + *
+ */ + public RetentionSchedule createRetentionSchedule(RetentionSchedule retentionScheduleModel, String recordCategoryId, String parameters) + { + mandatoryString("recordCategoryId", recordCategoryId); + mandatoryObject("retentionScheduleModel", retentionScheduleModel); + + return getRmRestWrapper().processModel(RetentionSchedule.class, requestWithBody( + POST, + toJson(retentionScheduleModel), + "record-categories/{recordCategoryId}/retention-schedules", + recordCategoryId, + parameters + )); + } + + /** + * See {@link #createRetentionSchedule(RetentionSchedule, String, String)} + */ + public RetentionSchedule createRetentionSchedule(RetentionSchedule retentionScheduleModel, String recordCategoryId) + { + return createRetentionSchedule(retentionScheduleModel, recordCategoryId, EMPTY); + } + + /** + * Gets the retentionSchedule of a record category. + * + * @param recordCategoryId The identifier of a record category + * @param parameters The URL parameters to add + * @return The {@link RetentionSchedule} for the given {@code recordCategoryId} + * @throws RuntimeException for the following cases: + *
    + *
  • authentication fails
  • + *
  • current user does not have permission to read {@code recordCategoryId}
  • + *
  • {@code recordCategoryId} does not exist
  • + *
+ */ + public RetentionScheduleCollection getRetentionSchedule(String recordCategoryId, String parameters) + { + mandatoryString("recordCategoryId", recordCategoryId); + + return getRmRestWrapper().processModels(RetentionScheduleCollection.class, simpleRequest( + GET, + "record-categories/{recordCategoryId}/retention-schedules?{parameters}", + recordCategoryId, + parameters + )); + } + + /** + * See {@link #getRetentionSchedule(String, String)} + */ + public RetentionScheduleCollection getRetentionSchedule(String recordCategoryId) + { + return getRetentionSchedule(recordCategoryId, EMPTY); + } +} \ No newline at end of file diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java new file mode 100644 index 0000000000..017530e385 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/retentionschedule/RetentionScheduleTests.java @@ -0,0 +1,270 @@ +/*- + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rest.rm.community.retentionschedule; + +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; +import org.alfresco.rest.rm.community.model.retentionschedule.RetentionSchedule; +import org.alfresco.rest.rm.community.model.retentionschedule.RetentionScheduleCollection; +import org.alfresco.rest.v0.RMRolesAndActionsAPI; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID; +import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.springframework.http.HttpStatus.CONFLICT; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.HttpStatus.UNAUTHORIZED; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.AssertJUnit.assertEquals; + +/** + * This class contains the tests for the Retention Schedule CRUD V1 API + */ +public class RetentionScheduleTests extends BaseRMRestTest +{ + private RecordCategory recordCategory; + private RetentionSchedule createdRetentionSchedule; + private UserModel nonRMuser; + @Autowired + private RMRolesAndActionsAPI rmRolesAndActionsAPI; + + @BeforeClass(alwaysRun = true) + public void preconditionForRetentionScheduleTests() + { + createRMSiteIfNotExists(); + // create a non rm user + nonRMuser = dataUser.createRandomTestUser("testUser"); + //Create record category + recordCategory = createRootCategory(getRandomName("recordCategory")); + + + } + /** + *
+     * Given that a record category exists
+     * When I ask the API to create a retention schedule with a user having no rights
+     * Then it will give 403 as status code
+     * 
+ */ + @Test(priority = 1) + public void createRetentionScheduleFor403() + { + RetentionSchedule retentionSchedule = new RetentionSchedule(); + + // Create retention schedule with user having no rights + getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).createRetentionSchedule(retentionSchedule, recordCategory.getId()); + + // Verify the status code + assertStatusCode(FORBIDDEN); + } + + /** + *
+     * Given that a record category does not exists
+     * When I ask the API to create a retention schedule on a category Id
+     * Then it will give 404 as a status code
+     * 
+ */ + @Test(priority = 2) + public void createRetentionScheduleFor404() + { + RetentionSchedule retentionSchedule = new RetentionSchedule(); + + //Create retention schedule with category id not exist + getRestAPIFactory().getRetentionScheduleAPI().createRetentionSchedule(retentionSchedule, getRandomAlphanumeric()); + + // Verify the status code + assertStatusCode(NOT_FOUND); + } + + /** + *
+     * Given that a record category exists
+     * When I ask the API to create a retention schedule on a category id with a user having unauthorized access
+     * Then it will give 401 as a status code
+     * 
+ */ + @Test(priority = 3) + public void createRetentionScheduleFor401() + { + RetentionSchedule retentionSchedule = new RetentionSchedule(); + + //Create retention schedule with a user with unauthorized access + createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword")).createRetentionSchedule(retentionSchedule, recordCategory.getId()); + + // Verify the status code + assertStatusCode(UNAUTHORIZED); + } + + /** + *
+     * Given that a record category exists
+     * When I ask the API to create a retention schedule with a user having access
+     * Then it is created with a 201 status code
+     * 
+ */ + @Test(priority = 4) + public void createRetentionScheduleFor201() + { + RetentionSchedule retentionSchedule = new RetentionSchedule(); + String authority = "authority" + getRandomAlphanumeric(); + String instructions = "instructions" + getRandomAlphanumeric(); + boolean isRecordLevel = false; + retentionSchedule.setAuthority(authority); + retentionSchedule.setInstructions(instructions); + retentionSchedule.setRecordLevel(isRecordLevel); + + //Create retention schedule with a valid user + createdRetentionSchedule = getRestAPIFactory().getRetentionScheduleAPI() + .createRetentionSchedule(retentionSchedule, recordCategory.getId()); + + // Verify the status code + assertStatusCode(CREATED); + assertEquals(createdRetentionSchedule.getAuthority(), authority); + assertEquals(createdRetentionSchedule.getInstructions(), instructions); + assertFalse(createdRetentionSchedule.isRecordLevel()); + assertNotNull(createdRetentionSchedule.getId()); + } + + /** + *
+     * Given that a record category exists
+     * When I ask the API to create a retention schedule on a category id having retention schedule already
+     * Then it will give 409 as a status code
+     * 
+ */ + @Test(priority = 5) + public void createRetentionScheduleFor409() + { + RetentionSchedule retentionSchedule = new RetentionSchedule(); + //Create retention schedule on a category with already having retention schedule + getRestAPIFactory().getRetentionScheduleAPI() + .createRetentionSchedule(retentionSchedule, recordCategory.getId()); + + assertStatusCode(CONFLICT); + } + + /** + *
+     * Given that a record category exists
+     * When I ask the API to get a retention schedule on a given categoryId with a user having no rights
+     * Then it will give 403
+     * 
+ */ + @Test(priority = 6) + public void retentionScheduleWith403() + { + //Get retention schedule with user having no rights + getRestAPIFactory().getRetentionScheduleAPI(nonRMuser).getRetentionSchedule(recordCategory.getId()); + + // Verify the status code + assertStatusCode(FORBIDDEN); + } + + /** + *
+     * Given that a record category does not exists
+     * When I ask the API to get a retention schedule on a category Id
+     * Then it will give 404 as a status code
+     * 
+ */ + @Test(priority = 7) + public void retentionScheduleWith404() + { + + //Get retention schedule with category id that does not exist + getRestAPIFactory().getRetentionScheduleAPI().getRetentionSchedule(getRandomAlphanumeric()); + + // Verify the status code + assertStatusCode(NOT_FOUND); + } + + /** + *
+     * Given that a record category exists
+     * When I ask the API to get a retention schedule on a categoryId with a user having unauthorized access
+     * Then it will give 401 as a status code
+     * 
+ */ + @Test(priority = 8) + public void retentionScheduleWith401() + { + //Create retention schedule with a user with unauthorized access + getRestAPIFactory().getRetentionScheduleAPI(new UserModel(getAdminUser().getUsername(), "wrongPassword")).getRetentionSchedule(recordCategory.getId()); + + // Verify the status code + assertStatusCode(UNAUTHORIZED); + } + + /** + *
+     * Given that a record category exists
+     * When I ask the API to get a retention schedule on a categoryId with a user having access
+     * Then it will give retentionSchedule with 200 as a status code
+     * 
+ */ + @Test(priority = 9) + public void retentionScheduleWith200() + { + RetentionScheduleCollection retentionScheduleCollection = getRestAPIFactory().getRetentionScheduleAPI().getRetentionSchedule(recordCategory.getId()); + // Verify the status code + assertStatusCode(OK); + retentionScheduleCollection.getEntries().forEach(c -> + { + RetentionSchedule retentionSchedule = c.getEntry(); + String retentionScheduleId = retentionSchedule.getId(); + assertNotNull(retentionScheduleId); + logger.info("Checking retention schedule " + retentionScheduleId); + + // Find this retention schedule is created one or not + assertEquals(createdRetentionSchedule.getId(), retentionScheduleId); + assertEquals(createdRetentionSchedule.getParentId(),retentionSchedule.getParentId()); + assertEquals(createdRetentionSchedule.getAuthority(), retentionSchedule.getAuthority()); + assertEquals(createdRetentionSchedule.getInstructions(), retentionSchedule.getInstructions()); + assertEquals(createdRetentionSchedule.isRecordLevel(), retentionSchedule.isRecordLevel()); + assertEquals(createdRetentionSchedule.isUnpublishedUpdates(), retentionSchedule.isUnpublishedUpdates()); + }); + } + + @AfterClass(alwaysRun = true) + public void cleanUpRetentionScheduleTests() + { + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, recordCategory.getName()); + deleteRecordCategory(recordCategory.getId()); + dataUser.deleteUser(nonRMuser); + } +} \ No newline at end of file diff --git a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml index f1f225c569..970c73a5ee 100644 --- a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml +++ b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml @@ -147,6 +147,13 @@ + + + + + + + diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index 282f190f28..cf87aaf2c1 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -59,6 +59,9 @@ 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.RetryingTransactionCallback; +import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; +import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -198,7 +201,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl /** * Behavior to initialize the disposition schedule of a newly filed record. * - * @see org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnFileRecord#onFileRecord(org.alfresco.service.cmr.repository.NodeRef) + * @see RecordsManagementPolicies.OnFileRecord#onFileRecord(NodeRef) */ @Override @Behaviour(kind=BehaviourKind.CLASS, type="rma:record") @@ -216,7 +219,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#refreshDispositionAction(NodeRef) + * @see DispositionService#refreshDispositionAction(NodeRef) */ @Override public void refreshDispositionAction(NodeRef nodeRef) @@ -242,7 +245,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl /** ========= Disposition Property Methods ========= */ /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#registerDispositionProperty(org.alfresco.module.org_alfresco_module_rm.disposition.property.DispositionProperty) + * @see DispositionService#registerDispositionProperty(DispositionProperty) */ @Override public void registerDispositionProperty(DispositionProperty dispositionProperty) @@ -251,7 +254,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionProperties(boolean, java.lang.String) + * @see DispositionService#getDispositionProperties(boolean, String) */ @Override public Collection getDispositionProperties(boolean isRecordLevel, String dispositionAction) @@ -270,7 +273,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionProperties() + * @see DispositionService#getDispositionProperties() */ @Override public Collection getDispositionProperties() @@ -281,12 +284,11 @@ public class DispositionServiceImpl extends ServiceBaseImpl /** ========= Disposition Schedule Methods ========= */ /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#getDispositionSchedule(NodeRef) */ @Override public DispositionSchedule getDispositionSchedule(final NodeRef nodeRef) { - DispositionSchedule ds = null; NodeRef dsNodeRef = null; if (isRecord(nodeRef)) { @@ -311,36 +313,33 @@ public class DispositionServiceImpl extends ServiceBaseImpl if (dsNextAction != null) { final NodeRef action = dsNextAction.getNextActionNodeRef(); - if (isNotTrue((Boolean)nodeService.getProperty(action, PROP_MANUALLY_SET_AS_OF))) + if (isNotTrue((Boolean)nodeService.getProperty(action, PROP_MANUALLY_SET_AS_OF)) && !dsNextAction.getWriteMode().equals(WriteMode.READ_ONLY)) { - if (!dsNextAction.getWriteMode().equals(WriteMode.READ_ONLY)) + final String dispositionActionName = dsNextAction.getNextActionName(); + final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf(); + + RunAsWork runAsWork = () -> { + nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate); + return null; + }; + + // if the current transaction is READ ONLY set the property on the node + // in a READ WRITE transaction + if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) { - final String dispositionActionName = dsNextAction.getNextActionName(); - final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf(); - - RunAsWork runAsWork = () -> { - nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate); - return null; - }; - - // if the current transaction is READ ONLY set the property on the node - // in a READ WRITE transaction - if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) - { - transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback) () -> { - AuthenticationUtil.runAsSystem(runAsWork); - return null; - }, false, true); - } - else - { + transactionService.getRetryingTransactionHelper().doInTransaction((RetryingTransactionCallback) () -> { AuthenticationUtil.runAsSystem(runAsWork); - } + return null; + }, false, true); + } + else + { + AuthenticationUtil.runAsSystem(runAsWork); + } - if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME)) - { - nodeService.setProperty(action, PROP_DISPOSITION_ACTION_NAME, dispositionActionName); - } + if (dsNextAction.getWriteMode().equals(WriteMode.DATE_AND_NAME)) + { + nodeService.setProperty(action, PROP_DISPOSITION_ACTION_NAME, dispositionActionName); } } @@ -352,7 +351,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl // Get the disposition instructions for the node reference provided dsNodeRef = getDispositionScheduleImpl(nodeRef); } - + DispositionSchedule ds = null; if (dsNodeRef != null) { ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dsNodeRef); @@ -382,7 +381,8 @@ public class DispositionServiceImpl extends ServiceBaseImpl } return result; } - + + @Override public DispositionSchedule getOriginDispositionSchedule(NodeRef nodeRef) { NodeRef parent = this.nodeService.getPrimaryParent(nodeRef).getParentRef(); @@ -406,7 +406,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getAssociatedDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#getAssociatedDispositionSchedule(NodeRef) */ @Override public DispositionSchedule getAssociatedDispositionSchedule(NodeRef nodeRef) @@ -437,7 +437,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl */ private NodeRef getAssociatedDispositionScheduleImpl(NodeRef nodeRef) { - NodeRef result = null; ParameterCheck.mandatory("nodeRef", nodeRef); // Make sure we are dealing with an RM node @@ -445,6 +444,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl { throw new AlfrescoRuntimeException("Can not find the associated retention schedule for a non records management component. (nodeRef=" + nodeRef.toString() + ")"); } + NodeRef result = null; if (getInternalNodeService().hasAspect(nodeRef, ASPECT_SCHEDULED)) { List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ASSOC_DISPOSITION_SCHEDULE, RegexQNamePattern.MATCH_ALL); @@ -459,7 +459,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getAssociatedRecordsManagementContainer(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule) + * @see DispositionService#getAssociatedRecordsManagementContainer(DispositionSchedule) */ @Override public NodeRef getAssociatedRecordsManagementContainer(DispositionSchedule dispositionSchedule) @@ -477,12 +477,9 @@ public class DispositionServiceImpl extends ServiceBaseImpl { // TODO in the future we should be able to support disposition schedule reuse, but for now just warn that // only the first disposition schedule will be considered - if (LOGGER.isWarnEnabled()) - { - LOGGER.warn("Retention schedule has more than one associated records management container. " + - "This is not currently supported so only the first container will be considered. " + - "(dispositionScheduleNodeRef=" + dispositionSchedule.getNodeRef().toString() + ")"); - } + LOGGER.atWarn().log("Retention schedule has more than one associated records management container. " + + "This is not currently supported so only the first container will be considered. " + + "(dispositionScheduleNodeRef={})", dispositionSchedule.getNodeRef()); } // Get the container reference @@ -495,7 +492,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#hasDisposableItems(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule) + * @see DispositionService#hasDisposableItems(DispositionSchedule) */ @Override public boolean hasDisposableItems(DispositionSchedule dispositionSchdule) @@ -537,19 +534,16 @@ public class DispositionServiceImpl extends ServiceBaseImpl return true; } } - else if (filePlanService.isRecordCategory(item) && getAssociatedDispositionScheduleImpl(item) == null) + else if (filePlanService.isRecordCategory(item) && getAssociatedDispositionScheduleImpl(item) == null && hasDisposableItemsImpl(isRecordLevelDisposition, item)) { - if (hasDisposableItemsImpl(isRecordLevelDisposition, item)); - { - return true; - } + return true; } } return false; } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getDisposableItems(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule) + * @see DispositionService#getDisposableItems(DispositionSchedule) */ @Override public List getDisposableItems(DispositionSchedule dispositionSchedule) @@ -564,7 +558,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isDisposableItem(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#isDisposableItem(NodeRef) */ @Override public boolean isDisposableItem(NodeRef nodeRef) @@ -604,20 +598,18 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#createDispositionSchedule(org.alfresco.service.cmr.repository.NodeRef, java.util.Map) + * @see DispositionService#createDispositionSchedule(NodeRef, Map) */ @Override public DispositionSchedule createDispositionSchedule(NodeRef nodeRef, Map props) { - NodeRef dsNodeRef = null; - // Check mandatory parameters ParameterCheck.mandatory("nodeRef", nodeRef); // Check exists if (!nodeService.exists(nodeRef)) { - throw new AlfrescoRuntimeException("Unable to create retention schedule, because node does not exist. (nodeRef=" + nodeRef.toString() + ")"); + throw new EntityNotFoundException(nodeRef.getId()); } // Check is sub-type of rm:recordCategory @@ -625,10 +617,12 @@ public class DispositionServiceImpl extends ServiceBaseImpl if (!TYPE_RECORD_CATEGORY.equals(nodeRefType) && !dictionaryService.isSubClass(nodeRefType, TYPE_RECORD_CATEGORY)) { - throw new AlfrescoRuntimeException("Unable to create retention schedule on a node that is not a records management container."); + throw new InvalidArgumentException("The given id:'" + nodeRef.getId() + "' (nodeType:" + nodeRef + + ") is not valid. Expected nodeType is:" + TYPE_RECORD_CATEGORY); } behaviourFilter.disableBehaviour(nodeRef, ASPECT_SCHEDULED); + NodeRef dsNodeRef = null; try { // Add the schedules aspect if required @@ -662,7 +656,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl else { // Error since the node already has a disposition schedule set - throw new AlfrescoRuntimeException("Unable to create retention schedule on node that already has a retention schedule."); + throw new ConstraintViolatedException("Unable to create retention schedule on node that already has a retention schedule."); } } finally @@ -686,7 +680,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl { // make sure at least a name has been defined String name = (String)actionDefinitionParams.get(PROP_DISPOSITION_ACTION_NAME); - if (name == null || name.length() == 0) + if (name == null || name.isEmpty()) { throw new IllegalArgumentException("'name' parameter is mandatory when creating a disposition action definition"); } @@ -695,10 +689,10 @@ public class DispositionServiceImpl extends ServiceBaseImpl // create the child association from the schedule to the action definition NodeRef actionNodeRef = this.nodeService.createNode(schedule.getNodeRef(), - RecordsManagementModel.ASSOC_DISPOSITION_ACTION_DEFINITIONS, + ASSOC_DISPOSITION_ACTION_DEFINITIONS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(name)), - RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef(); + TYPE_DISPOSITION_ACTION_DEFINITION, actionDefinitionParams).getChildRef(); // get the updated disposition schedule and retrieve the new action definition NodeRef scheduleParent = this.nodeService.getPrimaryParent(schedule.getNodeRef()).getParentRef(); @@ -707,7 +701,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#removeDispositionActionDefinition(org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule, org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition) + * @see DispositionService#removeDispositionActionDefinition(DispositionSchedule, DispositionActionDefinition) */ @Override public void removeDispositionActionDefinition(DispositionSchedule schedule, DispositionActionDefinition actionDefinition) @@ -777,16 +771,12 @@ public class DispositionServiceImpl extends ServiceBaseImpl DispositionAction da; // check if current transaction is a READ ONLY one and if true create the node in a READ WRITE transaction - if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) - { - da = - transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() - { - public DispositionAction execute() throws Throwable - { - return createDispositionAction(nodeRef, props); - } - }, false, true); + if (AlfrescoTransactionSupport.getTransactionReadState().equals(TxnReadState.TXN_READ_ONLY)) { + da = transactionService.getRetryingTransactionHelper().doInTransaction( + () -> createDispositionAction(nodeRef, props), + false, + true + ); } else { @@ -836,13 +826,13 @@ public class DispositionServiceImpl extends ServiceBaseImpl Period period = dispositionActionDefinition.getPeriod(); if (period != null) { - Date contextDate = null; + Date contextDate; // Get the period properties value QName periodProperty = dispositionActionDefinition.getPeriodProperty(); if (periodProperty != null) { - if (RecordsManagementModel.PROP_DISPOSITION_AS_OF.equals(periodProperty)) + if (PROP_DISPOSITION_AS_OF.equals(periodProperty)) { DispositionAction lastCompletedDispositionAction = getLastCompletedDispostionAction(nodeRef); if (lastCompletedDispositionAction != null) @@ -886,7 +876,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isNextDispositionActionEligible(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#isNextDispositionActionEligible(NodeRef) */ @Override public boolean isNextDispositionActionEligible(NodeRef nodeRef) @@ -940,7 +930,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl { NodeRef eventExecution = assoc.getChildRef(); Boolean isCompleteValue = (Boolean) getInternalNodeService().getProperty(eventExecution, PROP_EVENT_EXECUTION_COMPLETE); - boolean isComplete = false; + boolean isComplete; if (isCompleteValue != null) { isComplete = isCompleteValue.booleanValue(); @@ -987,7 +977,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getNextDispositionAction(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#getNextDispositionAction(NodeRef) */ @Override public DispositionAction getNextDispositionAction(NodeRef nodeRef) @@ -1006,7 +996,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl /** ========= Disposition Action History Methods ========= */ /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getCompletedDispositionActions(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#getCompletedDispositionActions(NodeRef) */ @Override public List getCompletedDispositionActions(NodeRef nodeRef) @@ -1022,7 +1012,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#getLastCompletedDispostionAction(org.alfresco.service.cmr.repository.NodeRef) + * @see DispositionService#getLastCompletedDispostionAction(NodeRef) */ @Override public DispositionAction getLastCompletedDispostionAction(NodeRef nodeRef) @@ -1038,7 +1028,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#isDisposableItemCutoff(NodeRef) + * @see DispositionService#isDisposableItemCutoff(NodeRef) */ @Override public boolean isDisposableItemCutoff(NodeRef nodeRef) @@ -1048,7 +1038,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef) + * @see DispositionService#updateNextDispositionAction(NodeRef) */ @Override public void updateNextDispositionAction(final NodeRef nodeRef) @@ -1058,7 +1048,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl RunAsWork runAsWork = new RunAsWork() { /** - * @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork() + * @see RunAsWork#doWork() */ @Override public Void doWork() @@ -1077,7 +1067,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef) + * @see DispositionService#updateNextDispositionAction(NodeRef) */ @Override public void updateNextDispositionAction(final NodeRef nodeRef, final DispositionSchedule dispositionSchedule) @@ -1087,7 +1077,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl RunAsWork runAsWork = new RunAsWork() { /** - * @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork() + * @see RunAsWork#doWork() */ @Override public Void doWork() @@ -1113,16 +1103,13 @@ public class DispositionServiceImpl extends ServiceBaseImpl } List dispositionActionDefinitions = dispositionSchedule.getDispositionActionDefinitions(); - DispositionActionDefinition currentDispositionActionDefinition = null; + DispositionActionDefinition currentDispositionActionDefinition; DispositionActionDefinition nextDispositionActionDefinition = null; - if (currentDispositionAction == null) + if (currentDispositionAction == null && !dispositionActionDefinitions.isEmpty()) { - if (!dispositionActionDefinitions.isEmpty()) - { - // The next disposition action is the first action - nextDispositionActionDefinition = dispositionActionDefinitions.get(0); - } + // The next disposition action is the first action + nextDispositionActionDefinition = dispositionActionDefinitions.get(0); } else { @@ -1167,7 +1154,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#cutoffDisposableItem(NodeRef) + * @see DispositionService#cutoffDisposableItem(NodeRef) */ @Override public void cutoffDisposableItem(final NodeRef nodeRef) @@ -1205,6 +1192,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl // runAs system so that we can close a record that has already been cutoff authenticationUtil.runAsSystem(new RunAsWork() { + @Override public Void doWork() throws Exception { recordFolderService.closeRecordFolder(nodeRef); @@ -1224,6 +1212,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl } } + @Override public Date getDispositionActionDate(NodeRef record, NodeRef dispositionSchedule, String dispositionActionName) { DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, dispositionSchedule); @@ -1243,7 +1232,8 @@ public class DispositionServiceImpl extends ServiceBaseImpl } return null; } - + + @Override public void recalculateNextDispositionStep(NodeRef record) { List recordFolders = recordFolderService.getRecordFolders(record); @@ -1384,14 +1374,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl Date calculatedDate = (nextDispositionActionDate != null ? nextDispositionActionDate : maxDate); // We only need to update the date if the current one is too early. - if (recordDate.before(calculatedDate)) - { - return WriteMode.DATE_ONLY; - } - else - { - return WriteMode.READ_ONLY; - } + return recordDate.before(calculatedDate) ? WriteMode.DATE_ONLY : WriteMode.READ_ONLY; } /** @@ -1414,7 +1397,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl DispositionSchedule ds = new DispositionScheduleImpl(serviceRegistry, nodeService, folderDS); List dispositionActionDefinitions = ds.getDispositionActionDefinitions(); - if (dispositionActionDefinitions != null && dispositionActionDefinitions.size() > 0) + if (dispositionActionDefinitions != null && !dispositionActionDefinitions.isEmpty()) { DispositionActionDefinition firstDispositionActionDef = dispositionActionDefinitions.get(0); dispositionNodeRef = folderDS; diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java index a48a7ae4cf..7cd3334d67 100644 --- a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/ApiNodesModelFactory.java @@ -34,10 +34,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.alfresco.model.ContentModel; +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.DispositionService; +import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.AssocChild; @@ -61,6 +64,8 @@ import org.alfresco.rm.rest.api.model.UnfiledContainer; import org.alfresco.rm.rest.api.model.UnfiledContainerChild; import org.alfresco.rm.rest.api.model.UnfiledRecordFolder; import org.alfresco.rm.rest.api.model.UnfiledRecordFolderChild; +import org.alfresco.rm.rest.api.model.RetentionSchedule; +import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -71,6 +76,8 @@ import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS; + /** * Utility class containing Alfresco and RM java services required by the API * endpoints @@ -891,4 +898,139 @@ public class ApiNodesModelFactory mapAssociations(record, info, parameters.getInclude()); return record; } -} + + /** + * Helper method that sets the information for the retention schedule type. + * @param dispositionSchedule + * @return RetentionSchedule + */ + public RetentionSchedule mapRetentionScheduleData(DispositionSchedule dispositionSchedule) + { + RetentionSchedule retentionSchedule = new RetentionSchedule(); + retentionSchedule.setId(dispositionSchedule.getNodeRef().getId()); + if(dispositionSchedule.getNodeRef() != null) { + NodeRef parent = this.nodeService.getPrimaryParent(dispositionSchedule.getNodeRef()).getParentRef(); + retentionSchedule.setParentId(parent.getId()); + } + retentionSchedule.setInstructions(dispositionSchedule.getDispositionInstructions()); + retentionSchedule.setAuthority(dispositionSchedule.getDispositionAuthority()); + retentionSchedule.setRecordLevel(dispositionSchedule.isRecordLevelDisposition()); + + boolean unpublishedUpdates = dispositionSchedule.getDispositionActionDefinitions().stream() + .map(DispositionActionDefinition::getNodeRef) + .anyMatch(actionDefNodeRef -> nodeService.hasAspect(actionDefNodeRef, RecordsManagementModel.ASPECT_UNPUBLISHED_UPDATE)); + retentionSchedule.setUnpublishedUpdates(unpublishedUpdates); + return retentionSchedule; + } + + /** + * Helper method that sets the information for the retention schedule action definition type. + * @param dispositionActionDefinition + * @return RetentionScheduleActionDefinition + */ + public RetentionScheduleActionDefinition mapRetentionScheduleActionDefData(DispositionActionDefinition dispositionActionDefinition) + { + RetentionScheduleActionDefinition retentionScheduleActionDefinition = new RetentionScheduleActionDefinition(); + // Mapping basic properties + mapRetentionActionProperties(dispositionActionDefinition, retentionScheduleActionDefinition); + // Mapping period and period amount + mapPeriodProperties(dispositionActionDefinition, retentionScheduleActionDefinition); + // Mapping events properties + mapEventsProperties(dispositionActionDefinition, retentionScheduleActionDefinition); + return retentionScheduleActionDefinition; + } + + /** + * Helper method that sets core information for the retention schedule action definition type. + * @param dispositionActionDefinition + * @param retentionScheduleActionDefinition + */ + private void mapRetentionActionProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition) + { + retentionScheduleActionDefinition.setId(dispositionActionDefinition.getId()); + retentionScheduleActionDefinition.setName(dispositionActionDefinition.getName()); + retentionScheduleActionDefinition.setDescription(dispositionActionDefinition.getDescription()); + retentionScheduleActionDefinition.setEligibleOnFirstCompleteEvent(dispositionActionDefinition.eligibleOnFirstCompleteEvent()); + if (nodeService.getProperty(dispositionActionDefinition.getNodeRef(), PROP_COMBINE_DISPOSITION_STEP_CONDITIONS) != null) + { + retentionScheduleActionDefinition.setCombineDispositionStepConditions((Boolean) nodeService.getProperty(dispositionActionDefinition.getNodeRef(), PROP_COMBINE_DISPOSITION_STEP_CONDITIONS)); + } + retentionScheduleActionDefinition.setLocation(dispositionActionDefinition.getLocation()); + if (dispositionActionDefinition.getGhostOnDestroy() != null) + { + retentionScheduleActionDefinition.setRetainRecordMetadataAfterDestruction(dispositionActionDefinition.getGhostOnDestroy().equals("ghost")); + } + retentionScheduleActionDefinition.setIndex(dispositionActionDefinition.getIndex()); + } + + /** + * Helper method that sets the period-related information for the retention schedule action definition type. + * @param dispositionActionDefinition + * @param retentionScheduleActionDefinition + */ + private void mapPeriodProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition) + { + if(dispositionActionDefinition.getPeriodProperty() != null) { + retentionScheduleActionDefinition.setPeriodProperty(dispositionActionDefinition.getPeriodProperty().toPrefixString(namespaceService)); + } + String period = dispositionActionDefinition.getPeriod().toString(); + if (!period.isEmpty()) + { + // In rest api we are splitting `period` property into `period` and `periodAmount`. + // so we need to split the period into two properties. + // ex. period -> 'month|10' so the split properties would be like below + // period -> 'month' + // periodAmount -> 10 + String[] periodArray = period.split("\\|"); + if (periodArray.length > 0) + { + retentionScheduleActionDefinition.setPeriod(periodArray[0]); + } + if (periodArray.length > 1) + { + try + { + retentionScheduleActionDefinition.setPeriodAmount(Integer.parseInt(periodArray[1])); + } + catch (NumberFormatException e) + { + throw new NumberFormatException("Error parsing period amount: " + e.getMessage()); + } + } + } + } + + /** + * Helper method that sets the events information for the retention schedule action definition type. + * @param dispositionActionDefinition + * @param retentionScheduleActionDefinition + */ + private void mapEventsProperties(DispositionActionDefinition dispositionActionDefinition, RetentionScheduleActionDefinition retentionScheduleActionDefinition) + { + List events = dispositionActionDefinition.getEvents(); + if (events != null && !events.isEmpty()) + { + List eventNames = events.stream() + .map(RecordsManagementEvent::getName) + .collect(Collectors.toList()); + retentionScheduleActionDefinition.setEvents(eventNames); + } + } + + /** + * Helper method that sets the optional information for the retention schedule type. + * @param retentionSchedule + * @param schedule + * @param includeParam + */ + public void mapRetentionScheduleOptionalInfo(RetentionSchedule retentionSchedule, DispositionSchedule schedule, List includeParam) + { + if (includeParam != null && !includeParam.isEmpty() && includeParam.contains("actions")) + { + List actions = schedule.getDispositionActionDefinitions().stream() + .map(this::mapRetentionScheduleActionDefData) + .collect(Collectors.toList()); + retentionSchedule.setActions(actions); + } + } +} \ No newline at end of file diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java new file mode 100644 index 0000000000..1f698d0f33 --- /dev/null +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionSchedule.java @@ -0,0 +1,45 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rm.rest.api.model; + +import lombok.Data; +import java.util.List; + +/** + * retention schedule + */ +@Data +public class RetentionSchedule +{ + private String id ; + private String parentId; + private String authority; + private String instructions; + private boolean isRecordLevel; + private boolean isUnpublishedUpdates; + private List actions; +} diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java new file mode 100644 index 0000000000..d9806e01df --- /dev/null +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/model/RetentionScheduleActionDefinition.java @@ -0,0 +1,51 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rm.rest.api.model; + +import java.util.List; + +import lombok.Data; + +/** + * retention schedule action definition + */ +@Data +public class RetentionScheduleActionDefinition +{ + private String id; + private String name; + private int periodAmount; + private String period; + private String periodProperty; + private boolean combineDispositionStepConditions; + private List events; + private boolean eligibleOnFirstCompleteEvent; + private String description; + private boolean retainRecordMetadataAfterDestruction; + private String location; + private int index; +} \ No newline at end of file diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java new file mode 100644 index 0000000000..60a7a3b856 --- /dev/null +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/RetentionScheduleRelation.java @@ -0,0 +1,108 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.rm.rest.api.retentionschedule; + +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; +import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.resource.RelationshipResource; +import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +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.RetentionSchedule; +import org.alfresco.rm.rest.api.recordcategories.RecordCategoriesEntityResource; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.namespace.QName; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_AUTHORITY; +import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_DISPOSITION_INSTRUCTIONS; +import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_RECORD_LEVEL_DISPOSITION; +import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.TYPE_RECORD_CATEGORY; +import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank; +import static org.alfresco.util.ParameterCheck.mandatory; +import lombok.Data; + +/** + * Retention schedule relation is used perform retention schedule operation for a record category. + */ +@RelationshipResource(name = "retention-schedules", entityResource = RecordCategoriesEntityResource.class, title = "Retention Schedule") +@Data +public class RetentionScheduleRelation implements RelationshipResourceAction.Read, + RelationshipResourceAction.Create +{ + + private FilePlanComponentsApiUtils apiUtils; + private ApiNodesModelFactory nodesModelFactory; + private DispositionService dispositionService; + protected NodeService nodeService; + + @Override + @WebApiDescription(title="Create a retention schedule for the particular record category using the 'recordCategoryId'") + public List create(String recordCategoryId, List nodeInfos, Parameters parameters) + { + checkNotBlank("recordCategoryId", recordCategoryId); + mandatory("entity", nodeInfos); + mandatory("parameters", parameters); + NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, recordCategoryId); + List result = new ArrayList<>(); + // Create the disposition schedule + Map dsProps = new HashMap<>(); + dsProps.put(PROP_DISPOSITION_AUTHORITY, nodeInfos.get(0).getAuthority()); + dsProps.put(PROP_DISPOSITION_INSTRUCTIONS, nodeInfos.get(0).getInstructions()); + dsProps.put(PROP_RECORD_LEVEL_DISPOSITION, nodeInfos.get(0).isRecordLevel()); + DispositionSchedule dispositionSchedule = dispositionService.createDispositionSchedule(parentNodeRef, dsProps); + RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(dispositionSchedule); + result.add(retentionSchedule); + return result; + } + + @Override + @WebApiDescription(title = "Return a paged list of retention schedule based on the 'recordCategoryId'") + public CollectionWithPagingInfo readAll(String recordCategoryId, Parameters parameters) + { + checkNotBlank("recordCategoryId", recordCategoryId); + mandatory("parameters", parameters); + NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(recordCategoryId, TYPE_RECORD_CATEGORY); + DispositionSchedule schedule = dispositionService.getDispositionSchedule(parentNodeRef); + RetentionSchedule retentionSchedule = nodesModelFactory.mapRetentionScheduleData(schedule); + List retentionScheduleList = new ArrayList<>(); + nodesModelFactory.mapRetentionScheduleOptionalInfo(retentionSchedule, schedule, parameters.getInclude()); + retentionScheduleList.add(retentionSchedule); + return CollectionWithPagingInfo.asPaged(parameters.getPaging(), retentionScheduleList, false, + retentionScheduleList.size()); + } +} \ No newline at end of file diff --git a/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/package-info.java b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/package-info.java new file mode 100644 index 0000000000..07e151ccb9 --- /dev/null +++ b/amps/ags/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/retentionschedule/package-info.java @@ -0,0 +1,34 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ + +/** + * Package info that defines the Information Governance Retention Schedule REST API + */ +@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1) +package org.alfresco.rm.rest.api.retentionschedule; +import org.alfresco.rest.framework.Api; +import org.alfresco.rest.framework.WebApi; \ No newline at end of file diff --git a/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java b/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java index e2b7cb7b5b..f584ce59dd 100644 --- a/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java +++ b/amps/ags/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java @@ -51,6 +51,8 @@ import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorReg import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; +import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; +import org.junit.Assert; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; @@ -437,19 +439,12 @@ public class DispositionServiceImplTest extends BaseRMTestCase // Check the disposition schedule checkDispositionSchedule(ds, "testCreateDispositionSchedule", "testCreateDispositionSchedule", false); - } - }); - // Failure: create disposition schedule on container with existing disposition schedule - doTestInTransaction(new FailureTest - ( - "Can not create a disposition schedule on a container with an existing disposition schedule" - ) - { - @Override - public void run() - { - utils.createBasicDispositionSchedule(rmContainer); + // Failure: create disposition schedule on container with existing disposition schedule + Assert.assertThrows(ConstraintViolatedException.class, + () -> { + utils.createBasicDispositionSchedule(rmContainer); + }); } }); } @@ -492,19 +487,12 @@ public class DispositionServiceImplTest extends BaseRMTestCase // Check the disposition schedule checkDispositionSchedule(testA, "testA", "testA", false); checkDispositionSchedule(testB, "testB", "testB", false); - } - }); - // Failure: create disposition schedule on container with existing disposition schedule - doTestInTransaction(new FailureTest - ( - "Can not create a disposition schedule on container with an existing disposition schedule" - ) - { - @Override - public void run() - { - utils.createBasicDispositionSchedule(mhContainer11); + // Failure: create disposition schedule on container with existing disposition schedule + Assert.assertThrows(ConstraintViolatedException.class, + () -> { + utils.createBasicDispositionSchedule(rmContainer); + }); } }); diff --git a/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java b/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java new file mode 100644 index 0000000000..2b89472fde --- /dev/null +++ b/amps/ags/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/disposition/RetentionScheduleModelUnitTest.java @@ -0,0 +1,110 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.module.org_alfresco_module_rm.disposition; + +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory; +import org.alfresco.rm.rest.api.model.RetentionSchedule; +import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.Period; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +/** + * Retention schedule model unit test + */ +public class RetentionScheduleModelUnitTest extends BaseUnitTest +{ + private static final String AUTHORITY = "authority"; + private static final String INSTRUCTIONS = "instructions"; + private static final String RETAIN_STEP = "retain"; + + @InjectMocks + private ApiNodesModelFactory apiNodesModelFactory; + + @Mock + DispositionSchedule dispositionSchedule; + + @Mock + DispositionActionDefinition dispositionActionDefinition; + + @Test + public void mapRetentionScheduleDataTest() + { + // Mock data + NodeRef nodeRef = generateNodeRef(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE, true); + ChildAssociationRef childAssociationRef = generateChildAssociationRef(filePlan, record); + when(dispositionSchedule.getDispositionAuthority()).thenReturn(AUTHORITY); + when(dispositionSchedule.getDispositionInstructions()).thenReturn(INSTRUCTIONS); + when(dispositionSchedule.getNodeRef()).thenReturn(nodeRef); + when(dispositionSchedule.isRecordLevelDisposition()).thenReturn(false); + when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef); + // Call the method + RetentionSchedule expectedResult = apiNodesModelFactory.mapRetentionScheduleData(dispositionSchedule); + assertEquals(expectedResult.getId(), dispositionSchedule.getNodeRef().getId()); + assertEquals(expectedResult.getAuthority(), dispositionSchedule.getDispositionAuthority()); + assertEquals(expectedResult.getInstructions(), dispositionSchedule.getDispositionInstructions()); + assertEquals(expectedResult.isRecordLevel(), dispositionSchedule.isRecordLevelDisposition()); + } + + @Test + public void mapRetentionScheduleActionDefDataTest() + { + // Mock data + NodeRef nodeRef = generateNodeRef(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE, true); + String period = "month|10"; + ChildAssociationRef childAssociationRef = generateChildAssociationRef(filePlan, record); + when(dispositionActionDefinition.getNodeRef()).thenReturn(nodeRef); + when(dispositionActionDefinition.getName()).thenReturn(RETAIN_STEP); + when(dispositionActionDefinition.getDescription()).thenReturn("Description"); + when(dispositionActionDefinition.getIndex()).thenReturn(1); + when(dispositionActionDefinition.getGhostOnDestroy()).thenReturn("ghost"); + when(dispositionActionDefinition.getPeriod()).thenReturn(new Period(period)); + when(dispositionActionDefinition.getLocation()).thenReturn("location"); + when(dispositionActionDefinition.getId()).thenReturn(nodeRef.getId()); + when(mockedNodeService.getPrimaryParent(nodeRef)).thenReturn(childAssociationRef); + // Call the method + RetentionScheduleActionDefinition expectedResult = apiNodesModelFactory.mapRetentionScheduleActionDefData(dispositionActionDefinition); + String resultPeriod = expectedResult.getPeriod() + "|" + expectedResult.getPeriodAmount(); + // Assertions + assertEquals(expectedResult.getId(), dispositionActionDefinition.getId()); + assertEquals(expectedResult.getName(), dispositionActionDefinition.getName()); + assertEquals(expectedResult.getDescription(), dispositionActionDefinition.getDescription()); + assertEquals(expectedResult.getIndex(), dispositionActionDefinition.getIndex()); + assertEquals(expectedResult.getLocation(), dispositionActionDefinition.getLocation()); + assertEquals(new Period(resultPeriod), dispositionActionDefinition.getPeriod()); + assertTrue(expectedResult.isRetainRecordMetadataAfterDestruction()); + } +} \ No newline at end of file From 060cf3aa3c89b302bbee758d9fa2cb4b2686d40e Mon Sep 17 00:00:00 2001 From: Damian Ujma <92095156+damianujma@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:47:08 +0200 Subject: [PATCH 05/10] ACS-8048 Fix HXIAM access token validation issues (#2706) * ACS-8047: WIP - Fixed HXIAM access token validation issues. * ACS-8048 Accept at+jwt token + make signature algorithm configurable * ACS-8048 Accept multiple signature algorithms * ACS-8048 Fix PMD issue * ACS-8048 Log using the default signature algorithm * ACS-8048 Refactor --------- Co-authored-by: Jamal Kaabi-Mofrad --- .../IdentityServiceConfig.java | 33 +++- .../IdentityServiceFacadeFactoryBean.java | 45 +++++- ...dentity-service-authentication-context.xml | 3 + ...identity-service-authentication.properties | 3 +- .../IdentityServiceFacadeFactoryBeanTest.java | 146 ++++++++++++++++-- 5 files changed, 204 insertions(+), 26 deletions(-) diff --git a/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceConfig.java b/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceConfig.java index c8b4b4be1d..6dbc91e2d0 100644 --- a/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceConfig.java +++ b/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceConfig.java @@ -4,30 +4,35 @@ * %% * Copyright (C) 2005 - 2024 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 . * #L% */ package org.alfresco.repo.security.authentication.identityservice; +import java.util.Objects; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; import org.springframework.web.util.UriComponentsBuilder; /** @@ -35,6 +40,7 @@ import org.springframework.web.util.UriComponentsBuilder; * * @author Gavin Cornwell */ +@SuppressWarnings("PMD.ExcessivePublicCount") public class IdentityServiceConfig { private static final String REALMS = "realms"; @@ -62,6 +68,7 @@ public class IdentityServiceConfig private String principalAttribute; private boolean clientIdValidationDisabled; private String adminConsoleRedirectPath; + private String signatureAlgorithms; /** * @@ -306,4 +313,18 @@ public class IdentityServiceConfig { this.adminConsoleRedirectPath = adminConsoleRedirectPath; } + + public Set getSignatureAlgorithms() + { + return Stream.of(signatureAlgorithms.split(",")) + .map(String::trim) + .map(SignatureAlgorithm::from) + .filter(Objects::nonNull) + .collect(Collectors.toUnmodifiableSet()); + } + + public void setSignatureAlgorithms(String signatureAlgorithms) + { + this.signatureAlgorithms = signatureAlgorithms; + } } diff --git a/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBean.java b/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBean.java index 54ef842e99..80dd2b9c91 100644 --- a/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBean.java +++ b/repository/src/main/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBean.java @@ -58,10 +58,13 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import com.nimbusds.jose.JOSEObjectType; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.jwk.source.DefaultJWKSetCache; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.jwk.source.RemoteJWKSet; +import com.nimbusds.jose.proc.BadJOSEException; +import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier; import com.nimbusds.jose.proc.JWSVerificationKeySelector; import com.nimbusds.jose.proc.SecurityContext; import com.nimbusds.jose.util.ResourceRetriever; @@ -129,6 +132,9 @@ import org.springframework.web.util.UriComponentsBuilder; public class IdentityServiceFacadeFactoryBean implements FactoryBean { private static final Log LOGGER = LogFactory.getLog(IdentityServiceFacadeFactoryBean.class); + + private static final JOSEObjectType AT_JWT = new JOSEObjectType("at+jwt"); + private boolean enabled; private SpringBasedIdentityServiceFacadeFactory factory; @@ -554,12 +560,20 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean signatureAlgorithms; JwtDecoderProvider(IdentityServiceConfig config) { this.config = requireNonNull(config); + this.signatureAlgorithms = ofNullable(config.getSignatureAlgorithms()) + .filter(not(Set::isEmpty)) + .orElseGet(() -> { + LOGGER.warn("Unable to find any valid signature algorithms in the configuration. " + + "Using the default signature algorithm: " + DEFAULT_SIGNATURE_ALGORITHM.getName() + "."); + return Set.of(DEFAULT_SIGNATURE_ALGORITHM); + }); } public JwtDecoder createJwtDecoder(RestOperations rest, ProviderDetails providerDetails) @@ -587,13 +601,13 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean( - JWSAlgorithm.parse(SIGNATURE_ALGORITHM.getName()), + signatureAlgorithms.stream() + .map(signatureAlgorithm -> JWSAlgorithm.parse(signatureAlgorithm.getName())) + .collect(Collectors.toSet()), cachingJWKSource)); + jwtProcessor.setJWSTypeVerifier(new CustomJOSEObjectTypeVerifier(JOSEObjectType.JWT, AT_JWT)); } private OAuth2TokenValidator createJwtTokenValidator(ProviderDetails providerDetails) @@ -759,7 +776,6 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean + { + public CustomJOSEObjectTypeVerifier(JOSEObjectType... allowedTypes) + { + super(Set.of(allowedTypes)); + } + + @Override + public void verify(JOSEObjectType type, SecurityContext context) throws BadJOSEException + { + super.verify(type, context); + } + } + private static boolean isDefined(String value) { return value != null && !value.isBlank(); } - } diff --git a/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication-context.xml b/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication-context.xml index 2e7a2da573..748baf8cec 100644 --- a/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication-context.xml +++ b/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication-context.xml @@ -155,6 +155,9 @@ ${identity-service.admin-console.redirect-path} + + ${identity-service.signature-algorithms:RS256,PS256} + diff --git a/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication.properties b/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication.properties index 4a26aa1d94..7357b01644 100644 --- a/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication.properties +++ b/repository/src/main/resources/alfresco/subsystems/Authentication/identity-service/identity-service-authentication.properties @@ -11,4 +11,5 @@ identity-service.realm=alfresco identity-service.resource=alfresco identity-service.credentials.secret= identity-service.public-client=true -identity-service.admin-console.redirect-path=/alfresco/s/admin/admin-communitysummary \ No newline at end of file +identity-service.admin-console.redirect-path=/alfresco/s/admin/admin-communitysummary +identity-service.signature-algorithms=RS256,PS256 \ No newline at end of file diff --git a/repository/src/test/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBeanTest.java b/repository/src/test/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBeanTest.java index 646e887119..ef0bf2201e 100644 --- a/repository/src/test/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBeanTest.java +++ b/repository/src/test/java/org/alfresco/repo/security/authentication/identityservice/IdentityServiceFacadeFactoryBeanTest.java @@ -25,53 +25,156 @@ */ package org.alfresco.repo.security.authentication.identityservice; +import static com.nimbusds.jose.HeaderParameterNames.KEY_ID; + import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; +import com.nimbusds.jose.Algorithm; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; import com.nimbusds.openid.connect.sdk.claims.PersonClaims; import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacadeFactoryBean.JwtAudienceValidator; import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacadeFactoryBean.JwtDecoderProvider; import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacadeFactoryBean.JwtIssuerValidator; import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.jwt.BadJwtException; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.web.client.RestOperations; public class IdentityServiceFacadeFactoryBeanTest { private static final String EXPECTED_ISSUER = "expected-issuer"; private static final String EXPECTED_AUDIENCE = "expected-audience"; + public final IdentityServiceConfig config = mock(IdentityServiceConfig.class); + public final RestOperations restOperations = mock(RestOperations.class); + public final ResponseEntity responseEntity = mock(ResponseEntity.class); + public final ProviderDetails providerDetails = mock(ProviderDetails.class); @Test public void shouldCreateJwtDecoderWithoutIDSWhenPublicKeyIsProvided() { - final IdentityServiceConfig config = mock(IdentityServiceConfig.class); - when(config.getRealmKey()).thenReturn("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve3MabX/rp3LbE7/zNqKxuid8WT7y4qSXsNaiPvl/OVbNWW/cu5td1VndItYhH6/gL7Z5W/r4MOeTlz/fOdXfjrRJou2f3UiPQwLV9RdOH3oS4/BUe+sviD8Q3eRfWBWWz3yw8f2YNtD4bMztIMMjqthvwdEEb9S9jbxxD0o71Bsrz/FwPi7HhSDA+Z/p01Hct8m4wx13ZlKRd4YjyC12FBmi9MSgsrFuWzyQHhHTeBDoALpfuiut3rhVxUtFmVTpy6p9vil7C5J5pok4MXPH0dJCyDNQz05ww5+fD+tfksIEpFeokRpN226F+P21oQVFUWwYIaXaFlG/hfvwmnlfQIDAQAB"); + when(config.getRealmKey()).thenReturn( + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve3MabX/rp3LbE7/zNqKxuid8WT7y4qSXsNaiPvl/OVbNWW/cu5td1VndItYhH6/gL7Z5W/r4MOeTlz/fOdXfjrRJou2f3UiPQwLV9RdOH3oS4/BUe+sviD8Q3eRfWBWWz3yw8f2YNtD4bMztIMMjqthvwdEEb9S9jbxxD0o71Bsrz/FwPi7HhSDA+Z/p01Hct8m4wx13ZlKRd4YjyC12FBmi9MSgsrFuWzyQHhHTeBDoALpfuiut3rhVxUtFmVTpy6p9vil7C5J5pok4MXPH0dJCyDNQz05ww5+fD+tfksIEpFeokRpN226F+P21oQVFUWwYIaXaFlG/hfvwmnlfQIDAQAB"); when(config.isClientIdValidationDisabled()).thenReturn(true); - - final ProviderDetails providerDetails = mock(ProviderDetails.class); when(providerDetails.getIssuerUri()).thenReturn("https://my.issuer"); final JwtDecoderProvider provider = new JwtDecoderProvider(config); final JwtDecoder decoder = provider.createJwtDecoder(null, providerDetails); - final Jwt decodedToken = decoder.decode("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjIxNDc0ODM2NDcsImp0aSI6IjEyMzQiLCJpc3MiOiJodHRwczovL215Lmlzc3VlciIsInN1YiI6ImFiYzEyMyIsInR5cCI6IkJlYXJlciIsInByZWZlcnJlZF91c2VybmFtZSI6InBpb3RyZWsifQ.k_KaOrLLh3QsT8mKphkcz2vKpulgxp92UoEDccpHJ1mxE3Pa3gFXPKTj4goUBKXieGPZRMvBDhfWNxMvRYZPiQr2NXJKapkh0bTd0qoaSWz9ICe9Nu3eg7_VA_nwUVPz_35wwmrxgVk0_kpUYQN_VtaO7ZgFE2sJzFjbkVls5aqfAMnEjEgQl837hqZvmlW2ZRWebtxXfQxAjtp0gcTg-xtAHKIINYo_1_uAtt_H9L8KqFaioxrVAEDDIlcKnb-Ks3Y62CrZauaGUJeN_aNj2gdOpdkhvCw79yJyZSGZ7okjGbidCNSAf7Bo2Y6h3dP1Gga7kRmD648ftZESrNvbyg"); + final Jwt decodedToken = decoder.decode( + "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjIxNDc0ODM2NDcsImp0aSI6IjEyMzQiLCJpc3MiOiJodHRwczovL215Lmlzc3VlciIsInN1YiI6ImFiYzEyMyIsInR5cCI6IkJlYXJlciIsInByZWZlcnJlZF91c2VybmFtZSI6InBpb3RyZWsifQ.k_KaOrLLh3QsT8mKphkcz2vKpulgxp92UoEDccpHJ1mxE3Pa3gFXPKTj4goUBKXieGPZRMvBDhfWNxMvRYZPiQr2NXJKapkh0bTd0qoaSWz9ICe9Nu3eg7_VA_nwUVPz_35wwmrxgVk0_kpUYQN_VtaO7ZgFE2sJzFjbkVls5aqfAMnEjEgQl837hqZvmlW2ZRWebtxXfQxAjtp0gcTg-xtAHKIINYo_1_uAtt_H9L8KqFaioxrVAEDDIlcKnb-Ks3Y62CrZauaGUJeN_aNj2gdOpdkhvCw79yJyZSGZ7okjGbidCNSAf7Bo2Y6h3dP1Gga7kRmD648ftZESrNvbyg"); assertThat(decodedToken).isNotNull(); final Map claims = decodedToken.getClaims(); assertThat(claims).isNotNull() - .isNotEmpty() - .containsEntry(PersonClaims.PREFERRED_USERNAME_CLAIM_NAME, "piotrek"); + .isNotEmpty() + .containsEntry(PersonClaims.PREFERRED_USERNAME_CLAIM_NAME, "piotrek"); + } + + @Test + public void shouldAcceptAndDecodeAtJwtToken() throws JOSEException + { + when(config.isClientIdValidationDisabled()).thenReturn(true); + when(config.getSignatureAlgorithms()).thenReturn(Set.of(SignatureAlgorithm.PS256, SignatureAlgorithm.ES512)); + when(restOperations.exchange(any(), any(Class.class))).thenReturn(responseEntity); + + final RSAKey rsaKey = getRsaKey(); + final RSAKey rsaPublicJWK = rsaKey.toPublicJWK(); + when(responseEntity.getStatusCode()).thenReturn(HttpStatus.OK); + when(responseEntity.getBody()).thenReturn(String.format("{\"keys\": [%s]}", rsaPublicJWK.toJSONString())); + + final SignedJWT signedJWT = getSignedJWT(rsaKey, "at+jwt", "userA", "https://my.issuer"); + signedJWT.sign(new RSASSASigner(rsaKey)); + + when(providerDetails.getIssuerUri()).thenReturn("https://my.issuer"); + when(providerDetails.getJwkSetUri()).thenReturn("https://my.jwkSetUri"); + + final JwtDecoderProvider provider = new JwtDecoderProvider(config); + + final JwtDecoder decoder = provider.createJwtDecoder(restOperations, providerDetails); + final Jwt decodedToken = decoder.decode(signedJWT.serialize()); + assertThat(decodedToken).isNotNull(); + + final Map claims = decodedToken.getClaims(); + assertThat(claims).isNotNull() + .isNotEmpty() + .containsEntry(PersonClaims.PREFERRED_USERNAME_CLAIM_NAME, "userA"); + } + + @Test + public void shouldFailWithNotMatchingAlgorithm() throws JOSEException + { + when(config.isClientIdValidationDisabled()).thenReturn(true); + when(config.getSignatureAlgorithms()).thenReturn(Set.of(SignatureAlgorithm.RS256)); + + when(restOperations.exchange(any(), any(Class.class))).thenReturn(responseEntity); + + final RSAKey rsaKey = getRsaKey(); + final RSAKey rsaPublicJWK = rsaKey.toPublicJWK(); + when(responseEntity.getStatusCode()).thenReturn(HttpStatus.OK); + when(responseEntity.getBody()).thenReturn(String.format("{\"keys\": [%s]}", rsaPublicJWK.toJSONString())); + + final SignedJWT signedJWT = getSignedJWT(rsaKey, "at+jwt", "userA", "https://my.issuer"); + signedJWT.sign(new RSASSASigner(rsaKey)); + + when(providerDetails.getIssuerUri()).thenReturn("https://my.issuer"); + when(providerDetails.getJwkSetUri()).thenReturn("https://my.jwkSetUri"); + + final JwtDecoderProvider provider = new JwtDecoderProvider(config); + + final JwtDecoder decoder = provider.createJwtDecoder(restOperations, providerDetails); + assertThrows(BadJwtException.class, () -> decoder.decode(signedJWT.serialize())); + } + + @Test + public void shouldFailWithNotAllowedJOSEHeaderTyp() throws JOSEException + { + when(config.isClientIdValidationDisabled()).thenReturn(true); + when(config.getSignatureAlgorithms()).thenReturn(Set.of(SignatureAlgorithm.PS256)); + when(restOperations.exchange(any(), any(Class.class))).thenReturn(responseEntity); + + final RSAKey rsaKey = getRsaKey(); + final RSAKey rsaPublicJWK = rsaKey.toPublicJWK(); + when(responseEntity.getStatusCode()).thenReturn(HttpStatus.OK); + when(responseEntity.getBody()).thenReturn(String.format("{\"keys\": [%s]}", rsaPublicJWK.toJSONString())); + + final SignedJWT signedJWT = getSignedJWT(rsaKey, "not-allowed-type", "userA", "https://my.issuer"); + signedJWT.sign(new RSASSASigner(rsaKey)); + + when(providerDetails.getIssuerUri()).thenReturn("https://my.issuer"); + when(providerDetails.getJwkSetUri()).thenReturn("https://my.jwkSetUri"); + + final JwtDecoderProvider provider = new JwtDecoderProvider(config); + + final JwtDecoder decoder = provider.createJwtDecoder(restOperations, providerDetails); + assertThrows(BadJwtException.class, () -> decoder.decode(signedJWT.serialize())); } @Test @@ -79,7 +182,8 @@ public class IdentityServiceFacadeFactoryBeanTest { final JwtIssuerValidator issuerValidator = new JwtIssuerValidator(EXPECTED_ISSUER); - final OAuth2TokenValidatorResult validationResult = issuerValidator.validate(tokenWithIssuer("different-issuer")); + final OAuth2TokenValidatorResult validationResult = issuerValidator.validate( + tokenWithIssuer("different-issuer")); assertThat(validationResult).isNotNull(); assertThat(validationResult.hasErrors()).isTrue(); assertThat(validationResult.getErrors()).hasSize(1); @@ -164,15 +268,35 @@ public class IdentityServiceFacadeFactoryBeanTest final JwtAudienceValidator audienceValidator = new JwtAudienceValidator(EXPECTED_AUDIENCE); final Jwt token = Jwt.withTokenValue(UUID.randomUUID().toString()) - .claim("aud", EXPECTED_AUDIENCE) - .header("JUST", "FOR TESTING") - .build(); + .claim("aud", EXPECTED_AUDIENCE) + .header("JUST", "FOR TESTING") + .build(); final OAuth2TokenValidatorResult validationResult = audienceValidator.validate(token); assertThat(validationResult).isNotNull(); assertThat(validationResult.hasErrors()).isFalse(); assertThat(validationResult.getErrors()).isEmpty(); } + private static RSAKey getRsaKey() throws JOSEException + { + return new RSAKeyGenerator(2048) + .keyUse(KeyUse.SIGNATURE) + .algorithm(new Algorithm("PS256")) + .keyID(KEY_ID) + .generate(); + } + + private static SignedJWT getSignedJWT(RSAKey rsaKey, String type, String usernameClaim, String issuer) + { + final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder() + .issuer(issuer) + .claim(PersonClaims.PREFERRED_USERNAME_CLAIM_NAME, usernameClaim) + .build(); + return new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.PS256) + .type(new JOSEObjectType(type)) + .keyID(rsaKey.getKeyID()).build(), claimsSet); + } + private Jwt tokenWithIssuer(String issuer) { return Jwt.withTokenValue(UUID.randomUUID().toString()) From ce27304eaeeef06fd9d1ee3b06ca7898f9e29a76 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:28:56 +0000 Subject: [PATCH 06/10] [maven-release-plugin][skip ci] prepare release 23.3.0.59 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 6051b2469b..7a16d55b50 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index c45e764903..f4506aeaf5 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 93923f5a41..7a3c985d2d 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 59c5da0fc2..ff8c02fdee 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 9d75c3d154..e36c659b0f 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index 7317a46013..0930ae219e 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/pom.xml b/amps/pom.xml index 23a57cbc6e..4ae167eef9 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 2612b85b6f..01e4480ccd 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/core/pom.xml b/core/pom.xml index 7e92b4ac9a..370c3a972c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/data-model/pom.xml b/data-model/pom.xml index 579d040c35..baf88757a8 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/mmt/pom.xml b/mmt/pom.xml index a9c9b6d6c6..9eb873f85f 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index df507d4663..188c6dfcfc 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59-SNAPSHOT + 23.3.0.59
diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 0b042cc8de..1e0f893eb9 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/pom.xml b/packaging/pom.xml index 80806bf878..8fec366773 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 7917e19983..d64e4f3ca4 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 531c34f7f4..d53435e40c 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 21a2364e59..e43c68bc90 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 2cacd91bf6..f426ea3f66 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 31719248c8..85dd26c359 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 36169d6923..31c4577c76 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 5b14540802..6c929e19fd 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/pom.xml b/pom.xml index 17670275f6..ebd72da809 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 23.3.0.59 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 82842eac22..941c4ffc12 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 diff --git a/repository/pom.xml b/repository/pom.xml index e1635b662c..86e8fc0cd9 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59-SNAPSHOT + 23.3.0.59 From 76be8d2bec51373ad89284b1eb4afe0bc817521b Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:28:59 +0000 Subject: [PATCH 07/10] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 7a16d55b50..0c5e9aea53 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index f4506aeaf5..10fcd96f0d 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 7a3c985d2d..5bc12c4465 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index ff8c02fdee..01429be15a 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index e36c659b0f..5554923dc2 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index 0930ae219e..f6b80b37a8 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index 4ae167eef9..3b5874f063 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 01e4480ccd..3c69615e46 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 370c3a972c..a28d2880c5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index baf88757a8..42a7cc0a0d 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index 9eb873f85f..94a89468cd 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 188c6dfcfc..0f10d94473 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 1e0f893eb9..4319f2cb9c 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index 8fec366773..5cfd013e1c 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index d64e4f3ca4..be96e7e3b9 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index d53435e40c..6d8972958d 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index e43c68bc90..c4023a3fba 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index f426ea3f66..417d167c34 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 85dd26c359..2b50f9a702 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 31c4577c76..1b582a24e4 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 6c929e19fd..1eb35376e5 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/pom.xml b/pom.xml index ebd72da809..942d41d482 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 23.3.0.59 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 941c4ffc12..96ed690db7 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index 86e8fc0cd9..82e2be5281 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.59 + 23.3.0.60-SNAPSHOT From abeaff52e8da466caae325c02b1f6c5b09352527 Mon Sep 17 00:00:00 2001 From: Suneet Gupta <89080268+suneet-gupta@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:05:57 +0530 Subject: [PATCH 08/10] [APPS-2019] Add Undeletable and Unmovable Aspects to Data Dictionary and its Level 1 sub-folders (#2705) * [force] Force release for 2024-06-09. * [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder * [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder * [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder * [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder * [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder * [APPS-2019] Added Undeletable and Unmovable Aspect to Data Dictionary Folder * [APPS-2019] [ags] [tas] Added Integration Test Cases * [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary * [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary * Added Undeletable and Unmovable Aspects to Data Dictionary Folder * [APPS-2019] Updated Integration Test Cases * [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary * [APPS-2019] [ags] [tas] Added fix for restricting the move folder for Data Dictionary * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments * [APPS-2019] [ags] [tas] Addressed review comments --------- Co-authored-by: Alfresco CI User --- .../bootstrap/RMDataDictionaryBootstrap.xml | 5 + .../bootstrap/customMessagesSpace.xml | 2 + .../alfresco/bootstrap/customModelsSpace.acp | Bin 1710 -> 1863 bytes .../customWebClientExtensionSpace.xml | 2 + .../bootstrap/customWorkflowDefsSpace.acp | Bin 1737 -> 1885 bytes .../alfresco/bootstrap/imapSpaces.acp | Bin 2280 -> 2321 bytes .../bootstrap/renderingActionSpace.xml | 4 + .../bootstrap/replicationActionSpace.xml | 4 + .../bootstrap/scheduledActionsFolder.xml | 4 + .../bootstrap/solrFacetsRootFolder.xml | 4 + .../resources/alfresco/bootstrap/spaces.xml | 42 +++++- .../alfresco/bootstrap/transferSpaces.xml | 5 +- .../alfresco/bootstrap/webScripts.xml | 2 + .../bootstrap/webScriptsExtensions.xml | 2 + .../model-specific-services-context.xml | 8 -- .../org/alfresco/AppContext01TestSuite.java | 3 +- .../bootstrap/DataDictionaryFolderTest.java | 124 ++++++++++++++++++ 17 files changed, 200 insertions(+), 11 deletions(-) create mode 100644 repository/src/test/java/org/alfresco/repo/bootstrap/DataDictionaryFolderTest.java diff --git a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml index 38fd599a62..aa98e6cd62 100644 --- a/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml +++ b/amps/ags/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml @@ -31,6 +31,11 @@ Configuration information for the Records Management application. + + + + + diff --git a/repository/src/main/resources/alfresco/bootstrap/customMessagesSpace.xml b/repository/src/main/resources/alfresco/bootstrap/customMessagesSpace.xml index c5099f4c11..7194d46ca8 100644 --- a/repository/src/main/resources/alfresco/bootstrap/customMessagesSpace.xml +++ b/repository/src/main/resources/alfresco/bootstrap/customMessagesSpace.xml @@ -4,6 +4,8 @@ view:childName="app:messages"> + + ${spaces.messages.description} diff --git a/repository/src/main/resources/alfresco/bootstrap/customModelsSpace.acp b/repository/src/main/resources/alfresco/bootstrap/customModelsSpace.acp index f57119b8b39d7bebeee38008eecaea577e31ed4b..969d192357c0efa7612970c2369b9f6c9d034d40 100644 GIT binary patch literal 1863 zcmZ|QX*kpi8wT+IFk*L?xA$DPY{=wmnx4nJ+RiZ+IoiGr9yS2nfAGuE%! zJ!EJJcP+b|F%C;{Mt8PO4?az9H43#m(J}g4Ia2X8=DH{{HcRI3E;+MVvYd7PdO5P` zH0#Ne-GEEPXo=Zw+-@$SMOqQ^wuM)ozEvVV;syJ(wsU`Hd4hNMZS?8x_62X+!sa9K zmUn4;yM58sw3#SoLQfCK${o(NQ`~v9wngYd?0L!e7m6^-|V{wvxj!GIR&eY9=Ltzo+Pf@4XnMxV3cvZ{y3CKxxgZnZ##Ce z>@ON9-xJ0Ska#nExOZs4?5DwbzIWB{Bdogk(p5O7 zwB#Bj^NoTCp~jTbTSO9>neoG1+~*Q7I^-$zG}lzOd{qI!`9x{jyfSKsokzN;?XE9% z3g#Z7X34TQ52==yQ|tK@o%mJ>YH7jn{%jtKeNncocc}w;IcF^sBCk7j;iam%&0RZ9 ze;ad0w#FcL0D^5Oaon|cCOv|%cx90A246uFtumXvP+2;Hq=K`I+Osld#VXyr5sGja z&p@s|H)gTbq?O0fa4$`G+WAmevtTRLdU_t>NQn|?~i`%$)zL(|J zH>IicT0eQ871cX^DafN0>Xn=W`f%2->%~JQx9U@gYO!r~x1q_JuCLmt1s#e1DUbw< zL>STV8}K64$|WqWi}*sPL*DiQa_-rb3>}Ls^s!4X_8AeXl5Tcw@NE#pgpwYp*hq|e zm*P9m@;v`O{=AMp;@TIfxAk%^hyHfL+e0nS*K#%Zh0e zN_7rpLK&km(s$=k+o{aZGO_W?MuH`N3s;vT3Mg-<5}!{ou}QaK^`EEa4>I{RraqOB zgjDMroKt3bn2L0z{E|Y>UvkAZn>1bn9pFQEg&3us4}xFy0>$BOvQWj*P3Wsh5ZSc; zJOxvPO~;5c+JMsio1UaE>?zx^z7A@ru5$dO?bzCieYyDP4c0^M?`!u|ToL;l!B&BC z;65&J-)z=oK*(I6{tT+&ehZUWy(>|m(86~rLB`?CeY{Mxi-C%ScU-8U-crw2g?~*Q zi7{ESbQ_pZm%Tqbuj0 zUB|8l>GxB3{qo;Aw$@ly=FVOOqbn@@(DS`bu8Nl>gJoO#E(DhRvHN1Yj`x>aJqBvF z2F_O7AIF{nC^Jz-;V$(P((pQVWZeThmcgcxNUMGp<_g=G?yHAP)DKVin zLsh}`MZb4g-<)3YI*%riV&`Wn~t4R2_* z#w`}6vGQD$Sn+v!mlI$|+@o6!4snZbu3KygeT;;%E^yviY~iBPbw9bRo|TH%?J#lvh|<`w{6+1` zVRg_)C6m0Q6q6+z3r?=WQ1^n?@m&7=18(A%+|L%A(d;DKF%57Q?AfEu(H?sn5EqR5 q-&{NM!#e-~{RlbfXZsiBc>br{{|RSr!}9~kpYI?5`(yw9&-GuKoo|8w delta 1686 zcmV;H25I@n4z3LwP)h>@6axSN2mr*Tk39m{$j2fE008|g000$}0S6d=?V3yTlQ0m# z?|zC7qhF9Ep~)jeJkyls`MV$O~z- zwUoxL;0wfw`@ptWroA@p5x@=sj7isuVN_^aYf_{PNdl{IJF|K7{h$X3nZOrDjobGokN^{^@I4()Pg_{sewp9 zF=~&Ov2;i?ViC^n0%)^fg7HsZUf{ zjbVpDL|&+BNJ9;OR-~iJj%-L1L^ugsUTUNb2%X5BGz-X(s*q{w?2^H#fJjrrA5`$; zG*eV?2H68@`TzS;s&blq>a|zK2V^MYYI%bZn987PF2-t2SQBF=X@x)2zMw<(mg;Hke3HfqNja60^=K5T(q#z@VTw!BBR>77} zNG*0h57hle-_Nb33MbYo**8aoQ%3R>Z%5)qLo5)*YbK%UF-tvLHUe58> zQgphOydAWEI?kh&l&ssDesjtL((zcf=Dx~H#kS;|2|?pAjssWJm(+$)I=#)IA{2H< zg2rMXxH>fs^#F|2rzCaXO3k;>EXV3fR14i*)jCmGjH%oZPUOu?xebf<+U>kN@(sFE z4lPZiRPC({{rZ?vB`5P-{+-MAlNpHT&dOgsT2IJ-z`i_u)RTu7=9ZdanvS;;?h0vF zM*mEZyD8Y6gE$Hx+U#j3X@3$jjMvTr+4i})S2?PcsV!1?ZViQM{ibF1)cih|<+{0k zn%i%|7DWMNWcKcukQt9>FRBCc?3DmkAHL5O62WMJ9A|PN^_A1QRZeFYPJ40+@4E@; zQHFMZV(ontFsKKmv0qJ`!;kOc=OSrgRcq~TUuoouY-oByz7w2r@{}DT{5g%IIAg)F z^rv5<-=O#q5v?Vv+R4V3exiy(PJ8WNMkv0_~9UcG`Fp3-O! zu`jowx@AzgC~M6{7=*x0P%sh*PjyV4k)(+nw`EZW zGbc&wISz7`D||)L_VMmiwl0)f)ZONuHIz2mejy_+s19TyxD$>L%OM$c^d$QCt_<*8}%>d{2Y;ZI9yL zM2Z{k5A7F-e%3E}iKjY$`t&a5VZt1)cY>ck^mn`YHGeDV+Z7&;+!bzwMHP;k0nmiw z4G}pBl>gER-qrenoee(QX^-4i6+H2z>&zp=QeeV>jfakTSKXn!+n{L_wA2@HpsVQU zytC75tT0m=C}hNk`wLJ@0Rj{Q6axSN2mr*Tk39m{$j2fE008|g000#L0000000000 gAb^wp1{)SoO9ci1000010096)000101^@s60P3khP5=M^ diff --git a/repository/src/main/resources/alfresco/bootstrap/customWebClientExtensionSpace.xml b/repository/src/main/resources/alfresco/bootstrap/customWebClientExtensionSpace.xml index 18df478072..aeb23a48eb 100644 --- a/repository/src/main/resources/alfresco/bootstrap/customWebClientExtensionSpace.xml +++ b/repository/src/main/resources/alfresco/bootstrap/customWebClientExtensionSpace.xml @@ -4,6 +4,8 @@ view:childName="app:webclient_extension"> + + ${spaces.web.client.extension.description} diff --git a/repository/src/main/resources/alfresco/bootstrap/customWorkflowDefsSpace.acp b/repository/src/main/resources/alfresco/bootstrap/customWorkflowDefsSpace.acp index af60348470c4d4fbd1748a0e6e21493af8aec208..9d85df1bdd2b8e70c26f447445756845a0584940 100644 GIT binary patch delta 1853 zcmV-D2g3Nt4c!hMP)h>@6aWAK2mlLK#9031F=LSi0046>000{R9FZLye^pco00W+* zUS^)7US@T83jhHG=mP)%1n2_*0PR{^Z`(E$e($d^guM;6B-=?GBT=!f=wmmaS@&2d zBGs_dZ6amIDEi+=Qj~oti4uJY)&Y5OV)C5tTzJl>BguDfpVMTr!6hYmcJKHz&zayX z$`Q%F+&h0hyq~U|x51mce+|LgwfLBD`Haec@0};cinZ%*x7%5m#3iOtKFiB5uGn=; zT;!Cnyxh40Hh43c)G#S#AqrV2R+=^ZT;wJDbr*yvCE1;;FLngqg$xIC&%2p=w^QGL z@UPd)>-FM#wwy11_WZTyX%JGp1A@y>b=-j_d|2*i{2m8xSQP6he@}}r+kJk@Q!Ez{ zi5S-id932=HZT8dv>N++Pw*6e`NY4WO>DvD84MUjvwY}>17Ii^`rTtXGz zC}S$Bmnc6L3{|6ae@rvVGlum%(v30UbOQxb@@$mkdr*`w8Aah~j62Ll>VGt~&_a!$ zNJo?I=$IxKVK{AhX;C&@sHbwuD#2r_LI&zQ7Nc3=B2Xh9RfzMl(o~{~R}WXK|IVb; z-f8^BjHmL$We8<@dvlP%aFuE;MuFzN<4h!5MNcF_AHtM_e{?v`fm|8V0!NJ2OEt5F z6(THrOfaWf?Q0{$&GXP=T=I(#R)XENMq1dfNE}9(o4IqfuZ@g2IeElF0(^lMtBhwB zOHbU^Mw)NHvLb9PvO3tJ%nMvH0+59}gg0|Q3+~cX{5$1I3af+$U&_>u*W%ESWXvhgC(ENe2?T(| zs%^G*f#Hmoa^td=h$35m+XgbAT|@~|uLgyoaJ6lG2RD05x}bn9jw*(Kp}Q=4D)TI_e`vDP{OOl40*Vij+&+n>I5%NZ^%rJK zCLq~k&gUUj^YvOkusebb#x0Y3fJkkswUe`A-{VFEJh{`8*Cx7z%Xc?<9EX(t2-=f zf4@F4LO)bVa__LR!cH*WJ#}u5wA-P0e-++b`Dapm8@nd@E6;-HJL!8ck@t%wZp5PW z?QjnudMenr+_Z+M;aWn&i8}XEpr8))XLFJR^w)9iJQ8fuY}uA}ga{6V51xpO2x@h; zSLi;2(BO;|sXIDCluGy{x>UMnk*311f1*wpm<@pf{~(jh5klVlB23b@p!meM<`V^A z=-iOkZc0)-WqhbOu62QDmuX<&DakfG_3$F3RxGMaae&PkjB-FH#!E1P0=4A>C4K}e zC=HP|e!x6HhRacLjUo1Gy$o>x9bpLFbt|4wDrc~TLbw2DD5N8pLunkzA4*G0f9mc4i`kxQt|A-QIf^Sy8 zbot)AbB8Z<{?pN2gfSH%TyA_{ts-=NnJ2FOcGNXt`Gbz{Hu1lX?~@;WWqh}Lwr+ml zYiqf=2hiSe4ZJKg30N2euN(C(S&)4{br=MdTJYyM%@(i&f5Bq_lQ0cHLx=n$c=In% zO928N0~7!N00;mJR>WBT1pot{ rqh4lpcnbgl1n2_*00ig*002-+1qJ{B000310RUkD008C&00000HC=BY delta 1701 zcmV;W23q;u4#^E0P)h>@6axSN2mk@5k3A~Xx1%uz002TQ000}45eFWB?V3xE(=ZT# z@BE4?;)dEJZP_hV3F0A+fW+&Fys-m@yojBa3i00==k2&@oHRv9u!nAH&y2_8na@tr z-IE`IKiiXp(I|Xu*bB>;kTkS9Ep~)jr@qCgg-kv2nRIW znNp)F_yTd_EG_GHZatdY_B;D#yS~}3ZWin1>Vai%Evqn5i>pRR@*$tMBZSpvRpYhi zm?)07ZWP2QJbwBT1te?0)a9Uol4JJu5GCI{KRSHE#ABK9+Cmn82U7{e&JDI+WM1O(A?R=a>F-bVhBdn zT2QO0Wlsx+jclPwyOzjmgqD#a#*9GIsm#g6sx;Umk%*8Il0C9wBlcaFUE zX1=+zEo-%ZeCRFh+np)tsFv^@w652=VBOT51gG35J?>{Rx#QWTG*CvsImDAkZsa?{ zKxPZZRC=2OhbZV97etC-;p)_=6az@9M@izm&Fs8|=4@nDqRI$$`Rj~kkxR1;%Hm{l+GK@RkL;Tf$=Q*jn~oH{ zFwx|6)AYNQZxdu)8T>ObRx?nYgE%=L+U#lPXm<`Wo2;#et4DX|=3b?!R-(2bf}NTW z)%uM~?6K*6F3ELM{WRa-f-Q=C%E;{9F(xw}%{~^$n!QOPNCGx{QK74g@n=hFZMhrQ z9bHm?9fkF%Raj@2aLhEN9YM`XOqp0E?0Cp$P$W`gx0*Q1AKyjKMJB^i*V<}dX=FlR zG(90dh?{cqlpRC&OA>`q%KT&LPq#$3LGdAiTT7_PxkrAQCuWa~L&Li$4e`#b+PVyz zEz7DvuX`m(HM6w^(ur}Z0aZP;HWw$qUG0c}Aasgn0@>X-$t6z%H}9)xI+&^BczGE$ z_1LLT&^l)4O9%w?E2uVF#P~%Uvb`0PuNY;oQr~}U@FXRM(_cM#YzB_2Al}}f+lTgr zh(8Vbhn5EDmGHe2@cyHL%SP<+t-c2kHRV(#H_uIgxwcSc@k(2Pj6cnl6wYe78oW7uTy%( zB|=nc3L#{pM!(g8oVc78(=lT>ImYpSf^kV~WIr+g2M|_&_ zELrbNAkTlSWAcnLnq=d)Eb3sU1GKkmY%gyo1Z@XymjiKoB{s^C)11F1kR1dk|zG_&tMn83qXXRtzzv&cT>^hoDuDM5DWp^65Fa1A= z>k@l9ZV#vTIEG*MApTvXxZ(WN`sK>6@|}DALT3nAu5ff0)0o2)COp1xHZH!I=85as zJz+g?Pq-2kWi)EeUlWa21mq}XO#Vy9cSq~lI_rI_(;itBJn@d}%*(=3V8nop*Nu5s z-68$dLDMK`$v?+|uA)Qv1y853!c1wPkP#owZ%|7C0u%!j0{{RB00E|tJu1|w=ZFyW82$xoHGcdBeU}j(d z6K}&#_supCi8YUZxaeln?O4&q^oy&4%x|6WI+goEwn%h+OH;42l{0%*~MPpfQ>#2rh?uR-{ zkA;=KT-#rD?zR(8hxhT2Ge4JlNliFrEwp9BzCx{OJ0D3-Ik8>guF<@|OPD4-co-^f z!YXU%*uCECS&s0}+|2F&S&pRly>*;sJuP~{MU`WFZ*wIYTkzK#iJfonDrB~7PuUjo z=;OlZHpwR?$9<p#==StUqU(My?wkAf)c)52t{?9%+SRbd@DGR0=Jx>Z=df{b53XV#mJFbjO&bQ<%A&FCD*<_@;!nVpFt&#^du^ z)@^KYJ-QQ4YM9%+V4o>)jp5Q473JsuQZ7gAGL8-nyHRD^_tnJnoQlJ-JuTS_VU zxQpjfIkz%+{N1lr`G~9H)7FIeZicll*=qiku5O;3z;tF~!;zaCx6e2E&3kfXZRF4L zt1BnPGZpQviu!$O){^T>ozz4u%o3(E=3Vpu9I|8D>i;(~Vn42NnsxAkR_edKFXtsW zN7rkqOMh8bc~|P-|Nhq*|E&8~r$3ZkzBTZm;@$SGo;B@}Z>wTh-7jvg delta 743 zcmV~66g`I-2@XAUuZu5HHL3)0ssKI3jhEP02Pz)1QdUI8Fo#HBz8?zcmx3U z0Tcl3R!xuFAP~LhS5RxOHtns7Z1&KqQZK!1bBq<^mveTx6c&UHh6F8~ZJL+MjpPMr6eP%Zj2Ay>30d^;W)#iAB&?+BixeBS zO~SHp%fBNMm{Yfr<(_RE&>E8B-fM+$4Bmo_`3tU6+(3WME}09J1bpm=aRD2;=e8mU zi>-6ZET8jUVOo>I>7tqP>W>hMO!}DGjcbI9Jh>$(DdW$w zIK~!UtqXsUiDYAW)OQjb1#4;)DIIqOqQW9i=Rq^_{_cpMwjBsdcQ1+(K_}eDW0v6rZJ4nS-9f-DRw#6 z@5)Jm-qo)=Tk`+yI?8{?b`4qhi{08(!QGp+A-+Se_Ne}WR&8f{pG3I*CaS-ihNvE* zruG95@&~h^2MYlk7XuUk000O86<=sR{xybgZUO)Rx(fgR4gd|4#t0%FdKq?2Rd@gZ ZP)h{{000001ONm8Pyqk{f(HNq002$0R2~2T diff --git a/repository/src/main/resources/alfresco/bootstrap/renderingActionSpace.xml b/repository/src/main/resources/alfresco/bootstrap/renderingActionSpace.xml index d2b6fe9563..fe25e02702 100644 --- a/repository/src/main/resources/alfresco/bootstrap/renderingActionSpace.xml +++ b/repository/src/main/resources/alfresco/bootstrap/renderingActionSpace.xml @@ -12,6 +12,10 @@ ${spaces.rendition.rendering_actions.name} ${spaces.rendition.rendering_actions.description} + + + + diff --git a/repository/src/main/resources/alfresco/bootstrap/replicationActionSpace.xml b/repository/src/main/resources/alfresco/bootstrap/replicationActionSpace.xml index 25c2a0dfef..c37eb279a5 100644 --- a/repository/src/main/resources/alfresco/bootstrap/replicationActionSpace.xml +++ b/repository/src/main/resources/alfresco/bootstrap/replicationActionSpace.xml @@ -12,6 +12,10 @@ ${spaces.replication.replication_actions.name} ${spaces.replication.replication_actions.description} + + + + diff --git a/repository/src/main/resources/alfresco/bootstrap/scheduledActionsFolder.xml b/repository/src/main/resources/alfresco/bootstrap/scheduledActionsFolder.xml index 38c9ecfdca..00133289b9 100644 --- a/repository/src/main/resources/alfresco/bootstrap/scheduledActionsFolder.xml +++ b/repository/src/main/resources/alfresco/bootstrap/scheduledActionsFolder.xml @@ -11,5 +11,9 @@ ${spaces.actions.scheduled_actions.name} ${spaces.actions.scheduled_actions.description} + + + + diff --git a/repository/src/main/resources/alfresco/bootstrap/solrFacetsRootFolder.xml b/repository/src/main/resources/alfresco/bootstrap/solrFacetsRootFolder.xml index 4b80d008e2..206befe90b 100644 --- a/repository/src/main/resources/alfresco/bootstrap/solrFacetsRootFolder.xml +++ b/repository/src/main/resources/alfresco/bootstrap/solrFacetsRootFolder.xml @@ -14,5 +14,9 @@ ${spaces.solr_facets.root.description} + + + + diff --git a/repository/src/main/resources/alfresco/bootstrap/spaces.xml b/repository/src/main/resources/alfresco/bootstrap/spaces.xml index c1faaec15f..744ab0ad4b 100644 --- a/repository/src/main/resources/alfresco/bootstrap/spaces.xml +++ b/repository/src/main/resources/alfresco/bootstrap/spaces.xml @@ -1,7 +1,7 @@ + xmlns:emailserver="http://www.alfresco.org/model/emailserver/1.0" xmlns:sys="http://www.alfresco.org/model/system/1.0"> @@ -30,6 +30,10 @@ space-icon-default ${spaces.dictionary.name} ${spaces.dictionary.description} + + + + @@ -37,6 +41,10 @@ space-icon-default ${spaces.templates.name} ${spaces.templates.description} + + + + @@ -45,6 +53,10 @@ space-icon-default ${spaces.templates.content.name} ${spaces.templates.content.description} + + + + @@ -53,6 +65,10 @@ space-icon-default ${spaces.templates.email.name} ${spaces.templates.email.description} + + + + @@ -79,6 +95,10 @@ space-icon-default ${spaces.templates.rss.name} ${spaces.templates.rss.description} + + + + @@ -93,6 +113,10 @@ space-icon-default ${spaces.savedsearches.name} ${spaces.savedsearches.description} + + + + @@ -100,6 +124,10 @@ space-icon-default ${spaces.scripts.name} ${spaces.scripts.description} + + + + @@ -107,6 +135,10 @@ space-icon-default ${spaces.nodeTemplatesSpace.name} ${spaces.nodeTemplatesSpace.description} + + + + @@ -120,6 +152,10 @@ space-icon-default ${spaces.smartfoldertemplates.name} ${spaces.smartfoldertemplates.description} + + + + @@ -133,6 +169,10 @@ space-icon-default ${spaces.smartdownloads.name} ${spaces.smartdownloads.description} + + + + diff --git a/repository/src/main/resources/alfresco/bootstrap/transferSpaces.xml b/repository/src/main/resources/alfresco/bootstrap/transferSpaces.xml index 07cd98dc6c..7a9c6dc200 100644 --- a/repository/src/main/resources/alfresco/bootstrap/transferSpaces.xml +++ b/repository/src/main/resources/alfresco/bootstrap/transferSpaces.xml @@ -4,10 +4,13 @@ xmlns:view="http://www.alfresco.org/view/repository/1.0" xmlns:cm="http://www.alfresco.org/model/content/1.0" xmlns:app="http://www.alfresco.org/model/application/1.0" - xmlns:trx="http://www.alfresco.org/model/transfer/1.0"> + xmlns:trx="http://www.alfresco.org/model/transfer/1.0" + xmlns:sys="http://www.alfresco.org/model/system/1.0"> + + ${spaces.transfers.description} diff --git a/repository/src/main/resources/alfresco/bootstrap/webScripts.xml b/repository/src/main/resources/alfresco/bootstrap/webScripts.xml index 064480500f..201598caac 100644 --- a/repository/src/main/resources/alfresco/bootstrap/webScripts.xml +++ b/repository/src/main/resources/alfresco/bootstrap/webScripts.xml @@ -3,6 +3,8 @@ + + ${webscripts.url_addressable_web_services} diff --git a/repository/src/main/resources/alfresco/bootstrap/webScriptsExtensions.xml b/repository/src/main/resources/alfresco/bootstrap/webScriptsExtensions.xml index 7e9884ff62..1586d3f24e 100644 --- a/repository/src/main/resources/alfresco/bootstrap/webScriptsExtensions.xml +++ b/repository/src/main/resources/alfresco/bootstrap/webScriptsExtensions.xml @@ -3,6 +3,8 @@ + + ${webscriptsextentions.customized_web_scripts} diff --git a/repository/src/main/resources/alfresco/model-specific-services-context.xml b/repository/src/main/resources/alfresco/model-specific-services-context.xml index 7bd52210b4..069357f4fa 100644 --- a/repository/src/main/resources/alfresco/model-specific-services-context.xml +++ b/repository/src/main/resources/alfresco/model-specific-services-context.xml @@ -68,14 +68,6 @@ /${spaces.company_home.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.rss.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.webscripts.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.extension_webscripts.childname} diff --git a/repository/src/test/java/org/alfresco/AppContext01TestSuite.java b/repository/src/test/java/org/alfresco/AppContext01TestSuite.java index 277bb60627..147626480a 100644 --- a/repository/src/test/java/org/alfresco/AppContext01TestSuite.java +++ b/repository/src/test/java/org/alfresco/AppContext01TestSuite.java @@ -76,7 +76,8 @@ import org.junit.runners.Suite; org.alfresco.repo.activities.SiteActivityTestCaseSensitivity.class, org.alfresco.repo.activities.feed.cleanup.FeedCleanerTestCaseSensitivity.class, org.alfresco.repo.activities.SiteActivityTestCaseInsensitivity.class, - org.alfresco.repo.admin.registry.RegistryServiceImplTest.class + org.alfresco.repo.admin.registry.RegistryServiceImplTest.class, + org.alfresco.repo.bootstrap.DataDictionaryFolderTest.class }) public class AppContext01TestSuite { diff --git a/repository/src/test/java/org/alfresco/repo/bootstrap/DataDictionaryFolderTest.java b/repository/src/test/java/org/alfresco/repo/bootstrap/DataDictionaryFolderTest.java new file mode 100644 index 0000000000..009fca7639 --- /dev/null +++ b/repository/src/test/java/org/alfresco/repo/bootstrap/DataDictionaryFolderTest.java @@ -0,0 +1,124 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2024 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 . + * #L% + */ +package org.alfresco.repo.bootstrap; + + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.BaseSpringTest; +import org.alfresco.util.test.junitrules.ApplicationContextInit; +import org.alfresco.util.test.junitrules.WellKnownNodes; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; + +import java.util.List; + +public class DataDictionaryFolderTest extends BaseSpringTest +{ + @ClassRule + private static final ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit(); + + private static final String DATA_DICTIONARY = "Data Dictionary"; + + @Rule + private WellKnownNodes wellKnownNodes = new WellKnownNodes(APP_CONTEXT_INIT); + + private NodeService nodeService; + + @Before + public void before() + { + ServiceRegistry serviceRegistry = (ServiceRegistry) this.applicationContext.getBean("ServiceRegistry"); + this.nodeService = serviceRegistry.getNodeService(); + } + + @Test + public void testDataDictionaryFolderIsUndeletable() + { + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + // get the company_home + NodeRef companyHomeRef = wellKnownNodes.getCompanyHome(); + // get the Data Dictionary + NodeRef dataDictionaryRef = nodeService.getChildByName(companyHomeRef, ContentModel.ASSOC_CONTAINS, DATA_DICTIONARY); + assertTrue(nodeService.hasAspect(dataDictionaryRef, ContentModel.ASPECT_UNDELETABLE)); + + List chilAssocsList = nodeService.getChildAssocs(dataDictionaryRef); + + chilAssocsList.stream() + .map(ChildAssociationRef::getChildRef) + .forEach(childNodeRef -> { + assertTrue(nodeService.hasAspect(childNodeRef, ContentModel.ASPECT_UNDELETABLE)); + try + { + nodeService.deleteNode(childNodeRef); + } + catch (Exception ex) + { + assertTrue(ex.getMessage().contains("deletion is not allowed")); + } + }); + } + + @Test + public void testDataDictionaryFolderIsUnmovable() + { + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + // get the company_home + NodeRef companyHomeRef = wellKnownNodes.getCompanyHome(); + // get the Data Dictionary + NodeRef dataDictionaryRef = nodeService.getChildByName(companyHomeRef, ContentModel.ASSOC_CONTAINS, DATA_DICTIONARY); + assertTrue(nodeService.hasAspect(dataDictionaryRef, ContentModel.ASPECT_UNMOVABLE)); + + List chilAssocsList = nodeService.getChildAssocs(dataDictionaryRef); + + chilAssocsList.stream() + .map(ChildAssociationRef::getChildRef) + .forEach(childNodeRef -> { + assertTrue(nodeService.hasAspect(childNodeRef, ContentModel.ASPECT_UNMOVABLE)); + NodeRef folderRef = nodeService.createNode( + companyHomeRef, + ContentModel.ASSOC_CONTAINS, + QName.createQName("testDeleteAndRestore-folder2-" + System.currentTimeMillis()), + ContentModel.TYPE_FOLDER + ).getChildRef(); + try + { + nodeService.moveNode(childNodeRef, folderRef, ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS); + } + catch (Exception ex) + { + assertTrue(ex.getMessage().contains("move is not allowed")); + } + }); + } +} \ No newline at end of file From 2206479e06b4bf39a248468406dc0d0364402526 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Thu, 27 Jun 2024 04:39:02 +0000 Subject: [PATCH 09/10] [maven-release-plugin][skip ci] prepare release 23.3.0.60 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 0c5e9aea53..61b42545df 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 10fcd96f0d..6c81d6ef92 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 5bc12c4465..639f7d07be 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 01429be15a..da09384f98 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 5554923dc2..d7fb3b1062 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index f6b80b37a8..b9b956247c 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/pom.xml b/amps/pom.xml index 3b5874f063..873b773a01 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 3c69615e46..fa59318717 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/core/pom.xml b/core/pom.xml index a28d2880c5..e3976d3b2d 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/data-model/pom.xml b/data-model/pom.xml index 42a7cc0a0d..49170b3cf4 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/mmt/pom.xml b/mmt/pom.xml index 94a89468cd..80c0fb5095 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 0f10d94473..0fce84f401 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 4319f2cb9c..58fb3de078 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/pom.xml b/packaging/pom.xml index 5cfd013e1c..7c122d16d6 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index be96e7e3b9..e3d08ee45e 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 6d8972958d..445c317abe 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index c4023a3fba..345d565908 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 417d167c34..284404e4e3 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 2b50f9a702..b9c25df08f 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 1b582a24e4..10f9f3e1d0 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 1eb35376e5..baa772a35b 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/pom.xml b/pom.xml index 942d41d482..4ef6b5510b 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 23.3.0.60 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 96ed690db7..82b50d0eb2 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 diff --git a/repository/pom.xml b/repository/pom.xml index 82e2be5281..5564d7941c 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60-SNAPSHOT + 23.3.0.60 From 8e15dba3ebef403787add6b7ab9d57cd3d595fc8 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Thu, 27 Jun 2024 04:39:04 +0000 Subject: [PATCH 10/10] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 61b42545df..80cd3d6fa0 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 6c81d6ef92..2a3bd30cbd 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 639f7d07be..c3c3778968 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index da09384f98..b0163be9a1 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index d7fb3b1062..a7cf0395a8 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index b9b956247c..59f55ce44f 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index 873b773a01..cde64b28e3 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index fa59318717..31e39694f5 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index e3976d3b2d..22c55b58ce 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index 49170b3cf4..b703d5918f 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index 80c0fb5095..f940ea4664 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 0fce84f401..211c0d904e 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 58fb3de078..3affd65da1 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index 7c122d16d6..6b6b298451 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index e3d08ee45e..5d585a9dd8 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 445c317abe..3f8800ea26 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 345d565908..1080873d7c 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 284404e4e3..e6b323086b 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index b9c25df08f..5a72760007 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 10f9f3e1d0..6bebe1a61f 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index baa772a35b..44817efdce 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/pom.xml b/pom.xml index 4ef6b5510b..84646c808e 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 23.3.0.60 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 82b50d0eb2..842546833b 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index 5564d7941c..24b4bf1ab2 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 23.3.0.60 + 23.3.0.61-SNAPSHOT