Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests related basic authentication. #2138

Merged

Conversation

lukasz-soszynski-eliatra
Copy link
Contributor

Signed-off-by: Lukasz Soszynski [email protected]

Description

[Describe what this change achieves]

  • Category (New feature [Tests])
    The feature introduces integration tests related to basic authentication. The tests are implemented with the usage of a newly developed test framework.

Issues Resolved

Testing

Production code can be treated as a test for tests

Check List

  • New functionality includes testing
  • New functionality has been documented
  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@lukasz-soszynski-eliatra lukasz-soszynski-eliatra requested a review from a team October 4, 2022 11:23
peternied
peternied previously approved these changes Oct 4, 2022
Copy link
Member

@peternied peternied left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments, thanks for adding these tests

return Arrays.stream(header)
.filter(header -> requireNonNull(name, "Header name is mandatory.").equalsIgnoreCase(header.getName()))
.findFirst()
.orElse(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it should throw if no header is found

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shifting to throwing an exception would prevent tests cases from having to cover this scenario

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code doesn't seem updated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 353 to 362
public void assertThatBrowserDoesNotAskUserForCredentials() {
Header header = getHeader(HttpHeaders.WWW_AUTHENTICATE);
assertThat(header, nullValue());
}

public void assertThatBrowserAskUserForCredentials() {
Header header = getHeader(HttpHeaders.WWW_AUTHENTICATE);
assertThat(header, notNullValue());
assertThat(header.getValue(), containsStringIgnoringCase("basic"));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These feel more special purpose to authentication test cases rather than methods that would be used in all test cases, what do you think about moving them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: I moved these methods to test classes.

Copy link
Member

@cwperks cwperks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great @lukasz-soszynski-eliatra! These tests are nice and readable using the new framework. I have a couple of questions, but the changes look good to me.

HttpResponse response = client.getAuthInfo();

assertThat(response, is(notNullValue()));
response.assertStatusCode(SC_OK);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add an additional assertion to ensure we can deserialize the response like what is done in testUserShouldNotHaveAssignedCustomAttributes?

Suggested change
response.assertStatusCode(SC_OK);
response.assertStatusCode(SC_OK);
AuthInfo authInfo = response.getBodyAs(AuthInfo.class);
assertThat(authInfo, is(notNullValue()));


@Test
public void shouldRespondWith401WhenUserDoesNotExist() {
try (TestRestClient client = cluster.getRestClient(NOT_EXISTING_USER, INVALID_PASSWORD)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would all of these tests pass if an exception is thrown in getRestClient? I see this pattern used in a number of places in the codebase and I also see one instance where we add:

} catch (IOException ioe) {
    fail("unexpected exception")
}

See:

try (RestHighLevelClient restHighLevelClient = getRestClient(clusterInfo, "kirk-keystore.jks", "truststore.jks")) {
for (IndexRequest ir: new DynamicSecurityConfig().setSecurityRoles("roles_2.yml").getDynamicConfig(getResourceFolder())) {
restHighLevelClient.index(ir, RequestOptions.DEFAULT);
GetResponse getDocumentResponse = restHighLevelClient.get(new GetRequest(ir.index(), ir.id()), RequestOptions.DEFAULT);
assertThat(getDocumentResponse.isExists(), equalTo(true));
}
} catch (IOException ioe) {
throw new RuntimeException("Unexpected exception", ioe);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. In case an exception is thrown, how is it expected to be handled?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read up more here https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

If there is an exception it is bubbled up as if the getRestClient was executed inside the try block, since there is no catch(Exception e) {} block in this test case there is nothing to capture.

TLDR: Exceptions work as expected, the test would fail if there was a problem 🥳

@@ -336,8 +337,20 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params

public static class AuthcDomain implements ToXContentObject {

private static String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqZbjLUAWc+DZTkinQAdvy1GFjPHPnxheU89hSiWoDD3NOW76H3u3T7cCDdOah2msdxSlBmCBH6wik8qLYkcV8owWukQg3PQmbEhrdPaKo0QCgomWs4nLgtmEYqcZ+QQldd82MdTlQ1QmoQmI9Uxqs1SuaKZASp3Gy19y8su5CV+FZ6BruUw9HELK055sAwl3X7j5ouabXGbcib2goBF3P52LkvbJLuWr5HDZEOeSkwIeqSeMojASM96K5SdotD+HwEyjaTjzRPL2Aa1BEQFWOQ6CFJLyLH7ZStDuPM1mJU1VxIVfMbZrhsUBjAnIhRynmWxML7YlNqkP9j6jyOIYQIDAQAB";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be using the new automatic test certificate generation for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this is not a certificate but just a public key. The public key does not contain any metadata so it never expires.

Copy link
Member

@DarshitChanpura DarshitChanpura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ty for this PR @lukasz-soszynski-eliatra !


@Test
public void shouldRespondWith401WhenUserDoesNotExist() {
try (TestRestClient client = cluster.getRestClient(NOT_EXISTING_USER, INVALID_PASSWORD)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. In case an exception is thrown, how is it expected to be handled?

}

private void assertThatBrowserDoesNotAskUserForCredentials(HttpResponse response) {
String reason = "Browser ask user for credentials what is not expected";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Browser asked user for credentials which is not expected

}

@Test
public void browserShouldRequestUserForCredentials() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: testBrowserShouldRequestForCredentials

}

@Test
public void userShouldHaveAssignedCustomAttributes() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: testUserShouldHaveAssignedCustomAttributes

.challenge(false).config(ImmutableMap.of("jwt_header", headerName, "signing_key", signingKey));
return this;
}

public AuthcDomain challengingAuthenticator(String type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this should probly be rename to httpAuthenticatorWithChallenge.

@peternied peternied merged commit ca4917c into opensearch-project:main Oct 5, 2022
stephen-crawford pushed a commit to stephen-crawford/security that referenced this pull request Nov 10, 2022
* A few first tests for basic authentication.

Signed-off-by: Lukasz Soszynski <[email protected]>
Co-authored-by: Lukasz Soszynski <[email protected]>
Signed-off-by: Stephen Crawford <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants