minor, add switches to enable/disable escape "DEFAULT".
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/036d70fd Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/036d70fd Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/036d70fd Branch: refs/heads/master Commit: 036d70fd0996ded0119c7c58369701eedac93a13 Parents: 2e845c2 Author: tttMelody <245915...@qq.com> Authored: Sun Sep 24 18:16:29 2017 +0800 Committer: Jiatao Tao <245915...@qq.com> Committed: Sun Sep 24 18:32:15 2017 +0800 ---------------------------------------------------------------------- .../apache/kylin/common/KylinConfigBase.java | 10 +- .../main/resources/kylin-defaults.properties | 14 +- .../org/apache/kylin/metadata/acl/TableACL.java | 2 +- .../relnode/OLAPToEnumerableConverter.java | 8 +- .../kylin/query/security/QueryIntercept.java | 64 ------- .../query/security/QueryInterceptUtil.java | 170 ------------------- .../kylin/query/security/QueryInterceptor.java | 64 +++++++ .../query/security/QueryInterceptorUtil.java | 170 +++++++++++++++++++ .../query/util/KeywordDefaultDirtyHack.java | 5 + .../apache/kylin/query/util/QueryUtilTest.java | 2 + .../kylin/rest/security/TableIntercept.java | 57 ------- .../kylin/rest/security/TableInterceptor.java | 57 +++++++ 12 files changed, 320 insertions(+), 303 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java ---------------------------------------------------------------------- diff --git a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java index b672a7a..ee05d69 100644 --- a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java +++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java @@ -1090,8 +1090,8 @@ abstract public class KylinConfigBase implements Serializable { return getOptionalStringArray("kylin.query.transformers", new String[0]); } - public String[] getQueryIntercept() { - return getOptionalStringArray("kylin.query.intercepts", new String[0]); + public String[] getQueryInterceptors() { + return getOptionalStringArray("kylin.query.interceptors", new String[0]); } public long getQueryDurationCacheThreshold() { @@ -1190,7 +1190,11 @@ abstract public class KylinConfigBase implements Serializable { } public boolean isTableACLEnabled() { - return Boolean.valueOf(this.getOptional("kylin.query.acl.table-acl-enabled", "true")); + return Boolean.valueOf(this.getOptional("kylin.query.security.table-acl-enabled", "true")); + } + + public boolean isEscapeDefaultKeywordEnabled() { + return Boolean.valueOf(this.getOptional("kylin.query.escape-default-keyword", "false")); } // ============================================================================ http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/core-common/src/main/resources/kylin-defaults.properties ---------------------------------------------------------------------- diff --git a/core-common/src/main/resources/kylin-defaults.properties b/core-common/src/main/resources/kylin-defaults.properties index 3bc534b..a317f8e 100644 --- a/core-common/src/main/resources/kylin-defaults.properties +++ b/core-common/src/main/resources/kylin-defaults.properties @@ -191,6 +191,16 @@ kylin.query.max-scan-bytes=0 kylin.query.cache-enabled=true +# TABLE ACL +kylin.query.security.table-acl-enabled=true + +# Usually should not modify this +kylin.query.interceptors=org.apache.kylin.rest.security.TableInterceptor + +kylin.query.escape-default-keyword=false + +# Usually should not modify this +kylin.query.transformers=org.apache.kylin.query.util.KeywordDefaultDirtyHack ### SECURITY ### @@ -277,7 +287,3 @@ kylin.engine.spark-conf.spark.hadoop.yarn.timeline-service.enabled=false #kylin.query.pushdown.jdbc.pool-max-total=8 #kylin.query.pushdown.jdbc.pool-max-idle=8 #kylin.query.pushdown.jdbc.pool-min-idle=0 - -### TABLE ACL -kylin.query.acl.table-acl-enabled=true -kylin.query.intercepts=org.apache.kylin.rest.security.TableIntercept \ No newline at end of file http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java ---------------------------------------------------------------------- diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java b/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java index 0b3ba4d..f4cfd1f 100644 --- a/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java +++ b/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java @@ -52,7 +52,7 @@ public class TableACL extends RootPersistentEntity { public Set<String> getTableBlackList(String username) { TableBlackList tableBlackList = userTableBlackList.get(username); - //table intercept will use this, return an empty set then null + //table interceptor will use this, return an empty set then null if (tableBlackList == null) { tableBlackList = new TableBlackList(); } http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java index 637f863..99dee11 100644 --- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java +++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPToEnumerableConverter.java @@ -35,8 +35,8 @@ import org.apache.calcite.sql.SqlExplainLevel; import org.apache.kylin.common.KylinConfig; import org.apache.kylin.common.util.ClassUtil; import org.apache.kylin.query.routing.RealizationChooser; -import org.apache.kylin.query.security.QueryIntercept; -import org.apache.kylin.query.security.QueryInterceptUtil; +import org.apache.kylin.query.security.QueryInterceptor; +import org.apache.kylin.query.security.QueryInterceptorUtil; import com.google.common.collect.Lists; @@ -75,8 +75,8 @@ public class OLAPToEnumerableConverter extends ConverterImpl implements Enumerab List<OLAPContext> contexts = listContextsHavingScan(); // intercept query - List<QueryIntercept> intercepts = QueryInterceptUtil.getQueryIntercepts(); - for (QueryIntercept intercept : intercepts) { + List<QueryInterceptor> intercepts = QueryInterceptorUtil.getQueryInterceptors(); + for (QueryInterceptor intercept : intercepts) { intercept.intercept(contexts); } http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/main/java/org/apache/kylin/query/security/QueryIntercept.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/security/QueryIntercept.java b/query/src/main/java/org/apache/kylin/query/security/QueryIntercept.java deleted file mode 100644 index 2312568..0000000 --- a/query/src/main/java/org/apache/kylin/query/security/QueryIntercept.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -package org.apache.kylin.query.security; - -import java.util.Collection; -import java.util.List; - -import org.apache.kylin.query.relnode.OLAPContext; - -public abstract class QueryIntercept { - - public void intercept(List<OLAPContext> contexts) { - if (!isEnabled()) { - return; - } - Collection<String> userIdentifierBlackList = getIdentifierBlackList(contexts); - intercept(contexts, userIdentifierBlackList); - } - - private void intercept(List<OLAPContext> contexts, Collection<String> blackList) { - if (blackList.isEmpty()) { - return; - } - - Collection<String> queryCols = getQueryIdentifiers(contexts); - for (String id : blackList) { - if (queryCols.contains(id.toUpperCase())) { - throw new AccessDeniedException(getIdentifierType() + ":" + id); - } - } - } - - protected abstract boolean isEnabled(); - - protected abstract Collection<String> getQueryIdentifiers(List<OLAPContext> contexts); - - protected abstract Collection<String> getIdentifierBlackList(List<OLAPContext> contexts); - - protected abstract String getIdentifierType(); - - protected String getProject(List<OLAPContext> contexts) { - return contexts.get(0).olapSchema.getProjectName(); - } - - protected String getUser(List<OLAPContext> contexts) { - return contexts.get(0).olapAuthen.getUsername(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/main/java/org/apache/kylin/query/security/QueryInterceptUtil.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/security/QueryInterceptUtil.java b/query/src/main/java/org/apache/kylin/query/security/QueryInterceptUtil.java deleted file mode 100644 index fa094db..0000000 --- a/query/src/main/java/org/apache/kylin/query/security/QueryInterceptUtil.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -package org.apache.kylin.query.security; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.apache.calcite.sql.SqlCall; -import org.apache.calcite.sql.SqlIdentifier; -import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.util.SqlBasicVisitor; -import org.apache.kylin.common.KylinConfig; -import org.apache.kylin.common.util.ClassUtil; -import org.apache.kylin.common.util.Pair; -import org.apache.kylin.metadata.MetadataManager; -import org.apache.kylin.metadata.model.ColumnDesc; -import org.apache.kylin.metadata.model.DataModelDesc; -import org.apache.kylin.metadata.model.TblColRef; -import org.apache.kylin.metadata.model.tool.CalciteParser; -import org.apache.kylin.query.relnode.OLAPContext; -import org.apache.kylin.query.relnode.OLAPTableScan; - -import com.google.common.base.Preconditions; - -public class QueryInterceptUtil { - private static List<QueryIntercept> queryIntercepts = new ArrayList<>(); - - private static void setQueryIntercept() { - if (queryIntercepts.size() > 0) { - return; - } - String[] classes = KylinConfig.getInstanceFromEnv().getQueryIntercept(); - for (String clz : classes) { - try { - QueryIntercept i = (QueryIntercept) ClassUtil.newInstance(clz); - queryIntercepts.add(i); - } catch (Exception e) { - throw new RuntimeException("Failed to load query intercept", e); - } - } - } - - public static List<QueryIntercept> getQueryIntercepts() { - setQueryIntercept(); - return queryIntercepts; - } - - public static Set<String> getAllColsWithTblAndSchema(String project, List<OLAPContext> contexts) { - // all columns with table and DB. Like DB.TABLE.COLUMN - Set<String> allColWithTblAndSchema = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - - for (OLAPContext context : contexts) { - for (TblColRef tblColRef : context.allColumns) { - ColumnDesc columnDesc = tblColRef.getColumnDesc(); - //computed column - if (columnDesc.isComputedColumnn()) { - allColWithTblAndSchema.addAll(getCCUsedCols(project, columnDesc)); - } - //normal column - allColWithTblAndSchema.add(tblColRef.getColumWithTableAndSchema()); - } - } - return allColWithTblAndSchema; - } - - private static Set<String> getCCUsedCols(String project, ColumnDesc columnDesc) { - Set<String> usedCols = new HashSet<>(); - Map<String, String> aliasTableMap = getAliasTableMap(project, columnDesc.getName()); - Preconditions.checkState(aliasTableMap.size() > 0, "can not find cc:" + columnDesc.getName() + "'s table alias"); - - List<Pair<String, String>> colsWithAlias = ExprIdentifierFinder.getExprIdentifiers(columnDesc.getComputedColumnExpr()); - for (Pair<String, String> cols : colsWithAlias) { - String tableIdentifier = aliasTableMap.get(cols.getFirst()); - usedCols.add(tableIdentifier + "." + cols.getSecond()); - } - //Preconditions.checkState(usedCols.size() > 0, "can not find cc:" + columnDesc.getName() + "'s used cols"); - return usedCols; - } - - private static Map<String, String> getAliasTableMap(String project, String ccName) { - DataModelDesc model = getModel(project, ccName); - Map<String, String> tableWithAlias = new HashMap<>(); - for (String alias : model.getAliasMap().keySet()) { - String tableName = model.getAliasMap().get(alias).getTableDesc().getIdentity(); - tableWithAlias.put(alias, tableName); - } - return tableWithAlias; - } - - private static DataModelDesc getModel(String project, String ccName) { - List<DataModelDesc> models = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv()).getModels(project); - for (DataModelDesc model : models) { - Set<String> computedColumnNames = model.getComputedColumnNames(); - if (computedColumnNames.contains(ccName)) { - return model; - } - } - return null; - } - - static class ExprIdentifierFinder extends SqlBasicVisitor<SqlNode> { - List<Pair<String, String>> columnWithTableAlias; - - ExprIdentifierFinder() { - this.columnWithTableAlias = new ArrayList<>(); - } - - List<Pair<String, String>> getIdentifiers() { - return columnWithTableAlias; - } - - static List<Pair<String, String>> getExprIdentifiers(String expr) { - SqlNode exprNode = CalciteParser.getExpNode(expr); - ExprIdentifierFinder id = new ExprIdentifierFinder(); - exprNode.accept(id); - return id.getIdentifiers(); - } - - @Override - public SqlNode visit(SqlCall call) { - for (SqlNode operand : call.getOperandList()) { - if (operand != null) { - operand.accept(this); - } - } - return null; - } - - @Override - public SqlNode visit(SqlIdentifier id) { - //Preconditions.checkState(id.names.size() == 2, "error when get identifier in cc's expr"); - if (id.names.size() == 2) { - columnWithTableAlias.add(Pair.newPair(id.names.get(0), id.names.get(1))); - } - return null; - } - } - - public static Set<String> getAllTblsWithSchema(List<OLAPContext> contexts) { - // all tables with DB, Like DB.TABLE - Set<String> tableWithSchema = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - for (OLAPContext context : contexts) { - for (OLAPTableScan tableScan : context.allTableScans) { - tableWithSchema.add(tableScan.getTableRef().getTableIdentity()); - } - } - return tableWithSchema; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/main/java/org/apache/kylin/query/security/QueryInterceptor.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/security/QueryInterceptor.java b/query/src/main/java/org/apache/kylin/query/security/QueryInterceptor.java new file mode 100644 index 0000000..0debd6c --- /dev/null +++ b/query/src/main/java/org/apache/kylin/query/security/QueryInterceptor.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.apache.kylin.query.security; + +import java.util.Collection; +import java.util.List; + +import org.apache.kylin.query.relnode.OLAPContext; + +public abstract class QueryInterceptor { + + public void intercept(List<OLAPContext> contexts) { + if (!isEnabled()) { + return; + } + Collection<String> userIdentifierBlackList = getIdentifierBlackList(contexts); + intercept(contexts, userIdentifierBlackList); + } + + private void intercept(List<OLAPContext> contexts, Collection<String> blackList) { + if (blackList.isEmpty()) { + return; + } + + Collection<String> queryCols = getQueryIdentifiers(contexts); + for (String id : blackList) { + if (queryCols.contains(id.toUpperCase())) { + throw new AccessDeniedException(getIdentifierType() + ":" + id); + } + } + } + + protected abstract boolean isEnabled(); + + protected abstract Collection<String> getQueryIdentifiers(List<OLAPContext> contexts); + + protected abstract Collection<String> getIdentifierBlackList(List<OLAPContext> contexts); + + protected abstract String getIdentifierType(); + + protected String getProject(List<OLAPContext> contexts) { + return contexts.get(0).olapSchema.getProjectName(); + } + + protected String getUser(List<OLAPContext> contexts) { + return contexts.get(0).olapAuthen.getUsername(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/main/java/org/apache/kylin/query/security/QueryInterceptorUtil.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/security/QueryInterceptorUtil.java b/query/src/main/java/org/apache/kylin/query/security/QueryInterceptorUtil.java new file mode 100644 index 0000000..cf9f3e3 --- /dev/null +++ b/query/src/main/java/org/apache/kylin/query/security/QueryInterceptorUtil.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.apache.kylin.query.security; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.util.SqlBasicVisitor; +import org.apache.kylin.common.KylinConfig; +import org.apache.kylin.common.util.ClassUtil; +import org.apache.kylin.common.util.Pair; +import org.apache.kylin.metadata.MetadataManager; +import org.apache.kylin.metadata.model.ColumnDesc; +import org.apache.kylin.metadata.model.DataModelDesc; +import org.apache.kylin.metadata.model.TblColRef; +import org.apache.kylin.metadata.model.tool.CalciteParser; +import org.apache.kylin.query.relnode.OLAPContext; +import org.apache.kylin.query.relnode.OLAPTableScan; + +import com.google.common.base.Preconditions; + +public class QueryInterceptorUtil { + private static List<QueryInterceptor> queryInterceptors = new ArrayList<>(); + + private static void setQueryInterceptor() { + if (queryInterceptors.size() > 0) { + return; + } + String[] classes = KylinConfig.getInstanceFromEnv().getQueryInterceptors(); + for (String clz : classes) { + try { + QueryInterceptor i = (QueryInterceptor) ClassUtil.newInstance(clz); + queryInterceptors.add(i); + } catch (Exception e) { + throw new RuntimeException("Failed to load query interceptors", e); + } + } + } + + public static List<QueryInterceptor> getQueryInterceptors() { + setQueryInterceptor(); + return queryInterceptors; + } + + public static Set<String> getAllColsWithTblAndSchema(String project, List<OLAPContext> contexts) { + // all columns with table and DB. Like DB.TABLE.COLUMN + Set<String> allColWithTblAndSchema = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + + for (OLAPContext context : contexts) { + for (TblColRef tblColRef : context.allColumns) { + ColumnDesc columnDesc = tblColRef.getColumnDesc(); + //computed column + if (columnDesc.isComputedColumnn()) { + allColWithTblAndSchema.addAll(getCCUsedCols(project, columnDesc)); + } + //normal column + allColWithTblAndSchema.add(tblColRef.getColumWithTableAndSchema()); + } + } + return allColWithTblAndSchema; + } + + private static Set<String> getCCUsedCols(String project, ColumnDesc columnDesc) { + Set<String> usedCols = new HashSet<>(); + Map<String, String> aliasTableMap = getAliasTableMap(project, columnDesc.getName()); + Preconditions.checkState(aliasTableMap.size() > 0, "can not find cc:" + columnDesc.getName() + "'s table alias"); + + List<Pair<String, String>> colsWithAlias = ExprIdentifierFinder.getExprIdentifiers(columnDesc.getComputedColumnExpr()); + for (Pair<String, String> cols : colsWithAlias) { + String tableIdentifier = aliasTableMap.get(cols.getFirst()); + usedCols.add(tableIdentifier + "." + cols.getSecond()); + } + //Preconditions.checkState(usedCols.size() > 0, "can not find cc:" + columnDesc.getName() + "'s used cols"); + return usedCols; + } + + private static Map<String, String> getAliasTableMap(String project, String ccName) { + DataModelDesc model = getModel(project, ccName); + Map<String, String> tableWithAlias = new HashMap<>(); + for (String alias : model.getAliasMap().keySet()) { + String tableName = model.getAliasMap().get(alias).getTableDesc().getIdentity(); + tableWithAlias.put(alias, tableName); + } + return tableWithAlias; + } + + private static DataModelDesc getModel(String project, String ccName) { + List<DataModelDesc> models = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv()).getModels(project); + for (DataModelDesc model : models) { + Set<String> computedColumnNames = model.getComputedColumnNames(); + if (computedColumnNames.contains(ccName)) { + return model; + } + } + return null; + } + + static class ExprIdentifierFinder extends SqlBasicVisitor<SqlNode> { + List<Pair<String, String>> columnWithTableAlias; + + ExprIdentifierFinder() { + this.columnWithTableAlias = new ArrayList<>(); + } + + List<Pair<String, String>> getIdentifiers() { + return columnWithTableAlias; + } + + static List<Pair<String, String>> getExprIdentifiers(String expr) { + SqlNode exprNode = CalciteParser.getExpNode(expr); + ExprIdentifierFinder id = new ExprIdentifierFinder(); + exprNode.accept(id); + return id.getIdentifiers(); + } + + @Override + public SqlNode visit(SqlCall call) { + for (SqlNode operand : call.getOperandList()) { + if (operand != null) { + operand.accept(this); + } + } + return null; + } + + @Override + public SqlNode visit(SqlIdentifier id) { + //Preconditions.checkState(id.names.size() == 2, "error when get identifier in cc's expr"); + if (id.names.size() == 2) { + columnWithTableAlias.add(Pair.newPair(id.names.get(0), id.names.get(1))); + } + return null; + } + } + + public static Set<String> getAllTblsWithSchema(List<OLAPContext> contexts) { + // all tables with DB, Like DB.TABLE + Set<String> tableWithSchema = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + for (OLAPContext context : contexts) { + for (OLAPTableScan tableScan : context.allTableScans) { + tableWithSchema.add(tableScan.getTableRef().getTableIdentity()); + } + } + return tableWithSchema; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java b/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java index cbffe03..253660b 100644 --- a/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java +++ b/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java @@ -18,10 +18,15 @@ package org.apache.kylin.query.util; +import org.apache.kylin.common.KylinConfig; + public class KeywordDefaultDirtyHack implements QueryUtil.IQueryTransformer { @Override public String transform(String sql, String project, String defaultSchema) { + if (!KylinConfig.getInstanceFromEnv().isEscapeDefaultKeywordEnabled()) { + return sql; + } // KYLIN-2108, DEFAULT is hive default database, but a sql keyword too, needs quote sql = sql.replace("DEFAULT.", "\"DEFAULT\"."); sql = sql.replace("default.", "\"default\"."); http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java ---------------------------------------------------------------------- diff --git a/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java b/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java index 7a0df84..80de581 100644 --- a/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java +++ b/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java @@ -18,6 +18,7 @@ package org.apache.kylin.query.util; +import org.apache.kylin.common.KylinConfig; import org.apache.kylin.common.util.LocalFileMetadataTestCase; import org.junit.After; import org.junit.Assert; @@ -91,6 +92,7 @@ public class QueryUtilTest extends LocalFileMetadataTestCase { @Test public void testKeywordDefaultDirtyHack() { { + KylinConfig.getInstanceFromEnv().setProperty("kylin.query.escape-default-keyword", "true"); String sql = "select * from DEFAULT.TEST_KYLIN_FACT"; String s = QueryUtil.massageSql(sql, null, 0, 0, "DEFAULT"); Assert.assertEquals("select * from \"DEFAULT\".TEST_KYLIN_FACT", s); http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/server-base/src/main/java/org/apache/kylin/rest/security/TableIntercept.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/TableIntercept.java b/server-base/src/main/java/org/apache/kylin/rest/security/TableIntercept.java deleted file mode 100644 index 442ce88..0000000 --- a/server-base/src/main/java/org/apache/kylin/rest/security/TableIntercept.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -package org.apache.kylin.rest.security; - -import java.util.List; -import java.util.Set; - -import org.apache.kylin.common.KylinConfig; -import org.apache.kylin.metadata.acl.TableACLManager; -import org.apache.kylin.query.relnode.OLAPContext; -import org.apache.kylin.query.security.QueryIntercept; -import org.apache.kylin.query.security.QueryInterceptUtil; - -public class TableIntercept extends QueryIntercept{ - - @Override - protected boolean isEnabled() { - return KylinConfig.getInstanceFromEnv().isTableACLEnabled(); - } - - @Override - public Set<String> getQueryIdentifiers(List<OLAPContext> contexts) { - return QueryInterceptUtil.getAllTblsWithSchema(contexts); - } - - @Override - protected Set<String> getIdentifierBlackList(List<OLAPContext> contexts) { - String project = getProject(contexts); - String username = getUser(contexts); - - return TableACLManager - .getInstance(KylinConfig.getInstanceFromEnv()) - .getTableACLByCache(project) - .getTableBlackList(username); - } - - @Override - protected String getIdentifierType() { - return "table"; - } -} http://git-wip-us.apache.org/repos/asf/kylin/blob/036d70fd/server-base/src/main/java/org/apache/kylin/rest/security/TableInterceptor.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/TableInterceptor.java b/server-base/src/main/java/org/apache/kylin/rest/security/TableInterceptor.java new file mode 100644 index 0000000..e87a630 --- /dev/null +++ b/server-base/src/main/java/org/apache/kylin/rest/security/TableInterceptor.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.apache.kylin.rest.security; + +import java.util.List; +import java.util.Set; + +import org.apache.kylin.common.KylinConfig; +import org.apache.kylin.metadata.acl.TableACLManager; +import org.apache.kylin.query.relnode.OLAPContext; +import org.apache.kylin.query.security.QueryInterceptor; +import org.apache.kylin.query.security.QueryInterceptorUtil; + +public class TableInterceptor extends QueryInterceptor { + + @Override + protected boolean isEnabled() { + return KylinConfig.getInstanceFromEnv().isTableACLEnabled(); + } + + @Override + public Set<String> getQueryIdentifiers(List<OLAPContext> contexts) { + return QueryInterceptorUtil.getAllTblsWithSchema(contexts); + } + + @Override + protected Set<String> getIdentifierBlackList(List<OLAPContext> contexts) { + String project = getProject(contexts); + String username = getUser(contexts); + + return TableACLManager + .getInstance(KylinConfig.getInstanceFromEnv()) + .getTableACLByCache(project) + .getTableBlackList(username); + } + + @Override + protected String getIdentifierType() { + return "table"; + } +}