From fb610efba520d574df53c95ae94eb7c950a098ca Mon Sep 17 00:00:00 2001 From: jaymode Date: Wed, 28 Nov 2018 10:44:58 -0700 Subject: [PATCH 1/2] Security: improve exact index matching performance This commit improves the efficiency of exact index name matching by separating exact matches from those that include wildcards or regular expressions. Internally, exact matching is done using a HashSet instead of adding the exact matches to the automata. For the wildcard and regular expression matches, the underlying implementation has not changed. --- .../authz/permission/IndicesPermission.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java index f0e2f2b7e6217..af510e3b0eca3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java @@ -64,6 +64,38 @@ public IndicesPermission(Group... groups) { } static Predicate indexMatcher(List indices) { + Set exactMatch = new HashSet<>(); + List nonExactMatch = new ArrayList<>(); + for (String indexPattern : indices) { + if (indexPattern.startsWith("/")) { + if (indexPattern.endsWith("/") || indexPattern.contains("*") || indexPattern.contains("?")) { + nonExactMatch.add(indexPattern); + } else { + exactMatch.add(indexPattern); + } + } else if (indexPattern.contains("*") || indexPattern.contains("?")) { + nonExactMatch.add(indexPattern); + } else { + exactMatch.add(indexPattern); + } + } + + if (exactMatch.isEmpty() && nonExactMatch.isEmpty()) { + return s -> false; + } else if (exactMatch.isEmpty()) { + return buildAutomataPredicate(nonExactMatch); + } else if (nonExactMatch.isEmpty()) { + return buildExactMatchPredicate(exactMatch); + } else { + return buildExactMatchPredicate(exactMatch).or(buildAutomataPredicate(nonExactMatch)); + } + } + + private static Predicate buildExactMatchPredicate(Set indices) { + return indices::contains; + } + + private static Predicate buildAutomataPredicate(List indices) { try { return Automatons.predicate(indices); } catch (TooComplexToDeterminizeException e) { From 341a58dbe0fb53bb52ba0343962cc84b7f7b331b Mon Sep 17 00:00:00 2001 From: jaymode Date: Thu, 29 Nov 2018 08:54:54 -0700 Subject: [PATCH 2/2] address review feedback --- .../security/authz/permission/IndicesPermission.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java index af510e3b0eca3..4936071ee8445 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/IndicesPermission.java @@ -67,13 +67,7 @@ static Predicate indexMatcher(List indices) { Set exactMatch = new HashSet<>(); List nonExactMatch = new ArrayList<>(); for (String indexPattern : indices) { - if (indexPattern.startsWith("/")) { - if (indexPattern.endsWith("/") || indexPattern.contains("*") || indexPattern.contains("?")) { - nonExactMatch.add(indexPattern); - } else { - exactMatch.add(indexPattern); - } - } else if (indexPattern.contains("*") || indexPattern.contains("?")) { + if (indexPattern.startsWith("/") || indexPattern.contains("*") || indexPattern.contains("?")) { nonExactMatch.add(indexPattern); } else { exactMatch.add(indexPattern); @@ -92,6 +86,10 @@ static Predicate indexMatcher(List indices) { } private static Predicate buildExactMatchPredicate(Set indices) { + if (indices.size() == 1) { + final String singleValue = indices.iterator().next(); + return singleValue::equals; + } return indices::contains; }