From a7e63a1a811810a7b15e6dc70953b2245c0a924e Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Wed, 18 Mar 2026 16:15:07 -0700 Subject: [PATCH] Stop passing SecurityPolicy parameter to Role.isApplicable() --- .../api/security/MutableSecurityPolicy.java | 2 +- .../api/security/PermissionsContext.java | 2 +- .../impersonation/ImpersonationTestCase.java | 2 +- .../RoleImpersonationContextFactory.java | 3 +- .../permissions/AbstractPermission.java | 3 +- .../permissions/AbstractSitePermission.java | 33 +++++++++---------- .../CanAccessLockedProjectsPermission.java | 3 +- .../roles/AbstractModuleScopedRole.java | 3 +- .../api/security/roles/AbstractRole.java | 3 +- .../roles/AbstractRootContainerRole.java | 3 +- .../labkey/api/security/roles/AuthorRole.java | 5 ++- .../labkey/api/security/roles/EditorRole.java | 5 ++- .../api/security/roles/FolderAdminRole.java | 3 +- .../api/security/roles/NoPermissionsRole.java | 3 +- .../api/security/roles/ProjectAdminRole.java | 3 +- .../labkey/api/security/roles/ReaderRole.java | 3 +- .../security/roles/RestrictedReaderRole.java | 3 +- .../org/labkey/api/security/roles/Role.java | 5 ++- .../api/security/roles/RoleManager.java | 3 +- .../core/security/SecurityApiActions.java | 2 +- .../src/org/labkey/pipeline/permission.jsp | 8 ++--- .../security/roles/AbstractSpecimenRole.java | 5 ++- .../org/labkey/study/security/datasets.jsp | 5 ++- 23 files changed, 46 insertions(+), 64 deletions(-) diff --git a/api/src/org/labkey/api/security/MutableSecurityPolicy.java b/api/src/org/labkey/api/security/MutableSecurityPolicy.java index 494fb31e232..baa7911ee51 100644 --- a/api/src/org/labkey/api/security/MutableSecurityPolicy.java +++ b/api/src/org/labkey/api/security/MutableSecurityPolicy.java @@ -86,7 +86,7 @@ public void addRoleAssignment(@NotNull UserPrincipal principal, @NotNull Role ro throw new IllegalArgumentException("This role may not be assigned: " + role.getName()); if (role.isExcludedPrincipal(principal)) throw new IllegalArgumentException("The principal " + principal.getName() + " may not be assigned the role " + role.getName() + "!"); - if (null != _resource && (validate && !role.isApplicable(this, _resource))) + if (null != _resource && (validate && !role.isApplicable(_resource))) throw new IllegalArgumentException("The role " + role.getName() + " is not applicable to this resource '" + _resource.getDebugName() + "'!"); RoleAssignment assignment = new RoleAssignment(getResourceId(), principal, role); diff --git a/api/src/org/labkey/api/security/PermissionsContext.java b/api/src/org/labkey/api/security/PermissionsContext.java index bfd321c41ac..f399639e3b2 100644 --- a/api/src/org/labkey/api/security/PermissionsContext.java +++ b/api/src/org/labkey/api/security/PermissionsContext.java @@ -59,7 +59,7 @@ default Stream getAssignedRoles(User user, SecurableResource resource) SecurityPolicy rootPolicy = root.getPolicy(); Stream ret = rootPolicy.getRoles(groups) .filter(role -> { - if (!role.isApplicable(rootPolicy, root)) + if (!role.isApplicable(root)) throw new IllegalStateException("Root role " + role.getName() + " is not applicable"); if (!(role instanceof AbstractRootContainerRole siteRole)) throw new IllegalStateException("Root roles should all be AbstractRootContainerRole"); diff --git a/api/src/org/labkey/api/security/impersonation/ImpersonationTestCase.java b/api/src/org/labkey/api/security/impersonation/ImpersonationTestCase.java index 6c6f49ea1a3..3433012d4b8 100644 --- a/api/src/org/labkey/api/security/impersonation/ImpersonationTestCase.java +++ b/api/src/org/labkey/api/security/impersonation/ImpersonationTestCase.java @@ -79,7 +79,7 @@ public void testPermissions() throws Exception assertTrue(projectUserCount < siteUserCount); // Should be at least one less because test_no_permissions@test.com doesn't have read int projectGroupCount = SecurityManager.getGroups(project, false).size(); int allGroupCount = siteGroupCount + projectGroupCount; - List projectRoles = RoleManager.getAllRoles().stream().filter(role -> role.isAssignable() && role.isApplicable(projectPolicy, project)).toList(); + List projectRoles = RoleManager.getAllRoles().stream().filter(role -> role.isAssignable() && role.isApplicable(project)).toList(); int projectRoleCount = projectRoles.size(); testImpersonator("SiteAdminRole", true, project, siteUserCount, siteGroupCount, siteRoleCount, siteUserCount, allGroupCount, projectRoleCount); diff --git a/api/src/org/labkey/api/security/impersonation/RoleImpersonationContextFactory.java b/api/src/org/labkey/api/security/impersonation/RoleImpersonationContextFactory.java index 6d8072cb784..4dc07b5c023 100644 --- a/api/src/org/labkey/api/security/impersonation/RoleImpersonationContextFactory.java +++ b/api/src/org/labkey/api/security/impersonation/RoleImpersonationContextFactory.java @@ -193,13 +193,12 @@ public static Stream getValidImpersonationRoles(@NotNull Container c, User { if (canImpersonate(c, user)) { - SecurityPolicy policy = SecurityPolicyManager.getPolicy(c); boolean canImpersonatePrivilegedRoles = user.hasRootPermission(ImpersonatePrivilegedSiteRolesPermission.class); // Stream the valid roles return RoleManager.getAllRoles().stream() .filter(Role::isAssignable) - .filter(role -> role.isApplicable(policy, c)) + .filter(role -> role.isApplicable(c)) .filter(role -> !role.isPrivileged() || canImpersonatePrivilegedRoles); } else diff --git a/api/src/org/labkey/api/security/permissions/AbstractPermission.java b/api/src/org/labkey/api/security/permissions/AbstractPermission.java index 92f5abd71c0..4a0f4d5c128 100644 --- a/api/src/org/labkey/api/security/permissions/AbstractPermission.java +++ b/api/src/org/labkey/api/security/permissions/AbstractPermission.java @@ -21,7 +21,6 @@ import org.labkey.api.module.Module; import org.labkey.api.module.ModuleLoader; import org.labkey.api.security.SecurableResource; -import org.labkey.api.security.SecurityPolicy; import org.labkey.api.security.UserPrincipal; import java.util.HashSet; @@ -144,7 +143,7 @@ public Set getExcludedPrincipals() } @Override - public boolean isApplicable(SecurityPolicy policy, SecurableResource resource) + public boolean isApplicable(SecurableResource resource) { return true; } diff --git a/api/src/org/labkey/api/security/permissions/AbstractSitePermission.java b/api/src/org/labkey/api/security/permissions/AbstractSitePermission.java index 17c8887bc43..7c8bcd6bf23 100644 --- a/api/src/org/labkey/api/security/permissions/AbstractSitePermission.java +++ b/api/src/org/labkey/api/security/permissions/AbstractSitePermission.java @@ -1,24 +1,23 @@ -/* - * Copyright (c) 2018 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/* + * Copyright (c) 2018 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.labkey.api.security.permissions; import org.jetbrains.annotations.NotNull; import org.labkey.api.data.Container; import org.labkey.api.security.SecurableResource; -import org.labkey.api.security.SecurityPolicy; public abstract class AbstractSitePermission extends AbstractPermission { @@ -28,7 +27,7 @@ protected AbstractSitePermission(@NotNull String name, @NotNull String descripti } @Override - public boolean isApplicable(SecurityPolicy policy, SecurableResource resource) + public boolean isApplicable(SecurableResource resource) { return resource instanceof Container && ((Container)resource).isRoot(); } diff --git a/api/src/org/labkey/api/security/permissions/CanAccessLockedProjectsPermission.java b/api/src/org/labkey/api/security/permissions/CanAccessLockedProjectsPermission.java index 6625e0f864d..314320deef2 100644 --- a/api/src/org/labkey/api/security/permissions/CanAccessLockedProjectsPermission.java +++ b/api/src/org/labkey/api/security/permissions/CanAccessLockedProjectsPermission.java @@ -1,7 +1,6 @@ package org.labkey.api.security.permissions; import org.labkey.api.security.SecurableResource; -import org.labkey.api.security.SecurityPolicy; // Assigned to Site, Application, and Project admins so they can access locked projects. Also used as a contextual role // to bypass the locked project check for specific scenarios (e.g., update user profile page). @@ -14,7 +13,7 @@ public CanAccessLockedProjectsPermission() // This prevents the dataset security UI (datasets.jsp) from attempting to examine this role @Override - public boolean isApplicable(SecurityPolicy policy, SecurableResource resource) + public boolean isApplicable(SecurableResource resource) { return false; } diff --git a/api/src/org/labkey/api/security/roles/AbstractModuleScopedRole.java b/api/src/org/labkey/api/security/roles/AbstractModuleScopedRole.java index 094a437801d..98d9d58116f 100644 --- a/api/src/org/labkey/api/security/roles/AbstractModuleScopedRole.java +++ b/api/src/org/labkey/api/security/roles/AbstractModuleScopedRole.java @@ -18,7 +18,6 @@ import org.labkey.api.data.Container; import org.labkey.api.module.Module; import org.labkey.api.security.SecurableResource; -import org.labkey.api.security.SecurityPolicy; import org.labkey.api.security.permissions.Permission; /** @@ -33,7 +32,7 @@ protected AbstractModuleScopedRole(String name, String description, Class getExcludedPrincipals() } @Override - public boolean isApplicable(SecurityPolicy policy, SecurableResource resource) + public boolean isApplicable(SecurableResource resource) { return resource instanceof Container && !((Container)resource).isRoot(); } diff --git a/api/src/org/labkey/api/security/roles/AbstractRootContainerRole.java b/api/src/org/labkey/api/security/roles/AbstractRootContainerRole.java index b5816bd6a7b..122d83cc897 100644 --- a/api/src/org/labkey/api/security/roles/AbstractRootContainerRole.java +++ b/api/src/org/labkey/api/security/roles/AbstractRootContainerRole.java @@ -18,7 +18,6 @@ import org.labkey.api.data.Container; import org.labkey.api.module.Module; import org.labkey.api.security.SecurableResource; -import org.labkey.api.security.SecurityPolicy; import org.labkey.api.security.permissions.Permission; /** @@ -56,7 +55,7 @@ public AbstractRootContainerRole(String name, String description, Iterable getAllRoles() public static Set getSiteRoles() { - SecurityPolicy policy = ContainerManager.getRoot().getPolicy(); return _roles.stream(). - filter(r -> r.isAssignable() && r.isApplicable(policy, ContainerManager.getRoot())). + filter(r -> r.isAssignable() && r.isApplicable(ContainerManager.getRoot())). collect(Collectors.toSet()); } diff --git a/core/src/org/labkey/core/security/SecurityApiActions.java b/core/src/org/labkey/core/security/SecurityApiActions.java index 34e2e51a29c..dae6a97ba6e 100644 --- a/core/src/org/labkey/core/security/SecurityApiActions.java +++ b/core/src/org/labkey/core/security/SecurityApiActions.java @@ -648,7 +648,7 @@ public ApiResponse execute(PolicyIdForm form, BindException errors) { for (Role role : RoleManager.getAllRoles()) { - if (role.isAssignable() && role.isApplicable(policy, resource)) + if (role.isAssignable() && role.isApplicable(resource)) relevantRoles.add(role.getUniqueName()); } } diff --git a/pipeline/src/org/labkey/pipeline/permission.jsp b/pipeline/src/org/labkey/pipeline/permission.jsp index 5562e819722..fc7990de551 100644 --- a/pipeline/src/org/labkey/pipeline/permission.jsp +++ b/pipeline/src/org/labkey/pipeline/permission.jsp @@ -81,7 +81,7 @@ These permissions control whether pipeline files can be downloaded and updated v HtmlString name = h(g.isUsers() ? "All Users" : g.getName()); %> <%=name%> - <%=getSelect(i, g.isGuests() ? optionsGuest : optionsFull, assignedRole, policy, pipeRoot)%> + <%=getSelect(i, g.isGuests() ? optionsGuest : optionsFull, assignedRole, pipeRoot)%> <% i++; } @@ -99,7 +99,7 @@ These permissions control whether pipeline files can be downloaded and updated v .orElse(RoleManager.getRole(NoPermissionsRole.class)); %> <%=h(g.getName())%> - <%=getSelect(i, g.isGuests() ? optionsGuest : optionsFull, assignedRole, policy, pipeRoot)%> + <%=getSelect(i, g.isGuests() ? optionsGuest : optionsFull, assignedRole, pipeRoot)%> <% i++; } @@ -124,7 +124,7 @@ function toggleEnableFTP(checkbox) <%! - SafeToRender getSelect(int i, List> options, Role role, SecurityPolicy policy, PipeRoot pipeRoot) + SafeToRender getSelect(int i, List> options, Role role, PipeRoot pipeRoot) { SelectBuilder select = select() .name("perms[" + i + "]") @@ -138,7 +138,7 @@ function toggleEnableFTP(checkbox) { select.selected(role.getUniqueName()); } - else if (role != null && role.isApplicable(policy, pipeRoot)) + else if (role != null && role.isApplicable(pipeRoot)) { select.addOption(role.getName(), role.getUniqueName()); select.selected(role.getUniqueName()); diff --git a/specimen/src/org/labkey/specimen/security/roles/AbstractSpecimenRole.java b/specimen/src/org/labkey/specimen/security/roles/AbstractSpecimenRole.java index 7a7efd7013a..97832c3c553 100644 --- a/specimen/src/org/labkey/specimen/security/roles/AbstractSpecimenRole.java +++ b/specimen/src/org/labkey/specimen/security/roles/AbstractSpecimenRole.java @@ -17,7 +17,6 @@ import org.labkey.api.data.Container; import org.labkey.api.security.SecurableResource; -import org.labkey.api.security.SecurityPolicy; import org.labkey.api.security.permissions.Permission; import org.labkey.api.security.roles.AbstractRole; import org.labkey.api.study.StudyService; @@ -37,9 +36,9 @@ protected AbstractSpecimenRole(String name, String description, Class