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
30 changes: 19 additions & 11 deletions src/org/labkey/test/tests/core/login/PasswordTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.labkey.test.pages.core.login.DatabaseAuthConfigureDialog;
import org.labkey.test.pages.core.login.LoginConfigurePage;
import org.labkey.test.params.login.DatabaseAuthenticationProvider;
import org.labkey.test.util.APIUserHelper;
import org.labkey.test.util.LogMethod;
import org.labkey.test.util.LoggedParam;
import org.labkey.test.util.core.login.DbLoginUtils;
Expand Down Expand Up @@ -256,7 +257,11 @@ public void testPasswordParameter()
@Test
public void testChooseNewPasswordMessages() throws IOException
{
// Hold an admin connection open, allowing us to reset the config regardless of what happens during the test
// Test bad API key
signOut();
signInShouldFailUiAndApi("apikey", "abc123", "The API key you provided is invalid.");

// Hold an admin API connection open, allowing us to reset the config without the browser session interfering
Connection adminConnection = WebTestHelper.getRemoteApiConnection();
DbLoginProperties savedProperties = DbLoginUtils.getDbLoginConfig(adminConnection);

Expand All @@ -268,25 +273,28 @@ public void testChooseNewPasswordMessages() throws IOException
);

// Set a weak password
signOut();
String resetUrl = userInitiatePasswordReset(USER);
beginAt(resetUrl);
new SetPasswordForm(getDriver())
.setNewPassword(WEAK_PASSWORD)
.clickSubmit();

// Test bogus password first
signOut();
signInShouldFail("bogus", "The email address and password you entered did not match any accounts on file.");
signIn(USER, WEAK_PASSWORD);
// Test bogus password
signOut();
signInShouldFailUiAndApi(USER, "bogus", "The email address and password you entered did not match any accounts on file.");

// Test deactivated user
APIUserHelper helper = new APIUserHelper(() -> adminConnection);
helper.deactivateUsers(_userId);
signInShouldFailUiAndApi(USER, WEAK_PASSWORD, "Your account has been deactivated.");
helper.activateUsers(_userId);

// Change the configuration and test password that no longer meets complexity requirements
DbLoginUtils.setDbLoginConfig(adminConnection,
PasswordStrength.Strong,
PasswordExpiration.Never
);
signInShouldFail(WEAK_PASSWORD, "Your password does not meet the complexity requirements; please choose a new password.");
signInShouldFailUiAndApi(USER, WEAK_PASSWORD, "Your password does not meet the complexity requirements; please choose a new password.");
String strongPassword = VERY_STRONG_PASSWORD + "!";
changeInvalidPassword(WEAK_PASSWORD, strongPassword);

Expand All @@ -297,7 +305,7 @@ public void testChooseNewPasswordMessages() throws IOException
);
// Wait six seconds for expiration
sleep(6000);
signInShouldFail(strongPassword, "Your password has expired; please choose a new password.");
signInShouldFailUiAndApi(USER, strongPassword, "Your password has expired; please choose a new password.");
changeInvalidPassword(strongPassword, VERY_STRONG_PASSWORD + "@");
}
finally
Expand All @@ -307,10 +315,10 @@ public void testChooseNewPasswordMessages() throws IOException
}

// Attempt to sign in via UI and API, expecting both to fail with the specified message
private void signInShouldFail(String password, String expectedMessage) throws IOException
private void signInShouldFailUiAndApi(String email, String password, String expectedMessage) throws IOException
{
signInShouldFail(USER, password, expectedMessage);
Connection userConnection = new Connection(WebTestHelper.getBaseURL(), USER, password);
signInShouldFail(email, password, expectedMessage);
Connection userConnection = new Connection(WebTestHelper.getBaseURL(), email, password);
EnsureLoginCommand ensureLoginCommand = new EnsureLoginCommand();
try
{
Expand Down
39 changes: 36 additions & 3 deletions src/org/labkey/test/util/APIUserHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.labkey.test.util;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.core5.http.message.BasicNameValuePair;
Expand All @@ -27,6 +28,7 @@
import org.labkey.remoteapi.Connection;
import org.labkey.remoteapi.PostCommand;
import org.labkey.remoteapi.SimpleGetCommand;
import org.labkey.remoteapi.SimplePostCommand;
import org.labkey.remoteapi.security.CreateUserCommand;
import org.labkey.remoteapi.security.CreateUserResponse;
import org.labkey.remoteapi.security.DeleteUserCommand;
Expand All @@ -52,7 +54,6 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class APIUserHelper extends AbstractUserHelper
{
Expand Down Expand Up @@ -239,14 +240,17 @@ private void deleteUser(@NotNull Integer userId)
protected void _deleteUsers(boolean failIfNotFound, String... userEmails)
{
Map<String, Integer> userIds = getUserIds(Arrays.asList(userEmails), true);
List<Integer> validUserIds = new ArrayList<>();
for (String userEmail : new HashSet<>(Arrays.asList(userEmails)))
{
Integer userId = userIds.get(userEmail);
if (failIfNotFound)
assertTrue(userEmail + " was not present", userId != null);
assertNotNull(userEmail + " was not present", userId);
if (userId != null)
deleteUser(userId);
validUserIds.add(userId);
}
if (!validUserIds.isEmpty())
deleteUsers(ArrayUtils.toPrimitive(validUserIds.toArray(new Integer[0])));
}

private static final Pattern regEmailVerification = Pattern.compile("verification=([A-Za-z0-9]+)");
Expand Down Expand Up @@ -289,6 +293,35 @@ public String setInitialPassword(int userId)
throw new RuntimeException(e);
}
}

public void deleteUsers(int... userIds)
{
updateUsersState(false, true, userIds);
}

public void deactivateUsers(int... userIds)
{
updateUsersState(false, false, userIds);
}

public void activateUsers(int... userIds)
{
updateUsersState(true, false, userIds);
}

private void updateUsersState(boolean activate, boolean delete, int... userIds)
{
SimplePostCommand updateUsers = new SimplePostCommand("user", "updateUsersStateApi");
updateUsers.setJsonObject(new JSONObject(Map.of("userId", userIds, "activate", activate, "delete", delete)));
try
{
updateUsers.execute(connectionSupplier.get(), null);
}
catch (IOException | CommandException e)
{
throw new RuntimeException(e);
}
}
}

class SetPasswordCommand extends PostCommand<CommandResponse>
Expand Down