Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
c8103238e4 Bump org.apache.commons:commons-csv from 1.9.0 to 1.14.0
Bumps [org.apache.commons:commons-csv](https://github.com/apache/commons-csv) from 1.9.0 to 1.14.0.
- [Changelog](https://github.com/apache/commons-csv/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/apache/commons-csv/compare/rel/commons-csv-1.9.0...rel/commons-csv-1.14.0)

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-csv
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-20 22:53:33 +00:00
262 changed files with 2155 additions and 6103 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -31,15 +31,15 @@ jobs:
!contains(github.event.head_commit.message, '[no release]') &&
github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.16.0
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}
@@ -60,15 +60,15 @@ jobs:
!contains(github.event.head_commit.message, '[no downstream]') &&
github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.16.0
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.16.0
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.16.0
- name: "Init"
run: bash ./scripts/ci/init.sh
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.16.0
with:
username: ${{ env.GIT_USERNAME }}
email: ${{ env.GIT_EMAIL }}

View File

@@ -11,9 +11,9 @@ jobs:
runs-on: ubuntu-latest
if: contains(github.event.head_commit.message, '[reformat code]')
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
with:
python-version: "3.9"
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
@@ -22,7 +22,7 @@ jobs:
extra_args: --all-files
- name: Update secrets baseline
run: pip install detect-secrets && detect-secrets scan --baseline .secrets.baseline
- uses: Alfresco/alfresco-build-tools/.github/actions/git-commit-changes@v8.24.1
- uses: Alfresco/alfresco-build-tools/.github/actions/git-commit-changes@v8.16.0
with:
username: ${{ secrets.BOT_GITHUB_USERNAME }}
add-options: -u

View File

@@ -127,6 +127,29 @@
}
],
"results": {
".github/workflows/ci.yml": [
{
"type": "Secret Keyword",
"filename": ".github/workflows/ci.yml",
"hashed_secret": "b86dc2f033a63f2b7b9e7d270ab806d2910d7572",
"is_verified": false,
"line_number": 295
},
{
"type": "Secret Keyword",
"filename": ".github/workflows/ci.yml",
"hashed_secret": "1bfb0e20f886150ba59b853bcd49dea893e00966",
"is_verified": false,
"line_number": 370
},
{
"type": "Secret Keyword",
"filename": ".github/workflows/ci.yml",
"hashed_secret": "128f14373ccfaff49e3664045d3a11b50cbb7b39",
"is_verified": false,
"line_number": 904
}
],
".github/workflows/master_release.yml": [
{
"type": "Secret Keyword",
@@ -1242,7 +1265,7 @@
"filename": "repository/src/main/resources/alfresco/repository.properties",
"hashed_secret": "1459a56410378e4d3ab470eff570e5eae1742762",
"is_verified": false,
"line_number": 314,
"line_number": 312,
"is_secret": false
},
{
@@ -1250,7 +1273,7 @@
"filename": "repository/src/main/resources/alfresco/repository.properties",
"hashed_secret": "84551ae5442affc9f1a2d3b4c86ae8b24860149d",
"is_verified": false,
"line_number": 773,
"line_number": 770,
"is_secret": false
}
],
@@ -1496,7 +1519,7 @@
"filename": "repository/src/test/java/org/alfresco/repo/rendition2/AbstractRenditionIntegrationTest.java",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 130,
"line_number": 128,
"is_secret": false
}
],
@@ -1584,7 +1607,7 @@
"filename": "repository/src/test/java/org/alfresco/repo/security/authentication/identityservice/SpringBasedIdentityServiceFacadeUnitTest.java",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 48,
"line_number": 47,
"is_secret": false
}
],
@@ -1845,5 +1868,5 @@
}
]
},
"generated_at": "2025-07-23T08:25:11Z"
"generated_at": "2025-03-17T14:00:53Z"
}

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<build>
@@ -74,6 +74,16 @@
<artifactId>alfresco-testng</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
@@ -83,7 +93,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.5.0</version>
<version>4.4</version>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>

View File

@@ -1,30 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model;
public record CapabilityModel(String name, String title, String description, GroupModel group, int index)
{}

View File

@@ -1,30 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model;
public record GroupModel(String id, String title)
{}

View File

@@ -1,91 +0,0 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.role;
import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.alfresco.rest.rm.community.model.CapabilityModel;
import org.alfresco.utility.model.TestModel;
/**
* POJO for role
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role extends TestModel
{
@JsonProperty(required = true)
private String name;
@JsonProperty(required = true)
private List<CapabilityModel> capabilities;
@JsonProperty(required = true)
private String displayLabel;
@JsonProperty(required = true)
private String groupShortName;
private List<String> assignedUsers;
private List<String> assignedGroups;
private String roleGroupName;
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
Role role = (Role) o;
return Objects.equals(name, role.name) && Objects.equals(capabilities, role.capabilities)
&& Objects.equals(displayLabel, role.displayLabel) && Objects.equals(groupShortName, role.groupShortName) && Objects.equals(assignedUsers, role.assignedUsers)
&& Objects.equals(assignedGroups, role.assignedGroups) && Objects.equals(roleGroupName, role.roleGroupName);
}
@Override
public int hashCode()
{
return Objects.hash(name, capabilities, displayLabel, groupShortName, assignedUsers, assignedGroups, roleGroupName);
}
}

View File

@@ -1,32 +0,0 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.role;
import org.alfresco.rest.core.RestModels;
public class RoleCollection extends RestModels<RoleEntry, RoleCollection>
{}

View File

@@ -1,47 +0,0 @@
/*-
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.role;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.alfresco.rest.core.RestModels;
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RoleEntry extends RestModels<Role, RoleEntry>
{
@JsonProperty
private Role entry;
}

View File

@@ -35,7 +35,7 @@ package org.alfresco.rest.rm.community.model.user;
*/
public enum UserRoles
{
IN_PLACE_WRITERS("ExtendedWriters", "In-Place Writers"), ROLE_RM_ADMIN("Administrator", "Records Management Administrator"), ROLE_RM_MANAGER("RecordsManager", "Records Management Manager"), ROLE_RM_POWER_USER("PowerUser", "Records Management Power User"), ROLE_RM_SECURITY_OFFICER("SecurityOfficer", "Records Management Security Officer"), ROLE_RM_USER("User", "Records Management User"), IN_PLACE_READERS("ExtendedReaders", "In-Place Readers");
IN_PLACE_WRITERS("ExtendedWriters", "In-Place Writers"), ROLE_RM_ADMIN("Administrator", "Records Management Administrator"), ROLE_RM_MANAGER("RecordsManager", "Records Management Manager"), ROLE_RM_POWER_USER("PowerUser", "Records Management Power User"), ROLE_RM_SECURITY_OFFICER("SecurityOfficer", "Records Management Security Officer"), ROLE_RM_USER("User", "Records Management User");
public final String roleId;
public final String displayName;

View File

@@ -43,7 +43,6 @@ import org.alfresco.rest.rm.community.model.hold.Hold;
import org.alfresco.rest.rm.community.model.hold.HoldCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryCollection;
import org.alfresco.rest.rm.community.model.role.RoleCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
@@ -304,39 +303,4 @@ public class FilePlanAPI extends RMModelRequest
{
return getHolds(filePlanId, EMPTY);
}
/**
* Gets the roles of a file plan.
*
* @param filePlanId
* The identifier of a file plan
* @param parameters
* The URL parameters to add
* @return The {Pagination and RoleModel Entries} for the given {@code filePlanId}
* @throws RuntimeException
* for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code filePlanId}</li>
* <li>{@code filePlanId} does not exist</li>
* </ul>
*/
public RoleCollection getFilePlanRoles(String filePlanId, String parameters)
{
mandatoryString("filePlanId", filePlanId);
return getRmRestWrapper().processModels(RoleCollection.class, simpleRequest(
GET,
"file-plans/{filePlanId}/roles?{parameters}",
filePlanId,
parameters));
}
/**
* See {@link #getFilePlanRoles(String, String)}
*/
public RoleCollection getFilePlanRoles(String filePlanId)
{
return getFilePlanRoles(filePlanId, EMPTY);
}
}

View File

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

View File

@@ -93,7 +93,6 @@ import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.rest.search.RestRequestQueryModel;
import org.alfresco.rest.search.SearchNodeModel;
import org.alfresco.rest.search.SearchRequest;
import org.alfresco.rest.v0.RMRolesAndActionsAPI;
import org.alfresco.rest.v0.SearchAPI;
import org.alfresco.utility.Utility;
import org.alfresco.utility.data.DataUserAIS;
@@ -128,10 +127,6 @@ public class BaseRMRestTest extends RestTest
@Getter(value = PROTECTED)
private SearchAPI searchApi;
@Autowired
@Getter(PROTECTED)
private RMRolesAndActionsAPI rmRolesAndActionsV0API;
protected static final String iso8601_DateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
/**

View File

@@ -28,7 +28,6 @@ package org.alfresco.rest.rm.community.fileplans;
import static java.util.Arrays.asList;
import static com.google.common.collect.Sets.newHashSet;
import static org.springframework.http.HttpStatus.CONFLICT;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
@@ -57,27 +56,19 @@ import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanCo
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.model.user.UserRoles.IN_PLACE_READERS;
import static org.alfresco.rest.rm.community.model.user.UserRoles.IN_PLACE_WRITERS;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_ADMIN;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_MANAGER;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_POWER_USER;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_SECURITY_OFFICER;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_USER;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.alfresco.utility.data.RandomData.getRandomName;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.DataProviderClass;
import org.alfresco.rest.rm.community.model.CapabilityModel;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.fileplan.FilePlanProperties;
import org.alfresco.rest.rm.community.model.hold.Hold;
@@ -85,9 +76,6 @@ import org.alfresco.rest.rm.community.model.hold.HoldCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryProperties;
import org.alfresco.rest.rm.community.model.role.Role;
import org.alfresco.rest.rm.community.model.role.RoleCollection;
import org.alfresco.rest.rm.community.model.user.UserCapabilities;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.utility.constants.ContainerName;
import org.alfresco.utility.model.UserModel;
@@ -99,7 +87,6 @@ import org.alfresco.utility.report.Bug;
* @author Rodica Sutu
* @since 2.6
*/
@SuppressWarnings("PMD.UnitTestShouldIncludeAssert")
public class FilePlanTests extends BaseRMRestTest
{
// ** Number of children (for children creation test) */
@@ -279,7 +266,7 @@ public class FilePlanTests extends BaseRMRestTest
* When I ask the API to create a root record category
* Then it is created as a root record category
* </pre>
*
*
* <pre>
* Given that a file plan exists
* When I use the API to create a folder (cm:folder type) into the fileplan
@@ -327,7 +314,7 @@ public class FilePlanTests extends BaseRMRestTest
* When I ask the API to create a root category having the same name
* Then the response code received is 409 - name clashes with an existing node
* </pre>
*
*
* <pre>
* Given a root category
* When I ask the API to create a root category having the same name with autoRename parameter on true
@@ -607,171 +594,4 @@ public class FilePlanTests extends BaseRMRestTest
}
});
}
/**
* <pre>
* Given that a file plan exists
* When rmAdmin user ask the API for roles
* It provides list of all default roles
* </pre>
*/
@Test
public void listFilePlanAllDefaultRoles()
{
List<String> defaultRolesDisplayNames = asList(IN_PLACE_READERS.displayName, ROLE_RM_ADMIN.displayName, ROLE_RM_MANAGER.displayName, ROLE_RM_POWER_USER.displayName, ROLE_RM_USER.displayName, IN_PLACE_WRITERS.displayName, ROLE_RM_SECURITY_OFFICER.displayName);
// Call to new API to get the roles and capabilities
RoleCollection roleCollection = getRestAPIFactory().getFilePlansAPI().getFilePlanRoles(FILE_PLAN_ALIAS);
assertStatusCode(OK);
roleCollection.getEntries().forEach(roleModelEntry -> {
Role role = roleModelEntry.getEntry();
assertTrue(defaultRolesDisplayNames.contains(role.getDisplayLabel()));
assertNotNull(role.getCapabilities());
});
}
/**
* <pre>
* Given that a file plan exists
* When rmAdmin user ask the API for roles with SystemRoles as false
* It provides list of all roles excluding SystemRoles
* </pre>
*/
@Test
public void listFilePlanAllRolesExcludeSystemRoles()
{
String parameters = "where=(systemRoles=false)";
List<String> systemRolesDisplayNames = asList(IN_PLACE_WRITERS.displayName, IN_PLACE_READERS.displayName);
// Call to new API to get the roles and capabilities
RoleCollection roleCollection = getRestAPIFactory().getFilePlansAPI().getFilePlanRoles(FILE_PLAN_ALIAS, parameters);
assertStatusCode(OK);
roleCollection.getEntries().forEach(roleModelEntry -> {
Role role = roleModelEntry.getEntry();
assertFalse(systemRolesDisplayNames.contains(role.getDisplayLabel()));
assertNotNull(role.getCapabilities());
});
}
/**
* <pre>
* Given that a file plan exists
* When a non-RM user asks the API for the roles
* Then the status code 403 (Permission denied) is return
* </pre>
*/
@Test
public void nonRmUserFilePlanRoles()
{
// Create a random user
UserModel nonRMuser = getDataUser().createRandomTestUser("testUser");
// Call to new API to get the roles and capabilities
getRestAPIFactory().getFilePlansAPI(nonRMuser).getFilePlanRoles(FILE_PLAN_ALIAS);
assertStatusCode(FORBIDDEN);
}
/**
* <pre>
* Given that a file plan exists
* When a RM_Manager user asks the API for the roles
* returns the RM_Manager role and capabilities
* </pre>
*/
@Test
public void rmManagerFilePlanRolesAndCapabilities()
{
// Create a random user
UserModel managerUser = getDataUser().createRandomTestUser("managerUser");
// Assign RecordsManager role to user
getRestAPIFactory().getRMUserAPI().assignRoleToUser(managerUser.getUsername(), ROLE_RM_MANAGER.roleId);
String parameters = "where=(personId='" + managerUser.getUsername() + "')";
// Call to new API to get the roles and capabilities
RoleCollection roleCollection = getRestAPIFactory().getFilePlansAPI(managerUser).getFilePlanRoles(FILE_PLAN_ALIAS, parameters);
roleCollection.getEntries().forEach(roleModelEntry -> {
Role role = roleModelEntry.getEntry();
assertEquals(ROLE_RM_MANAGER.displayName, role.getDisplayLabel());
assertNotNull(role.getCapabilities());
});
}
/**
* <pre>
* Given that a file plan exists
* When a User with more than one role asks the API for the roles and relation
* returns the roles and capabilities
* </pre>
*/
@Test
public void multipleRoleUserFilePlanRolesAndCapabilities()
{
// Create a random user
UserModel rmUser = getDataUser().createRandomTestUser("rmUser");
// Assign rmUser role to user
getRestAPIFactory().getRMUserAPI().assignRoleToUser(rmUser.getUsername(), ROLE_RM_USER.roleId);
getRestAPIFactory().getRMUserAPI().assignRoleToUser(rmUser.getUsername(), ROLE_RM_POWER_USER.roleId);
String parameters = "where=(personId='" + rmUser.getUsername() + "')";
// Call to new API to get the roles and capabilities
RoleCollection roleCollection = getRestAPIFactory().getFilePlansAPI(rmUser).getFilePlanRoles(FILE_PLAN_ALIAS, parameters);
assertStatusCode(OK);
assertEquals(roleCollection.getEntries().size(), 2);
roleCollection.getEntries().forEach(roleModelEntry -> {
Role role = roleModelEntry.getEntry();
assertTrue(role.getDisplayLabel().equals(ROLE_RM_USER.displayName) || role.getDisplayLabel().equals(ROLE_RM_POWER_USER.displayName));
assertNotNull(role.getCapabilities());
});
}
/**
* <pre>
* Given that a file plan exists
* When a new user with a new role asks the API for the roles and relation
* returns the new role and new capabilities
* </pre>
*/
@Test
public void newRoleUserFilePlanRolesAndCapabilities()
{
/** A list of capabilities. */
Set<String> newCapabilities = newHashSet(UserCapabilities.VIEW_RECORDS_CAP, UserCapabilities.DECLARE_RECORDS_CAP);
// Create a new role using old API
getRmRolesAndActionsV0API().createRole(getAdminUser().getUsername(), getAdminUser().getPassword(), "NewTestRole",
"New Role Label", newCapabilities);
// Create a random user
UserModel rmNewUser = getDataUser().createRandomTestUser("rmPowerUser");
// Assign New role to user
getRestAPIFactory().getRMUserAPI().assignRoleToUser(rmNewUser.getUsername(), "NewTestRole");
String parameters = "where=(personId='" + rmNewUser.getUsername() + "')";
// Call to new API to get the roles and capabilities
RoleCollection roleCollection = getRestAPIFactory().getFilePlansAPI(rmNewUser).getFilePlanRoles(FILE_PLAN_ALIAS, parameters);
assertStatusCode(OK);
assertEquals(roleCollection.getEntries().size(), 1);
roleCollection.getEntries().forEach(roleModelEntry -> {
List<CapabilityModel> capabilities = roleModelEntry.getEntry().getCapabilities();
capabilities.forEach(capabilityModel -> {
assertTrue(newCapabilities.contains(capabilityModel.name()));
});
});
}
/**
* <pre>
* Given that a file plan exists
* When API call happens with Capability filter
* returns roles associated with the capability
* </pre>
*/
@Test
public void filePlanRolesAndCapabilitiesFilter()
{
String parameters = "where=(systemRoles=true and capabilityName in ('ManageRules'))";
// Call to new API to get the roles and capabilities, filter by capability, include assigned users
RoleCollection roleCollection = getRestAPIFactory().getFilePlansAPI().getFilePlanRoles(FILE_PLAN_ALIAS, parameters);
assertStatusCode(OK);
assertEquals(roleCollection.getEntries().size(), 1);
roleCollection.getEntries().forEach(roleModelEntry -> {
Role role = roleModelEntry.getEntry();
assertEquals(ROLE_RM_ADMIN.displayName, role.getDisplayLabel());
assertNotNull(role.getCapabilities());
});
}
}

View File

@@ -134,16 +134,6 @@ public class AddToHoldsBulkV1Tests extends BaseRMRestTest
.until(() -> getRestAPIFactory().getSearchAPI(null).search(searchRequest).getPagination()
.getTotalItems() == NUMBER_OF_FILES);
RestRequestQueryModel ancestorReq = getContentFromFolderAndAllSubfoldersQuery(rootFolder.getNodeRefWithoutVersion());
SearchRequest ancestorSearchRequest = new SearchRequest();
ancestorSearchRequest.setQuery(ancestorReq);
STEP("Wait until paths are indexed.");
// to improve stability on CI - seems that sometimes during big load we need to wait longer for the condition
await().atMost(120, TimeUnit.SECONDS)
.until(() -> getRestAPIFactory().getSearchAPI(null).search(ancestorSearchRequest).getPagination()
.getTotalItems() == NUMBER_OF_FILES);
holdBulkOperation = HoldBulkOperation.builder()
.query(queryReq)
.op(HoldBulkOperationType.ADD).build();

View File

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

View File

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

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -23,7 +23,7 @@ Recorded content can be explicitly destroyed whilst maintaining the original nod
* License: Alfresco Community
* Issue Tracker Link: [JIRA RM](https://issues.alfresco.com/jira/projects/RM/summary)
* Contribution Model: Alfresco Closed Source
* Documentation: [docs.alfresco.com (Records Management)](https://support.hyland.com/access?dita:id=job1721300866386&vrm_version=25.1&component=Alfresco%20Governance%20Services%20Community%20Edition)
* Documentation: [docs.alfresco.com (Records Management)](https://support.hyland.com/r/Alfresco/Alfresco-Governance-Services-Community-Edition/23.4/Alfresco-Governance-Services-Community-Edition/Introduction)
***

View File

@@ -21,18 +21,18 @@ RM is split into two main parts - a repository integration and a Share integrati
* [Community License](../LICENSE.txt)
* [Enterprise License](../../rm-enterprise/LICENSE.txt) (this file will only be present in clones of the Enterprise repository)
* [Issue Tracker Link](https://issues.alfresco.com/jira/projects/RM)
* [Community Documentation Link](https://support.hyland.com/access?dita:id=job1721300866386&vrm_version=25.1&component=Alfresco%20Governance%20Services%20Community%20Edition)
* [Enterprise Documentation Link](https://support.hyland.com/access?dita:id=job1721300866386&vrm_version=25.1)
* [Community Documentation Link](https://support.hyland.com/r/Alfresco/Alfresco-Governance-Services-Community-Edition/23.4/Alfresco-Governance-Services-Community-Edition/Introduction)
* [Enterprise Documentation Link](https://support.hyland.com/r/Alfresco/Alfresco-Governance-Services/23.4/Alfresco-Governance-Services/Introduction)
* [Contribution Model](../../CONTRIBUTING.md)
***
### Prerequisite Knowledge
An understanding of Alfresco Content Services is assumed. The following pages from the [developer documentation](https://support.hyland.com/access?dita:id=lsl1724405261585&vrm_version=25.2&component=Alfresco%20Content%20Services%20Community%20Edition) give useful background information:
An understanding of Alfresco Content Services is assumed. The following pages from the [developer documentation](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services-Community-Edition/23.4/Alfresco-Content-Services-Community-Edition/Develop) give useful background information:
* [ACS Architecture](https://support.hyland.com/access?dita:id=lfo1719554691023&vrm_version=25.2)
* [Platform Extensions](https://support.hyland.com/access?dita:id=ifr1720080387005&vrm_version=25.2)
* [Share Extensions](https://support.hyland.com/access?dita:id=wqu1720687386891&vrm_version=25.2)
* [ACS Architecture](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/Software-Architecture)
* [Platform Extensions](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/Extension-Points-Overview)
* [Share Extensions](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/Share-UI-Extension-Points)
***
@@ -44,12 +44,12 @@ The RM Share module communicates with the repository module via REST APIs. Inter
* A DAO layer responsible for CRUD operations against the database.
#### REST API
The REST API endpoints fall into two main types - v0 (Webscripts) and v1. The [v0 API](https://support.hyland.com/access?dita:id=fga1720080409048&vrm_version=25.2) is older and not recommended for integrations. The [v1 API](https://support.hyland.com/access?dita:id=cmm1721136574006&vrm_version=25.2) is newer but isn't yet feature complete. If you are running RM locally then the GS API Explorer will be available at [this link](http://localhost:8080/gs-api-explorer/).
The REST API endpoints fall into two main types - v0 (Webscripts) and v1. The [v0 API](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/In-Process-Platform-Extension-Points/Web-Scripts) is older and not recommended for integrations. The [v1 API](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/REST-API-Guide) is newer but isn't yet feature complete. If you are running RM locally then the GS API Explorer will be available at [this link](http://localhost:8080/gs-api-explorer/).
Internally the GS v1 REST API is built on the [Alfresco v1 REST API framework](https://community.alfresco.com/community/ecm/blog/2016/10/11/v1-rest-api-part-1-introduction). It aims to be consistent with this in terms of behaviour and naming.
#### Java Public API
The Java service layer is fronted by a [Java Public API](https://support.hyland.com/access?dita:id=lol1721390191517&vrm_version=25.2), which we will ensure backward compatible with previous releases. Before we remove any methods there will first be a release containing that method deprecated to allow third party integrations to migrate to a new method. The Java Public API also includes a set of POJO objects which are needed to communicate with the services. It is easy to identify classes that are part of the Java Public API as they are annotated `@AlfrescoPublicApi`.
The Java service layer is fronted by a [Java Public API](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/Reference/Java-Foundation-API), which we will ensure backward compatible with previous releases. Before we remove any methods there will first be a release containing that method deprecated to allow third party integrations to migrate to a new method. The Java Public API also includes a set of POJO objects which are needed to communicate with the services. It is easy to identify classes that are part of the Java Public API as they are annotated `@AlfrescoPublicApi`.
Each Java service will have at least four beans defined for it:
@@ -61,7 +61,7 @@ Each Java service will have at least four beans defined for it:
#### DAOs
The DAOs are not part of the Java Public API, but handle CRUD operations against RM stored data. We have some custom queries to improve performance for particularly heavy operations.
We use standard Alfresco [data modelling](https://support.hyland.com/access?dita:id=ekx1720080373621&vrm_version=25.2) to store RM metadata. We extend the [Alfresco patching mechanism](https://support.hyland.com/access?dita:id=ato1720080396825&vrm_version=25.2) to provide community and enterprise schema upgrades.
We use standard Alfresco [data modelling](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/In-Process-Platform-Extension-Points/Content-Model-Extension-Point) to store RM metadata. We extend the [Alfresco patching mechanism](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/In-Process-Platform-Extension-Points/Patches) to provide community and enterprise schema upgrades.
***

View File

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

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.16
SOLR6_TAG=2.0.15
POSTGRES_TAG=16.6
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8

View File

@@ -119,11 +119,6 @@ rm.patch.v35.holdNewChildAssocPatch.batchSize=1000
rm.haspermissionmap.read=Read
rm.haspermissionmap.write=WriteProperties,AddChildren,ReadContent
# Extended Permissions
# Enable matching the given username with the correct casing username when retrieving an IPR group.
# Only needs to be used if there are owners that don't have the username in the correct casing.
rm.extendedSecurity.enableUsernameNormalization=false
#
# Extended auto-version behaviour. If true and other auto-version properties are satisfied, then
# a document will be auto-versioned when its type is changed.

View File

@@ -33,8 +33,5 @@
<!-- content cleanser -->
<bean id="contentCleanser.522022M" class="org.alfresco.module.org_alfresco_module_rm.content.cleanser.ContentCleanser522022M"/>
<!-- content cleanser -->
<bean id="contentCleanser.SevenPass" class="org.alfresco.module.org_alfresco_module_rm.content.cleanser.ContentCleanserSevenPass"/>
</beans>

View File

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

View File

@@ -78,12 +78,6 @@
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.fileplans.FilePlanRolesRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="rmRoles" ref="rm.roles" />
<property name="filePlanService" ref="FilePlanService" />
</bean>
<bean class="org.alfresco.rm.rest.api.holds.HoldsEntityResource" >
<property name="holdService" ref="HoldService" />
<property name="apiUtils" ref="apiUtils" />
@@ -234,11 +228,6 @@
<property name="siteSurfConfig" ref="rm.siteSurfConfig" />
</bean>
<bean id="rm.roles" class="org.alfresco.rm.rest.api.impl.RMRolesImpl">
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="filePlanRoleService" ref="FilePlanRoleService"/>
</bean>
<bean id="rm.siteSurfConfig" class="org.alfresco.rest.api.impl.SiteSurfConfig">
<property name="configPath" value="alfresco/module/org_alfresco_module_rm/bootstrap/site"/>
</bean>
@@ -291,4 +280,4 @@
<property name="beanName" value="restJsonModule" />
<property name="extendingBeanName" value="rm.restJsonModule" />
</bean>
</beans>
</beans>

View File

@@ -611,7 +611,6 @@
<property name="authorityService" ref="authorityService"/>
<property name="permissionService" ref="permissionService"/>
<property name="transactionService" ref="transactionService"/>
<property name="enableUsernameNormalization" value="${rm.extendedSecurity.enableUsernameNormalization}" />
</bean>
<bean id="ExtendedSecurityService" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>
@@ -84,6 +84,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>

View File

@@ -1,51 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.content.cleanser;
import java.io.File;
/**
* DoD 5220-22M Seven Pass data cleansing implementation.
*
*/
public class ContentCleanserSevenPass extends ContentCleanser522022M
{
/**
* @see org.alfresco.module.org_alfresco_module_rm.content.cleanser.ContentCleanser#cleanse(java.io.File)
*/
@Override
public void cleanse(File file)
{
super.cleanse(file);
overwrite(file, overwriteZeros);
overwrite(file, overwriteZeros);
overwrite(file, overwriteOnes);
overwrite(file, overwriteRandom);
}
}

View File

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

View File

@@ -36,10 +36,8 @@ import java.util.Set;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.extensions.webscripts.ui.common.StringUtils;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
@@ -98,8 +96,6 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
/** transaction service */
private TransactionService transactionService;
private boolean enableUsernameNormalization;
/**
* @param filePlanService
* file plan service
@@ -145,15 +141,6 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
this.transactionService = transactionService;
}
/**
* @param enableUsernameNormalization
* enable username normalization to ensure correct casing
*/
public void setEnableUsernameNormalization(boolean enableUsernameNormalization)
{
this.enableUsernameNormalization = enableUsernameNormalization;
}
/**
* Application context refresh event handler
*/
@@ -372,18 +359,12 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
{
String group = null;
// If enabled, the authorities are forced to match the correct casing of the usernames in case they were set
// with the incorrect casing.
// If not, it will just use the authorities as they are.
// In normal circumstances, the authorities are in the correct casing, so this is disabled by default.
Set<String> authoritySet = normalizeAuthorities(authorities);
// find group or determine what the next index is if no group exists or there is a clash
Pair<String, Integer> groupResult = findIPRGroup(groupPrefix, authoritySet);
Pair<String, Integer> groupResult = findIPRGroup(groupPrefix, authorities);
if (groupResult.getFirst() == null)
{
group = createIPRGroup(groupPrefix, authoritySet, groupResult.getSecond());
group = createIPRGroup(groupPrefix, authorities, groupResult.getSecond());
}
else
{
@@ -418,8 +399,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
while (hasMoreItems == true)
{
// get matching authorities
PagingResults<String> results = authorityService.getAuthorities(
AuthorityType.GROUP,
PagingResults<String> results = authorityService.getAuthorities(AuthorityType.GROUP,
RMAuthority.ZONE_APP_RM,
groupShortNamePrefix,
false,
@@ -447,63 +427,6 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
return new Pair<>(iprGroup, nextGroupIndex);
}
/**
* Given a set of authorities, normalizes the authority names to ensure correct casing.
*
* @param authNames
* @return
*/
private Set<String> normalizeAuthorities(Set<String> authNames)
{
// If disabled or no authorities, return as is
if (!enableUsernameNormalization || authNames == null || authNames.isEmpty())
{
return authNames;
}
Set<String> normalizedAuthorities = new HashSet<>();
for (String authorityName : authNames)
{
normalizedAuthorities.add(normalizeAuthorityName(authorityName));
}
return normalizedAuthorities;
}
/**
* Usernames are case insensitive but affect the IPR group matching when set with different casing. For a given authority of type user, this method normalizes the authority name. If group, it returns the name as-is.
*
* @param authorityName
* the authority name to normalize
* @return the normalized authority name
*/
private String normalizeAuthorityName(String authorityName)
{
if (authorityName == null || authorityName.startsWith(GROUP_PREFIX))
{
return authorityName;
}
// For users, attempt to get the correct casing from the username property of the user node
if (authorityService.authorityExists(authorityName))
{
try
{
NodeRef authorityNodeRef = authorityService.getAuthorityNodeRef(authorityName);
if (authorityNodeRef != null)
{
String username = (String) nodeService.getProperty(authorityNodeRef, ContentModel.PROP_USERNAME);
return username != null ? username : authorityName;
}
}
catch (Exception e)
{
// If anything goes wrong, fallback to the original name
}
}
return authorityName;
}
/**
* Determines whether a group exactly matches a list of authorities.
*
@@ -650,8 +573,8 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
}
catch (DuplicateChildNodeNameException ex)
{
// Rethrow as ConcurrencyFailureException so that is can be retried and linked to the group created by the concurrent transaction
throw new ConcurrencyFailureException("IPR group creation failed due to concurrent duplicate group name creation: " + groupShortName);
// the group was concurrently created
group = authorityService.getName(AuthorityType.GROUP, groupShortName);
}
return group;

View File

@@ -1,56 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.RoleModel;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* RM Roles API
*/
public interface RMRoles
{
String PARAM_INCLUDE_ASSIGNED_USERS = "assignedUsers";
String PARAM_INCLUDE_ASSIGNED_GROUPS = "assignedGroups";
String PARAM_INCLUDE_SYSTEM_ROLES = "systemRoles";
String PARAM_CAPABILITY_NAME = "capabilityName";
String PARAM_PERSON_ID = "personId";
/**
* Gets a list of roles.
*
* @param filePlan
* the file plan node reference
* @param parameters
* the {@link Parameters} object to get the parameters passed into the request including: - filter, sort & paging params (where, orderBy, skipCount, maxItems) - include param (personId, includeSystemRoles)
* @return a paged list of {@code org.alfresco.rm.rest.api.model.RoleModel} objects
*/
CollectionWithPagingInfo<RoleModel> getRoles(NodeRef filePlan, Parameters parameters);
}

View File

@@ -1,96 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.fileplans;
import static org.alfresco.util.ParameterCheck.mandatory;
import org.springframework.beans.factory.InitializingBean;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
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.RMRoles;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.RoleModel;
import org.alfresco.service.cmr.repository.NodeRef;
@RelationshipResource(name = "roles", entityResource = FilePlanEntityResource.class, title = "Roles in a file plan")
public class FilePlanRolesRelation implements RelationshipResourceAction.Read<RoleModel>, InitializingBean
{
private RMRoles rmRoles;
private FilePlanService filePlanService;
private FilePlanComponentsApiUtils apiUtils;
@Override
public void afterPropertiesSet() throws Exception
{
mandatory("rmRoles", this.rmRoles);
mandatory("apiUtils", this.apiUtils);
mandatory("filePlanService", this.filePlanService);
}
@Override
public CollectionWithPagingInfo<RoleModel> readAll(String filePlanId, Parameters params)
{
NodeRef filePlanNodeRef = getFilePlan(filePlanId);
if (filePlanNodeRef == null)
{
throw new EntityNotFoundException(filePlanId);
}
return rmRoles.getRoles(filePlanNodeRef, params);
}
private NodeRef getFilePlan(String filePlanId)
{
NodeRef filePlanNodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, RecordsManagementModel.TYPE_FILE_PLAN);
if (!FilePlanComponentsApiUtils.FILE_PLAN_ALIAS.equals(filePlanId))
{
filePlanNodeRef = filePlanService.getFilePlan(filePlanNodeRef);
}
return filePlanNodeRef;
}
public void setRmRoles(RMRoles rmRoles)
{
this.rmRoles = rmRoles;
}
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
}

View File

@@ -30,7 +30,6 @@ package org.alfresco.rm.rest.api.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -43,15 +42,12 @@ import org.slf4j.LoggerFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
import org.alfresco.module.org_alfresco_module_rm.capability.Group;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinitionImpl;
import org.alfresco.module.org_alfresco_module_rm.disposition.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.module.org_alfresco_module_rm.role.Role;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.AssocChild;
import org.alfresco.rest.api.model.ContentInfo;
@@ -59,9 +55,7 @@ import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.api.model.UserInfo;
import org.alfresco.rest.framework.jacksonextensions.BeanPropertiesFilter;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.CapabilityModel;
import org.alfresco.rm.rest.api.model.FilePlan;
import org.alfresco.rm.rest.api.model.GroupModel;
import org.alfresco.rm.rest.api.model.HoldModel;
import org.alfresco.rm.rest.api.model.RMNode;
import org.alfresco.rm.rest.api.model.Record;
@@ -72,7 +66,6 @@ import org.alfresco.rm.rest.api.model.RetentionPeriod;
import org.alfresco.rm.rest.api.model.RetentionSchedule;
import org.alfresco.rm.rest.api.model.RetentionScheduleActionDefinition;
import org.alfresco.rm.rest.api.model.RetentionSteps;
import org.alfresco.rm.rest.api.model.RoleModel;
import org.alfresco.rm.rest.api.model.Transfer;
import org.alfresco.rm.rest.api.model.TransferChild;
import org.alfresco.rm.rest.api.model.TransferContainer;
@@ -703,36 +696,6 @@ public class ApiNodesModelFactory
(String) info.getProperties().get(RecordsManagementModel.PROP_HOLD_REASON));
}
public RoleModel createRoleModel(Role role, List<String> assignedUsers, List<String> assignedGroups)
{
return new RoleModel(role.getName(),
role.getDisplayLabel(),
role.getCapabilities()
.stream()
.map(this::createCapabilityModel)
.sorted(Comparator.comparing(CapabilityModel::name))
.toList(),
role.getRoleGroupName(),
role.getGroupShortName(),
assignedUsers,
assignedGroups);
}
public CapabilityModel createCapabilityModel(Capability capability)
{
return new CapabilityModel(capability.getName(), capability.getTitle(), capability.getDescription(),
createGroupModel(capability.getGroup()), capability.getIndex());
}
public GroupModel createGroupModel(Group group)
{
if (group == null)
{
return null;
}
return new GroupModel(group.getId(), group.getTitle());
}
/**
* Creates an object of type FilePlan
*

View File

@@ -1,264 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.role.Role;
import org.alfresco.rest.antlr.WhereClauseParser;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.where.Query;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker;
import org.alfresco.rm.rest.api.RMRoles;
import org.alfresco.rm.rest.api.model.RoleModel;
import org.alfresco.service.cmr.repository.NodeRef;
public class RMRolesImpl implements RMRoles
{
private ApiNodesModelFactory nodesModelFactory;
private FilePlanRoleService filePlanRoleService;
private static final Set<String> LIST_ROLES_QUERY_PROPERTIES = new HashSet<>(List.of(PARAM_PERSON_ID, PARAM_INCLUDE_SYSTEM_ROLES, PARAM_CAPABILITY_NAME));
@Override
public CollectionWithPagingInfo<RoleModel> getRoles(NodeRef filePlan, Parameters parameters)
{
var rolesFilter = getRolesFilter(parameters.getQuery());
var roles = getRolesByFilter(filePlan, rolesFilter);
var filteredRoles = roles.stream()
.map(role -> createRoleModel(filePlan, role, parameters.getInclude()))
.filter(hasRoleCapabilities(rolesFilter.getCapabilities()))
.toList();
var page = filteredRoles
.stream()
.sorted(Comparator.comparing(RoleModel::name))
.skip(parameters.getPaging().getSkipCount())
.limit(parameters.getPaging().getMaxItems())
.collect(Collectors.toCollection(LinkedList::new));
int totalItems = filteredRoles.size();
boolean hasMore = parameters.getPaging().getSkipCount() + parameters.getPaging().getMaxItems() < totalItems;
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, hasMore, totalItems);
}
private Predicate<RoleModel> hasRoleCapabilities(List<String> capabilities)
{
return role -> capabilities == null ||
capabilities.isEmpty() ||
role.capabilities().stream().anyMatch(capability -> capabilities.contains(capability.name()));
}
private Set<Role> getRolesByFilter(NodeRef filePlan, RolesFilter rolesFilter)
{
if (rolesFilter.getPersonId() != null)
{
return filePlanRoleService.getRolesByUser(filePlan, rolesFilter.getPersonId(), rolesFilter.includeSystemRoles());
}
else
{
return filePlanRoleService.getRoles(filePlan, rolesFilter.includeSystemRoles());
}
}
private RoleModel createRoleModel(NodeRef filePlan, Role role, List<String> include)
{
List<String> assignedUsers = getAssignedUsers(filePlan, role, include);
List<String> assignedGroups = getAssignedGroups(filePlan, role, include);
return nodesModelFactory.createRoleModel(role, assignedUsers, assignedGroups);
}
private List<String> getAssignedUsers(NodeRef filePlan, Role role, List<String> include)
{
if (include != null && include.contains(PARAM_INCLUDE_ASSIGNED_USERS))
{
return new ArrayList<>(filePlanRoleService.getAllAssignedToRole(filePlan, role.getName()));
}
return null;
}
private List<String> getAssignedGroups(NodeRef filePlan, Role role, List<String> include)
{
if (include != null && include.contains(PARAM_INCLUDE_ASSIGNED_GROUPS))
{
return new ArrayList<>(filePlanRoleService.getGroupsAssignedToRole(filePlan, role.getName()));
}
return null;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setFilePlanRoleService(FilePlanRoleService filePlanRoleService)
{
this.filePlanRoleService = filePlanRoleService;
}
private RolesFilter getRolesFilter(Query queryParameters)
{
var rolesFilterBuilder = RolesFilter.builder();
if (queryParameters != null)
{
var propertyWalker = new RolesQueryWalker();
QueryHelper.walk(queryParameters, propertyWalker);
rolesFilterBuilder
.withPersonId(propertyWalker.getPersonId())
.withCapabilities(propertyWalker.getCapabilitiesNames())
.withIncludeSystemRoles(propertyWalker.includeSystemRoles());
}
return rolesFilterBuilder.build();
}
private static class RolesQueryWalker extends MapBasedQueryWalker
{
private List<String> capabilitiesNames;
public RolesQueryWalker()
{
super(LIST_ROLES_QUERY_PROPERTIES, null);
}
@Override
public void in(String propertyName, boolean negated, String... propertyValues)
{
if (negated)
{
throw new InvalidArgumentException("Cannot use NOT for " + propertyName);
}
if (PARAM_CAPABILITY_NAME.equalsIgnoreCase(propertyName))
{
capabilitiesNames = Arrays.asList(propertyValues);
}
}
@Override
public void and()
{
// allow AND, e.g. personId='123' AND includeSystemRoles=true
}
public List<String> getCapabilitiesNames()
{
return this.capabilitiesNames;
}
public String getPersonId()
{
return getProperty(PARAM_PERSON_ID, WhereClauseParser.EQUALS, String.class);
}
public Boolean includeSystemRoles()
{
return getProperty(PARAM_INCLUDE_SYSTEM_ROLES, WhereClauseParser.EQUALS, Boolean.class);
}
}
}
class RolesFilter
{
private String personId;
private boolean includeSystemRoles;
private List<String> capabilities;
private RolesFilter()
{}
public static RolesFilterBuilder builder()
{
return new RolesFilterBuilder();
}
public String getPersonId()
{
return personId;
}
public boolean includeSystemRoles()
{
return includeSystemRoles;
}
public List<String> getCapabilities()
{
return capabilities;
}
public static class RolesFilterBuilder
{
private String personId;
private boolean includeSystemRoles = true;
private List<String> capabilities;
public RolesFilterBuilder withPersonId(String personId)
{
this.personId = personId;
return this;
}
public RolesFilterBuilder withIncludeSystemRoles(Boolean includeSystemRoles)
{
if (includeSystemRoles != null)
{
this.includeSystemRoles = includeSystemRoles;
}
return this;
}
public RolesFilterBuilder withCapabilities(List<String> capabilities)
{
this.capabilities = capabilities;
return this;
}
public RolesFilter build()
{
RolesFilter rolesFilter = new RolesFilter();
rolesFilter.personId = this.personId;
rolesFilter.includeSystemRoles = this.includeSystemRoles;
rolesFilter.capabilities = this.capabilities;
return rolesFilter;
}
}
}

View File

@@ -1,30 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
public record CapabilityModel(String name, String title, String description, GroupModel group, int index)
{}

View File

@@ -1,30 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
public record GroupModel(String id, String title)
{}

View File

@@ -1,32 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
import java.util.List;
public record RoleModel(String name, String displayLabel, List<CapabilityModel> capabilities, String roleGroupName, String groupShortName, List<String> assignedUsers, List<String> assignedGroups)
{}

View File

@@ -1,32 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.model;
import java.util.List;
public record RoleModelList(List<RoleModel> roleModelList)
{}

View File

@@ -1,37 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/**
* Package info that defines the Information Governance Roles REST API
*
* @author Damian Ujma
*/
@WebApi(name = "gs", scope = Api.SCOPE.PUBLIC, version = 1)
package org.alfresco.rm.rest.api.roles;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.WebApi;

View File

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

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -4,7 +4,7 @@
# Version label
version.major=25
version.minor=3
version.minor=2
version.revision=0
version.label=

View File

@@ -1,100 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.content.cleanser;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.service.cmr.repository.ContentIOException;
/**
* Eager content store cleaner unit test.
*
*/
public class ContentCleanserSevenPassUnitTest extends BaseUnitTest
{
@InjectMocks
@Spy
private ContentCleanserSevenPass contentCleanserSevenPass = new ContentCleanserSevenPass()
{
/** dummy implementations */
@Override
protected void overwrite(File file, OverwriteOperation overwriteOperation)
{
// Intentionally left empty
}
};
@Mock
private File mockedFile;
/**
* Given that a file exists When I cleanse it Then the content is overwritten
*/
@Test
public void cleanseFile()
{
when(mockedFile.exists()).thenReturn(true);
when(mockedFile.canWrite()).thenReturn(true);
contentCleanserSevenPass.cleanse(mockedFile);
verify(contentCleanserSevenPass, times(2)).overwrite(mockedFile, contentCleanserSevenPass.overwriteOnes);
verify(contentCleanserSevenPass, times(3)).overwrite(mockedFile, contentCleanserSevenPass.overwriteZeros);
verify(contentCleanserSevenPass, times(2)).overwrite(mockedFile, contentCleanserSevenPass.overwriteRandom);
}
/**
* Given that the file does not exist When I cleanse it Then an exception is thrown
*/
@Test(expected = ContentIOException.class)
public void fileDoesNotExist()
{
when(mockedFile.exists()).thenReturn(false);
when(mockedFile.canWrite()).thenReturn(true);
contentCleanserSevenPass.cleanse(mockedFile);
}
/**
* Given that I can not write to the file When I cleanse it Then an exception is thrown
*/
@Test(expected = ContentIOException.class)
public void cantWriteToFile()
{
when(mockedFile.exists()).thenReturn(true);
when(mockedFile.canWrite()).thenReturn(false);
contentCleanserSevenPass.cleanse(mockedFile);
}
}

View File

@@ -52,7 +52,6 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
@@ -68,7 +67,6 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
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.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityService;
@@ -524,104 +522,6 @@ public class ExtendedSecurityServiceImplUnitTest
verify(mockedPermissionService).setPermission(nodeRef, writeGroup, RMPermissionModel.FILING, true);
}
/**
* Given a node with no previous IPR groups assigned
* And having pre-existing IPR groups matching the ones we need
* When I add some read and write authorities but with a different casing
* Then the existing IPR groups are used
*/
@SuppressWarnings("unchecked")
@Test public void addExtendedSecurityWithMixedCasingUsernames()
{
// Have the usernames in the node as the correct usernames but with incorrect casing
String user1 = "UseR";
String user2 = "UseR_w";
// Incorrect IPR Group names
Set<String> diffCasingReaders = Stream.of(user1, GROUP).collect(Collectors.toSet());
Set<String> diffCasingWriters = Stream.of(user2, GROUP_W).collect(Collectors.toSet());
String wrongReadGroupPrefix = extendedSecurityService.getIPRGroupPrefixShortName(READER_GROUP_PREFIX, diffCasingReaders);
String wrongWriteGroupPrefix = extendedSecurityService.getIPRGroupPrefixShortName(WRITER_GROUP_PREFIX, diffCasingWriters);
String wrongReadGroup = wrongReadGroupPrefix + "0";
String wrongWriteGroup = wrongWriteGroupPrefix + "0";
// Correct Group names
String correctReadGroup = readGroupPrefix + "0";
String correctWriteGroup = writeGroupPrefix + "0";
// If queried for the correct groups, return the results
PagingResults<String> mockedCorrectReadPResults = mock(PagingResults.class);
PagingResults<String> mockedCorrectWritePResults = mock(PagingResults.class);
when(mockedCorrectReadPResults.getPage())
.thenReturn(Stream.of(GROUP_PREFIX + correctReadGroup).collect(Collectors.toList()));
when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
eq(readGroupPrefix),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedCorrectReadPResults);
when(mockedCorrectWritePResults.getPage())
.thenReturn(Stream.of(GROUP_PREFIX + correctWriteGroup).collect(Collectors.toList()));
when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
eq(writeGroupPrefix),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedCorrectWritePResults);
// Don't return results for the incorrect groups (lenient as these may not be called with normalization enabled)
PagingResults<String> mockedWrongReadPResults = mock(PagingResults.class);
PagingResults<String> mockedWrongWritePResults = mock(PagingResults.class);
lenient().when(mockedWrongReadPResults.getPage())
.thenReturn(Collections.emptyList());
lenient().when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
eq(wrongReadGroupPrefix),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedWrongReadPResults);
lenient().when(mockedWrongWritePResults.getPage())
.thenReturn(Collections.emptyList());
lenient().when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
eq(wrongWriteGroupPrefix),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedWrongWritePResults);
// The users do exist, despite being in a different casing and are able to be retrieved
NodeRef noderefUser1 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, USER);
when(mockedAuthorityService.authorityExists(user1)).thenReturn(true);
when(mockedAuthorityService.getAuthorityNodeRef(user1)).thenReturn(noderefUser1);
when(mockedNodeService.getProperty(noderefUser1, ContentModel.PROP_USERNAME)).thenReturn(USER);
NodeRef noderefUser2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, USER_W);
when(mockedAuthorityService.authorityExists(user2)).thenReturn(true);
when(mockedAuthorityService.getAuthorityNodeRef(user2)).thenReturn(noderefUser2);
when(mockedNodeService.getProperty(noderefUser2, ContentModel.PROP_USERNAME)).thenReturn(USER_W);
// Set the extended security service to normalize usernames
extendedSecurityService.setEnableUsernameNormalization(true);
extendedSecurityService.set(nodeRef, diffCasingReaders, diffCasingWriters);
// Verify that the incorrect read group is not created
verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, wrongReadGroup, wrongReadGroup, Collections.singleton(RMAuthority.ZONE_APP_RM));
// Verify that the incorrect write group is not created
verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, wrongWriteGroup, wrongWriteGroup, Collections.singleton(RMAuthority.ZONE_APP_RM));
}
/**
* Given a node with no previous IPR groups assigned
@@ -671,7 +571,7 @@ public class ExtendedSecurityServiceImplUnitTest
.thenReturn(Stream
.of(USER_W, AlfMock.generateText())
.collect(Collectors.toSet()));
// add extended security
extendedSecurityService.set(nodeRef, READERS, WRITERS);
@@ -995,7 +895,7 @@ public class ExtendedSecurityServiceImplUnitTest
// group names
String readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_FULL_PREFIX, READERS, 0);
String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_FULL_PREFIX, WRITERS, 0);
// setup renditions
NodeRef renditionNodeRef = AlfMock.generateNodeRef(mockedNodeService);
when(mockedNodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_RECORD))
@@ -1004,7 +904,7 @@ public class ExtendedSecurityServiceImplUnitTest
.thenReturn(renditionNodeRef);
when(mockedNodeService.getChildAssocs(nodeRef, RenditionModel.ASSOC_RENDITION, RegexQNamePattern.MATCH_ALL))
.thenReturn(Collections.singletonList(mockedChildAssociationRef));
// setup permissions
Set<AccessPermission> permissions = Stream
.of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, readGroup, 0),
@@ -1013,17 +913,17 @@ public class ExtendedSecurityServiceImplUnitTest
.collect(Collectors.toSet());
when(mockedPermissionService.getAllSetPermissions(nodeRef))
.thenReturn(permissions);
// remove extended security
extendedSecurityService.remove(nodeRef);
// verify that the groups permissions have been removed
verify(mockedPermissionService).clearPermission(nodeRef, readGroup);
verify(mockedPermissionService).clearPermission(nodeRef, writeGroup);
// verify that the groups permissions have been removed from the rendition
verify(mockedPermissionService).clearPermission(renditionNodeRef, readGroup);
verify(mockedPermissionService).clearPermission(renditionNodeRef, writeGroup);
}
}

View File

@@ -1,177 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* -
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* -
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rm.rest.api.impl;
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.role.Role;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
import org.alfresco.rm.rest.api.model.CapabilityModel;
import org.alfresco.rm.rest.api.model.RoleModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
public class RMRolesImplUnitTest extends BaseUnitTest {
private final RecognizedParamsExtractor queryExtractor = new RecognizedParamsExtractor() {};
private RMRolesImpl rmRolesImpl;
private FilePlanRoleService mockedFilePlanRoleService;
private ApiNodesModelFactory mockedNodesModelFactory;
private final Capability viewRecordsCapability = mock(Capability.class);
private final Capability editMetadataCapability = mock(Capability.class);
private final Role role1 = new Role("Role1", "Role 1", Set.of(viewRecordsCapability), "Group1");
private final Role role2 = new Role("Role2", "Role 2", Set.of(editMetadataCapability), "Group2");
private final RoleModel roleModel1 = new RoleModel("Role1", "Role 1", List.of(new CapabilityModel("ViewRecords", "", "", null, 0)), "Group1", null, List.of("User1"), List.of("Group1"));
private final RoleModel roleModel2 = new RoleModel("Role2", "Role 2", List.of(new CapabilityModel("EditMetadata", "", "", null, 0)), "Group2", null, List.of("User2"), List.of("Group2"));
private final NodeRef filePlan = new NodeRef("workspace://SpacesStore/testFilePlan");
private final Parameters parameters = mock(Parameters.class);
private final Paging paging = mock(Paging.class);
@Before
public void setUp() {
mockedFilePlanRoleService = mock(FilePlanRoleService.class);
mockedNodesModelFactory = mock(ApiNodesModelFactory.class);
rmRolesImpl = new RMRolesImpl();
rmRolesImpl.setFilePlanRoleService(mockedFilePlanRoleService);
rmRolesImpl.setNodesModelFactory(mockedNodesModelFactory);
when(mockedFilePlanRoleService.getRoles(filePlan, true)).thenReturn(Set.of(role1, role2));
when(mockedNodesModelFactory.createRoleModel(eq(role1), any(), any())).thenReturn(roleModel1);
when(mockedNodesModelFactory.createRoleModel(eq(role2), any(), any())).thenReturn(roleModel2);
when(viewRecordsCapability.getName()).thenReturn("ViewRecords");
when(editMetadataCapability.getName()).thenReturn("EditMetadata");
when(parameters.getPaging()).thenReturn(paging);
when(paging.getSkipCount()).thenReturn(0);
when(paging.getMaxItems()).thenReturn(10);
}
@Test
public void testGetRoles_NoFilters() {
// when
CollectionWithPagingInfo<RoleModel> result = rmRolesImpl.getRoles(filePlan, parameters);
// then
List<RoleModel> roleModelList = (List<RoleModel>) result.getCollection();
assertEquals(2, (int) result.getTotalItems());
assertEquals(List.of(roleModel1, roleModel2), roleModelList);
verify(mockedFilePlanRoleService).getRoles(filePlan, true);
verify(mockedNodesModelFactory).createRoleModel(eq(role1), any(), any());
verify(mockedNodesModelFactory).createRoleModel(eq(role2), any(), any());
}
@Test
public void testGetRoles_WithPersonId() {
// given
String personId = "testUser";
when(mockedFilePlanRoleService.getRolesByUser(filePlan, personId, true)).thenReturn(Set.of(role1));
when(parameters.getQuery()).thenReturn(queryExtractor.getWhereClause("(personId='" + personId + "')"));
// when
CollectionWithPagingInfo<RoleModel> result = rmRolesImpl.getRoles(filePlan, parameters);
// then
assertEquals(1, (int) result.getTotalItems());
assertEquals(List.of(roleModel1), result.getCollection());
verify(mockedFilePlanRoleService).getRolesByUser(filePlan, personId, true);
verify(mockedNodesModelFactory).createRoleModel(eq(role1), any(), any());
}
@Test
public void testGetNonSystemRoles() {
//given
when(mockedFilePlanRoleService.getRoles(filePlan, false)).thenReturn(Set.of(role2));
when(parameters.getQuery()).thenReturn(queryExtractor.getWhereClause("(systemRoles=false)"));
// when
CollectionWithPagingInfo<RoleModel> result = rmRolesImpl.getRoles(filePlan, parameters);
// then
assertEquals(1, (int) result.getTotalItems());
assertEquals(List.of(roleModel2), result.getCollection());
verify(mockedFilePlanRoleService).getRoles(filePlan, false);
verify(mockedNodesModelFactory).createRoleModel(eq(role2), any(), any());
}
@Test
public void testGetRoles_WithCapabilitiesFilter() {
// given
when(parameters.getQuery()).thenReturn(queryExtractor.getWhereClause("(capabilityName IN ('ViewRecords'))"));
// when
CollectionWithPagingInfo<RoleModel> result = rmRolesImpl.getRoles(filePlan, parameters);
// then
assertEquals(1, (int) result.getTotalItems());
assertEquals(List.of(roleModel1), result.getCollection());
verify(mockedFilePlanRoleService).getRoles(filePlan, true);
verify(mockedNodesModelFactory).createRoleModel(eq(role1), any(), any());
}
@Test
public void testGetRoles_IncludeAssignedUsersAndGroups() {
// given
when(mockedFilePlanRoleService.getRoles(filePlan, true)).thenReturn(Set.of(role1));
when(mockedFilePlanRoleService.getAllAssignedToRole(filePlan, "Role1")).thenReturn(Set.of("User1"));
when(mockedFilePlanRoleService.getGroupsAssignedToRole(filePlan, "Role1")).thenReturn(Set.of("Group1"));
when(parameters.getInclude()).thenReturn(List.of("assignedUsers", "assignedGroups"));
// when
CollectionWithPagingInfo<RoleModel> result = rmRolesImpl.getRoles(filePlan, parameters);
// then
List<RoleModel> roleModelList = (List<RoleModel>) result.getCollection();
assertEquals(1, (int) result.getTotalItems());
assertEquals(List.of(roleModel1), roleModelList);
assertEquals(List.of("User1"), roleModelList.get(0).assignedUsers());
assertEquals(List.of("Group1"), roleModelList.get(0).assignedGroups());
verify(mockedFilePlanRoleService).getRoles(filePlan, true);
verify(mockedFilePlanRoleService).getAllAssignedToRole(filePlan, "Role1");
verify(mockedFilePlanRoleService).getGroupsAssignedToRole(filePlan, "Role1");
verify(mockedNodesModelFactory).createRoleModel(role1, List.of("User1"), List.of("Group1"));
}
}

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

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

View File

@@ -540,66 +540,6 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/file-plans/{filePlanId}/roles':
get:
tags:
- file-plans
summary: Get roles in a file plan
description: |
Gets a list of roles for the specified file plan **filePlanId**.
You can use the **include** parameter to return additional information.
The **where** parameter can also be used to filter by **personId**, **systemRoles** and **capabilityName**.
You can use the **where** parameter to
* filter roles by user:
`where=(personId='admin')`
* not include system roles in the results:
`where=(systemRoles=false)`
* filter roles by specified capabilities:
`where=(capabilityName in ('AddToHold', 'ViewRecords'))`
This may be combined with all filter, as shown below:
`where=(systemRoles=false and personId='johndoe' and capabilityName in ('AddToHold', 'ViewRecords'))`
operationId: getFilePlanRoles
parameters:
- $ref: '#/parameters/filePlanIdWithAliasParam'
- $ref: '#/parameters/whereParam'
- $ref: '#/parameters/rolesIncludeParam'
- $ref: '#/parameters/skipCountParam'
- $ref: '#/parameters/maxItemsParam'
produces:
- application/json
responses:
'200':
description: Successful response
schema:
type: object
properties:
list:
type: array
items:
$ref: '#/definitions/RoleModel'
pagination:
$ref: '#/definitions/Pagination'
'400':
description: |
Invalid parameter: value of **maxItems** or **skipCount**, or **include**, or **where** is invalid
'401':
description: Authentication failed
'403':
description: Current user does not have permission to read **filePlanId**
'404':
description: "**filePlanId** does not exist"
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
## Unfiled records containers
'/unfiled-containers/{unfiledContainerId}':
get:
@@ -3367,21 +3307,6 @@ parameters:
* actions
required: false
type: string
rolesIncludeParam:
name: include
in: query
description: |
Returns additional information about roles. Any optional field from the response model can be requested. For example:
* assignedUsers
* assignedGroups
required: false
type: string
whereParam:
name: where
in: query
description: A string to restrict the returned objects by using a predicate.
required: false
type: string
definitions:
FilePlanComponentBodyUpdate:
type: object
@@ -4464,49 +4389,6 @@ definitions:
query:
description: The query which may have been generated in some way from the userQuery
type: string
CapabilityModel:
type: object
properties:
name:
type: string
title:
type: string
description:
type: string
group:
$ref: '#/definitions/GroupModel'
index:
type: integer
GroupModel:
type: object
properties:
id:
type: string
title:
type: string
RoleModel:
type: object
properties:
name:
type: string
displayLabel:
type: string
capabilities:
type: array
items:
$ref: '#/definitions/CapabilityModel'
roleGroupName:
type: string
groupShortName:
type: string
assignedUsers:
type: array
items:
type: string
assignedGroups:
type: array
items:
type: string
HoldBulkOperation:
type: object
properties:
@@ -5047,4 +4929,4 @@ definitions:
- SiteConsumer
- SiteCollaborator
- SiteContributor
- SiteManager
- SiteManager

View File

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

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>
@@ -51,8 +51,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<scope>provided</scope>
</dependency>
@@ -70,6 +70,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>

View File

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

View File

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

View File

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

View File

@@ -80,11 +80,6 @@ function runAction(p_params)
{
result.fileExist = true;
}
if (error.indexOf("FolderExistsException") != -1)
{
result.fileExist = true;
result.type = "folder";
}
}
results.push(result);

View File

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

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>
@@ -126,6 +126,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>
@@ -144,7 +144,7 @@
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
<version>7.1.1</version>
<version>7.0.0</version>
</dependency>
<!-- the cxf libs were updated, see dependencyManagement section -->
@@ -247,6 +247,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>gunit</artifactId>

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>
@@ -46,6 +46,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

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

View File

@@ -0,0 +1,141 @@
Instructions for Generating Repository SSL Keystores
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<store password> is the keystore password. The file ${dir.keystore}/ssl-keystore-passwords.properties contains passwords for the SSL keystore,
${dir.keystore}/ssl-truststore-passwords.properties contains passwords for the SSL truststore.
These instructions will create an RSA public/private key pair for the repository with a certificate that has been signed by the Alfresco Certificate Authority (CA).
It will also create a truststore for the repository containing the CA certificate; this will be used to authenticate connections to specific repository
URLs from Solr. It assumes the existence of the Alfresco CA key and certificate to sign the repository certificate; for security reasons these are not generally available.
You can either generate your own CA key and certificate (see instructions below) or use a recognised Certificate Authority such as Verisign. For Alfresco employees the key
and certificate are available in svn.
(i) Generate the repository public/private key pair in a keystore:
$ keytool -genkey -alias ssl.repo -keyalg RSA -keystore ssl.keystore -storetype JCEKS -storepass <store password>
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: Alfresco Repository
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]: Alfresco Software Ltd.
What is the name of your City or Locality?
[Unknown]: Maidenhead
What is the name of your State or Province?
[Unknown]: UK
What is the two-letter country code for this unit?
[Unknown]: GB
Is CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB correct?
[no]: yes
Enter key password for <ssl.repo>
(RETURN if same as keystore password):
(ii) Generate a certificate request for the repository key
$ keytool -keystore ssl.keystore -alias ssl.repo -certreq -file repo.csr -storetype JCEKS -storepass <store password>
(iii) Alfresco CA signs the certificate request, creating a certificate that is valid for 365 days.
$ openssl x509 -CA ca.crt -CAkey ca.key -CAcreateserial -req -in repo.csr -out repo.crt -days 365
Signature ok
subject=/C=GB/ST=UK/L=Maidenhead/O=Alfresco Software Ltd./OU=Unknown/CN=Alfresco Repository
Getting CA Private Key
Enter pass phrase for ca.key:
(iv) Import the Alfresco CA key into the repository key store
$ keytool -import -alias ssl.alfreco.ca -file ca.crt -keystore ssl.keystore -storetype JCEKS -storepass <store password>
Enter keystore password:
Owner: CN=Alfresco CA, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
Issuer: CN=Alfresco CA, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
Serial number: 805ba6dc8f62f8b8
Valid from: Fri Aug 12 13:28:58 BST 2011 until: Mon Aug 09 13:28:58 BST 2021
Certificate fingerprints:
MD5: 4B:45:94:2D:8E:98:E8:12:04:67:AD:AE:48:3C:F5:A0
SHA1: 74:42:22:D0:52:AD:82:7A:FD:37:46:37:91:91:F4:77:89:3A:C9:A3
Signature algorithm name: SHA1withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 08 42 40 DC FE 4A 50 87 05 2B 38 4D 92 70 8E 51 .B@..JP..+8M.p.Q
0010: 4E 38 71 D6 N8q.
]
]
#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 08 42 40 DC FE 4A 50 87 05 2B 38 4D 92 70 8E 51 .B@..JP..+8M.p.Q
0010: 4E 38 71 D6 N8q.
]
[CN=Alfresco CA, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB]
SerialNumber: [ 805ba6dc 8f62f8b8]
]
Trust this certificate? [no]: yes
Certificate was added to keystore
(v) Import the CA-signed repository certificate into the repository keystore
$ keytool -import -alias ssl.repo -file repo.crt -keystore ssl.keystore -storetype JCEKS -storepass <store password>
Enter keystore password:
Certificate reply was installed in keystore
(vi) Convert the repository keystore to a pkcs12 keystore (for use in browsers such as Firefox). Give the pkcs12 key store the key store password 'alfresco'.
keytool -importkeystore -srckeystore ssl.keystore -srcstorepass <keystore password> -srcstoretype JCEKS -srcalias ssl.repo -srckeypass kT9X6oe68t -destkeystore firefox.p12 -deststoretype pkcs12 -deststorepass alfresco -destalias ssl.repo -destkeypass alfresco
(vi) Create a repository truststore containing the Alfresco CA certificate
keytool -import -alias ssl.alfreco.ca -file ca.crt -keystore ssl.keystore -storetype JCEKS -storepass <store password>
keytool -import -alias alfreco.ca -file ca.crt -keystore ssl.truststore -storetype JCEKS -storepass <store password>
(vii) Copy the keystore and truststore to the repository keystore location defined by the property 'dir.keystore'.
(viii) Update the SSL properties i.e. properties starting with the prefixes 'alfresco.encryption.ssl.keystore' and 'alfresco.encryption.ssl.truststore'.
Instructions for Generating a Certificate Authority (CA) Key and Certificate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(i) Generate the CA private key
$ openssl genrsa -des3 -out ca.key 1024
Generating RSA private key, 1024 bit long modulus
..........++++++
..++++++
e is 65537 (0x10001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:
(ii) Generate the CA self-signed certificate
$ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:UK
Locality Name (eg, city) []:Maidenhead
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Alfresco Software Ltd.
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Alfresco CA
Email Address []:

View File

@@ -0,0 +1,58 @@
@rem Please edit the variables below to suit your installation
@rem Note: for an installation created by the Alfresco installer, you only need to edit ALFRESCO_HOME
@rem Alfresco installation directory
set ALFRESCO_HOME=C:\Alfresco-5.2
@rem The directory containing the alfresco keystores, as referenced by keystoreFile and truststoreFile attributes in tomcat\conf\server.xml
set ALFRESCO_KEYSTORE_HOME=%ALFRESCO_HOME%\alf_data\keystore
@rem Java installation directory
set JAVA_HOME=%ALFRESCO_HOME%\java
@rem Location in which new keystore files will be generated
set CERTIFICATE_HOME=%USERPROFILE%
@rem The repository server certificate subject name, as specified in tomcat\conf\tomcat-users.xml with roles="repository"
set REPO_CERT_DNAME=CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
@rem The SOLR client certificate subject name, as specified in tomcat\conf\tomcat-users.xml with roles="repoclient"
set SOLR_CLIENT_CERT_DNAME=CN=Alfresco Repository Client, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
@rem The number of days before the certificate expires
set CERTIFICATE_VALIDITY=36525
@rem Ensure certificate output dir exists
@if not exist "%CERTIFICATE_HOME%" mkdir "%CERTIFICATE_HOME%"
@rem Remove old output files (note they are backed up elsewhere)
@if exist "%CERTIFICATE_HOME%\ssl.keystore" del "%CERTIFICATE_HOME%\ssl.keystore"
@if exist "%CERTIFICATE_HOME%\ssl.truststore" del "%CERTIFICATE_HOME%\ssl.truststore"
@if exist "%CERTIFICATE_HOME%\browser.p12" del "%CERTIFICATE_HOME%\browser.p12"
@if exist "%CERTIFICATE_HOME%\ssl.repo.client.keystore" del "%CERTIFICATE_HOME%\ssl.repo.client.keystore"
@if exist "%CERTIFICATE_HOME%\ssl.repo.client.truststore" del "%CERTIFICATE_HOME%\ssl.repo.client.truststore"
@rem Generate new self-signed certificates for the repository and solr
"%JAVA_HOME%\bin\keytool" -genkeypair -keyalg RSA -dname "%REPO_CERT_DNAME%" -validity %CERTIFICATE_VALIDITY% -alias ssl.repo -keypass kT9X6oe68t -keystore "%CERTIFICATE_HOME%\ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
"%JAVA_HOME%\bin\keytool" -exportcert -alias ssl.repo -file "%CERTIFICATE_HOME%\ssl.repo.crt" -keystore "%CERTIFICATE_HOME%\ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
"%JAVA_HOME%\bin\keytool" -genkeypair -keyalg RSA -dname "%SOLR_CLIENT_CERT_DNAME%" -validity %CERTIFICATE_VALIDITY% -alias ssl.repo.client -keypass kT9X6oe68t -keystore "%CERTIFICATE_HOME%\ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
"%JAVA_HOME%\bin\keytool" -exportcert -alias ssl.repo.client -file "%CERTIFICATE_HOME%\ssl.repo.client.crt" -keystore "%CERTIFICATE_HOME%\ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
@rem Create trust relationship between repository and solr
"%JAVA_HOME%\bin\keytool" -importcert -noprompt -alias ssl.repo.client -file "%CERTIFICATE_HOME%\ssl.repo.client.crt" -keystore "%CERTIFICATE_HOME%\ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
@rem Create trust relationship between repository and itself - used for searches
"%JAVA_HOME%\bin\keytool" -importcert -noprompt -alias ssl.repo -file "%CERTIFICATE_HOME%\ssl.repo.crt" -keystore "%CERTIFICATE_HOME%\ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
@rem Create trust relationship between solr and repository
"%JAVA_HOME%\bin\keytool" -importcert -noprompt -alias ssl.repo -file "%CERTIFICATE_HOME%\ssl.repo.crt" -keystore "%CERTIFICATE_HOME%\ssl.repo.client.truststore" -storetype JCEKS -storepass kT9X6oe68t
@rem Export repository keystore to pkcs12 format for browser compatibility
"%JAVA_HOME%\bin\keytool" -importkeystore -srckeystore "%CERTIFICATE_HOME%\ssl.keystore" -srcstorepass kT9X6oe68t -srcstoretype JCEKS -srcalias ssl.repo -srckeypass kT9X6oe68t -destkeystore "%CERTIFICATE_HOME%\browser.p12" -deststoretype pkcs12 -deststorepass alfresco -destalias ssl.repo -destkeypass alfresco
@rem Ensure keystore dir actually exists
@if not exist "%ALFRESCO_KEYSTORE_HOME%" mkdir "%ALFRESCO_KEYSTORE_HOME%"
@rem Install the new files
copy /Y "%CERTIFICATE_HOME%\ssl.keystore" "%ALFRESCO_KEYSTORE_HOME%\ssl.keystore"
copy /Y "%CERTIFICATE_HOME%\ssl.truststore" "%ALFRESCO_KEYSTORE_HOME%\ssl.truststore"
copy /Y "%CERTIFICATE_HOME%\browser.p12" "%ALFRESCO_KEYSTORE_HOME%\browser.p12"
@echo ****************************************
@echo You must copy the following files to the correct location.
@echo %CERTIFICATE_HOME%\ssl.repo.client.keystore
@echo %CERTIFICATE_HOME%\ssl.repo.client.truststore
@echo eg. for Solr 4 the location is SOLR_HOME\workspace-SpacesStore\conf and SOLR_HOME\archive-SpacesStore\conf
@echo Please ensure that you set dir.keystore=%ALFRESCO_KEYSTORE_HOME% in alfresco-global.properties
@echo ****************************************

View File

@@ -0,0 +1,82 @@
#! /bin/sh
# Please edit the variables below to suit your installation
# Note: for an installation created by the Alfresco installer, you only need to edit ALFRESCO_HOME
# Alfresco installation directory
if [ -z "$ALFRESCO_HOME" ]; then
ALFRESCO_HOME=/opt/alfresco-5.2
echo "Setting ALFRESCO_HOME to $ALFRESCO_HOME"
fi
# The directory containing the alfresco keystores, as referenced by keystoreFile and truststoreFile attributes in tomcat/conf/server.xml
ALFRESCO_KEYSTORE_HOME=$ALFRESCO_HOME/alf_data/keystore
# Location in which new keystore files will be generated
if [ -z "$CERTIFICATE_HOME" ]; then
CERTIFICATE_HOME=$HOME
echo "Certificates will be generated in $CERTIFICATE_HOME and then moved to $ALFRESCO_KEYSTORE_HOME"
fi
# Java installation directory
JAVA_HOME=$ALFRESCO_HOME/java
# The repository server certificate subject name, as specified in tomcat/conf/tomcat-users.xml with roles="repository"
REPO_CERT_DNAME="CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB"
# The SOLR client certificate subject name, as specified in tomcat/conf/tomcat-users.xml with roles="repoclient"
SOLR_CLIENT_CERT_DNAME="CN=Alfresco Repository Client, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB"
# The number of days before the certificate expires
CERTIFICATE_VALIDITY=36525
# Stop
if [ -f "$ALFRESCO_HOME/alfresco.sh" ]; then "$ALFRESCO_HOME/alfresco.sh" stop; fi
# Ensure certificate output dir exists
mkdir -p "$CERTIFICATE_HOME"
# Remove old output files (note they are backed up elsewhere)
if [ -f "$CERTIFICATE_HOME/ssl.keystore" ]; then rm "$CERTIFICATE_HOME/ssl.keystore"; fi
if [ -f "$CERTIFICATE_HOME/ssl.truststore" ]; then rm "$CERTIFICATE_HOME/ssl.truststore"; fi
if [ -f "$CERTIFICATE_HOME/browser.p12" ]; then rm "$CERTIFICATE_HOME/browser.p12"; fi
if [ -f "$CERTIFICATE_HOME/ssl.repo.client.keystore" ]; then rm "$CERTIFICATE_HOME/ssl.repo.client.keystore"; fi
if [ -f "$CERTIFICATE_HOME/ssl.repo.client.truststore" ]; then rm "$CERTIFICATE_HOME/ssl.repo.client.truststore"; fi
# Generate new self-signed certificates for the repository and solr
"$JAVA_HOME/bin/keytool" -genkeypair -keyalg RSA -dname "$REPO_CERT_DNAME" -validity $CERTIFICATE_VALIDITY -alias ssl.repo -keypass kT9X6oe68t -keystore "$CERTIFICATE_HOME/ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
"$JAVA_HOME/bin/keytool" -exportcert -alias ssl.repo -file "$CERTIFICATE_HOME/ssl.repo.crt" -keystore "$CERTIFICATE_HOME/ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
"$JAVA_HOME/bin/keytool" -genkeypair -keyalg RSA -dname "$SOLR_CLIENT_CERT_DNAME" -validity $CERTIFICATE_VALIDITY -alias ssl.repo.client -keypass kT9X6oe68t -keystore "$CERTIFICATE_HOME/ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
"$JAVA_HOME/bin/keytool" -exportcert -alias ssl.repo.client -file "$CERTIFICATE_HOME/ssl.repo.client.crt" -keystore "$CERTIFICATE_HOME/ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
# Create trust relationship between repository and solr
"$JAVA_HOME/bin/keytool" -importcert -noprompt -alias ssl.repo.client -file "$CERTIFICATE_HOME/ssl.repo.client.crt" -keystore "$CERTIFICATE_HOME/ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
# Create trust relationship between repository and itself - used for searches
"$JAVA_HOME/bin/keytool" -importcert -noprompt -alias ssl.repo -file "$CERTIFICATE_HOME/ssl.repo.crt" -keystore "$CERTIFICATE_HOME/ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
# Create trust relationship between solr and repository
"$JAVA_HOME/bin/keytool" -importcert -noprompt -alias ssl.repo -file "$CERTIFICATE_HOME/ssl.repo.crt" -keystore "$CERTIFICATE_HOME/ssl.repo.client.truststore" -storetype JCEKS -storepass kT9X6oe68t
# Export repository keystore to pkcs12 format for browser compatibility
"$JAVA_HOME/bin/keytool" -importkeystore -srckeystore "$CERTIFICATE_HOME/ssl.keystore" -srcstorepass kT9X6oe68t -srcstoretype JCEKS -srcalias ssl.repo -srckeypass kT9X6oe68t -destkeystore "$CERTIFICATE_HOME/browser.p12" -deststoretype pkcs12 -deststorepass alfresco -destalias ssl.repo -destkeypass alfresco
# Ensure keystore dir actually exists
mkdir -p "$ALFRESCO_KEYSTORE_HOME"
# Back up old files
cp "$ALFRESCO_KEYSTORE_HOME/ssl.keystore" "$ALFRESCO_KEYSTORE_HOME/ssl.keystore.old"
cp "$ALFRESCO_KEYSTORE_HOME/ssl.truststore" "$ALFRESCO_KEYSTORE_HOME/ssl.truststore.old"
cp "$ALFRESCO_KEYSTORE_HOME/browser.p12" "$ALFRESCO_KEYSTORE_HOME/browser.p12.old"
# Install the new files
cp "$CERTIFICATE_HOME/ssl.keystore" "$ALFRESCO_KEYSTORE_HOME/ssl.keystore"
cp "$CERTIFICATE_HOME/ssl.truststore" "$ALFRESCO_KEYSTORE_HOME/ssl.truststore"
cp "$CERTIFICATE_HOME/browser.p12" "$ALFRESCO_KEYSTORE_HOME/browser.p12"
echo " "
echo "*******************************************"
echo "You must copy the following files to the correct location."
echo " "
echo " $CERTIFICATE_HOME/ssl.repo.client.keystore"
echo " $CERTIFICATE_HOME/ssl.repo.client.truststore"
echo " eg. for Solr 4 the location is SOLR_HOME/workspace-SpacesStore/conf/ and SOLR_HOME/archive-SpacesStore/conf/"
echo " "
echo "$ALFRESCO_KEYSTORE_HOME/browser.p12 has also been generated."
echo " "
echo "Please ensure that you set dir.keystore=$ALFRESCO_KEYSTORE_HOME in alfresco-global.properties"
echo "*******************************************"

View File

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

View File

@@ -1,5 +1,6 @@
# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
FROM alfresco/alfresco-base-tomcat:tomcat10-jre17-rockylinux9@sha256:00d89fb84bda7bb37c17b0117adb2cfe4f7cbddcd6c1e42b0a67ea8dbb41a734
FROM alfresco/alfresco-base-tomcat:tomcat10-jre17-rockylinux9@sha256:9622418e142fb4fe1c5320666ad61ea292bc5c98f3dd0b550b6add33d18f659f
# Set default docker_context.
ARG resource_path=target

View File

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

View File

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

View File

@@ -1,3 +1,3 @@
SOLR6_TAG=2.0.16
SOLR6_TAG=2.0.15
POSTGRES_TAG=16.6
ACTIVEMQ_TAG=5.18.3-jre17-rockylinux8

View File

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

View File

@@ -49,6 +49,5 @@ then
echo "Docker Compose started ok"
else
echo "Docker Compose failed to start" >&2
docker compose ${DOCKER_COMPOSES} logs --tail 200
exit 1
fi
fi

View File

@@ -27,7 +27,7 @@
## Synopsis
**TAS**( **T**est **A**utomation **S**ystem)- **CMIS** is the project that handles the automated tests related only to CMIS API integrated with Alfresco One [Alfresco CMIS API](https://support.hyland.com/access?dita:id=kvf1721390177551&vrm_version=25.2).
**TAS**( **T**est **A**utomation **S**ystem)- **CMIS** is the project that handles the automated tests related only to CMIS API integrated with Alfresco One [Alfresco CMIS API](https://support.hyland.com/r/Alfresco/Alfresco-Content-Services/23.4/Alfresco-Content-Services/Develop/Reference/CMIS-API).
It is based on Apache Maven, compatible with major IDEs and is using also Spring capabilities for dependency injection.

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<organization>
@@ -68,6 +68,16 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

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

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<developers>
@@ -36,6 +36,11 @@
<artifactId>jakarta.mail-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<developers>
@@ -44,6 +44,18 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<properties>
@@ -17,7 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<rest.api.explorer.branch>master</rest.api.explorer.branch>
<httpclient-osgi-version>4.5.6</httpclient-osgi-version>
<commons-lang3.version>3.18.0</commons-lang3.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<scribejava-apis.version>8.3.3</scribejava-apis.version>
<java.version>17</java.version>
</properties>
@@ -79,6 +79,18 @@
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
@@ -159,14 +171,14 @@
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.25</version>
<version>3.0.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-json-->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-json</artifactId>
<version>3.0.25</version>
<version>3.0.22</version>
</dependency>
<dependency>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -747,7 +747,7 @@ public class CreateRulesTests extends RulesRestTest
.createSingleRule(ruleModel);
restClient.assertStatusCodeIs(NOT_FOUND);
restClient.assertLastError().containsSummary("Destination folder having Id: non-existent-node no longer exists. Please update your rule definition.");
restClient.assertLastError().containsSummary("The entity with id: non-existent-node was not found");
}
/**

View File

@@ -1,95 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2025 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.search;
import static org.testng.Assert.*;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.http.HttpStatus;
import org.testng.annotations.Test;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.model.RestNodeModel;
import org.alfresco.utility.RetryOperation;
import org.alfresco.utility.Utility;
import org.alfresco.utility.model.ContentModel;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.TestGroup;
import org.alfresco.utility.model.UserModel;
import org.alfresco.utility.testrail.ExecutionType;
import org.alfresco.utility.testrail.annotation.TestRail;
public class NodeContentTest extends RestTest
{
@TestRail(section = {TestGroup.REST_API,
TestGroup.SEARCH}, executionType = ExecutionType.SANITY, description = "Check basic functionality of GET queries/sites")
@Test(groups = {TestGroup.REST_API, TestGroup.RATINGS, TestGroup.CORE})
public void testNodeContent() throws Exception
{
UserModel adminUser = dataContent.getAdminUser();
final String fileName = "nodecontent.pdf";
final String term = "babekyrtso";
FileModel fileModel = FileModel.getFileModelBasedOnTestDataFile(fileName);
restClient.authenticateUser(adminUser)
.configureRequestSpec()
.addMultiPart("filedata", fileModel.toFile());
RestNodeModel node = restClient.authenticateUser(adminUser).withCoreAPI().usingNode(ContentModel.my()).createNode();
restClient.assertStatusCodeIs(HttpStatus.CREATED);
SearchRequest query = new SearchRequest();
RestRequestQueryModel queryModel = new RestRequestQueryModel();
queryModel.setLanguage("afts");
queryModel.setQuery(term);
query.setQuery(queryModel);
RetryOperation op = () -> {
List<SearchNodeModel> entries = restClient.authenticateUser(adminUser)
.withSearchAPI()
.search(query).getEntries();
assertFalse(CollectionUtils.isEmpty(entries), "Search results should not be empty");
boolean fileFound = entries.stream()
.map(SearchNodeModel::getModel)
.anyMatch(e -> fileName.equals(e.getName()));
assertTrue(fileFound, "Search results should contain the file: " + fileName);
restClient.assertStatusCodeIs(HttpStatus.OK);
};
Utility.sleep(300, 100000, op);
restClient.authenticateUser(adminUser)
.withCoreAPI()
.usingNode(ContentModel.my())
.deleteNode(node);
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
}
}

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

@@ -15,7 +15,6 @@
<package name="org.alfresco.rest.people.*"/>
<package name="org.alfresco.rest.queries.*"/>
<package name="org.alfresco.rest.ratings.*"/>
<package name="org.alfresco.rest.search.*"/>
</packages>
</test>
</suite>

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<developers>
@@ -31,6 +31,11 @@
<artifactId>webdav</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -0,0 +1 @@
com.epam.reportportal.testng.ReportPortalTestNGListener

View File

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

View File

@@ -4,7 +4,7 @@
<!-- Resource defaultTransactionIsolation="-1" defaultAutoCommit="false" maxActive="100" initialSize="10" password="alfresco" username="alfresco" url="jdbc:mysql:///alfresco" driverClassName="org.gjt.mm.mysql.Driver" type="javax.sql.DataSource" auth="Container" name="jdbc/dataSource"/-->
<Environment override="false" type="java.lang.Boolean" name="properties/startup.enable" description="A flag that globally enables or disables startup of the major Alfresco subsystems." value="true"/>
<Environment override="false" type="java.lang.String" name="properties/dir.root" description="The filesystem directory below which content and index data is stored. Should be on a shared disk if this is a clustered installation."/>
<Environment override="false" type="java.lang.String" name="properties/hibernate.dialect" description="The fully qualified name of a org.hibernate.dialect.Dialect subclass that allows Hibernate to generate SQL optimized for a particular relational database. Choose from org.hibernate.dialect.DerbyDialect, org.hibernate.dialect.MySQLInnoDBDialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect, org.alfresco.repo.domain.hibernate.dialect.SQLServerDialect, org.hibernate.dialect.PostgreSQLDialect"/>
<Environment override="false" type="java.lang.String" name="properties/hibernate.dialect" description="The fully qualified name of a org.hibernate.dialect.Dialect subclass that allows Hibernate to generate SQL optimized for a particular relational database. Choose from org.hibernate.dialect.DerbyDialect, org.hibernate.dialect.MySQLInnoDBDialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect, org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect, org.hibernate.dialect.PostgreSQLDialect"/>
<Environment override="false" type="java.lang.String" name="properties/hibernate.query.substitutions" description="Mapping from tokens in Hibernate queries to SQL tokens. For PostgreSQL, set this to &quot;true TRUE, false FALSE&quot;."/>
<Environment override="false" type="java.lang.Boolean" name="properties/hibernate.jdbc.use_get_generated_keys" description="Enable use of JDBC3 PreparedStatement.getGeneratedKeys() to retrieve natively generated keys after insert. Requires JDBC3+ driver. Set to false if your driver has problems with the Hibernate identifier generators. By default, tries to determine the driver capabilities using connection metadata."/>
<Environment override="false" type="java.lang.String" name="properties/hibernate.default_schema" description="Qualify unqualified table names with the given schema/tablespace in generated SQL. It may be necessary to set this when the target database has more than one schema."/>

View File

@@ -500,7 +500,7 @@
org.hibernate.dialect.MySQLInnoDBDialect,
org.alfresco.repo.domain.hibernate.dialect.AlfrescoOracle9Dialect,
org.alfresco.repo.domain.hibernate.dialect.AlfrescoSybaseAnywhereDialect,
org.alfresco.repo.domain.hibernate.dialect.SQLServerDialect, org.hibernate.dialect.PostgreSQLDialect</description>
org.alfresco.repo.domain.hibernate.dialect.AlfrescoSQLServerDialect, org.hibernate.dialect.PostgreSQLDialect</description>
<env-entry-name>properties/hibernate.dialect</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value/> <!-- Empty value included for JBoss compatibility -->

112
pom.xml
View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name>
@@ -24,7 +24,7 @@
<properties>
<acs.version.major>25</acs.version.major>
<acs.version.minor>3</acs.version.minor>
<acs.version.minor>2</acs.version.minor>
<acs.version.revision>0</acs.version.revision>
<acs.version.label />
<amp.min.version>${acs.version.major}.0.0</amp.min.version>
@@ -51,42 +51,41 @@
<dependency.alfresco-server-root.version>7.0.2</dependency.alfresco-server-root.version>
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
<dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.2.2-A.4</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.2.2-A.2</dependency.alfresco-transform-service.version>
<dependency.alfresco-transform-core.version>5.1.7</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.7</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>1.0.9</dependency.acs-event-model.version>
<dependency.acs-event-model.version>1.0.2</dependency.acs-event-model.version>
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
<dependency.spring.version>6.2.8</dependency.spring.version>
<dependency.spring-security.version>6.3.9</dependency.spring-security.version>
<dependency.spring.version>6.2.2</dependency.spring.version>
<dependency.spring-security.version>6.3.7</dependency.spring-security.version>
<dependency.antlr.version>3.5.3</dependency.antlr.version>
<dependency.jackson.version>2.17.2</dependency.jackson.version>
<dependency.cxf.version>4.1.2</dependency.cxf.version>
<dependency.cxf.version>4.1.0</dependency.cxf.version>
<dependency.opencmis.version>1.0.0-jakarta-1</dependency.opencmis.version>
<dependency.webscripts.version>10.2</dependency.webscripts.version>
<dependency.bouncycastle.version>1.81</dependency.bouncycastle.version>
<dependency.mockito-core.version>5.18.0</dependency.mockito-core.version>
<dependency.webscripts.version>10.0</dependency.webscripts.version>
<dependency.bouncycastle.version>1.79</dependency.bouncycastle.version>
<dependency.mockito-core.version>5.14.1</dependency.mockito-core.version>
<dependency.assertj.version>3.27.3</dependency.assertj.version>
<dependency.org-json.version>20250517</dependency.org-json.version>
<dependency.org-json.version>20240303</dependency.org-json.version>
<dependency.commons-dbcp.version>2.12.0</dependency.commons-dbcp.version>
<dependency.commons-io.version>2.20.0</dependency.commons-io.version>
<dependency.gson.version>2.13.1</dependency.gson.version>
<dependency.commons-io.version>2.18.0</dependency.commons-io.version>
<dependency.gson.version>2.12.1</dependency.gson.version>
<dependency.guava.version>33.3.1-jre</dependency.guava.version>
<dependency.httpclient.version>4.5.14</dependency.httpclient.version>
<dependency.httpcore.version>4.4.16</dependency.httpcore.version>
<dependency.httpcomponents-httpclient5.version>5.5</dependency.httpcomponents-httpclient5.version>
<dependency.httpcomponents-httpcore5.version>5.3.4</dependency.httpcomponents-httpcore5.version>
<dependency.httpcomponents-httpcore5-h2.version>5.3.4</dependency.httpcomponents-httpcore5-h2.version>
<dependency.httpcomponents-httpclient5.version>5.4.1</dependency.httpcomponents-httpclient5.version>
<dependency.httpcomponents-httpcore5.version>5.3.3</dependency.httpcomponents-httpcore5.version>
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>2.0.16</dependency.slf4j.version>
<dependency.log4j.version>2.25.1</dependency.log4j.version>
<dependency.groovy.version>3.0.25</dependency.groovy.version>
<dependency.tika.version>3.2.3</dependency.tika.version>
<dependency.log4j.version>2.24.3</dependency.log4j.version>
<dependency.groovy.version>3.0.23</dependency.groovy.version>
<dependency.tika.version>2.9.2</dependency.tika.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version>
<dependency.poi.version>5.4.0</dependency.poi.version>
<dependency.poi.version>5.3.0</dependency.poi.version>
<dependency.jboss.logging.version>3.5.0.Final</dependency.jboss.logging.version>
<dependency.camel.version>4.11.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
<dependency.camel.version>4.6.0</dependency.camel.version> <!-- when bumping this version, please keep track/sync with included netty.io dependencies -->
<dependency.netty.version>4.1.118.Final</dependency.netty.version> <!-- must be in sync with camels transitive dependencies, e.g.: netty-common -->
<dependency.activemq.version>5.18.6</dependency.activemq.version>
<dependency.apache-compress.version>1.27.1</dependency.apache-compress.version>
@@ -115,19 +114,19 @@
<dependency.jakarta-json-path.version>2.9.0</dependency.jakarta-json-path.version>
<dependency.json-smart.version>2.5.2</dependency.json-smart.version>
<alfresco.googledrive.version>4.1.0</alfresco.googledrive.version>
<alfresco.aos-module.version>3.3.0</alfresco.aos-module.version>
<alfresco.api-explorer.version>25.2.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.aos-module.version>3.2.0</alfresco.aos-module.version>
<alfresco.api-explorer.version>25.1.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
<license-maven-plugin.version>2.4.0</license-maven-plugin.version>
<spotless-plugin.version>2.45.0</spotless-plugin.version>
<spotless-plugin.version>2.44.2</spotless-plugin.version>
<dependency.postgresql.version>42.7.5</dependency.postgresql.version>
<dependency.mysql.version>8.0.30</dependency.mysql.version>
<dependency.mysql-image.version>8</dependency.mysql-image.version>
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
<dependency.tas-utility.version>5.0.2</dependency.tas-utility.version>
<dependency.rest-assured.version>5.5.5</dependency.rest-assured.version>
<dependency.rest-assured.version>5.5.0</dependency.rest-assured.version>
<dependency.tas-email.version>2.0.0</dependency.tas-email.version>
<dependency.tas-webdav.version>1.21</dependency.tas-webdav.version>
<dependency.tas-ftp.version>1.19</dependency.tas-ftp.version>
@@ -154,7 +153,7 @@
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
<url>https://github.com/Alfresco/alfresco-community-repo</url>
<tag>25.3.0.43</tag>
<tag>HEAD</tag>
</scm>
<distributionManagement>
@@ -170,12 +169,6 @@
<dependencyManagement>
<dependencies>
<!-- v1.10 has 0BSD license it must be consulted with Legal -->
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.9</version>
</dependency>
<!-- Jakarta... -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
@@ -407,20 +400,15 @@
<artifactId>httpcore5</artifactId>
<version>${dependency.httpcomponents-httpcore5.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-h2</artifactId>
<version>${dependency.httpcomponents-httpcore5-h2.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.5</version>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.11.0</version>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -428,9 +416,9 @@
<version>1.18.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.18.0</version>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
@@ -450,8 +438,8 @@
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-fileupload2-jakarta-servlet6</artifactId>
<version>2.0.0-M4</version>
<artifactId>commons-fileupload2-jakarta</artifactId>
<version>2.0.0-M1</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
@@ -714,13 +702,13 @@
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.5.8</version>
<version>1.5.5</version>
</dependency>
<!-- upgrade dependency from TIKA -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.21.1</version>
<version>1.18.1</version>
</dependency>
<!-- upgrade dependency from TIKA -->
<dependency>
@@ -731,7 +719,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.9.0</version>
<version>1.14.0</version>
</dependency>
<!-- upgrade dependency from TIKA -->
<dependency>
@@ -804,7 +792,7 @@
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.14.0</version>
<version>2.13.1</version>
</dependency>
<!-- provided dependencies -->
@@ -834,6 +822,18 @@
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>gunit</artifactId>
@@ -949,7 +949,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
<version>1.18.36</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -1006,7 +1006,7 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.46.0</version>
<version>0.45.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
@@ -1087,7 +1087,7 @@
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<version>1.10.20</version>
<version>1.10.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -1131,10 +1131,16 @@
<exclude>jakarta.xml.soap:jakarta.xml.soap-api:(, 2.0.1)</exclude>
<exclude>jakarta.jws:jakarta.jws-api:(, 3.0.0)</exclude>
<!-- Enforce ban bouncycastle dependencies other than specified under <includes> section-->
<exclude>org.bouncycastle:(,1.81)</exclude>
<exclude>org.bouncycastle</exclude>
<!-- Enforce one version of Jaxb-->
<exclude>com.sun.xml.bind</exclude>
</excludes>
<includes>
<include>org.bouncycastle:bcprov-jdk18on:[1.78.1,)</include>
<include>org.bouncycastle:bcmail-jdk18on:[1.78.1,)</include>
<include>org.bouncycastle:bcpkix-jdk18on:[1.78.1,)</include>
<include>org.bouncycastle:bcutil-jdk18on:[1.78.1,)</include>
</includes>
</bannedDependencies>
</rules>
<fail>true</fail>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId>
<version>25.3.0.43</version>
<version>25.2.0.3-SNAPSHOT</version>
</parent>
<dependencies>
@@ -45,7 +45,7 @@
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>4.0.4</version>
<version>4.0.3</version>
</dependency>
<!-- newer version, see REPO-3133 -->
<dependency>
@@ -66,6 +66,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.epam.reportportal</groupId>
<artifactId>agent-java-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -46,7 +46,7 @@ import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.external.ExternalUserAuthenticator;
import org.alfresco.repo.security.authentication.external.AdminConsoleAuthenticator;
import org.alfresco.repo.security.authentication.external.RemoteUserMapper;
import org.alfresco.repo.web.auth.AuthenticationListener;
import org.alfresco.repo.web.auth.TicketCredentials;
@@ -71,11 +71,9 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
protected RemoteUserMapper remoteUserMapper;
protected AuthenticationComponent authenticationComponent;
protected ExternalUserAuthenticator adminConsoleAuthenticator;
protected ExternalUserAuthenticator webScriptsHomeAuthenticator;
protected AdminConsoleAuthenticator adminConsoleAuthenticator;
private boolean alwaysAllowBasicAuthForAdminConsole = true;
private boolean alwaysAllowBasicAuthForWebScriptsHome = true;
List<String> adminConsoleScriptFamilies;
long getRemoteUserTimeoutMilliseconds = GET_REMOTE_USER_TIMEOUT_MILLISECONDS_DEFAULT;
@@ -99,16 +97,6 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
this.alwaysAllowBasicAuthForAdminConsole = alwaysAllowBasicAuthForAdminConsole;
}
public boolean isAlwaysAllowBasicAuthForWebScriptsHome()
{
return alwaysAllowBasicAuthForWebScriptsHome;
}
public void setAlwaysAllowBasicAuthForWebScriptsHome(boolean alwaysAllowBasicAuthForWebScriptsHome)
{
this.alwaysAllowBasicAuthForWebScriptsHome = alwaysAllowBasicAuthForWebScriptsHome;
}
public List<String> getAdminConsoleScriptFamilies()
{
return adminConsoleScriptFamilies;
@@ -130,17 +118,11 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
}
public void setAdminConsoleAuthenticator(
ExternalUserAuthenticator adminConsoleAuthenticator)
AdminConsoleAuthenticator adminConsoleAuthenticator)
{
this.adminConsoleAuthenticator = adminConsoleAuthenticator;
}
public void setWebScriptsHomeAuthenticator(
ExternalUserAuthenticator webScriptsHomeAuthenticator)
{
this.webScriptsHomeAuthenticator = webScriptsHomeAuthenticator;
}
@Override
public Authenticator create(WebScriptServletRequest req, WebScriptServletResponse res)
{
@@ -154,8 +136,6 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
*/
public class RemoteUserAuthenticator extends BasicHttpAuthenticator
{
private static final String WEB_SCRIPTS_BASE_PATH = "org/springframework/extensions/webscripts";
public RemoteUserAuthenticator(WebScriptServletRequest req, WebScriptServletResponse res, AuthenticationListener listener)
{
super(req, res, listener);
@@ -176,47 +156,24 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
{
if (servletReq.getServiceMatch() != null &&
isAdminConsole(servletReq.getServiceMatch().getWebScript()) && isAdminConsoleAuthenticatorActive())
isAdminConsoleWebScript(servletReq.getServiceMatch().getWebScript()) && isAdminConsoleAuthenticatorActive())
{
userId = getAdminConsoleUser();
}
else if (servletReq.getServiceMatch() != null &&
isWebScriptsHome(servletReq.getServiceMatch().getWebScript()) && isWebScriptsHomeAuthenticatorActive())
{
userId = getWebScriptsHomeUser();
}
if (userId == null)
{
if (isAlwaysAllowBasicAuthForAdminConsole())
{
boolean shouldUseTimeout = shouldUseTimeoutForAdminAccessingAdminConsole(required, isGuest);
final boolean useTimeoutForAdminAccessingAdminConsole = shouldUseTimeoutForAdminAccessingAdminConsole(required, isGuest);
if (shouldUseTimeout && isBasicAuthHeaderPresentForAdmin())
if (useTimeoutForAdminAccessingAdminConsole && isBasicAuthHeaderPresentForAdmin())
{
return callBasicAuthForAdminConsoleOrWebScriptsHomeAccess(required, isGuest);
return callBasicAuthForAdminConsoleAccess(required, isGuest);
}
try
{
userId = getRemoteUserWithTimeout(shouldUseTimeout);
}
catch (AuthenticationTimeoutException e)
{
// return basic auth challenge
return false;
}
}
else if (isAlwaysAllowBasicAuthForWebScriptsHome())
{
boolean shouldUseTimeout = shouldUseTimeoutForAdminAccessingWebScriptsHome(required, isGuest);
if (shouldUseTimeout && isBasicAuthHeaderPresentForAdmin())
{
return callBasicAuthForAdminConsoleOrWebScriptsHomeAccess(required, isGuest);
}
try
{
userId = getRemoteUserWithTimeout(shouldUseTimeout);
userId = getRemoteUserWithTimeout(useTimeoutForAdminAccessingAdminConsole);
}
catch (AuthenticationTimeoutException e)
{
@@ -295,63 +252,38 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
authenticated = super.authenticate(required, isGuest);
}
}
if (!authenticated && servletReq.getServiceMatch() != null)
if (!authenticated && servletReq.getServiceMatch() != null &&
isAdminConsoleWebScript(servletReq.getServiceMatch().getWebScript()) && isAdminConsoleAuthenticatorActive())
{
WebScript webScript = servletReq.getServiceMatch().getWebScript();
if (isAdminConsole(webScript) && isAdminConsoleAuthenticatorActive())
{
adminConsoleAuthenticator.requestAuthentication(
this.servletReq.getHttpServletRequest(),
this.servletRes.getHttpServletResponse());
}
else if (isWebScriptsHome(webScript)
&& isWebScriptsHomeAuthenticatorActive())
{
webScriptsHomeAuthenticator.requestAuthentication(
this.servletReq.getHttpServletRequest(),
this.servletRes.getHttpServletResponse());
}
adminConsoleAuthenticator.requestAuthentication(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
}
return authenticated;
}
private boolean callBasicAuthForAdminConsoleOrWebScriptsHomeAccess(RequiredAuthentication required, boolean isGuest)
private boolean callBasicAuthForAdminConsoleAccess(RequiredAuthentication required, boolean isGuest)
{
// return REST call, after a timeout/basic auth challenge
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("An Admin Console or WebScripts Home request has come in with Basic Auth headers present for an admin user.");
LOGGER.trace("An Admin Console request has come in with Basic Auth headers present for an admin user.");
}
// In order to prompt for another password, in case it was not entered correctly,
// the output of this method should be returned by the calling "authenticate" method;
// This would also mean, that once the admin basic auth header is present,
// the authentication chain will not be used for access
// the authentication chain will not be used for the admin console access
return super.authenticate(required, isGuest);
}
private boolean shouldUseTimeoutForAdminAccessingAdminConsole(RequiredAuthentication required, boolean isGuest)
{
boolean adminConsoleTimeout = RequiredAuthentication.admin.equals(required) && !isGuest &&
servletReq.getServiceMatch() != null && isAdminConsole(servletReq.getServiceMatch().getWebScript());
boolean useTimeoutForAdminAccessingAdminConsole = RequiredAuthentication.admin.equals(required) && !isGuest &&
servletReq.getServiceMatch() != null && isAdminConsoleWebScript(servletReq.getServiceMatch().getWebScript());
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("Should ensure that the admins can login with basic auth: " + adminConsoleTimeout);
LOGGER.trace("Should ensure that the admins can login with basic auth: " + useTimeoutForAdminAccessingAdminConsole);
}
return adminConsoleTimeout;
}
private boolean shouldUseTimeoutForAdminAccessingWebScriptsHome(RequiredAuthentication required, boolean isGuest)
{
boolean adminWebScriptsHomeTimeout = RequiredAuthentication.admin.equals(required) && !isGuest &&
servletReq.getServiceMatch() != null && isWebScriptsHome(servletReq.getServiceMatch().getWebScript());
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("Should ensure that the admins can login with basic auth: " + adminWebScriptsHomeTimeout);
}
return adminWebScriptsHomeTimeout;
return useTimeoutForAdminAccessingAdminConsole;
}
private boolean isRemoteUserMapperActive()
@@ -364,12 +296,7 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
return adminConsoleAuthenticator != null && (!(adminConsoleAuthenticator instanceof ActivateableBean) || ((ActivateableBean) adminConsoleAuthenticator).isActive());
}
private boolean isWebScriptsHomeAuthenticatorActive()
{
return webScriptsHomeAuthenticator != null && (!(webScriptsHomeAuthenticator instanceof ActivateableBean) || ((ActivateableBean) webScriptsHomeAuthenticator).isActive());
}
protected boolean isAdminConsole(WebScript webScript)
protected boolean isAdminConsoleWebScript(WebScript webScript)
{
if (webScript == null || adminConsoleScriptFamilies == null || webScript.getDescription() == null
|| webScript.getDescription().getFamilys() == null)
@@ -383,7 +310,7 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
}
// intersect the "family" sets defined
Set<String> families = new HashSet<>(webScript.getDescription().getFamilys());
Set<String> families = new HashSet<String>(webScript.getDescription().getFamilys());
families.retainAll(adminConsoleScriptFamilies);
final boolean isAdminConsole = !families.isEmpty();
@@ -395,23 +322,6 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
return isAdminConsole;
}
protected boolean isWebScriptsHome(WebScript webScript)
{
if (webScript == null || webScript.toString() == null)
{
return false;
}
boolean isWebScriptsHome = webScript.toString().startsWith(WEB_SCRIPTS_BASE_PATH);
if (LOGGER.isTraceEnabled() && isWebScriptsHome)
{
LOGGER.trace("Detected a WebScripts Home webscript: " + webScript);
}
return isWebScriptsHome;
}
protected String getRemoteUserWithTimeout(boolean useTimeout) throws AuthenticationTimeoutException
{
if (!useTimeout)
@@ -507,21 +417,7 @@ public class RemoteUserAuthenticatorFactory extends BasicHttpAuthenticatorFactor
if (isRemoteUserMapperActive())
{
userId = adminConsoleAuthenticator.getUserId(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
}
logRemoteUserID(userId);
return userId;
}
protected String getWebScriptsHomeUser()
{
String userId = null;
if (isRemoteUserMapperActive())
{
userId = webScriptsHomeAuthenticator.getUserId(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
userId = adminConsoleAuthenticator.getAdminConsoleUser(this.servletReq.getHttpServletRequest(), this.servletRes.getHttpServletResponse());
}
logRemoteUserID(userId);

View File

@@ -30,7 +30,7 @@ import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload2.core.FileItemInput;
import org.apache.commons.fileupload2.core.FileItemInputIterator;
import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletFileUpload;
import org.apache.commons.fileupload2.jakarta.JakartaServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Status;

Some files were not shown because too many files have changed in this diff Show More