@@ -352,14 +352,30 @@ public void testAuthenticateWithRoleMapping() throws Exception {
352352 final boolean principalIsEmailAddress = randomBoolean ();
353353 final Boolean populateUserMetadata = randomFrom (Boolean .TRUE , Boolean .FALSE , null );
354354 final String authenticatingRealm = randomBoolean () ? REALM_NAME : null ;
355- AuthenticationResult <User > result = performAuthentication (
356- roleMapper ,
357- useNameId ,
358- principalIsEmailAddress ,
359- populateUserMetadata ,
360- false ,
361- authenticatingRealm
362- );
355+ final boolean testWithDelimiter = randomBoolean ();
356+ final AuthenticationResult <User > result ;
357+
358+ if (testWithDelimiter ) {
359+ result = performAuthentication (
360+ roleMapper ,
361+ useNameId ,
362+ principalIsEmailAddress ,
363+ populateUserMetadata ,
364+ false ,
365+ authenticatingRealm ,
366+ List .of ("STRIKE Team: Delta$shield" ),
367+ "$"
368+ );
369+ } else {
370+ result = performAuthentication (
371+ roleMapper ,
372+ useNameId ,
373+ principalIsEmailAddress ,
374+ populateUserMetadata ,
375+ false ,
376+ authenticatingRealm
377+ );
378+ }
363379 assertThat (result , notNullValue ());
364380 assertThat (result .getStatus (), equalTo (AuthenticationResult .Status .SUCCESS ));
365381 assertThat (result .getValue ().principal (), equalTo (useNameId ? "clint.barton" : "cbarton" ));
@@ -377,7 +393,11 @@ public void testAuthenticateWithRoleMapping() throws Exception {
377393 }
378394
379395 assertThat (userData .get ().getUsername (), equalTo (useNameId ? "clint.barton" : "cbarton" ));
380- assertThat (userData .get ().getGroups (), containsInAnyOrder ("avengers" , "shield" ));
396+ if (testWithDelimiter ) {
397+ assertThat (userData .get ().getGroups (), containsInAnyOrder ("STRIKE Team: Delta" , "shield" ));
398+ } else {
399+ assertThat (userData .get ().getGroups (), containsInAnyOrder ("avengers" , "shield" ));
400+ }
381401 }
382402
383403 public void testAuthenticateWithAuthorizingRealm () throws Exception {
@@ -431,6 +451,28 @@ private AuthenticationResult<User> performAuthentication(
431451 Boolean populateUserMetadata ,
432452 boolean useAuthorizingRealm ,
433453 String authenticatingRealm
454+ ) throws Exception {
455+ return performAuthentication (
456+ roleMapper ,
457+ useNameId ,
458+ principalIsEmailAddress ,
459+ populateUserMetadata ,
460+ useAuthorizingRealm ,
461+ authenticatingRealm ,
462+ Arrays .asList ("avengers" , "shield" ),
463+ null
464+ );
465+ }
466+
467+ private AuthenticationResult <User > performAuthentication (
468+ UserRoleMapper roleMapper ,
469+ boolean useNameId ,
470+ boolean principalIsEmailAddress ,
471+ Boolean populateUserMetadata ,
472+ boolean useAuthorizingRealm ,
473+ String authenticatingRealm ,
474+ List <String > groups ,
475+ String groupsDelimiter
434476 ) throws Exception {
435477 final EntityDescriptor idp = mockIdp ();
436478 final SpConfiguration sp = new SpConfiguration ("<sp>" , "https://saml/" , null , null , null , Collections .emptyList ());
@@ -453,8 +495,12 @@ private AuthenticationResult<User> performAuthentication(
453495
454496 final Settings .Builder settingsBuilder = Settings .builder ()
455497 .put (getFullSettingKey (REALM_NAME , SamlRealmSettings .PRINCIPAL_ATTRIBUTE .getAttribute ()), useNameId ? "nameid" : "uid" )
456- .put (getFullSettingKey (REALM_NAME , SamlRealmSettings .GROUPS_ATTRIBUTE .getAttribute ()), "groups" )
498+ .put (getFullSettingKey (REALM_NAME , SamlRealmSettings .GROUPS_ATTRIBUTE .getAttributeSetting (). getAttribute ()), "groups" )
457499 .put (getFullSettingKey (REALM_NAME , SamlRealmSettings .MAIL_ATTRIBUTE .getAttribute ()), "mail" );
500+
501+ if (groupsDelimiter != null ) {
502+ settingsBuilder .put (getFullSettingKey (REALM_NAME , SamlRealmSettings .GROUPS_ATTRIBUTE .getDelimiter ()), groupsDelimiter );
503+ }
458504 if (principalIsEmailAddress ) {
459505 final boolean anchoredMatch = randomBoolean ();
460506 settingsBuilder .put (
@@ -497,7 +543,7 @@ private AuthenticationResult<User> performAuthentication(
497543 randomAlphaOfLength (16 ),
498544 Arrays .asList (
499545 new SamlAttributes .SamlAttribute ("urn:oid:0.9.2342.19200300.100.1.1" , "uid" , Collections .singletonList (uidValue )),
500- new SamlAttributes .SamlAttribute ("urn:oid:1.3.6.1.4.1.5923.1.5.1.1" , "groups" , Arrays . asList ( "avengers" , "shield" ) ),
546+ new SamlAttributes .SamlAttribute ("urn:oid:1.3.6.1.4.1.5923.1.5.1.1" , "groups" , groups ),
501547 new SamlAttributes .
SamlAttribute (
"urn:oid:0.9.2342.19200300.100.1.3" ,
"mail" ,
Arrays .
asList (
"[email protected] " ))
502548 )
503549 );
@@ -534,7 +580,120 @@ public SamlRealm buildRealm(
534580 }
535581 }
536582
537- public void testAttributeSelectionWithRegex () throws Exception {
583+ public void testAttributeSelectionWithSplit () {
584+ List <String > strings = performAttributeSelectionWithSplit ("," , "departments" , "engineering" , "elasticsearch-admins" , "employees" );
585+ assertThat ("For attributes: " + strings , strings , contains ("engineering" , "elasticsearch-admins" , "employees" ));
586+ }
587+
588+ public void testAttributeSelectionWithSplitEmptyInput () {
589+ List <String > strings = performAttributeSelectionWithSplit ("," , "departments" );
590+ assertThat ("For attributes: " + strings , strings , is (empty ()));
591+ }
592+
593+ public void testAttributeSelectionWithSplitJustDelimiter () {
594+ List <String > strings = performAttributeSelectionWithSplit ("," , "," );
595+ assertThat ("For attributes: " + strings , strings , is (empty ()));
596+ }
597+
598+ public void testAttributeSelectionWithSplitNoDelimiter () {
599+ List <String > strings = performAttributeSelectionWithSplit ("," , "departments" , "elasticsearch-team" );
600+ assertThat ("For attributes: " + strings , strings , contains ("elasticsearch-team" ));
601+ }
602+
603+ private List <String > performAttributeSelectionWithSplit (String delimiter , String groupAttributeName , String ... returnedGroups ) {
604+ final Settings settings = Settings .builder ()
605+ .put (REALM_SETTINGS_PREFIX + ".attributes.groups" , groupAttributeName )
606+ .put (REALM_SETTINGS_PREFIX + ".attribute_delimiters.groups" , delimiter )
607+ .build ();
608+
609+ final RealmConfig config = buildConfig (settings );
610+
611+ final SamlRealmSettings .AttributeSettingWithDelimiter groupSetting = new SamlRealmSettings .AttributeSettingWithDelimiter ("groups" );
612+ final SamlRealm .AttributeParser parser = SamlRealm .AttributeParser .forSetting (logger , groupSetting , config );
613+
614+ final SamlAttributes attributes = new SamlAttributes (
615+ new SamlNameId (NameIDType .TRANSIENT , randomAlphaOfLength (24 ), null , null , null ),
616+ randomAlphaOfLength (16 ),
617+ Collections .singletonList (
618+ new SamlAttributes .SamlAttribute (
619+ "departments" ,
620+ "departments" ,
621+ Collections .singletonList (String .join (delimiter , returnedGroups ))
622+ )
623+ )
624+ );
625+ return parser .getAttribute (attributes );
626+ }
627+
628+ public void testAttributeSelectionWithDelimiterAndPatternThrowsSettingsException () throws Exception {
629+ final Settings settings = Settings .builder ()
630+ .put (REALM_SETTINGS_PREFIX + ".attributes.groups" , "departments" )
631+ .put (REALM_SETTINGS_PREFIX + ".attribute_delimiters.groups" , "," )
632+ .put (REALM_SETTINGS_PREFIX + ".attribute_patterns.groups" , "^(.+)@\\ w+.example.com$" )
633+ .build ();
634+
635+ final RealmConfig config = buildConfig (settings );
636+
637+ final SamlRealmSettings .AttributeSettingWithDelimiter groupSetting = new SamlRealmSettings .AttributeSettingWithDelimiter ("groups" );
638+
639+ final SettingsException settingsException = expectThrows (
640+ SettingsException .class ,
641+ () -> SamlRealm .AttributeParser .forSetting (logger , groupSetting , config )
642+ );
643+
644+ assertThat (settingsException .getMessage (), containsString (REALM_SETTINGS_PREFIX + ".attribute_delimiters.groups" ));
645+ assertThat (settingsException .getMessage (), containsString (REALM_SETTINGS_PREFIX + ".attribute_patterns.groups" ));
646+ }
647+
648+ public void testAttributeSelectionNoGroupsConfiguredThrowsSettingsException () {
649+ String delimiter = "," ;
650+ final Settings settings = Settings .builder ().put (REALM_SETTINGS_PREFIX + ".attribute_delimiters.groups" , delimiter ).build ();
651+ final RealmConfig config = buildConfig (settings );
652+ final SamlRealmSettings .AttributeSettingWithDelimiter groupSetting = new SamlRealmSettings .AttributeSettingWithDelimiter ("groups" );
653+
654+ final SettingsException settingsException = expectThrows (
655+ SettingsException .class ,
656+ () -> SamlRealm .AttributeParser .forSetting (logger , groupSetting , config )
657+ );
658+
659+ assertThat (settingsException .getMessage (), containsString (REALM_SETTINGS_PREFIX + ".attribute_delimiters.groups" ));
660+ assertThat (settingsException .getMessage (), containsString (REALM_SETTINGS_PREFIX + ".attributes.groups" ));
661+ }
662+
663+ public void testAttributeSelectionWithSplitAndListThrowsSecurityException () {
664+ String delimiter = "," ;
665+
666+ final Settings settings = Settings .builder ()
667+ .put (REALM_SETTINGS_PREFIX + ".attributes.groups" , "departments" )
668+ .put (REALM_SETTINGS_PREFIX + ".attribute_delimiters.groups" , delimiter )
669+ .build ();
670+
671+ final RealmConfig config = buildConfig (settings );
672+
673+ final SamlRealmSettings .AttributeSettingWithDelimiter groupSetting = new SamlRealmSettings .AttributeSettingWithDelimiter ("groups" );
674+ final SamlRealm .AttributeParser parser = SamlRealm .AttributeParser .forSetting (logger , groupSetting , config );
675+
676+ final SamlAttributes attributes = new SamlAttributes (
677+ new SamlNameId (NameIDType .TRANSIENT , randomAlphaOfLength (24 ), null , null , null ),
678+ randomAlphaOfLength (16 ),
679+ Collections .singletonList (
680+ new SamlAttributes .SamlAttribute (
681+ "departments" ,
682+ "departments" ,
683+ List .of ("engineering" , String .join (delimiter , "elasticsearch-admins" , "employees" ))
684+ )
685+ )
686+ );
687+
688+ ElasticsearchSecurityException securityException = expectThrows (
689+ ElasticsearchSecurityException .class ,
690+ () -> parser .getAttribute (attributes )
691+ );
692+
693+ assertThat (securityException .getMessage (), containsString ("departments" ));
694+ }
695+
696+ public void testAttributeSelectionWithRegex () {
538697 final boolean useFriendlyName = randomBoolean ();
539698 final Settings settings = Settings .builder ()
540699 .put (REALM_SETTINGS_PREFIX + ".attributes.principal" , useFriendlyName ? "mail" : "urn:oid:0.9.2342.19200300.100.1.3" )
0 commit comments