package com.constellio.app.ui.pages.rm.folder; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import java.util.List; import com.constellio.app.modules.rm.navigation.RMNavigationConfiguration; import org.junit.Test; import org.openqa.selenium.By; import com.constellio.app.modules.rm.RMTestRecords; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.ui.tools.ButtonWebElement; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.search.SearchServices; import com.constellio.model.services.search.query.logical.LogicalSearchQuery; import com.constellio.sdk.tests.ConstellioTest; import com.constellio.sdk.tests.annotations.SlowTest; import com.constellio.sdk.tests.annotations.UiTest; import com.constellio.sdk.tests.selenium.adapters.constellio.ConstellioWebDriver; import com.constellio.sdk.tests.selenium.adapters.constellio.ConstellioWebElement; @UiTest public class BruteForceFolderSecurityAcceptTest extends ConstellioTest { SearchServices searchServices; RMSchemasRecordsServices rm; RMTestRecords records = new RMTestRecords(zeCollection); RecordServices recordServices; ConstellioWebDriver driver; private String[] folderButtons = new String[] { "Ajouter un document", "Ajouter un sous-dossier", "Modifier la fiche dossier", "Partager ce dossier" }; private String[] documentButtons = new String[] { "Éditer la fiche du document", "Partager ce document" }; private void prepare() throws Exception { prepareSystem( withZeCollection().withConstellioRMModule().withAllTestUsers().withRMTest( records).withFoldersAndContainersOfEveryStatus() .withEvents() ); inCollection(zeCollection).setCollectionTitleTo("Collection de test"); recordServices = getModelLayerFactory().newRecordServices(); searchServices = getModelLayerFactory().newSearchServices(); rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory()); } private boolean isEnabled() { String parameterValue = getCurrentTestSession().getProperty("bruteForceRMSecurityTest"); return parameterValue != null && "true".equals(parameterValue.toLowerCase().trim()); } @Test @SlowTest public void validateUserCanClickOnAllEnabledButtonsOfEveryFolders() throws Exception { if (!isEnabled()) { return; } prepare(); LogicalSearchQuery allFoldersQuery = new LogicalSearchQuery() .setCondition(from(rm.folderSchemaType()).returnAll()); List<String> folders = searchServices.searchRecordIds(allFoldersQuery); List<User> users = getModelLayerFactory().newUserServices().getAllUsersInCollection(zeCollection); int progression = 0; int total = folders.size() * users.size(); for (User user : users) { logAs(user.getUsername()); LogicalSearchQuery allFoldersWithReadQuery = new LogicalSearchQuery() .setCondition(from(rm.folderSchemaType()).returnAll()) .filteredWithUser(user); List<String> foldersWithReadAccess = searchServices.searchRecordIds(allFoldersWithReadQuery); for (String folderId : folders) { System.out.println("" + (++progression) + " / " + total); driver.navigateTo().url(RMNavigationConfiguration.DISPLAY_FOLDER + "/" + folderId); if (foldersWithReadAccess.contains(folderId)) { assertThat(isOnHomePage()).describedAs("User " + user.getUsername() + " should be able to view folder '" + folderId + "'") .isFalse(); for (String folderButton : folderButtons) { ButtonWebElement button = getButtonIfEnabled(folderButton); if (button != null) { if (!clickValidateNotHomePageAndReturn(button)) { fail("User " + user.getUsername() + " can click on the button '" + folderButton + "' on folder '" + folderId + "', but has no access to the page"); } } } } else { assertThat(isOnHomePage()).describedAs("User " + user.getUsername() + " should not be able to view folder '" + folderId + "'") .isTrue(); } } } } @Test @SlowTest public void validateUserCanClickOnAllEnabledButtonsOfEveryDocuments() throws Exception { if (!isEnabled()) { return; } prepare(); LogicalSearchQuery allDocumentsQuery = new LogicalSearchQuery() .setCondition(from(rm.documentSchemaType()).returnAll()); List<String> documents = searchServices.searchRecordIds(allDocumentsQuery); List<User> users = getModelLayerFactory().newUserServices().getAllUsersInCollection(zeCollection); int progression = 0; int total = documents.size() * users.size(); for (User user : users) { logAs(user.getUsername()); LogicalSearchQuery allDocumentsWithReadQuery = new LogicalSearchQuery() .setCondition(from(rm.documentSchemaType()).returnAll()) .filteredWithUser(user); List<String> documentsWithReadAccess = searchServices.searchRecordIds(allDocumentsWithReadQuery); for (String documentId : documents) { System.out.println("" + (++progression) + " / " + total); driver.navigateTo().url(RMNavigationConfiguration.DISPLAY_DOCUMENT + "/" + documentId); if (documentsWithReadAccess.contains(documentId)) { assertThat(isOnHomePage()).describedAs("User " + user.getUsername() + " should be able to view document '" + documentId + "'") .isFalse(); for (String folderButton : documentButtons) { ButtonWebElement button = getButtonIfEnabled(folderButton); if (button != null) { if (!clickValidateNotHomePageAndReturn(button)) { fail("User " + user.getUsername() + " can click on the button '" + folderButton + "' on document '" + documentId + "', but has no access to the page"); } } } } else { assertThat(isOnHomePage()).describedAs("User " + user.getUsername() + " should not be able to view document '" + documentId + "'") .isTrue(); } } } } private boolean clickValidateNotHomePageAndReturn(ButtonWebElement button) { String currentUrl = driver.getCurrentPage(); button.clickAndWaitForPageReload(); boolean homePage = isOnHomePage(); driver.navigateTo().url(currentUrl); return !homePage; } private boolean isOnHomePage() { return driver.getCurrentUrl().endsWith("/constellio/#!/lastViewedFolders"); } private void logAs(String user) { driver = newWebDriver(loggedAsUserInCollection(user, zeCollection)); } private ButtonWebElement getButtonIfEnabled(String buttonName) { List<ConstellioWebElement> listButtonActionMenu = driver.findAdaptElements(By.className("action-menu-button")); for (ConstellioWebElement buttonElement : listButtonActionMenu) { if (buttonElement.getText().contains(buttonName)) { ButtonWebElement currentButton = new ButtonWebElement(buttonElement); if (currentButton.isEnabled()) { return currentButton; } else { return null; } } } return null; } }