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:
Damian Ujma
2025-05-16 18:55:45 +02:00
committed by GitHub
parent c4dcef73e1
commit ee5e34ca32
21 changed files with 1233 additions and 5 deletions

View File

@@ -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)
{}

View File

@@ -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)
{}

View File

@@ -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);
}
}

View File

@@ -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>
{}

View File

@@ -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;
}

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_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;

View File

@@ -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);
}
}

View File

@@ -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";
/**

View File

@@ -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());
});
}
}

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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
*

View File

@@ -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;
}
}
}

View File

@@ -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)
{}

View File

@@ -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)
{}

View File

@@ -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)
{}

View File

@@ -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)
{}

View File

@@ -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;

View File

@@ -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"));
}
}

View File

@@ -4929,4 +4929,4 @@ definitions:
- SiteConsumer
- SiteCollaborator
- SiteContributor
- SiteManager
- SiteManager