7
7
package org .elasticsearch .xpack .security .authc ;
8
8
9
9
import com .google .common .collect .Sets ;
10
-
11
10
import org .elasticsearch .ElasticsearchSecurityException ;
12
11
import org .elasticsearch .action .DocWriteResponse ;
13
12
import org .elasticsearch .action .admin .cluster .health .ClusterHealthResponse ;
50
49
import java .util .concurrent .ExecutionException ;
51
50
import java .util .concurrent .TimeUnit ;
52
51
import java .util .stream .Collectors ;
52
+ import java .util .stream .Stream ;
53
53
54
54
import static org .elasticsearch .index .mapper .MapperService .SINGLE_MAPPING_NAME ;
55
55
import static org .elasticsearch .xpack .core .security .index .RestrictedIndicesNames .SECURITY_MAIN_ALIAS ;
@@ -90,6 +90,8 @@ public void wipeSecurityIndex() throws Exception {
90
90
@ Override
91
91
public String configRoles () {
92
92
return super .configRoles () + "\n " +
93
+ "no_api_key_role:\n " +
94
+ " cluster: [\" manage_token\" ]\n " +
93
95
"manage_api_key_role:\n " +
94
96
" cluster: [\" manage_api_key\" ]\n " +
95
97
"manage_own_api_key_role:\n " +
@@ -101,13 +103,15 @@ public String configUsers() {
101
103
final String usersPasswdHashed = new String (
102
104
getFastStoredHashAlgoForTests ().hash (SecuritySettingsSourceField .TEST_PASSWORD_SECURE_STRING ));
103
105
return super .configUsers () +
106
+ "user_with_no_api_key_role:" + usersPasswdHashed + "\n " +
104
107
"user_with_manage_api_key_role:" + usersPasswdHashed + "\n " +
105
108
"user_with_manage_own_api_key_role:" + usersPasswdHashed + "\n " ;
106
109
}
107
110
108
111
@ Override
109
112
public String configUsersRoles () {
110
113
return super .configUsersRoles () +
114
+ "no_api_key_role:user_with_no_api_key_role\n " +
111
115
"manage_api_key_role:user_with_manage_api_key_role\n " +
112
116
"manage_own_api_key_role:user_with_manage_own_api_key_role\n " ;
113
117
}
@@ -560,6 +564,51 @@ public void testGetApiKeysOwnedByCurrentAuthenticatedUser() throws InterruptedEx
560
564
response , userWithManageApiKeyRoleApiKeys .stream ().map (o -> o .getId ()).collect (Collectors .toSet ()), null );
561
565
}
562
566
567
+ public void testGetAllApiKeys () throws InterruptedException , ExecutionException {
568
+ int noOfSuperuserApiKeys = randomIntBetween (3 , 5 );
569
+ int noOfApiKeysForUserWithManageApiKeyRole = randomIntBetween (3 , 5 );
570
+ int noOfApiKeysForUserWithManageOwnApiKeyRole = randomIntBetween (3 ,7 );
571
+ List <CreateApiKeyResponse > defaultUserCreatedKeys = createApiKeys (noOfSuperuserApiKeys , null );
572
+ List <CreateApiKeyResponse > userWithManageApiKeyRoleApiKeys = createApiKeys ("user_with_manage_api_key_role" ,
573
+ noOfApiKeysForUserWithManageApiKeyRole , null , "monitor" );
574
+ List <CreateApiKeyResponse > userWithManageOwnApiKeyRoleApiKeys = createApiKeys ("user_with_manage_own_api_key_role" ,
575
+ noOfApiKeysForUserWithManageOwnApiKeyRole , null , "monitor" );
576
+
577
+ final Client client = client ().filterWithHeader (Collections .singletonMap ("Authorization" , UsernamePasswordToken
578
+ .basicAuthHeaderValue ("user_with_manage_api_key_role" , SecuritySettingsSourceField .TEST_PASSWORD_SECURE_STRING )));
579
+ final SecurityClient securityClient = new SecurityClient (client );
580
+ PlainActionFuture <GetApiKeyResponse > listener = new PlainActionFuture <>();
581
+ securityClient .getApiKey (new GetApiKeyRequest (), listener );
582
+ GetApiKeyResponse response = listener .get ();
583
+ int totalApiKeys = noOfSuperuserApiKeys + noOfApiKeysForUserWithManageApiKeyRole + noOfApiKeysForUserWithManageOwnApiKeyRole ;
584
+ List <CreateApiKeyResponse > allApiKeys = new ArrayList <>();
585
+ Stream .of (defaultUserCreatedKeys , userWithManageApiKeyRoleApiKeys , userWithManageOwnApiKeyRoleApiKeys ).forEach (
586
+ allApiKeys ::addAll );
587
+ verifyGetResponse (new String []{SecuritySettingsSource .TEST_SUPERUSER , "user_with_manage_api_key_role" ,
588
+ "user_with_manage_own_api_key_role" }, totalApiKeys , allApiKeys , response ,
589
+ allApiKeys .stream ().map (o -> o .getId ()).collect (Collectors .toSet ()), null );
590
+ }
591
+
592
+ public void testGetAllApiKeysFailsForUserWithNoRoleOrRetrieveOwnApiKeyRole () throws InterruptedException , ExecutionException {
593
+ int noOfSuperuserApiKeys = randomIntBetween (3 , 5 );
594
+ int noOfApiKeysForUserWithManageApiKeyRole = randomIntBetween (3 , 5 );
595
+ int noOfApiKeysForUserWithManageOwnApiKeyRole = randomIntBetween (3 ,7 );
596
+ List <CreateApiKeyResponse > defaultUserCreatedKeys = createApiKeys (noOfSuperuserApiKeys , null );
597
+ List <CreateApiKeyResponse > userWithManageApiKeyRoleApiKeys = createApiKeys ("user_with_manage_api_key_role" ,
598
+ noOfApiKeysForUserWithManageApiKeyRole , null , "monitor" );
599
+ List <CreateApiKeyResponse > userWithManageOwnApiKeyRoleApiKeys = createApiKeys ("user_with_manage_own_api_key_role" ,
600
+ noOfApiKeysForUserWithManageOwnApiKeyRole , null , "monitor" );
601
+
602
+ final String withUser = randomFrom ("user_with_manage_own_api_key_role" , "user_with_no_api_key_role" );
603
+ final Client client = client ().filterWithHeader (Collections .singletonMap ("Authorization" , UsernamePasswordToken
604
+ .basicAuthHeaderValue (withUser , SecuritySettingsSourceField .TEST_PASSWORD_SECURE_STRING )));
605
+ final SecurityClient securityClient = new SecurityClient (client );
606
+ PlainActionFuture <GetApiKeyResponse > listener = new PlainActionFuture <>();
607
+ securityClient .getApiKey (new GetApiKeyRequest (), listener );
608
+ ElasticsearchSecurityException ese = expectThrows (ElasticsearchSecurityException .class , () -> listener .actionGet ());
609
+ assertErrorMessage (ese , "cluster:admin/xpack/security/api_key/get" , withUser );
610
+ }
611
+
563
612
public void testInvalidateApiKeysOwnedByCurrentAuthenticatedUser () throws InterruptedException , ExecutionException {
564
613
int noOfSuperuserApiKeys = randomIntBetween (3 , 5 );
565
614
int noOfApiKeysForUserWithManageApiKeyRole = randomIntBetween (3 , 5 );
@@ -646,6 +695,11 @@ private void verifyGetResponse(int expectedNumberOfApiKeys, List<CreateApiKeyRes
646
695
647
696
private void verifyGetResponse (String user , int expectedNumberOfApiKeys , List <CreateApiKeyResponse > responses ,
648
697
GetApiKeyResponse response , Set <String > validApiKeyIds , List <String > invalidatedApiKeyIds ) {
698
+ verifyGetResponse (new String []{user }, expectedNumberOfApiKeys , responses , response , validApiKeyIds , invalidatedApiKeyIds );
699
+ }
700
+
701
+ private void verifyGetResponse (String [] user , int expectedNumberOfApiKeys , List <CreateApiKeyResponse > responses ,
702
+ GetApiKeyResponse response , Set <String > validApiKeyIds , List <String > invalidatedApiKeyIds ) {
649
703
assertThat (response .getApiKeyInfos ().length , equalTo (expectedNumberOfApiKeys ));
650
704
List <String > expectedIds = responses .stream ().filter (o -> validApiKeyIds .contains (o .getId ())).map (o -> o .getId ())
651
705
.collect (Collectors .toList ());
@@ -658,7 +712,7 @@ private void verifyGetResponse(String user, int expectedNumberOfApiKeys, List<Cr
658
712
.collect (Collectors .toList ());
659
713
assertThat (actualNames , containsInAnyOrder (expectedNames .toArray (Strings .EMPTY_ARRAY )));
660
714
Set <String > expectedUsernames = (validApiKeyIds .isEmpty ()) ? Collections .emptySet ()
661
- : Collections . singleton (user );
715
+ : Sets . newHashSet (user );
662
716
Set <String > actualUsernames = Arrays .stream (response .getApiKeyInfos ()).filter (o -> o .isInvalidated () == false )
663
717
.map (o -> o .getUsername ()).collect (Collectors .toSet ());
664
718
assertThat (actualUsernames , containsInAnyOrder (expectedUsernames .toArray (Strings .EMPTY_ARRAY )));
@@ -695,4 +749,9 @@ private void assertErrorMessage(final ElasticsearchSecurityException ese, String
695
749
assertThat (ese .getMessage (),
696
750
is ("action [" + action + "] is unauthorized for API key id [" + apiKeyId + "] of user [" + userName + "]" ));
697
751
}
752
+
753
+ private void assertErrorMessage (final ElasticsearchSecurityException ese , String action , String userName ) {
754
+ assertThat (ese .getMessage (),
755
+ is ("action [" + action + "] is unauthorized for user [" + userName + "]" ));
756
+ }
698
757
}
0 commit comments