| 
7 | 7 | 
 
  | 
8 | 8 | package org.elasticsearch.xpack.security.audit;  | 
9 | 9 | 
 
  | 
 | 10 | +import org.apache.http.entity.ContentType;  | 
 | 11 | +import org.apache.http.entity.StringEntity;  | 
10 | 12 | import org.elasticsearch.client.Request;  | 
11 | 13 | import org.elasticsearch.client.Response;  | 
12 | 14 | import org.elasticsearch.common.bytes.BytesReference;  | 
 | 
27 | 29 | import org.junit.ClassRule;  | 
28 | 30 | 
 
  | 
29 | 31 | import java.io.IOException;  | 
 | 32 | +import java.nio.charset.StandardCharsets;  | 
30 | 33 | import java.time.Instant;  | 
31 | 34 | import java.time.ZonedDateTime;  | 
32 | 35 | import java.time.format.DateTimeFormatter;  | 
 | 
37 | 40 | import java.util.concurrent.TimeUnit;  | 
38 | 41 | import java.util.function.Predicate;  | 
39 | 42 | 
 
  | 
 | 43 | +import static org.hamcrest.Matchers.allOf;  | 
40 | 44 | import static org.hamcrest.Matchers.containsString;  | 
41 | 45 | import static org.hamcrest.Matchers.hasEntry;  | 
42 | 46 | import static org.hamcrest.Matchers.hasKey;  | 
@@ -103,6 +107,25 @@ public void testFilteringOfRequestBodies() throws Exception {  | 
103 | 107 |         });  | 
104 | 108 |     }  | 
105 | 109 | 
 
  | 
 | 110 | +    public void testAuditAuthenticationSuccessForStreamingRequest() throws Exception {  | 
 | 111 | +        final Request request = new Request("POST", "/testindex/_bulk");  | 
 | 112 | +        request.setEntity(new StringEntity("""  | 
 | 113 | +            {"index":{}}  | 
 | 114 | +            {}  | 
 | 115 | +            """, ContentType.create("application/x-ndjson", StandardCharsets.UTF_8)));  | 
 | 116 | +        executeAndVerifyAudit(  | 
 | 117 | +            request,  | 
 | 118 | +            AuditLevel.AUTHENTICATION_SUCCESS,  | 
 | 119 | +            event -> assertThat(  | 
 | 120 | +                event,  | 
 | 121 | +                allOf(  | 
 | 122 | +                    hasEntry(LoggingAuditTrail.AUTHENTICATION_TYPE_FIELD_NAME, "REALM"),  | 
 | 123 | +                    hasEntry(LoggingAuditTrail.REQUEST_BODY_FIELD_NAME, "Request body had not been received at the time of the audit event")  | 
 | 124 | +                )  | 
 | 125 | +            )  | 
 | 126 | +        );  | 
 | 127 | +    }  | 
 | 128 | + | 
106 | 129 |     private void executeAndVerifyAudit(Request request, AuditLevel eventType, CheckedConsumer<Map<String, Object>, Exception> assertions)  | 
107 | 130 |         throws Exception {  | 
108 | 131 |         Instant start = Instant.now();  | 
 | 
0 commit comments