mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-9399 Add AGS Roles V1 API (Read) (#3350)
Co-authored-by: SatyamSah5 <satyam.sah25@rediffmail.com> Co-authored-by: bsayan2 <sayan.bhattacharya@hyland.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* #%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)
|
||||
{}
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* #%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)
|
||||
{}
|
@@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* #%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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
/*-
|
||||
* #%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>
|
||||
{}
|
@@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* #%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;
|
||||
}
|
@@ -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_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");
|
||||
|
||||
public final String roleId;
|
||||
public final String displayName;
|
||||
|
@@ -43,6 +43,7 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -303,4 +304,39 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -93,6 +93,7 @@ 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;
|
||||
@@ -127,6 +128,10 @@ 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";
|
||||
|
||||
/**
|
||||
|
@@ -28,6 +28,7 @@ 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;
|
||||
@@ -56,19 +57,27 @@ 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;
|
||||
@@ -76,6 +85,9 @@ 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;
|
||||
@@ -87,6 +99,7 @@ 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) */
|
||||
@@ -266,7 +279,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
|
||||
@@ -314,7 +327,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
|
||||
@@ -594,4 +607,171 @@ 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());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -78,6 +78,11 @@
|
||||
<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" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rm.rest.api.holds.HoldsEntityResource" >
|
||||
<property name="holdService" ref="HoldService" />
|
||||
<property name="apiUtils" ref="apiUtils" />
|
||||
@@ -228,6 +233,11 @@
|
||||
<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>
|
||||
@@ -280,4 +290,4 @@
|
||||
<property name="beanName" value="restJsonModule" />
|
||||
<property name="extendingBeanName" value="rm.restJsonModule" />
|
||||
</bean>
|
||||
</beans>
|
||||
</beans>
|
||||
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* #%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);
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* #%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.model.RecordsManagementModel;
|
||||
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 FilePlanComponentsApiUtils apiUtils;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
mandatory("rmRoles", this.rmRoles);
|
||||
mandatory("apiUtils", this.apiUtils);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<RoleModel> readAll(String filePlanId, Parameters params)
|
||||
{
|
||||
NodeRef filePlanNodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, RecordsManagementModel.TYPE_FILE_PLAN);
|
||||
return rmRoles.getRoles(filePlanNodeRef, params);
|
||||
}
|
||||
|
||||
public void setRmRoles(RMRoles rmRoles)
|
||||
{
|
||||
this.rmRoles = rmRoles;
|
||||
}
|
||||
|
||||
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
|
||||
{
|
||||
this.apiUtils = apiUtils;
|
||||
}
|
||||
}
|
@@ -30,6 +30,7 @@ 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;
|
||||
@@ -42,12 +43,15 @@ 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;
|
||||
@@ -55,7 +59,9 @@ 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;
|
||||
@@ -66,6 +72,7 @@ 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;
|
||||
@@ -696,6 +703,36 @@ 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
|
||||
*
|
||||
|
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* #%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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* #%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)
|
||||
{}
|
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* #%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)
|
||||
{}
|
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* #%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)
|
||||
{}
|
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* #%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)
|
||||
{}
|
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* #%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;
|
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* #%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"));
|
||||
}
|
||||
}
|
@@ -4929,4 +4929,4 @@ definitions:
|
||||
- SiteConsumer
|
||||
- SiteCollaborator
|
||||
- SiteContributor
|
||||
- SiteManager
|
||||
- SiteManager
|
||||
|
Reference in New Issue
Block a user