1111
1212package org .opensearch .security .auditlog .compliance ;
1313
14+ import java .io .IOException ;
1415import java .util .Collections ;
16+ import java .util .List ;
1517
1618import com .google .common .collect .ImmutableMap ;
1719import org .apache .http .Header ;
3032import org .opensearch .security .auditlog .AbstractAuditlogiUnitTest ;
3133import org .opensearch .security .auditlog .AuditTestUtils ;
3234import org .opensearch .security .auditlog .config .AuditConfig ;
35+ import org .opensearch .security .auditlog .impl .AuditMessage ;
3336import org .opensearch .security .auditlog .integration .TestAuditlogImpl ;
37+ import org .opensearch .security .auditlog .integration .TestAuditlogImpl .MessagesNotFoundException ;
3438import org .opensearch .security .compliance .ComplianceConfig ;
3539import org .opensearch .security .support .ConfigConstants ;
3640import org .opensearch .security .test .DynamicSecurityConfig ;
3741import org .opensearch .security .test .helper .rest .RestHelper .HttpResponse ;
3842
39- import static org .junit .Assert .assertFalse ;
43+ import static org .hamcrest .MatcherAssert .assertThat ;
44+ import static org .hamcrest .core .IsEqual .equalTo ;
45+ import static org .junit .Assert .assertThrows ;
4046import static org .junit .Assert .assertTrue ;
4147
4248public class ComplianceAuditlogTest extends AbstractAuditlogiUnitTest {
4349
4450 @ Test
4551 public void testSourceFilter () throws Exception {
46-
4752 Settings additionalSettings = Settings .builder ()
4853 .put ("plugins.security.audit.type" , TestAuditlogImpl .class .getName ())
4954 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT , true )
5055 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS , true )
5156 .put (ConfigConstants .OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED , false )
52- //.put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "emp")
5357 .put (ConfigConstants .OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS , "emp" )
5458 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES , "authenticated,GRANTED_PRIVILEGES" )
5559 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES , "authenticated,GRANTED_PRIVILEGES" )
@@ -66,7 +70,6 @@ public void testSourceFilter() throws Exception {
6670 rh .sendAdminCertificate = sendAdminCertificate ;
6771 rh .keystore = keystore ;
6872
69- System .out .println ("#### test source includes" );
7073 String search = "{" +
7174 " \" _source\" :[" +
7275 " \" Gender\" " +
@@ -80,13 +83,11 @@ public void testSourceFilter() throws Exception {
8083 " }" +
8184 "}" ;
8285
83- TestAuditlogImpl .clear ();
84- HttpResponse response = rh .executePostRequest ("_search?pretty" , search , encodeBasicHeader ("admin" , "admin" ));
85- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
86- System .out .println (response .getBody ());
87- Thread .sleep (1500 );
88- System .out .println (TestAuditlogImpl .sb .toString ());
89- Assert .assertTrue (TestAuditlogImpl .messages .size () >= 1 );
86+ final AuditMessage message = TestAuditlogImpl .doThenWaitForMessage (() -> {
87+ final HttpResponse response = rh .executePostRequest ("_search?pretty" , search , encodeBasicHeader ("admin" , "admin" ));
88+ Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
89+ });
90+
9091 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("COMPLIANCE_DOC_READ" ));
9192 Assert .assertFalse (TestAuditlogImpl .sb .toString ().contains ("Designation" ));
9293 Assert .assertFalse (TestAuditlogImpl .sb .toString ().contains ("Salary" ));
@@ -102,8 +103,6 @@ public void testComplianceEnable() throws Exception {
102103
103104 setup (additionalSettings );
104105
105- final boolean sendAdminCertificate = rh .sendAdminCertificate ;
106- final String keystore = rh .keystore ;
107106 rh .sendAdminCertificate = true ;
108107 rh .keystore = "auditlog/kirk-keystore.jks" ;
109108
@@ -112,21 +111,21 @@ public void testComplianceEnable() throws Exception {
112111 updateAuditConfig (AuditTestUtils .createAuditPayload (auditConfig ));
113112
114113 // make an event happen
115- TestAuditlogImpl .clear ();
116- rh .executePutRequest ("emp/_doc/0?refresh" , "{\" Designation\" : \" CEO\" , \" Gender\" : \" female\" , \" Salary\" : 100}" );
114+ TestAuditlogImpl .doThenWaitForMessages (() -> {
115+ rh .executePutRequest ("emp/_doc/0?refresh" , "{\" Designation\" : \" CEO\" , \" Gender\" : \" female\" , \" Salary\" : 100}" );
116+ }, 7 );
117117 assertTrue (TestAuditlogImpl .messages .toString ().contains ("COMPLIANCE_DOC_WRITE" ));
118-
119118 // disable compliance
120119 auditConfig = new AuditConfig (true , AuditConfig .Filter .DEFAULT , ComplianceConfig .from (ImmutableMap .of ("enabled" , false , "write_watched_indices" , Collections .singletonList ("emp" )), additionalSettings ));
121120 updateAuditConfig (AuditTestUtils .createAuditPayload (auditConfig ));
122121
123- // make an event happen
124- TestAuditlogImpl . clear ();
125- rh . executePutRequest ( "emp/_doc/1?refresh" , "{ \" Designation \" : \" CEO \" , \" Gender \" : \" female \" , \" Salary \" : 100}" );
126- assertFalse ( TestAuditlogImpl . messages . toString (). contains ( "COMPLIANCE_DOC_WRITE" ) );
127-
128- rh . sendAdminCertificate = sendAdminCertificate ;
129- rh . keystore = keystore ;
122+ // trigger an event that it not captured by the audit log
123+ final MessagesNotFoundException ex = assertThrows ( MessagesNotFoundException . class , () -> {
124+ TestAuditlogImpl . doThenWaitForMessage (() -> {
125+ rh . executePutRequest ( "emp/_doc/1?refresh" , "{ \" Designation \" : \" CEO \" , \" Gender \" : \" female \" , \" Salary \" : 100}" );
126+ });
127+ }) ;
128+ assertThat ( ex . getMissingCount (), equalTo ( 1 )) ;
130129 }
131130
132131 @ Test
@@ -154,7 +153,6 @@ public void testSourceFilterMsearch() throws Exception {
154153 rh .sendAdminCertificate = sendAdminCertificate ;
155154 rh .keystore = keystore ;
156155
157- System .out .println ("#### test source includes" );
158156 String search = "{}" +System .lineSeparator ()
159157 + "{" +
160158 " \" _source\" :[" +
@@ -211,22 +209,23 @@ public void testInternalConfig() throws Exception {
211209 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES , "authenticated,GRANTED_PRIVILEGES" )
212210 .build ();
213211
214- TestAuditlogImpl .clear ();
215212 setup (additionalSettings );
216213
217- try (RestHighLevelClient restHighLevelClient = getRestClient (clusterInfo , "kirk-keystore.jks" , "truststore.jks" )) {
218- for (IndexRequest ir : new DynamicSecurityConfig ().setSecurityRoles ("roles_2.yml" ).getDynamicConfig (getResourceFolder ())) {
219- restHighLevelClient .index (ir , RequestOptions .DEFAULT );
220- GetResponse getDocumentResponse = restHighLevelClient .get (new GetRequest (ir .index (), ir .id ()), RequestOptions .DEFAULT );
221- Assert .assertTrue ("Document not found:" + getDocumentResponse , getDocumentResponse .isExists ());
214+ final List <AuditMessage > messages = TestAuditlogImpl .doThenWaitForMessages (() -> {
215+ try (RestHighLevelClient restHighLevelClient = getRestClient (clusterInfo , "kirk-keystore.jks" , "truststore.jks" )) {
216+ for (IndexRequest ir : new DynamicSecurityConfig ().setSecurityRoles ("roles_2.yml" ).getDynamicConfig (getResourceFolder ())) {
217+ restHighLevelClient .index (ir , RequestOptions .DEFAULT );
218+ GetResponse getDocumentResponse = restHighLevelClient .get (new GetRequest (ir .index (), ir .id ()), RequestOptions .DEFAULT );
219+ assertThat (getDocumentResponse .isExists (), equalTo (true ));
220+ }
221+ } catch (IOException ioe ) {
222+ throw new RuntimeException ("Unexpected exception" , ioe );
222223 }
223- }
224224
225- HttpResponse response = rh .executeGetRequest ("_search?pretty" , encodeBasicHeader ("admin" , "admin" ));
226- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
227- Thread .sleep (1500 );
228- System .out .println (TestAuditlogImpl .sb .toString ());
229- Assert .assertTrue (TestAuditlogImpl .messages .size () >= 15 );
225+ HttpResponse response = rh .executeGetRequest ("_search?pretty" , encodeBasicHeader ("admin" , "admin" ));
226+ assertThat (response .getStatusCode (), equalTo (HttpStatus .SC_OK ));
227+ }, 14 );
228+
230229 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("COMPLIANCE_INTERNAL_CONFIG_READ" ));
231230 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("COMPLIANCE_INTERNAL_CONFIG_WRITE" ));
232231 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("anonymous_auth_enabled" ));
@@ -247,7 +246,7 @@ public void testInternalConfig() throws Exception {
247246 @ Test
248247 public void testExternalConfig () throws Exception {
249248
250- Settings additionalSettings = Settings .builder ()
249+ final Settings additionalSettings = Settings .builder ()
251250 .put ("plugins.security.audit.type" , TestAuditlogImpl .class .getName ())
252251 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT , false )
253252 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_ENABLE_REST , false )
@@ -258,23 +257,23 @@ public void testExternalConfig() throws Exception {
258257 .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES , "authenticated,GRANTED_PRIVILEGES" )
259258 .build ();
260259
261- TestAuditlogImpl .clear ();
262-
263- setup (additionalSettings );
264-
265- try (Client tc = getClient ()) {
260+ TestAuditlogImpl .doThenWaitForMessages (() -> {
261+ try {
262+ setup (additionalSettings );
263+ } catch (final Exception ex ) {
264+ throw new RuntimeException (ex );
265+ }
266266
267- for (IndexRequest ir : new DynamicSecurityConfig ().setSecurityRoles ("roles_2.yml" ).getDynamicConfig (getResourceFolder ())) {
268- tc .index (ir ).actionGet ();
267+ try (Client tc = getClient ()) {
268+ for (IndexRequest ir : new DynamicSecurityConfig ().setSecurityRoles ("roles_2.yml" ).getDynamicConfig (getResourceFolder ())) {
269+ tc .index (ir ).actionGet ();
270+ }
269271 }
270272
271- }
273+ final HttpResponse response = rh .executeGetRequest ("_search?pretty" , encodeBasicHeader ("admin" , "admin" ));
274+ Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
275+ }, 4 );
272276
273- HttpResponse response = rh .executeGetRequest ("_search?pretty" , encodeBasicHeader ("admin" , "admin" ));
274- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
275- System .out .println (response .getBody ());
276- Thread .sleep (1500 );
277- System .out .println (TestAuditlogImpl .sb .toString ());
278277 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("external_configuration" ));
279278 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("COMPLIANCE_EXTERNAL_CONFIG" ));
280279 Assert .assertTrue (TestAuditlogImpl .sb .toString ().contains ("opensearch_yml" ));
@@ -306,73 +305,29 @@ public void testUpdate() throws Exception {
306305 .actionGet ();
307306 }
308307
309- TestAuditlogImpl .clear ();
310-
311- String body = "{\" doc\" : {\" Age\" :123}}" ;
312-
313- HttpResponse response = rh .executePostRequest ("humanresources/_doc/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
314- Assert .assertEquals (HttpStatus .SC_CREATED , response .getStatusCode ());
315-
316- body = "{\" doc\" : {\" Age\" :456}}" ;
308+ final MessagesNotFoundException ex1 = assertThrows (MessagesNotFoundException .class , () -> {
309+ TestAuditlogImpl .doThenWaitForMessage (() -> {
310+ final String body = "{\" doc\" : {\" Age\" :123}}" ;
311+ final HttpResponse response = rh .executePostRequest ("humanresources/_doc/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
312+ Assert .assertEquals (HttpStatus .SC_CREATED , response .getStatusCode ());
313+ });
314+ });
315+ assertThat (ex1 .getMissingCount (), equalTo (1 ));
316+
317+
318+ final MessagesNotFoundException ex2 = assertThrows (MessagesNotFoundException .class , () -> {
319+ TestAuditlogImpl .doThenWaitForMessage (() -> {
320+ final String body = "{\" doc\" : {\" Age\" :456}}" ;
321+ final HttpResponse response = rh .executePostRequest ("humanresources/_update/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
322+ Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
323+ });
324+ });
325+ assertThat (ex2 .getMissingCount (), equalTo (1 ));
317326
318- response = rh .executePostRequest ("humanresources/_update/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
319- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
320- System .out .println (response .getBody ());
321- Thread .sleep (1500 );
322327 Assert .assertTrue (TestAuditlogImpl .messages .isEmpty ());
323328 Assert .assertTrue (validateMsgs (TestAuditlogImpl .messages ));
324329 }
325330
326- @ Test
327- public void testUpdatePerf () throws Exception {
328-
329- Settings additionalSettings = Settings .builder ()
330- .put ("plugins.security.audit.type" , TestAuditlogImpl .class .getName ())
331- .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT , false )
332- .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_ENABLE_REST , false )
333- .put (ConfigConstants .OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS , true )
334- .put (ConfigConstants .OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED , false )
335- .put (ConfigConstants .SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED , false )
336- .put (ConfigConstants .OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES , "humanresources" )
337- .put (ConfigConstants .OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS , "humanresources,*" )
338- .build ();
339-
340- setup (additionalSettings );
341- TestAuditlogImpl .clear ();
342-
343- /*try (TransportClient tc = getInternalTransportClient()) {
344- for(int i=0; i<5000; i++) {
345-
346- tc.prepareIndex("humanresources", "employees")
347- //.setRefreshPolicy(RefreshPolicy.IMMEDIATE)
348- .setSource("Age", 456+i)
349- .execute();
350- }
351- }*/
352-
353-
354-
355- for (int i =0 ; i <1 ; i ++) {
356- HttpResponse response = rh .executePostRequest ("humanresources/_doc/" +i +"" , "{\" customer\" : {\" Age\" :" +i +"}}" , encodeBasicHeader ("admin" , "admin" ));
357- Assert .assertEquals (HttpStatus .SC_CREATED , response .getStatusCode ());
358- response = rh .executePostRequest ("humanresources/_doc/" +i +"" , "{\" customer\" : {\" Age\" :" +(i +2 )+"}}" , encodeBasicHeader ("admin" , "admin" ));
359- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
360- response = rh .executePostRequest ("humanresources/_update/" +i +"?pretty" , "{\" doc\" : {\" doesel\" :" +(i +3 )+"}}" , encodeBasicHeader ("admin" , "admin" ));
361- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
362- }
363-
364- /*Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode());
365- System.out.println(response.getBody());
366- Thread.sleep(1500);
367- Assert.assertTrue(TestAuditlogImpl.messages.isEmpty());
368- Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages));*/
369-
370- Thread .sleep (1500 );
371- System .out .println ("Messages: " +TestAuditlogImpl .messages .size ());
372- //System.out.println(TestAuditlogImpl.sb.toString());
373-
374- }
375-
376331 @ Test
377332 public void testWriteHistory () throws Exception {
378333
@@ -387,7 +342,6 @@ public void testWriteHistory() throws Exception {
387342
388343 setup (additionalSettings );
389344
390-
391345 try (Client tc = getClient ()) {
392346 tc .prepareIndex ("humanresources" )
393347 .setRefreshPolicy (RefreshPolicy .IMMEDIATE )
@@ -396,24 +350,18 @@ public void testWriteHistory() throws Exception {
396350 .actionGet ();
397351 }
398352
399- TestAuditlogImpl .clear ();
400-
401- String body = "{\" doc\" : {\" Age\" :123}}" ;
402-
403- HttpResponse response = rh .executePostRequest ("humanresources/_doc/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
404- Assert .assertEquals (HttpStatus .SC_CREATED , response .getStatusCode ());
405- System .out .println (response .getBody ());
406- Thread .sleep (1500 );
407- System .out .println (TestAuditlogImpl .sb .toString ());
353+ TestAuditlogImpl .doThenWaitForMessage (() -> {
354+ final String body = "{\" doc\" : {\" Age\" :123}}" ;
355+ final HttpResponse response = rh .executePostRequest ("humanresources/_doc/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
356+ Assert .assertEquals (HttpStatus .SC_CREATED , response .getStatusCode ());
357+ });
408358 Assert .assertTrue (TestAuditlogImpl .sb .toString ().split (".*audit_compliance_diff_content.*replace.*" ).length == 1 );
409359
410- body = "{\" doc\" : {\" Age\" :555}}" ;
411- TestAuditlogImpl .clear ();
412- response = rh .executePostRequest ("humanresources/_update/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
413- Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
414- System .out .println (response .getBody ());
415- Thread .sleep (1500 );
416- System .out .println (TestAuditlogImpl .sb .toString ());
360+ TestAuditlogImpl .doThenWaitForMessage (() -> {
361+ final String body = "{\" doc\" : {\" Age\" :555}}" ;
362+ final HttpResponse response = rh .executePostRequest ("humanresources/_update/100?pretty" , body , encodeBasicHeader ("admin" , "admin" ));
363+ Assert .assertEquals (HttpStatus .SC_OK , response .getStatusCode ());
364+ });
417365 Assert .assertTrue (TestAuditlogImpl .sb .toString ().split (".*audit_compliance_diff_content.*replace.*" ).length == 1 );
418366 }
419367}
0 commit comments