mirror of https://github.com/apache/kafka.git
				
				
				
			KAFKA-8860: Let SslPrincipalMapper split SSL principal mapping rules
Author: teebee <tb@teebee.de> Reviewers: Reviewers: Manikumar Reddy <manikumar.reddy@gmail.com> Closes #7140 from teebee/teebee/ssl-principal-mapping-rules-handling
This commit is contained in:
		
							parent
							
								
									364794866f
								
							
						
					
					
						commit
						88d1b6de1f
					
				|  | @ -55,7 +55,7 @@ public class BrokerSecurityConfigs { | ||||||
|             " see <a href=\"#security_authz\"> security authorization and acls</a>. Note that this configuration is ignored" + |             " see <a href=\"#security_authz\"> security authorization and acls</a>. Note that this configuration is ignored" + | ||||||
|             " if an extension of KafkaPrincipalBuilder is provided by the <code>" + PRINCIPAL_BUILDER_CLASS_CONFIG + "</code>" + |             " if an extension of KafkaPrincipalBuilder is provided by the <code>" + PRINCIPAL_BUILDER_CLASS_CONFIG + "</code>" + | ||||||
|            " configuration."; |            " configuration."; | ||||||
|     public static final List<String> DEFAULT_SSL_PRINCIPAL_MAPPING_RULES = Collections.singletonList("DEFAULT"); |     public static final String DEFAULT_SSL_PRINCIPAL_MAPPING_RULES = "DEFAULT"; | ||||||
| 
 | 
 | ||||||
|     public static final String SASL_KERBEROS_PRINCIPAL_TO_LOCAL_RULES_DOC = "A list of rules for mapping from principal " + |     public static final String SASL_KERBEROS_PRINCIPAL_TO_LOCAL_RULES_DOC = "A list of rules for mapping from principal " + | ||||||
|             "names to short names (typically operating system usernames). The rules are evaluated in order and the " + |             "names to short names (typically operating system usernames). The rules are evaluated in order and the " + | ||||||
|  |  | ||||||
|  | @ -35,7 +35,6 @@ import java.net.InetAddress; | ||||||
| import java.net.InetSocketAddress; | import java.net.InetSocketAddress; | ||||||
| import java.nio.channels.SelectionKey; | import java.nio.channels.SelectionKey; | ||||||
| import java.nio.channels.SocketChannel; | import java.nio.channels.SocketChannel; | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.function.Supplier; | import java.util.function.Supplier; | ||||||
|  | @ -63,8 +62,7 @@ public class SslChannelBuilder implements ChannelBuilder, ListenerReconfigurable | ||||||
|     public void configure(Map<String, ?> configs) throws KafkaException { |     public void configure(Map<String, ?> configs) throws KafkaException { | ||||||
|         try { |         try { | ||||||
|             this.configs = configs; |             this.configs = configs; | ||||||
|             @SuppressWarnings("unchecked") |             String sslPrincipalMappingRules = (String) configs.get(BrokerSecurityConfigs.SSL_PRINCIPAL_MAPPING_RULES_CONFIG); | ||||||
|             List<String> sslPrincipalMappingRules = (List<String>) configs.get(BrokerSecurityConfigs.SSL_PRINCIPAL_MAPPING_RULES_CONFIG); |  | ||||||
|             if (sslPrincipalMappingRules != null) |             if (sslPrincipalMappingRules != null) | ||||||
|                 sslPrincipalMapper = SslPrincipalMapper.fromRules(sslPrincipalMappingRules); |                 sslPrincipalMapper = SslPrincipalMapper.fromRules(sslPrincipalMappingRules); | ||||||
|             this.sslFactory = new SslFactory(mode, null, isInterBrokerListener); |             this.sslFactory = new SslFactory(mode, null, isInterBrokerListener); | ||||||
|  |  | ||||||
|  | @ -18,53 +18,44 @@ package org.apache.kafka.common.security.ssl; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.regex.Matcher; | import java.util.regex.Matcher; | ||||||
| import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||||
| 
 | 
 | ||||||
|  | import static org.apache.kafka.common.config.internals.BrokerSecurityConfigs.DEFAULT_SSL_PRINCIPAL_MAPPING_RULES; | ||||||
|  | 
 | ||||||
| public class SslPrincipalMapper { | public class SslPrincipalMapper { | ||||||
| 
 | 
 | ||||||
|     private static final Pattern RULE_PARSER = Pattern.compile("((DEFAULT)|(RULE:(([^/]*)/([^/]*))/([LU])?))"); |     private static final String RULE_PATTERN = "(DEFAULT)|RULE:((\\\\.|[^\\\\/])*)/((\\\\.|[^\\\\/])*)/([LU]?).*?|(.*?)"; | ||||||
|  |     private static final Pattern RULE_SPLITTER = Pattern.compile("\\s*(" + RULE_PATTERN + ")\\s*(,\\s*|$)"); | ||||||
|  |     private static final Pattern RULE_PARSER = Pattern.compile(RULE_PATTERN); | ||||||
| 
 | 
 | ||||||
|     private final List<Rule> rules; |     private final List<Rule> rules; | ||||||
| 
 | 
 | ||||||
|     public SslPrincipalMapper(List<Rule> sslPrincipalMappingRules) { |     public SslPrincipalMapper(String sslPrincipalMappingRules) { | ||||||
|         this.rules = sslPrincipalMappingRules; |         this.rules = parseRules(splitRules(sslPrincipalMappingRules)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static SslPrincipalMapper fromRules(List<String> sslPrincipalMappingRules) { |     public static SslPrincipalMapper fromRules(String sslPrincipalMappingRules) { | ||||||
|         List<String> rules = sslPrincipalMappingRules == null ? Collections.singletonList("DEFAULT") : sslPrincipalMappingRules; |         return new SslPrincipalMapper(sslPrincipalMappingRules); | ||||||
|         return new SslPrincipalMapper(parseRules(rules)); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static List<String> joinSplitRules(List<String> rules) { |     private static List<String> splitRules(String sslPrincipalMappingRules) { | ||||||
|         String rule = "RULE:"; |         if (sslPrincipalMappingRules == null) { | ||||||
|         String defaultRule = "DEFAULT"; |             sslPrincipalMappingRules = DEFAULT_SSL_PRINCIPAL_MAPPING_RULES; | ||||||
|         List<String> retVal = new ArrayList<>(); |  | ||||||
|         StringBuilder currentRule = new StringBuilder(); |  | ||||||
|         for (String r : rules) { |  | ||||||
|             if (currentRule.length() > 0) { |  | ||||||
|                 if (r.startsWith(rule) || r.equals(defaultRule)) { |  | ||||||
|                     retVal.add(currentRule.toString()); |  | ||||||
|                     currentRule.setLength(0); |  | ||||||
|                     currentRule.append(r); |  | ||||||
|                 } else { |  | ||||||
|                     currentRule.append(String.format(",%s", r)); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 currentRule.append(r); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         if (currentRule.length() > 0) { | 
 | ||||||
|             retVal.add(currentRule.toString()); |         List<String> result = new ArrayList<>(); | ||||||
|  |         Matcher matcher = RULE_SPLITTER.matcher(sslPrincipalMappingRules.trim()); | ||||||
|  |         while (matcher.find()) { | ||||||
|  |             result.add(matcher.group(1)); | ||||||
|         } |         } | ||||||
|         return retVal; | 
 | ||||||
|  |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static List<Rule> parseRules(List<String> rules) { |     private static List<Rule> parseRules(List<String> rules) { | ||||||
|         rules = joinSplitRules(rules); |  | ||||||
|         List<Rule> result = new ArrayList<>(); |         List<Rule> result = new ArrayList<>(); | ||||||
|         for (String rule : rules) { |         for (String rule : rules) { | ||||||
|             Matcher matcher = RULE_PARSER.matcher(rule); |             Matcher matcher = RULE_PARSER.matcher(rule); | ||||||
|  | @ -74,15 +65,18 @@ public class SslPrincipalMapper { | ||||||
|             if (rule.length() != matcher.end()) { |             if (rule.length() != matcher.end()) { | ||||||
|                 throw new IllegalArgumentException("Invalid rule: `" + rule + "`, unmatched substring: `" + rule.substring(matcher.end()) + "`"); |                 throw new IllegalArgumentException("Invalid rule: `" + rule + "`, unmatched substring: `" + rule.substring(matcher.end()) + "`"); | ||||||
|             } |             } | ||||||
|             if (matcher.group(2) != null) { | 
 | ||||||
|  |             // empty rules are ignored | ||||||
|  |             if (matcher.group(1) != null) { | ||||||
|                 result.add(new Rule()); |                 result.add(new Rule()); | ||||||
|             } else { |             } else if (matcher.group(2) != null) { | ||||||
|                 result.add(new Rule(matcher.group(5), |                 result.add(new Rule(matcher.group(2), | ||||||
|                                     matcher.group(6), |                                     matcher.group(4), | ||||||
|                                     "L".equals(matcher.group(7)), |                                     "L".equals(matcher.group(6)), | ||||||
|                                     "U".equals(matcher.group(7)))); |                                     "U".equals(matcher.group(6)))); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,8 +30,6 @@ import javax.net.ssl.SSLSession; | ||||||
| import javax.security.sasl.SaslServer; | import javax.security.sasl.SaslServer; | ||||||
| import java.net.InetAddress; | import java.net.InetAddress; | ||||||
| import java.security.Principal; | import java.security.Principal; | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.List; |  | ||||||
| 
 | 
 | ||||||
| import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.ArgumentMatchers.any; | import static org.mockito.ArgumentMatchers.any; | ||||||
|  | @ -143,7 +141,7 @@ public class DefaultKafkaPrincipalBuilderTest { | ||||||
|                                         .thenReturn(new X500Principal("CN=duke, OU=JavaSoft, O=Sun Microsystems")) |                                         .thenReturn(new X500Principal("CN=duke, OU=JavaSoft, O=Sun Microsystems")) | ||||||
|                                         .thenReturn(new X500Principal("OU=JavaSoft, O=Sun Microsystems, C=US")); |                                         .thenReturn(new X500Principal("OU=JavaSoft, O=Sun Microsystems, C=US")); | ||||||
| 
 | 
 | ||||||
|         List<String> rules = Arrays.asList( |         String rules = String.join(", ", | ||||||
|             "RULE:^CN=(.*),OU=ServiceUsers.*$/$1/L", |             "RULE:^CN=(.*),OU=ServiceUsers.*$/$1/L", | ||||||
|             "RULE:^CN=(.*),OU=(.*),O=(.*),L=(.*),ST=(.*),C=(.*)$/$1@$2/L", |             "RULE:^CN=(.*),OU=(.*),O=(.*),L=(.*),ST=(.*),C=(.*)$/$1@$2/L", | ||||||
|             "RULE:^.*[Cc][Nn]=([a-zA-Z0-9.]*).*$/$1/U", |             "RULE:^.*[Cc][Nn]=([a-zA-Z0-9.]*).*$/$1/U", | ||||||
|  |  | ||||||
|  | @ -18,9 +18,6 @@ package org.apache.kafka.common.security.ssl; | ||||||
| 
 | 
 | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| 
 | 
 | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.junit.Assert.fail; | import static org.junit.Assert.fail; | ||||||
| 
 | 
 | ||||||
|  | @ -28,59 +25,37 @@ public class SslPrincipalMapperTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void testValidRules() { |     public void testValidRules() { | ||||||
|         testValidRule(Arrays.asList("DEFAULT")); |         testValidRule("DEFAULT"); | ||||||
|         testValidRule(Arrays.asList("RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/")); |         testValidRule("RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/"); | ||||||
|         testValidRule(Arrays.asList("RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/L", "DEFAULT")); |         testValidRule("RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/L, DEFAULT"); | ||||||
|         testValidRule(Arrays.asList("RULE:^CN=(.*?),OU=(.*?),O=(.*?),L=(.*?),ST=(.*?),C=(.*?)$/$1@$2/")); |         testValidRule("RULE:^CN=(.*?),OU=(.*?),O=(.*?),L=(.*?),ST=(.*?),C=(.*?)$/$1@$2/"); | ||||||
|         testValidRule(Arrays.asList("RULE:^.*[Cc][Nn]=([a-zA-Z0-9.]*).*$/$1/L")); |         testValidRule("RULE:^.*[Cc][Nn]=([a-zA-Z0-9.]*).*$/$1/L"); | ||||||
|         testValidRule(Arrays.asList("RULE:^cn=(.?),ou=(.?),dc=(.?),dc=(.?)$/$1@$2/U")); |         testValidRule("RULE:^cn=(.?),ou=(.?),dc=(.?),dc=(.?)$/$1@$2/U"); | ||||||
|  | 
 | ||||||
|  |         testValidRule("RULE:^CN=([^,ADEFLTU,]+)(,.*|$)/$1/"); | ||||||
|  |         testValidRule("RULE:^CN=([^,DEFAULT,]+)(,.*|$)/$1/"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     private void testValidRule(String rules) { | ||||||
|     public void testValidSplitRules() { |  | ||||||
|         testValidRule(Arrays.asList("DEFAULT")); |  | ||||||
|         testValidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=ServiceUsers.*$/$1/")); |  | ||||||
|         testValidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=ServiceUsers.*$/$1/L", "DEFAULT")); |  | ||||||
|         testValidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=(.*?),O=(.*?),L=(.*?)", "ST=(.*?)", "C=(.*?)$/$1@$2/")); |  | ||||||
|         testValidRule(Arrays.asList("RULE:^.*[Cc][Nn]=([a-zA-Z0-9.]*).*$/$1/L")); |  | ||||||
|         testValidRule(Arrays.asList("RULE:^cn=(.?)", "ou=(.?)", "dc=(.?)", "dc=(.?)$/$1@$2/U")); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void testValidRule(List<String> rules) { |  | ||||||
|         SslPrincipalMapper.fromRules(rules); |         SslPrincipalMapper.fromRules(rules); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void testInvalidRules() { |     public void testInvalidRules() { | ||||||
|         testInvalidRule(Arrays.asList("default")); |         testInvalidRule("default"); | ||||||
|         testInvalidRule(Arrays.asList("DEFAUL")); |         testInvalidRule("DEFAUL"); | ||||||
|         testInvalidRule(Arrays.asList("DEFAULT/L")); |         testInvalidRule("DEFAULT/L"); | ||||||
|         testInvalidRule(Arrays.asList("DEFAULT/U")); |         testInvalidRule("DEFAULT/U"); | ||||||
| 
 | 
 | ||||||
|         testInvalidRule(Arrays.asList("RULE:CN=(.*?),OU=ServiceUsers.*/$1")); |         testInvalidRule("RULE:CN=(.*?),OU=ServiceUsers.*/$1"); | ||||||
|         testInvalidRule(Arrays.asList("rule:^CN=(.*?),OU=ServiceUsers.*$/$1/")); |         testInvalidRule("rule:^CN=(.*?),OU=ServiceUsers.*$/$1/"); | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/L/U")); |         testInvalidRule("RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/L/U"); | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?),OU=ServiceUsers.*$/L")); |         testInvalidRule("RULE:^CN=(.*?),OU=ServiceUsers.*$/L"); | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?),OU=ServiceUsers.*$/U")); |         testInvalidRule("RULE:^CN=(.*?),OU=ServiceUsers.*$/U"); | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?),OU=ServiceUsers.*$/LU")); |         testInvalidRule("RULE:^CN=(.*?),OU=ServiceUsers.*$/LU"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     private void testInvalidRule(String rules) { | ||||||
|     public void testInvalidSplitRules() { |  | ||||||
|         testInvalidRule(Arrays.asList("default")); |  | ||||||
|         testInvalidRule(Arrays.asList("DEFAUL")); |  | ||||||
|         testInvalidRule(Arrays.asList("DEFAULT/L")); |  | ||||||
|         testInvalidRule(Arrays.asList("DEFAULT/U")); |  | ||||||
| 
 |  | ||||||
|         testInvalidRule(Arrays.asList("RULE:CN=(.*?)", "OU=ServiceUsers.*/$1")); |  | ||||||
|         testInvalidRule(Arrays.asList("rule:^CN=(.*?)", "OU=ServiceUsers.*$/$1/")); |  | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=ServiceUsers.*$/$1/L/U")); |  | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=ServiceUsers.*$/L")); |  | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=ServiceUsers.*$/U")); |  | ||||||
|         testInvalidRule(Arrays.asList("RULE:^CN=(.*?)", "OU=ServiceUsers.*$/LU")); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void testInvalidRule(List<String> rules) { |  | ||||||
|         try { |         try { | ||||||
|             System.out.println(SslPrincipalMapper.fromRules(rules)); |             System.out.println(SslPrincipalMapper.fromRules(rules)); | ||||||
|             fail("should have thrown IllegalArgumentException"); |             fail("should have thrown IllegalArgumentException"); | ||||||
|  | @ -90,7 +65,7 @@ public class SslPrincipalMapperTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void testSslPrincipalMapper() throws Exception { |     public void testSslPrincipalMapper() throws Exception { | ||||||
|         List<String> rules = Arrays.asList( |         String rules = String.join(", ", | ||||||
|             "RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/L", |             "RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/L", | ||||||
|             "RULE:^CN=(.*?),OU=(.*?),O=(.*?),L=(.*?),ST=(.*?),C=(.*?)$/$1@$2/L", |             "RULE:^CN=(.*?),OU=(.*?),O=(.*?),L=(.*?),ST=(.*?),C=(.*?)$/$1@$2/L", | ||||||
|             "RULE:^cn=(.*?),ou=(.*?),dc=(.*?),dc=(.*?)$/$1@$2/U", |             "RULE:^cn=(.*?),ou=(.*?),dc=(.*?),dc=(.*?)$/$1@$2/U", | ||||||
|  | @ -107,4 +82,47 @@ public class SslPrincipalMapperTest { | ||||||
|         assertEquals("OU=JavaSoft,O=Sun Microsystems,C=US", mapper.getName("OU=JavaSoft,O=Sun Microsystems,C=US")); |         assertEquals("OU=JavaSoft,O=Sun Microsystems,C=US", mapper.getName("OU=JavaSoft,O=Sun Microsystems,C=US")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private void testRulesSplitting(String expected, String rules) { | ||||||
|  |         SslPrincipalMapper mapper = SslPrincipalMapper.fromRules(rules); | ||||||
|  |         assertEquals(String.format("SslPrincipalMapper(rules = %s)", expected), mapper.toString()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testRulesSplitting() { | ||||||
|  |         // seeing is believing | ||||||
|  |         testRulesSplitting("[]", ""); | ||||||
|  |         testRulesSplitting("[DEFAULT]", "DEFAULT"); | ||||||
|  |         testRulesSplitting("[RULE:/]", "RULE://"); | ||||||
|  |         testRulesSplitting("[RULE:/.*]", "RULE:/.*/"); | ||||||
|  |         testRulesSplitting("[RULE:/.*/L]", "RULE:/.*/L"); | ||||||
|  |         testRulesSplitting("[RULE:/, DEFAULT]", "RULE://,DEFAULT"); | ||||||
|  |         testRulesSplitting("[RULE:/, DEFAULT]", "  RULE:// ,  DEFAULT  "); | ||||||
|  |         testRulesSplitting("[RULE:   /     , DEFAULT]", "  RULE:   /     / ,  DEFAULT  "); | ||||||
|  |         testRulesSplitting("[RULE:  /     /U, DEFAULT]", "  RULE:  /     /U   ,DEFAULT  "); | ||||||
|  |         testRulesSplitting("[RULE:([A-Z]*)/$1/U, RULE:([a-z]+)/$1, DEFAULT]", "  RULE:([A-Z]*)/$1/U   ,RULE:([a-z]+)/$1/,   DEFAULT  "); | ||||||
|  | 
 | ||||||
|  |         // empty rules are ignored | ||||||
|  |         testRulesSplitting("[]", ",   , , ,      , , ,   "); | ||||||
|  |         testRulesSplitting("[RULE:/, DEFAULT]", ",,RULE://,,,DEFAULT,,"); | ||||||
|  |         testRulesSplitting("[RULE: /   , DEFAULT]", ",  , RULE: /   /    ,,,   DEFAULT, ,   "); | ||||||
|  |         testRulesSplitting("[RULE:   /  /U, DEFAULT]", "     ,  , RULE:   /  /U    ,,  ,DEFAULT, ,"); | ||||||
|  | 
 | ||||||
|  |         // escape sequences | ||||||
|  |         testRulesSplitting("[RULE:\\/\\\\\\(\\)\\n\\t/\\/\\/]", "RULE:\\/\\\\\\(\\)\\n\\t/\\/\\//"); | ||||||
|  |         testRulesSplitting("[RULE:\\**\\/+/*/L, RULE:\\/*\\**/**]", "RULE:\\**\\/+/*/L,RULE:\\/*\\**/**/"); | ||||||
|  | 
 | ||||||
|  |         // rules rule | ||||||
|  |         testRulesSplitting( | ||||||
|  |             "[RULE:,RULE:,/,RULE:,\\//U, RULE:,/RULE:,, RULE:,RULE:,/L,RULE:,/L, RULE:, DEFAULT, /DEFAULT, DEFAULT]", | ||||||
|  |             "RULE:,RULE:,/,RULE:,\\//U,RULE:,/RULE:,/,RULE:,RULE:,/L,RULE:,/L,RULE:, DEFAULT, /DEFAULT/,DEFAULT" | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCommaWithWhitespace() throws Exception { | ||||||
|  |         String rules = "RULE:^CN=((\\\\, *|\\w)+)(,.*|$)/$1/,DEFAULT"; | ||||||
|  | 
 | ||||||
|  |         SslPrincipalMapper mapper = SslPrincipalMapper.fromRules(rules); | ||||||
|  |         assertEquals("Tkac\\, Adam", mapper.getName("CN=Tkac\\, Adam,OU=ITZ,DC=geodis,DC=cz")); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1059,7 +1059,7 @@ object KafkaConfig { | ||||||
|       .define(SslSecureRandomImplementationProp, STRING, null, LOW, SslSecureRandomImplementationDoc) |       .define(SslSecureRandomImplementationProp, STRING, null, LOW, SslSecureRandomImplementationDoc) | ||||||
|       .define(SslClientAuthProp, STRING, Defaults.SslClientAuthentication, in(Defaults.SslClientAuthenticationValidValues:_*), MEDIUM, SslClientAuthDoc) |       .define(SslClientAuthProp, STRING, Defaults.SslClientAuthentication, in(Defaults.SslClientAuthenticationValidValues:_*), MEDIUM, SslClientAuthDoc) | ||||||
|       .define(SslCipherSuitesProp, LIST, Collections.emptyList(), MEDIUM, SslCipherSuitesDoc) |       .define(SslCipherSuitesProp, LIST, Collections.emptyList(), MEDIUM, SslCipherSuitesDoc) | ||||||
|       .define(SslPrincipalMappingRulesProp, LIST, Defaults.SslPrincipalMappingRules, LOW, SslPrincipalMappingRulesDoc) |       .define(SslPrincipalMappingRulesProp, STRING, Defaults.SslPrincipalMappingRules, LOW, SslPrincipalMappingRulesDoc) | ||||||
| 
 | 
 | ||||||
|       /** ********* Sasl Configuration ****************/ |       /** ********* Sasl Configuration ****************/ | ||||||
|       .define(SaslMechanismInterBrokerProtocolProp, STRING, Defaults.SaslMechanismInterBrokerProtocol, MEDIUM, SaslMechanismInterBrokerProtocolDoc) |       .define(SaslMechanismInterBrokerProtocolProp, STRING, Defaults.SaslMechanismInterBrokerProtocol, MEDIUM, SaslMechanismInterBrokerProtocolDoc) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue