@@ -115,31 +115,36 @@ public void getUser(String username, ActionListener<User> listener) {
115
115
*/
116
116
public void getUsers (String [] userNames , final ActionListener <Collection <User >> listener ) {
117
117
final Consumer <Exception > handleException = (t ) -> {
118
- if (t instanceof IndexNotFoundException ) {
119
- logger .trace ("could not retrieve users because security index does not exist" );
120
- // We don't invoke the onFailure listener here, instead just pass an empty list
121
- listener .onResponse (Collections .emptyList ());
122
- } else {
123
- listener .onFailure (t );
118
+ if (TransportActions .isShardNotAvailableException (t )) {
119
+ logger .trace ("could not retrieve users because of a shard not available exception" , t );
120
+ if (t instanceof IndexNotFoundException ) {
121
+ // We don't invoke the onFailure listener here, instead just pass an empty list
122
+ // as the index doesn't exist. Could have been deleted between checks and execution
123
+ listener .onResponse (Collections .emptyList ());
124
+ } else {
125
+ listener .onFailure (t );
126
+ }
124
127
}
128
+ listener .onFailure (t );
125
129
};
126
130
127
- if ( securityIndex .indexExists () == false ) {
128
- // TODO remove this short circuiting and fix tests that fail without this!
131
+ final SecurityIndexManager frozenSecurityIndex = this . securityIndex .freeze ();
132
+ if ( frozenSecurityIndex . indexExists () == false ) {
129
133
listener .onResponse (Collections .emptyList ());
134
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
135
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
130
136
} else if (userNames .length == 1 ) { // optimization for single user lookup
131
137
final String username = userNames [0 ];
132
138
getUserAndPassword (username , ActionListener .wrap (
133
139
(uap ) -> listener .onResponse (uap == null ? Collections .emptyList () : Collections .singletonList (uap .user ())),
134
140
handleException ));
135
141
} else {
136
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () -> {
142
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () -> {
137
143
final QueryBuilder query ;
138
144
if (userNames == null || userNames .length == 0 ) {
139
145
query = QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), USER_DOC_TYPE );
140
146
} else {
141
- final String [] users = Arrays .asList (userNames ).stream ()
142
- .map (s -> getIdForUser (USER_DOC_TYPE , s )).toArray (String []::new );
147
+ final String [] users = Arrays .stream (userNames ).map (s -> getIdForUser (USER_DOC_TYPE , s )).toArray (String []::new );
143
148
query = QueryBuilders .boolQuery ().filter (QueryBuilders .idsQuery (NativeUserStoreField .INDEX_TYPE ).addIds (users ));
144
149
}
145
150
final Supplier <ThreadContext .StoredContext > supplier = client .threadPool ().getThreadContext ().newRestorableContext (false );
@@ -161,10 +166,13 @@ public void getUsers(String[] userNames, final ActionListener<Collection<User>>
161
166
}
162
167
163
168
void getUserCount (final ActionListener <Long > listener ) {
164
- if (securityIndex .indexExists () == false ) {
169
+ final SecurityIndexManager frozenSecurityIndex = this .securityIndex .freeze ();
170
+ if (frozenSecurityIndex .indexExists () == false ) {
165
171
listener .onResponse (0L );
172
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
173
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
166
174
} else {
167
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
175
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
168
176
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
169
177
client .prepareSearch (SECURITY_INDEX_NAME )
170
178
.setQuery (QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), USER_DOC_TYPE ))
@@ -188,11 +196,16 @@ public void onFailure(Exception e) {
188
196
* Async method to retrieve a user and their password
189
197
*/
190
198
private void getUserAndPassword (final String user , final ActionListener <UserAndPassword > listener ) {
191
- if (securityIndex .indexExists () == false ) {
192
- // TODO remove this short circuiting and fix tests that fail without this!
199
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
200
+ if (frozenSecurityIndex .isAvailable () == false ) {
201
+ if (frozenSecurityIndex .indexExists ()) {
202
+ logger .trace ("could not retrieve user [{}] because security index does not exist" , user );
203
+ } else {
204
+ logger .error ("security index is unavailable. short circuiting retrieval of user [{}]" , user );
205
+ }
193
206
listener .onResponse (null );
194
207
} else {
195
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
208
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
196
209
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
197
210
client .prepareGet (SECURITY_INDEX_NAME ,
198
211
NativeUserStoreField .INDEX_TYPE , getIdForUser (USER_DOC_TYPE , user )).request (),
@@ -473,26 +486,31 @@ public void onFailure(Exception e) {
473
486
}
474
487
475
488
public void deleteUser (final DeleteUserRequest deleteUserRequest , final ActionListener <Boolean > listener ) {
489
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
476
490
if (isTribeNode ) {
477
491
listener .onFailure (new UnsupportedOperationException ("users may not be deleted using a tribe node" ));
492
+ } else if (frozenSecurityIndex .indexExists () == false ) {
493
+ listener .onResponse (false );
494
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
495
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
478
496
} else {
479
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () -> {
497
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () -> {
480
498
DeleteRequest request = client .prepareDelete (SECURITY_INDEX_NAME ,
481
- NativeUserStoreField .INDEX_TYPE , getIdForUser (USER_DOC_TYPE , deleteUserRequest .username ())).request ();
499
+ NativeUserStoreField .INDEX_TYPE , getIdForUser (USER_DOC_TYPE , deleteUserRequest .username ())).request ();
482
500
request .setRefreshPolicy (deleteUserRequest .getRefreshPolicy ());
483
501
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN , request ,
484
- new ActionListener <DeleteResponse >() {
485
- @ Override
486
- public void onResponse (DeleteResponse deleteResponse ) {
487
- clearRealmCache (deleteUserRequest .username (), listener ,
488
- deleteResponse .getResult () == DocWriteResponse .Result .DELETED );
489
- }
502
+ new ActionListener <DeleteResponse >() {
503
+ @ Override
504
+ public void onResponse (DeleteResponse deleteResponse ) {
505
+ clearRealmCache (deleteUserRequest .username (), listener ,
506
+ deleteResponse .getResult () == DocWriteResponse .Result .DELETED );
507
+ }
490
508
491
- @ Override
492
- public void onFailure (Exception e ) {
493
- listener .onFailure (e );
494
- }
495
- }, client ::delete );
509
+ @ Override
510
+ public void onFailure (Exception e ) {
511
+ listener .onFailure (e );
512
+ }
513
+ }, client ::delete );
496
514
});
497
515
}
498
516
}
@@ -516,11 +534,13 @@ void verifyPassword(String username, final SecureString password, ActionListener
516
534
}
517
535
518
536
void getReservedUserInfo (String username , ActionListener <ReservedUserInfo > listener ) {
519
- if ( securityIndex .indexExists () == false ) {
520
- // TODO remove this short circuiting and fix tests that fail without this!
537
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
538
+ if ( frozenSecurityIndex . indexExists () == false ) {
521
539
listener .onResponse (null );
540
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
541
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
522
542
} else {
523
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
543
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
524
544
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
525
545
client .prepareGet (SECURITY_INDEX_NAME , NativeUserStoreField .INDEX_TYPE ,
526
546
getIdForUser (NativeUserStoreField .RESERVED_USER_TYPE , username )).request (),
@@ -559,49 +579,56 @@ public void onFailure(Exception e) {
559
579
}
560
580
561
581
void getAllReservedUserInfo (ActionListener <Map <String , ReservedUserInfo >> listener ) {
562
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
563
- executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
564
- client .prepareSearch (SECURITY_INDEX_NAME )
565
- .setQuery (QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), NativeUserStoreField .RESERVED_USER_TYPE ))
582
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
583
+ if (frozenSecurityIndex .indexExists () == false ) {
584
+ listener .onResponse (Collections .emptyMap ());
585
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
586
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
587
+ } else {
588
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
589
+ executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
590
+ client .prepareSearch (SECURITY_INDEX_NAME )
591
+ .setQuery (QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), RESERVED_USER_TYPE ))
566
592
.setFetchSource (true ).request (),
567
- new ActionListener <SearchResponse >() {
568
- @ Override
569
- public void onResponse (SearchResponse searchResponse ) {
570
- Map <String , ReservedUserInfo > userInfos = new HashMap <>();
571
- assert searchResponse .getHits ().getTotalHits () <= 10 :
593
+ new ActionListener <SearchResponse >() {
594
+ @ Override
595
+ public void onResponse (SearchResponse searchResponse ) {
596
+ Map <String , ReservedUserInfo > userInfos = new HashMap <>();
597
+ assert searchResponse .getHits ().getTotalHits () <= 10 :
572
598
"there are more than 10 reserved users we need to change this to retrieve them all!" ;
573
- for (SearchHit searchHit : searchResponse .getHits ().getHits ()) {
574
- Map <String , Object > sourceMap = searchHit .getSourceAsMap ();
575
- String password = (String ) sourceMap .get (Fields .PASSWORD .getPreferredName ());
576
- Boolean enabled = (Boolean ) sourceMap .get (Fields .ENABLED .getPreferredName ());
577
- final String id = searchHit .getId ();
578
- assert id != null && id .startsWith (NativeUserStoreField . RESERVED_USER_TYPE ) :
599
+ for (SearchHit searchHit : searchResponse .getHits ().getHits ()) {
600
+ Map <String , Object > sourceMap = searchHit .getSourceAsMap ();
601
+ String password = (String ) sourceMap .get (Fields .PASSWORD .getPreferredName ());
602
+ Boolean enabled = (Boolean ) sourceMap .get (Fields .ENABLED .getPreferredName ());
603
+ final String id = searchHit .getId ();
604
+ assert id != null && id .startsWith (RESERVED_USER_TYPE ) :
579
605
"id [" + id + "] does not start with reserved-user prefix" ;
580
- final String username = id .substring (NativeUserStoreField .RESERVED_USER_TYPE .length () + 1 );
581
- if (password == null ) {
582
- listener .onFailure (new IllegalStateException ("password hash must not be null!" ));
583
- return ;
584
- } else if (enabled == null ) {
585
- listener .onFailure (new IllegalStateException ("enabled must not be null!" ));
586
- return ;
587
- } else {
588
- userInfos .put (username , new ReservedUserInfo (password .toCharArray (), enabled , false ));
606
+ final String username = id .substring (RESERVED_USER_TYPE .length () + 1 );
607
+ if (password == null ) {
608
+ listener .onFailure (new IllegalStateException ("password hash must not be null!" ));
609
+ return ;
610
+ } else if (enabled == null ) {
611
+ listener .onFailure (new IllegalStateException ("enabled must not be null!" ));
612
+ return ;
613
+ } else {
614
+ userInfos .put (username , new ReservedUserInfo (password .toCharArray (), enabled , false ));
615
+ }
589
616
}
617
+ listener .onResponse (userInfos );
590
618
}
591
- listener .onResponse (userInfos );
592
- }
593
619
594
- @ Override
595
- public void onFailure (Exception e ) {
596
- if (e instanceof IndexNotFoundException ) {
597
- logger .trace ("could not retrieve built in users since security index does not exist" , e );
598
- listener .onResponse (Collections .emptyMap ());
599
- } else {
600
- logger .error ("failed to retrieve built in users" , e );
601
- listener .onFailure (e );
620
+ @ Override
621
+ public void onFailure (Exception e ) {
622
+ if (e instanceof IndexNotFoundException ) {
623
+ logger .trace ("could not retrieve built in users since security index does not exist" , e );
624
+ listener .onResponse (Collections .emptyMap ());
625
+ } else {
626
+ logger .error ("failed to retrieve built in users" , e );
627
+ listener .onFailure (e );
628
+ }
602
629
}
603
- }
604
- }, client :: search ));
630
+ }, client :: search ));
631
+ }
605
632
}
606
633
607
634
private <Response > void clearRealmCache (String username , ActionListener <Response > listener , Response response ) {
0 commit comments