Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/org/labkey/test/tests/AbstractAdminConsoleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.List;

import static org.labkey.test.util.PermissionsHelper.APP_ADMIN_ROLE;
import static org.labkey.test.util.PermissionsHelper.TROUBLESHOOTER_ROLE;

public abstract class AbstractAdminConsoleTest extends BaseWebDriverTest
{
Expand Down Expand Up @@ -79,7 +80,7 @@ protected void createTestUsers()

int troubleshooterId = _userHelper.createUser(TROUBLESHOOTER_USER, true, false).getUserId();
setInitialPassword(troubleshooterId);
apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER_USER, "Troubleshooter", PermissionsHelper.MemberType.user, "/");
apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER_USER, TROUBLESHOOTER_ROLE, PermissionsHelper.MemberType.user, "/");
}

@Override
Expand Down
11 changes: 6 additions & 5 deletions src/org/labkey/test/tests/AdminConsoleNavigationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.labkey.test.util.PermissionsHelper.TROUBLESHOOTER_ROLE;

@Category({Git.class})
@BaseWebDriverTest.ClassTimeout(minutes = 6)
public class AdminConsoleNavigationTest extends BaseWebDriverTest
{
private static final String TROUBLESHOOTER = "troubleshooter@adminconsolelinks.test";
private static final String TROUBLESHOOTER_USER = "troubleshooter@adminconsolelinks.test";
private static final String NON_ADMIN = "nonadmin@adminconsolelinks.test";

public ApiPermissionsHelper _apiPermissionsHelper = new ApiPermissionsHelper(this);
Expand All @@ -52,16 +53,16 @@ public static void setupProject()

private void doSetup()
{
_userHelper.createUser(TROUBLESHOOTER);
_apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER, "Troubleshooter", PermissionsHelper.MemberType.user, "/");
_userHelper.createUser(TROUBLESHOOTER_USER);
_apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER_USER, TROUBLESHOOTER_ROLE, PermissionsHelper.MemberType.user, "/");

_userHelper.createUser(NON_ADMIN);
}

@Override
protected void doCleanup(boolean afterTest)
{
_userHelper.deleteUsers(false, TROUBLESHOOTER, NON_ADMIN);
_userHelper.deleteUsers(false, TROUBLESHOOTER_USER, NON_ADMIN);
}

@Test
Expand Down Expand Up @@ -120,7 +121,7 @@ public void testTroubleshooterLinkAccess()
"Profiler" //Profiler can be edited by the troubleshooter
));
ShowAdminPage adminConsole = goToAdminConsole();
impersonate(TROUBLESHOOTER);
impersonate(TROUBLESHOOTER_USER);
Map<String, String> linkHrefs = new LinkedHashMap<>();
List<WebElement> troubleshooterLinks = adminConsole.getAllAdminConsoleLinks();
assertTrue(String.format("Failed sanity check. Only found %s admin links. There should be more.", troubleshooterLinks.size()), troubleshooterLinks.size() > 10);
Expand Down
11 changes: 6 additions & 5 deletions src/org/labkey/test/tests/core/admin/CspResourceHostsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,20 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.labkey.test.util.PermissionsHelper.MemberType.user;
import static org.labkey.test.util.PermissionsHelper.TROUBLESHOOTER_ROLE;

@Category({Daily.class})
public class CspResourceHostsTest extends BaseWebDriverTest
{
private static final String APP_ADMIN = "csp_app_admin@cspresourcehoststest.test";
private static final String TROUBLESHOOTER = "csp_troubleshooter@cspresourcehoststest.test";
private static final String TROUBLESHOOTER_USER = "csp_troubleshooter@cspresourcehoststest.test";

private final CspConfigHelper _cspConfigHelper = new CspConfigHelper(this);

@Override
protected void doCleanup(boolean afterTest)
{
_userHelper.deleteUsers(afterTest, APP_ADMIN, TROUBLESHOOTER);
_userHelper.deleteUsers(afterTest, APP_ADMIN, TROUBLESHOOTER_USER);
}

@BeforeClass
Expand All @@ -53,10 +54,10 @@ public static void setupProject()
private void doSetup()
{
_userHelper.createUser(APP_ADMIN);
_userHelper.createUser(TROUBLESHOOTER);
_userHelper.createUser(TROUBLESHOOTER_USER);
ApiPermissionsHelper apiPermissionsHelper = new ApiPermissionsHelper(this);
apiPermissionsHelper.addUserAsAppAdmin(APP_ADMIN);
apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER, "Troubleshooter", user, null);
apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER_USER, TROUBLESHOOTER_ROLE, user, null);
}

@Before
Expand Down Expand Up @@ -84,7 +85,7 @@ public void testTroubleshooterPermissions() throws Exception
checker().verifyEquals("Defined directives", expectedHosts, externalSourcesPage.getExistingHosts());
checker().screenShotIfNewError("site_admin_csp");

impersonate(TROUBLESHOOTER);
impersonate(TROUBLESHOOTER_USER);
externalSourcesPage = ShowAdminPage.beginAt(this).clickAllowedExternalResourceHosts();

buttons = getTexts(Locator.lkButton().findElements(getDriver()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void testModifyPrivilegedPermission() throws Exception
public void testAdminConsoleVisibility()
{
signOut();
signIn(TROUBLESHOOTER);
signIn(TROUBLESHOOTER_USER);
log("Verify permissions from troubleshooter");
verifySitePermissionSetting(false);

Expand All @@ -81,12 +81,12 @@ public void testAdminConsoleVisibility()

private ApiPermissionsHelper apiAsTroubleshooter()
{
return new ApiPermissionsHelper(this, () -> new Connection(WebTestHelper.getBaseURL(), TROUBLESHOOTER, PasswordUtil.getPassword()));
return new ApiPermissionsHelper(this, () -> new Connection(WebTestHelper.getBaseURL(), TROUBLESHOOTER_USER, PasswordUtil.getPassword()));
}

private ApiPermissionsHelper apiAsImpersonatingSiteAdmin() throws IOException, CommandException
{
Connection connection = new Connection(WebTestHelper.getBaseURL(), TROUBLESHOOTER, PasswordUtil.getPassword());
Connection connection = new Connection(WebTestHelper.getBaseURL(), TROUBLESHOOTER_USER, PasswordUtil.getPassword());
new ImpersonateRolesCommand(toRole(SITE_ADMIN_ROLE)).execute(connection, "/");
return new ApiPermissionsHelper(this, () -> connection);
}
Expand Down
93 changes: 77 additions & 16 deletions src/org/labkey/test/tests/core/security/TroubleshooterRoleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,39 @@

import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.Nullable;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.labkey.test.BaseWebDriverTest;
import org.labkey.test.Locator;
import org.labkey.test.Locators;
import org.labkey.test.TestTimeoutException;
import org.labkey.test.WebTestHelper;
import org.labkey.test.categories.Git;
import org.labkey.test.pages.core.admin.ShowAdminPage;
import org.labkey.test.pages.core.admin.ShowAuditLogPage;
import org.labkey.test.params.list.IntListDefinition;
import org.labkey.test.util.AbstractDataRegionExportOrSignHelper;
import org.labkey.test.util.ApiPermissionsHelper;
import org.labkey.test.util.DataRegionExportHelper;
import org.labkey.test.util.DataRegionTable;
import org.labkey.test.util.PermissionsHelper;
import org.labkey.test.util.SummaryStatisticsHelper;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertTrue;
import static org.labkey.test.util.PermissionsHelper.TROUBLESHOOTER_ROLE;

@Category({Git.class})
@BaseWebDriverTest.ClassTimeout(minutes = 4)
public class TroubleshooterRoleTest extends BaseWebDriverTest
{
protected static final String TROUBLESHOOTER = "troubleshooter@troubleshooter.test";
protected static final String TROUBLESHOOTER_USER = "troubleshooter@troubleshooter.test";
protected int _troubleShooterId;

@BeforeClass
Expand All @@ -39,30 +47,30 @@ public static void setupProject()
@Override
protected void doCleanup(boolean afterTest) throws TestTimeoutException
{
_userHelper.deleteUsers(false, TROUBLESHOOTER);
_userHelper.deleteUsers(false, TROUBLESHOOTER_USER);
_containerHelper.deleteProject(getProjectName(), afterTest);
}

protected void doSetup()
{
_troubleShooterId = _userHelper.createUser(TROUBLESHOOTER).getUserId();
_troubleShooterId = _userHelper.createUser(TROUBLESHOOTER_USER).getUserId();
ApiPermissionsHelper apiPermissionsHelper = new ApiPermissionsHelper(this);
apiPermissionsHelper.addMemberToRole(TROUBLESHOOTER, getRole(), PermissionsHelper.MemberType.user,"/");
apiPermissionsHelper.addMemberToRole(_troubleShooterId, getRole(), "/");
_containerHelper.createProject(getProjectName());
}

protected String getRole()
{
return "Troubleshooter";
return TROUBLESHOOTER_ROLE;
}

@Test
public void testAuditLogsIsAccessible() throws Exception
{
// Ensure that there is at least on event to see
// Ensure that there is at least one event to see
new IntListDefinition("AuditList", "id").create(createDefaultConnection(), getProjectName());

impersonate(TROUBLESHOOTER);
impersonate(TROUBLESHOOTER_USER);
ShowAdminPage showAdminPage = goToAdminConsole().goToSettingsSection();

log("Verifying audit log link is present");
Expand All @@ -82,7 +90,7 @@ public void testAuditLogsIsAccessible() throws Exception
@Test
public void testAdminConsoleVisibility()
{
impersonate(TROUBLESHOOTER);
impersonate(TROUBLESHOOTER_USER);

log("Verify permissions from troubleshooter");
verifySitePermissionSetting(false);
Expand All @@ -93,20 +101,19 @@ public void testAdminConsoleVisibility()
verifySitePermissionSetting(true);
}

/**
* Issue 47508: auditLog table visibility is inconsistent
* Assert broken behavior to prompt a test update once issue is fixed.
*/
// Verify fix for Issue 47508 / GitHub Issue #26: auditLog table visibility is inconsistent
@Test
public void testAllAuditTableVisibility()
{
impersonate(TROUBLESHOOTER);
impersonate(TROUBLESHOOTER_USER);
ShowAdminPage showAdminPage = goToAdminConsole().goToSettingsSection();

log("Verify the export file is non empty");
log("Verify \"Group and role\" audit event table is viewable");
ShowAuditLogPage auditLogPage = showAdminPage.clickAuditLog();
auditLogPage.selectView("Group and role events");
assertTextPresent("You do not have permission to see this data.");
assertTextNotPresent("You do not have permission to see this data.");
DataRegionTable logTable = auditLogPage.getLogTable();
assertTrue(logTable.getDataRowCount() > 0);
}

protected void verifySitePermissionSetting(boolean canSave)
Expand All @@ -132,6 +139,60 @@ protected void verifySitePermissionSetting(boolean canSave)
isElementPresent(Locator.button("Save and Finish")));
}

// Verifications for GitHub Issue #785 - Troubleshooters should have read access in the root (but not elsewhere)
@Test
public void testQueryAccessInRoot()
{
goToAdminConsole();
impersonate(TROUBLESHOOTER_USER);
testQueryAccess();
stopImpersonating();

goToAdminConsole();
impersonateRole(TROUBLESHOOTER_ROLE);
testQueryAccess();
stopImpersonating();
}

private void testQueryAccess()
{
// Verify that Troubleshooters can access the schema browser and view an arbitrary query in the root
goToSchemaBrowser(null, false);
DataRegionTable dataRegionTable = viewQueryData("core", "Modules");
dataRegionTable.showAll();
int rowCount = dataRegionTable.getDataRowCount();
assertTrue(rowCount > 6);

// Verify that basic summary statistics work
dataRegionTable.setSummaryStatistic("Name", SummaryStatisticsHelper.BASE_STAT_COUNT, String.valueOf(rowCount));

// Verify that exports using POST work
DataRegionExportHelper exportHelper = new DataRegionExportHelper(dataRegionTable);
exportHelper.exportExcel(AbstractDataRegionExportOrSignHelper.ExcelFileType.XLSX);
exportHelper.exportScript(DataRegionExportHelper.ScriptExportType.JAVA);

// Troubleshooters should NOT have read access outside the root
goToProjectHome();
assertTextPresent("User does not have permission to perform this operation.");
goToSchemaBrowser(getProjectName(), true);
}

// Troubleshooters don't get the "Go To Module" menu item, so can't use goToSchemaBrowser()
public void goToSchemaBrowser(@Nullable String container, boolean expectPermissionError)
{
beginAt(WebTestHelper.buildRelativeUrl("query", container,"begin"));

if (expectPermissionError)
{
assertTextPresent("User does not have permission to perform this operation.");
}
else
{
shortWait().until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.lk-sb-instructions")));
waitForElement(Locators.pageSignal("queryTreeRendered"));
}
}

@Override
protected String getProjectName()
{
Expand Down
24 changes: 12 additions & 12 deletions src/org/labkey/test/util/ApiPermissionsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -444,11 +444,16 @@ public void addMemberToRole(String userOrGroupName, String roleName, MemberType
}

public void addMemberToRole(String userOrGroupName, String roleName, MemberType memberType, String container)
{
Integer principalId = getPrincipalId(userOrGroupName, memberType, container);
addMemberToRole(principalId, roleName, container);
}

public void addMemberToRole(Integer principalId, String roleName, String container)
{
AddAssignmentCommand command = new AddAssignmentCommand();
Connection connection = getConnection();

Integer principalId = getPrincipalId(userOrGroupName, memberType, container);
command.setPrincipalId(principalId);
command.setRoleClassName(toRole(roleName));

Expand All @@ -464,22 +469,17 @@ public void addMemberToRole(String userOrGroupName, String roleName, MemberType

public void addMemberToRoles(String userOrGroupName, List<String> roleNames, MemberType memberType)
{
roleNames.forEach(roleName -> {addMemberToRole(userOrGroupName, roleName, memberType);});
roleNames.forEach(roleName -> addMemberToRole(userOrGroupName, roleName, memberType));
}

protected Integer getPrincipalId(String userOrGroupName, MemberType principalType, String project)
{
switch (principalType)
return switch (principalType)
{
case user:
return getUserId(userOrGroupName);
case group:
return getProjectGroupId(userOrGroupName, project);
case siteGroup:
return getSiteGroupId(userOrGroupName);
default:
throw new IllegalArgumentException("Unknown principal type: " + principalType);
}
case user -> getUserId(userOrGroupName);
case group -> getProjectGroupId(userOrGroupName, project);
case siteGroup -> getSiteGroupId(userOrGroupName);
};
}

@Override
Expand Down
1 change: 1 addition & 0 deletions src/org/labkey/test/util/PermissionsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public abstract class PermissionsHelper
public static final String APP_ADMIN_ROLE = "Application Admin";
public static final String DEVELOPER_ROLE = "Platform Developer";
public static final String IMP_TROUBLESHOOTER_ROLE = "Impersonating Troubleshooter";
public static final String TROUBLESHOOTER_ROLE = "Troubleshooter";
public static final String PROJECT_ADMIN_ROLE = "Project Administrator";
public static final String FOLDER_ADMIN_ROLE = "Folder Administrator";
public static final String READER_ROLE = "Reader";
Expand Down