Skip to content

Commit

Permalink
Refactor InternalUsers REST API test
Browse files Browse the repository at this point in the history
Split up UserApiTest into 3 diff tests:
 - InternalUsersRestApiIntegrationTest
 - InternalUsersRegExpPasswordRulesRestApiIntegrationTest
 - InternalUsersScoreBasedPasswordRulesRestApiIntegrationTest

 Fixes:
 - Added validation for the security roles for PATCH
 - Added validation for restricted character in username for PATCH

Signed-off-by: Andrey Pleskach <ples@aiven.io>
  • Loading branch information
willyborankin committed Jul 1, 2024
1 parent 2b5a811 commit 1b1cc89
Show file tree
Hide file tree
Showing 10 changed files with 1,080 additions and 1,182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,37 @@ void assertResponseBody(final String responseBody) {
assertThat(responseBody, not(equalTo("")));
}

static ToXContentObject configJsonArray(final String... values) {
return (builder, params) -> {
builder.startArray();
if (values != null) {
for (final var v : values) {
if (v == null) {
builder.nullValue();
} else {
builder.value(v);
}
}
}
return builder.endArray();
};
}

static String[] generateArrayValues(boolean useNulls) {
final var length = randomIntBetween(1, 5);
final var values = new String[length];
final var nullIndex = randomIntBetween(0, length - 1);
for (var i = 0; i < values.length; i++) {
if (useNulls && i == nullIndex) values[i] = null;
else values[i] = randomAsciiAlphanumOfLength(10);
}
return values;
}

static ToXContentObject randomConfigArray(final boolean useNulls) {
return useNulls
? configJsonArray(generateArrayValues(useNulls))
: randomFrom(List.of(configJsonArray(generateArrayValues(false)), configJsonArray()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -82,33 +82,6 @@ public AbstractConfigEntityApiIntegrationTest(final String path, final TestDescr
this.testDescriptor = testDescriptor;
}

static ToXContentObject configJsonArray(final String... values) {
return (builder, params) -> {
builder.startArray();
if (values != null) {
for (final var v : values) {
if (v == null) {
builder.nullValue();
} else {
builder.value(v);
}
}
}
return builder.endArray();
};
}

static String[] generateArrayValues(boolean useNulls) {
final var length = randomIntBetween(1, 5);
final var values = new String[length];
final var nullIndex = randomIntBetween(0, length - 1);
for (var i = 0; i < values.length; i++) {
if (useNulls && i == nullIndex) values[i] = null;
else values[i] = randomAsciiAlphanumOfLength(10);
}
return values;
}

@Override
protected String apiPath(String... paths) {
final StringJoiner fullPath = new StringJoiner("/").add(super.apiPath(path));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.api;

import java.net.URLEncoder;
import java.util.StringJoiner;

import org.junit.Test;

import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.security.dlic.rest.validation.PasswordValidator;
import org.opensearch.security.dlic.rest.validation.RequestContentValidator;
import org.opensearch.security.support.ConfigConstants;

import static org.opensearch.security.api.PatchPayloadHelper.addOp;
import static org.opensearch.security.api.PatchPayloadHelper.patch;

public class InternalUsersRegExpPasswordRulesRestApiIntegrationTest extends AbstractApiIntegrationTest {

final static String PASSWORD_VALIDATION_ERROR_MESSAGE = "xxxxxxxx";

static {
clusterSettings.put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE, PASSWORD_VALIDATION_ERROR_MESSAGE)
.put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX, "(?=.*[A-Z])(?=.*[^a-zA-Z\\\\d])(?=.*[0-9])(?=.*[a-z]).{8,}")
.put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name());
}

String internalUsers(String... path) {
final var fullPath = new StringJoiner("/").add(super.apiPath("internalusers"));
if (path != null) {
for (final var p : path)
fullPath.add(p);
}
return fullPath.toString();
}

ToXContentObject internalUserWithPassword(final String password) {
return (builder, params) -> builder.startObject()
.field("password", password)
.field("backend_roles", randomConfigArray(false))
.endObject();
}

@Test
public void canNotCreateUsersWithPassword() throws Exception {
withUser(ADMIN_USER_NAME, client -> {
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("")));
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("123")));
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("1234567")));
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("1Aa%")));
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("123456789")));
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("a123456789")));
badRequest(() -> client.putJson(internalUsers("tooshoort"), internalUserWithPassword("A123456789")));
badRequest(() -> client.putJson(internalUsers("$1aAAAAAAAAC"), internalUserWithPassword("$1aAAAAAAAAC")));
badRequest(() -> client.putJson(internalUsers("$1aAAAAAAAac"), internalUserWithPassword("$1aAAAAAAAAC")));
badRequest(
() -> client.putJson(
internalUsers(URLEncoder.encode("$1aAAAAAAAac%!=\"/\\;:test&~@^", "UTF-8").replace("+", "%2B")),
internalUserWithPassword("$1aAAAAAAAac%!=\\\"/\\\\;:test&~@^")
)
);
badRequest(
() -> client.putJson(
internalUsers(URLEncoder.encode("$1aAAAAAAAac%!=\"/\\;: test&", "UTF-8")),
internalUserWithPassword("$1aAAAAAAAac%!=\\\"/\\\\;: test&123")
)
);
badRequestWithReason(
() -> client.patch(
internalUsers(),
patch(
addOp("testuser1", internalUserWithPassword("$aA123456789")),
addOp("testuser2", internalUserWithPassword("testpassword2"))
)
),
PASSWORD_VALIDATION_ERROR_MESSAGE
);
badRequestWithReason(
() -> client.putJson(internalUsers("some_user_name"), internalUserWithPassword("H3235,cc,some_User_Name")),
RequestContentValidator.ValidationError.SIMILAR_PASSWORD.message()
);
});
}

@Test
public void canCreateUsersWithPassword() throws Exception {
withUser(ADMIN_USER_NAME, client -> {
created(() -> client.putJson(internalUsers("ok1"), internalUserWithPassword("$aA123456789")));
created(() -> client.putJson(internalUsers("ok2"), internalUserWithPassword("$Aa123456789")));
created(() -> client.putJson(internalUsers("ok3"), internalUserWithPassword("$1aAAAAAAAAA")));
ok(() -> client.putJson(internalUsers("ok3"), internalUserWithPassword("$1aAAAAAAAAC")));
ok(() -> client.patch(internalUsers(), patch(addOp("ok3", internalUserWithPassword("$1aAAAAAAAAB")))));
ok(() -> client.putJson(internalUsers("ok1"), internalUserWithPassword("Admin_123")));
});
}

}
Loading

0 comments on commit 1b1cc89

Please sign in to comment.