Skip to content

Commit

Permalink
Validate sign-in option is configured at backend
Browse files Browse the repository at this point in the history
Signed-off-by: David Osorno <[email protected]>
  • Loading branch information
davidosorno committed Mar 12, 2024
1 parent 62fb645 commit 46c296f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.opensearch.security.securityconf.impl.DashboardSignInOption;
import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration;
import org.opensearch.security.securityconf.impl.v7.ConfigV7;
import org.opensearch.security.securityconf.impl.v7.ConfigV7.Authc;
import org.opensearch.security.support.ConfigConstants;
import org.opensearch.threadpool.ThreadPool;

Expand Down Expand Up @@ -185,7 +186,7 @@ private void updateAndValidatesValues(final ConfigV7 config, final JsonNode json
}
if (jsonContent.hasNonNull(SIGN_IN_OPTIONS) && jsonContent.findValue(SIGN_IN_OPTIONS).isEmpty() == false) {
JsonNode newOptions = jsonContent.findValue(SIGN_IN_OPTIONS);
List<DashboardSignInOption> options = getNewSignInOptions(newOptions);
List<DashboardSignInOption> options = getNewSignInOptions(newOptions, config.dynamic.authc);
config.dynamic.kibana.sign_in_options = options;
}

Expand Down Expand Up @@ -214,16 +215,29 @@ private void updateAndValidatesValues(final ConfigV7 config, final JsonNode json
}
}

private List<DashboardSignInOption> getNewSignInOptions(JsonNode newOptions) {
private List<DashboardSignInOption> getNewSignInOptions(JsonNode newOptions, Authc authc) {
List<DashboardSignInOption> options = new ArrayList<>();
for (int i = 0; i < newOptions.size(); i++) {
try {
String option = newOptions.get(i).asText();
options.add(DashboardSignInOption.valueOf(option));
if (isOptionConfiguredAtBackEnd(authc, option)) {
options.add(DashboardSignInOption.valueOf(option));
}
} catch (Exception e) {
throw new IllegalArgumentException("Invalid sign-in option. " + e.getMessage());
throw new IllegalArgumentException("Invalid sign-in option: " + e.getMessage());
}
}
return options;
}

private boolean isOptionConfiguredAtBackEnd(Authc authc, String option) {
for (String key : authc.getDomains().keySet()) {
if (key.contains(option.toLowerCase())) {
return true;
}
}
throw new IllegalArgumentException(
"Validation failure: " + option.toUpperCase() + " authentication provider is not available for this cluster."
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ private void verifyTenantUpdate(final Header... header) throws Exception {
);
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), hasItem(DashboardSignInOption.BASIC.toString()));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), not(hasItem(DashboardSignInOption.SAML.toString())));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), not(hasItem(DashboardSignInOption.OPENID.toString())));

final HttpResponse updateDashboardSignInOptions = rh.executePutRequest(
"/_plugins/_security/api/tenancy/config",
"{\"sign_in_options\": [\"BASIC\", \"SAML\"]}",
"{\"sign_in_options\": [\"BASIC\", \"OPENID\"]}",
header
);
assertThat(updateDashboardSignInOptions.getBody(), updateDashboardSignInOptions.getStatusCode(), equalTo(HttpStatus.SC_OK));
Expand All @@ -72,7 +73,27 @@ private void verifyTenantUpdate(final Header... header) throws Exception {
assertThat(getDashboardsinfoResponse.findValueInJson("default_tenant"), equalTo("Private"));

assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), hasItem((DashboardSignInOption.BASIC.toString())));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), hasItem((DashboardSignInOption.SAML.toString())));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), hasItem((DashboardSignInOption.OPENID.toString())));

final HttpResponse updateUnavailableSignInOption = rh.executePutRequest(
"/_plugins/_security/api/tenancy/config",
"{\"sign_in_options\": [\"BASIC\", \"SAML\"]}",
header
);
assertThat(updateUnavailableSignInOption.getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST));
assertThat(
updateUnavailableSignInOption.findValueInJson("error.reason"),
containsString("Validation failure: SAML authentication provider is not available for this cluster.")
);

// Ensuring the sign in options array has not been modified due to the Bad Request response.
getDashboardsinfoResponse = rh.executeGetRequest("/_plugins/_security/dashboardsinfo", ADMIN_FULL_ACCESS_USER);
assertThat(getDashboardsinfoResponse.getStatusCode(), equalTo(HttpStatus.SC_OK));

assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options").size(), equalTo(2));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), hasItem(DashboardSignInOption.BASIC.toString()));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), hasItem(DashboardSignInOption.OPENID.toString()));
assertThat(getDashboardsinfoResponse.findArrayInJson("sign_in_options"), not(hasItem(DashboardSignInOption.SAML.toString())));
}

@Test
Expand Down Expand Up @@ -186,7 +207,7 @@ private void verifyTenantUpdateFailed(final Header... header) throws Exception {
assertThat(
invalidSignInOption.getBody(),
invalidSignInOption.findValueInJson("error.reason"),
containsString("Invalid sign-in option.")
containsString("Invalid sign-in option")
);
}

Expand Down
12 changes: 12 additions & 0 deletions src/test/resources/restapi/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ config:
internalProxies: "192\\.168\\.0\\.10|192\\.168\\.0\\.11"
remoteIpHeader: "x-forwarded-for"
authc:
openid_auth_domain:
http_enabled: true
transport_enabled: true
order: 4
http_authenticator:
type: openid
challenge: false
config: {}
authentication_backend:
type: "noop"
config: {}
description: "Migrated from v6"
authentication_domain_kerb:
http_enabled: false
transport_enabled: false
Expand Down

0 comments on commit 46c296f

Please sign in to comment.