Skip to content

Commit

Permalink
Fixes authtoken endpoint (opensearch-project#4628)
Browse files Browse the repository at this point in the history
Signed-off-by: Darshit Chanpura <[email protected]>
  • Loading branch information
DarshitChanpura committed Aug 9, 2024
1 parent e73fc24 commit 9e62096
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ public void availableForRestAdmin() throws Exception {
withUser(REST_API_ADMIN_SSL_INFO, this::verifySSLCertsInfo);
}

@Test
public void timeoutTest() throws Exception {
withUser(REST_ADMIN_USER, this::verifyTimeoutRequest);
}

private void verifyTimeoutRequest(final TestRestClient client) throws Exception {
TestRestClient.HttpResponse response = ok(() -> client.get(sslCertsPath() + "?timeout=0"));
final var body = response.bodyAsJsonNode();
assertThat(body.get("nodes").size(), is(0));
}

private void verifySSLCertsInfo(final TestRestClient client) throws Exception {
assertSSLCertsInfo(
localCluster.nodes(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,18 @@ void assertFilterByUsers(final HttpResponse response, final boolean hasServiceUs
assertThat(response.getBody(), response.bodyAsJsonNode().has(NEW_USER), is(hasInternalUser));
}

@Test
public void verifyPOSTOnlyForAuthTokenEndpoint() throws Exception {
withUser(ADMIN_USER_NAME, client -> {
badRequest(() -> client.post(apiPath(ADMIN_USER_NAME, "authtoken")));
ok(() -> client.post(apiPath(SERVICE_ACCOUNT_USER, "authtoken")));
/*
should be notImplement but the call doesn't reach {@link org.opensearch.security.dlic.rest.api.InternalUsersApiAction#withAuthTokenPath(RestRequest)}
*/
methodNotAllowed(() -> client.post(apiPath("randomPath")));
});
}

@Test
public void userApiWithDotsInName() throws Exception {
withUser(ADMIN_USER_NAME, client -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ protected CType getConfigType() {
protected void consumeParameters(RestRequest request) {
request.param("nodeId");
request.param("cert_type");
request.param("timeout");
}

private void securitySSLCertsRequestHandlers(RequestHandler.RequestHandlersBuilder requestHandlersBuilder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ protected final UserFilterType filterParam(final RestRequest request) {
ValidationResult<String> withAuthTokenPath(final RestRequest request) throws IOException {
return endpointValidator.withRequiredEntityName(nameParam(request)).map(username -> {
// Handle auth token fetching
if (!(request.uri().contains("/internalusers/" + username + "/authtoken") && request.uri().endsWith("/authtoken"))) {
return ValidationResult.error(RestStatus.NOT_IMPLEMENTED, methodNotImplementedMessage(request.method()));
if (request.uri().contains("/internalusers/" + username + "/authtoken") && request.uri().endsWith("/authtoken")) {
return ValidationResult.success(username);
}
return ValidationResult.success(username);
return ValidationResult.error(RestStatus.NOT_IMPLEMENTED, methodNotImplementedMessage(request.method()));
});
}

Expand Down
19 changes: 6 additions & 13 deletions src/main/java/org/opensearch/security/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import com.google.common.collect.ImmutableList;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -243,14 +242,8 @@ public static String generatePassword() {
CharacterRule lowercaseCharacterRule = new CharacterRule(EnglishCharacterData.LowerCase, 1);
CharacterRule uppercaseCharacterRule = new CharacterRule(EnglishCharacterData.UpperCase, 1);
CharacterRule numericCharacterRule = new CharacterRule(EnglishCharacterData.Digit, 1);
CharacterRule specialCharacterRule = new CharacterRule(EnglishCharacterData.Special, 1);

List<CharacterRule> rules = Arrays.asList(
lowercaseCharacterRule,
uppercaseCharacterRule,
numericCharacterRule,
specialCharacterRule
);
List<CharacterRule> rules = Arrays.asList(lowercaseCharacterRule, uppercaseCharacterRule, numericCharacterRule);
PasswordGenerator passwordGenerator = new PasswordGenerator();

Random random = Randomness.get();
Expand All @@ -275,17 +268,17 @@ public AuthToken generateAuthToken(String accountName) throws IOException {

String authToken = null;
try {
final ObjectMapper mapper = DefaultObjectMapper.objectMapper;
JsonNode accountDetails = mapper.readTree(internalUsersConfiguration.getCEntry(accountName).toString());
final var accountEntry = DefaultObjectMapper.writeValueAsString(internalUsersConfiguration.getCEntry(accountName), false);
JsonNode accountDetails = DefaultObjectMapper.readTree(accountEntry);
final ObjectNode contentAsNode = (ObjectNode) accountDetails;
SecurityJsonNode securityJsonNode = new SecurityJsonNode(contentAsNode);

Optional.ofNullable(securityJsonNode.get("service"))
Optional.ofNullable(securityJsonNode.get("attributes").get("service"))
.map(SecurityJsonNode::asString)
.filter("true"::equalsIgnoreCase)
.orElseThrow(() -> new UserServiceException(AUTH_TOKEN_GENERATION_MESSAGE));

Optional.ofNullable(securityJsonNode.get("enabled"))
Optional.ofNullable(securityJsonNode.get("attributes").get("enabled"))
.map(SecurityJsonNode::asString)
.filter("true"::equalsIgnoreCase)
.orElseThrow(() -> new UserServiceException(AUTH_TOKEN_GENERATION_MESSAGE));
Expand All @@ -306,7 +299,7 @@ public AuthToken generateAuthToken(String accountName) throws IOException {
saveAndUpdateConfigs(getUserConfigName().toString(), client, CType.INTERNALUSERS, internalUsersConfiguration);

authToken = Base64.getUrlEncoder().encodeToString((accountName + ":" + plainTextPassword).getBytes(StandardCharsets.UTF_8));
return new BasicAuthToken(authToken);
return new BasicAuthToken("Basic " + authToken);

} catch (JsonProcessingException ex) {
throw new UserServiceException(FAILED_ACCOUNT_RETRIEVAL_MESSAGE);
Expand Down

0 comments on commit 9e62096

Please sign in to comment.