diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index eb58f9f49f..ea849d81b6 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -942,19 +942,25 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter { @Override public boolean visit(SQLJoinTableSource x) { x.getLeft().accept(this); + incrementIndent(); + if (x.getJoinType() == JoinType.COMMA) { print(","); } else { - print(" "); + println(); print(JoinType.toString(x.getJoinType())); } print(" "); x.getRight().accept(this); if (x.getCondition() != null) { + incrementIndent(); print(" ON "); x.getCondition().accept(this); + decrementIndent(); } + + decrementIndent(); return false; } diff --git a/src/main/java/com/alibaba/druid/wall/WallVisitor.java b/src/main/java/com/alibaba/druid/wall/WallVisitor.java index 5e5a2a435a..f1fccfeb24 100644 --- a/src/main/java/com/alibaba/druid/wall/WallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/WallVisitor.java @@ -28,6 +28,8 @@ public interface WallVisitor extends SQLASTVisitor { List getViolations(); + void addViolation(Violation violation); + boolean isPermitTable(String name); String toSQL(SQLObject obj); diff --git a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java index e66e515b4c..9d691b2dce 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/MySqlWallVisitor.java @@ -71,6 +71,10 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi public WallConfig getConfig() { return config; } + + public void addViolation(Violation violation) { + this.violations.add(violation); + } public List getViolations() { return violations; diff --git a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java index 1bd22f2bdb..8752c45a3d 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/OracleWallVisitor.java @@ -71,6 +71,10 @@ public class OracleWallVisitor extends OracleASTVisitorAdapter implements WallVi return config; } + public void addViolation(Violation violation) { + this.violations.add(violation); + } + public List getViolations() { return violations; } diff --git a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java index 83d0635bf5..90e35f73b4 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -68,6 +68,10 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements return this.config; } + public void addViolation(Violation violation) { + this.violations.add(violation); + } + @Override public List getViolations() { return violations; diff --git a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java index ae54bab3c0..f8ebcb76ce 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/wall/spi/WallVisitorUtils.java @@ -69,761 +69,794 @@ import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation; public class WallVisitorUtils { - private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class); - - public static void check(WallVisitor visitor, SQLInListExpr x) { - - } - - public static void check(WallVisitor visitor, SQLBinaryOpExpr x) { - - } - - public static void check(WallVisitor visitor, SQLPropertyExpr x) { - checkSchema(visitor, x.getOwner()); - } - - public static void checkInsert(WallVisitor visitor, SQLInsertInto x) { - checkReadOnly(visitor, x.getTableSource()); - - if (!visitor.getConfig().isInsertAllow()) { - visitor.getViolations().add( - new IllegalSQLObjectViolation(visitor.toSQL(x))); - } - } - - public static void checkSelelct(WallVisitor visitor, SQLSelectQueryBlock x) { - if (x.getInto() != null) { - checkReadOnly(visitor, x.getInto()); - } - - if (!visitor.getConfig().isSelectIntoAllow() && x.getInto() != null) { - addViolation(visitor, x); - return; - } - - if (!visitor.getConfig().isSelectWhereAlwayTrueCheck()) { - return; - } - - SQLExpr where = x.getWhere(); - - if (where != null) { - x.getWhere().setParent(x); - checkCondition(visitor, x.getWhere()); - - if (Boolean.TRUE == getValue(where)) { - if (where instanceof SQLBinaryOpExpr) { - SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) where; - if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality - || binaryOpExpr.getOperator() == SQLBinaryOperator.NotEqual) { - if (binaryOpExpr.getLeft() instanceof SQLIntegerExpr - && binaryOpExpr.getRight() instanceof SQLIntegerExpr) { - return; - } - } - } - - addViolation(visitor, x); - } - - } - checkConditionForMultiTenant(visitor, x.getWhere(), x); - } - - public static void checkHaving(WallVisitor visitor, SQLExpr x) { - if (x == null) { - return; - } - - if (!visitor.getConfig().isSelectHavingAlwayTrueCheck()) { - return; - } - - if (Boolean.TRUE == getValue(x)) { - addViolation(visitor, x); - } - } - - public static void checkDelete(WallVisitor visitor, SQLDeleteStatement x) { - checkReadOnly(visitor, x.getExprTableSource()); - - if (!visitor.getConfig().isDeleteAllow()) { - addViolation(visitor, x); - return; - } - - if (!visitor.getConfig().isDeleteWhereAlwayTrueCheck()) { - return; - } - - if (x.getWhere() == null || Boolean.TRUE == getValue(x.getWhere())) { - addViolation(visitor, x); - return; - } - - x.getWhere().setParent(x); - checkCondition(visitor, x.getWhere()); - checkConditionForMultiTenant(visitor, x.getWhere(), x); - } - - private static void checkCondition(WallVisitor visitor, SQLExpr x) { - if (x == null) { - return; - } - - if (visitor.getConfig().isMustParameterized()) { - ExportParameterVisitor exportParameterVisitor = visitor - .getProvider().createExportParameterVisitor(); - x.accept(exportParameterVisitor); - - if (exportParameterVisitor.getParameters().size() > 0) { - addViolation(visitor, x); - return; - } - } - - } - - public static void checkConditionForMultiTenant(WallVisitor visitor, - SQLExpr x, SQLObject parent) { - String tenantTablePattern = visitor.getConfig().getTenantTablePattern(); - if (tenantTablePattern == null || tenantTablePattern.length() == 0) { - return; - } - - if (parent == null) { - throw new IllegalStateException("parent is null"); - } - - SQLTableSource tableSource; - if (parent instanceof SQLDeleteStatement) { - tableSource = ((SQLDeleteStatement) parent).getTableSource(); - } else if (parent instanceof SQLUpdateStatement) { - tableSource = ((SQLUpdateStatement) parent).getTableSource(); - } else if (parent instanceof SQLSelectQueryBlock) { - tableSource = ((SQLSelectQueryBlock) parent).getFrom(); - } else { - throw new IllegalStateException("not support parent : " - + parent.getClass()); - } - - String matchTableName = null; - if (tableSource instanceof SQLExprTableSource) { - SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr(); - - if (tableExpr instanceof SQLIdentifierExpr) { - String tableName = ((SQLIdentifierExpr) tableExpr).getName(); - if (ServletPathMatcher.getInstance().matches( - tenantTablePattern, tableName)) { - matchTableName = tableName; - } - } - } - - if (matchTableName == null) { - return; - } - - SQLExpr left, right; - if (tableSource.getAlias() != null) { - left = new SQLPropertyExpr(new SQLIdentifierExpr( - tableSource.getAlias()), visitor.getConfig() - .getTenantColumn()); - } else { - left = new SQLPropertyExpr(new SQLIdentifierExpr(matchTableName), - visitor.getConfig().getTenantColumn()); - } - - Object tenantValue = WallProvider.getTenantValue(); - if (tenantValue instanceof Number) { - right = new SQLNumberExpr((Number) tenantValue); - } else if (tenantValue instanceof String) { - right = new SQLCharExpr((String) tenantValue); - } else { - throw new IllegalStateException("tenant value not support type " - + tenantValue); - } - - SQLBinaryOpExpr tenantCondition = new SQLBinaryOpExpr(left, - SQLBinaryOperator.Equality, right); - - SQLExpr condition; - if (x == null) { - condition = tenantCondition; - } else { - condition = new SQLBinaryOpExpr(tenantCondition, - SQLBinaryOperator.BooleanAnd, x); - } - - if (parent instanceof SQLDeleteStatement) { - ((SQLDeleteStatement) parent).setWhere(condition); - } else if (parent instanceof SQLUpdateStatement) { - ((SQLUpdateStatement) parent).setWhere(condition); - } else if (parent instanceof SQLSelectQueryBlock) { - ((SQLSelectQueryBlock) parent).setWhere(condition); - } - } - - public static void checkReadOnly(WallVisitor visitor, - SQLTableSource tableSource) { - if (tableSource instanceof SQLExprTableSource) { - String tableName = null; - SQLExpr tableNameExpr = ((SQLExprTableSource) tableSource) - .getExpr(); - if (tableNameExpr instanceof SQLName) { - tableName = ((SQLName) tableNameExpr).getSimleName(); - } - - if (tableName != null) { - tableName = form(tableName); - if (visitor.getConfig().getReadOnlyTables().contains(tableName)) { - addViolation(visitor, tableSource); - } - } - } else if (tableSource instanceof SQLJoinTableSource) { - SQLJoinTableSource join = (SQLJoinTableSource) tableSource; - - checkReadOnly(visitor, join.getLeft()); - checkReadOnly(visitor, join.getRight()); - } - } - - public static void checkUpdate(WallVisitor visitor, SQLUpdateStatement x) { - checkReadOnly(visitor, x.getTableSource()); - - if (!visitor.getConfig().isUpdateAllow()) { - addViolation(visitor, x); - return; - } - - if (!visitor.getConfig().isUpdateWhereAlayTrueCheck()) { - return; - } - - if (x.getWhere() == null || Boolean.TRUE == getValue(x.getWhere())) { - addViolation(visitor, x); - return; - } - - x.getWhere().setParent(x); - checkCondition(visitor, x.getWhere()); - checkConditionForMultiTenant(visitor, x.getWhere(), x); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Object getValue(SQLBinaryOpExpr x) { - x.getLeft().setParent(x); - x.getRight().setParent(x); - - if (x.getLeft() instanceof SQLName && x.getRight() instanceof SQLName) { - if (x.getLeft().toString() - .equalsIgnoreCase(x.getRight().toString())) { - if (x.getOperator() == SQLBinaryOperator.Equality) { - return Boolean.TRUE; - } else if (x.getOperator() == SQLBinaryOperator.NotEqual) { - return Boolean.FALSE; - } - - switch (x.getOperator()) { - case Equality: - case Like: - return Boolean.TRUE; - case NotEqual: - case GreaterThan: - case GreaterThanOrEqual: - case LessThan: - case LessThanOrEqual: - case LessThanOrGreater: - case NotLike: - return Boolean.FALSE; - default: - break; - } - } - } - - if (x.getOperator() == SQLBinaryOperator.BooleanOr) { - List groupList = new ArrayList(); - SQLExpr left = x.getLeft(); - for (;;) { - if (left instanceof SQLBinaryOpExpr - && ((SQLBinaryOpExpr) left).getOperator() == x - .getOperator()) { - SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left; - groupList.add(binaryLeft.getRight()); - left = binaryLeft.getLeft(); - } else { - groupList.add(left); - break; - } - } - groupList.add(x.getRight()); - - boolean allFalse = true; - for (int i = groupList.size() - 1; i >= 0; --i) { - Object result = getValue(groupList.get(i)); - if (Boolean.TRUE == result) { - return true; - } - - if (Boolean.FALSE != result) { - allFalse = false; - } - } - - if (allFalse) { - return false; - } - - return null; - } - - Object leftResult = getValue(x.getLeft()); - Object rightResult = getValue(x.getRight()); - - if (x.getOperator() == SQLBinaryOperator.BooleanAnd) { - if (Boolean.FALSE == leftResult || Boolean.FALSE == rightResult) { - return false; - } - - if (Boolean.TRUE == leftResult && Boolean.TRUE == rightResult) { - return true; - } - } - - if (x.getOperator() == SQLBinaryOperator.Like) { - if (x.getRight() instanceof SQLCharExpr) { - String text = ((SQLCharExpr) x.getRight()).getText(); - - if (text.length() >= 0) { - for (char ch : text.toCharArray()) { - if (ch != '%') { - return null; - } - } - - return true; - } - - } - } - - if (leftResult == null || rightResult == null) { - return null; - } - - if (x.getOperator() == SQLBinaryOperator.Equality) { - if (x.getLeft() instanceof SQLNullExpr - && x.getRight() instanceof SQLNullExpr) { - return true; - } - - return leftResult.equals(rightResult); - } - - if (x.getOperator() == SQLBinaryOperator.NotEqual - || x.getOperator() == SQLBinaryOperator.LessThanOrGreater) { - if (x.getLeft() instanceof SQLNullExpr - && x.getRight() instanceof SQLNullExpr) { - return false; - } - - if (leftResult == null || rightResult == null) { - return null; - } - - return !leftResult.equals(rightResult); - } - - if (x.getOperator() == SQLBinaryOperator.GreaterThan) { - if (x.getLeft() instanceof SQLNullExpr - && x.getRight() instanceof SQLNullExpr) { - return false; - } - - if (leftResult == null || rightResult == null) { - return null; - } - - if (leftResult instanceof Comparable) { - return (((Comparable) leftResult).compareTo(rightResult) > 0); - } - } - - if (x.getOperator() == SQLBinaryOperator.GreaterThanOrEqual) { - if (x.getLeft() instanceof SQLNullExpr - && x.getRight() instanceof SQLNullExpr) { - return false; - } - - if (leftResult == null || rightResult == null) { - return null; - } - - if (leftResult instanceof Comparable) { - return ((Comparable) leftResult).compareTo(rightResult) >= 0; - } - } - - if (x.getOperator() == SQLBinaryOperator.LessThan) { - if (x.getLeft() instanceof SQLNullExpr - && x.getRight() instanceof SQLNullExpr) { - return false; - } - - if (leftResult == null || rightResult == null) { - return null; - } - - if (leftResult instanceof Comparable) { - return (((Comparable) leftResult).compareTo(rightResult) < 0); - } - } - - if (x.getOperator() == SQLBinaryOperator.LessThanOrEqual) { - if (x.getLeft() instanceof SQLNullExpr - && x.getRight() instanceof SQLNullExpr) { - return false; - } - - if (leftResult == null || rightResult == null) { - return null; - } - - if (leftResult instanceof Comparable) { - return ((Comparable) leftResult).compareTo(rightResult) <= 0; - } - } - - if (x.getOperator() == SQLBinaryOperator.Concat) { - return leftResult.toString() + rightResult.toString(); - } - - if (x.getOperator() == SQLBinaryOperator.Add) { - if (leftResult == null || rightResult == null) { - return null; - } - - if (leftResult instanceof String || rightResult instanceof String) { - return leftResult.toString() + rightResult.toString(); - } - - if (leftResult instanceof Number || rightResult instanceof Number) { - return add((Number) leftResult, (Number) rightResult); - } - } - - return null; - } - - private static Number add(Number a, Number b) { - if (a instanceof BigDecimal) { - return ((BigDecimal) a).add(new BigDecimal(b.toString())); - } - - return a.longValue() + b.longValue(); - } - - public static Object getValue(SQLExpr x) { - if (x instanceof SQLBinaryOpExpr) { - return getValue((SQLBinaryOpExpr) x); - } - - if (x instanceof MySqlBooleanExpr) { - return ((MySqlBooleanExpr) x).getValue(); - } - - if (x instanceof SQLNumericLiteralExpr) { - return ((SQLNumericLiteralExpr) x).getNumber(); - } - - if (x instanceof SQLCharExpr) { - return ((SQLCharExpr) x).getText(); - } - - if (x instanceof SQLNCharExpr) { - return ((SQLNCharExpr) x).getText(); - } - - if (x instanceof SQLNotExpr) { - Object result = getValue(((SQLNotExpr) x).getExpr()); - if (result instanceof Boolean) { - return !((Boolean) result).booleanValue(); - } - } - - if (x instanceof SQLQueryExpr) { - if (isSimpleCountTableSource(((SQLQueryExpr) x).getSubQuery())) { - return Integer.valueOf(1); - } - } - - if (x instanceof SQLMethodInvokeExpr) { - return getValue((SQLMethodInvokeExpr) x); - } - - return null; - } - - public static Object getValue(SQLMethodInvokeExpr x) { - String methodName = x.getMethodName(); - if ("len".equalsIgnoreCase(methodName) - || "length".equalsIgnoreCase(methodName)) { - Object firstValue = null; - if (x.getParameters().size() > 0) { - firstValue = (getValue(x.getParameters().get(0))); - } - - if (firstValue instanceof String) { - return ((String) firstValue).length(); - } - } - - if ("if".equalsIgnoreCase(methodName) && x.getParameters().size() == 3) { - SQLExpr first = x.getParameters().get(0); - Object firstResult = getValue(first); - - if (Boolean.TRUE == firstResult) { - return getValue(x.getParameters().get(1)); - } - - if (Boolean.FALSE == firstResult) { - getValue(x.getParameters().get(2)); - } - } - - if ("chr".equalsIgnoreCase(methodName) && x.getParameters().size() == 1) { - SQLExpr first = x.getParameters().get(0); - Object firstResult = getValue(first); - if (firstResult instanceof Number) { - int intValue = ((Number) firstResult).intValue(); - char ch = (char) intValue; - - return "" + ch; - } - } - - if ("concat".equalsIgnoreCase(methodName)) { - StringBuffer buf = new StringBuffer(); - for (SQLExpr expr : x.getParameters()) { - Object value = getValue(expr); - if (value == null) { - return null; - } - - buf.append(value.toString()); - } - return buf.toString(); - } - - return null; - } - - public static boolean isSimpleCountTableSource(SQLTableSource tableSource) { - if (!(tableSource instanceof SQLSubqueryTableSource)) { - return false; - } - - SQLSubqueryTableSource subQuery = (SQLSubqueryTableSource) tableSource; - - return isSimpleCountTableSource(subQuery.getSelect()); - } - - public static boolean isSimpleCountTableSource(SQLSelect select) { - SQLSelectQuery query = select.getQuery(); - - if (query instanceof SQLSelectQueryBlock) { - SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; - - boolean allawTrueWhere = false; - - if (queryBlock.getWhere() == null) { - allawTrueWhere = true; - } else { - Object whereValue = getValue(queryBlock.getWhere()); - if (whereValue == Boolean.TRUE) { - allawTrueWhere = true; - } else if (whereValue == Boolean.FALSE) { - return false; - } - } - boolean simpleCount = false; - if (queryBlock.getSelectList().size() == 1) { - SQLExpr selectItemExpr = queryBlock.getSelectList().get(0) - .getExpr(); - if (selectItemExpr instanceof SQLAggregateExpr) { - if (((SQLAggregateExpr) selectItemExpr).getMethodName() - .equalsIgnoreCase("COUNT")) { - simpleCount = true; - } - } - } - - if (allawTrueWhere && simpleCount) { - return true; - } - } - - return false; - } - - public static void checkFunction(WallVisitor visitor, SQLMethodInvokeExpr x) { - checkSchema(visitor, x.getOwner()); - - if (!visitor.getConfig().isFunctionCheck()) { - return; - } - - String methodName = x.getMethodName(); - - if (visitor.getConfig().isPermitFunction(methodName.toLowerCase())) { - addViolation(visitor, x); - } - - } - - private static void checkSchema(WallVisitor visitor, SQLExpr x) { - if (x instanceof SQLName) { - String owner = ((SQLName) x).getSimleName(); - owner = WallVisitorUtils.form(owner); - if (visitor.getConfig().isPermitSchema(owner)) { - addViolation(visitor, x); - } - - if (visitor.getConfig().isPermitObjects(owner)) { - addViolation(visitor, x); - } - } - - // if (ownerExpr instanceof SQLPropertyExpr) { - if (x instanceof SQLPropertyExpr) { - checkSchema(visitor, ((SQLPropertyExpr) x).getOwner()); - } - } - - public static void check(WallVisitor visitor, SQLExprTableSource x) { - SQLExpr expr = x.getExpr(); - - if (expr instanceof SQLPropertyExpr) { - checkSchema(visitor, ((SQLPropertyExpr) expr).getOwner()); - } - - if (expr instanceof SQLName) { - String tableName = ((SQLName) expr).getSimleName(); - if (visitor.isPermitTable(tableName)) { - addViolation(visitor, x); - } - } - } - - private static void addViolation(WallVisitor visitor, SQLObject x) { - visitor.getViolations().add( - new IllegalSQLObjectViolation(visitor.toSQL(x))); - } - - public static void checkUnion(WallVisitor visitor, SQLUnionQuery x) { - if (!visitor.getConfig().isSelectUnionCheck()) { - return; - } - - if (WallVisitorUtils.queryBlockFromIsNull(x.getLeft()) - || WallVisitorUtils.queryBlockFromIsNull(x.getRight())) { - addViolation(visitor, x); - } - } - - public static boolean queryBlockFromIsNull(SQLSelectQuery query) { - if (query instanceof SQLSelectQueryBlock) { - SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; - SQLTableSource from = queryBlock.getFrom(); - - if (from == null) { - return true; - } - - if (from instanceof SQLExprTableSource) { - SQLExpr fromExpr = ((SQLExprTableSource) from).getExpr(); - if (fromExpr instanceof SQLName) { - String name = fromExpr.toString(); - - name = form(name); - - if (name.equalsIgnoreCase("DUAL")) { - return true; - } - } - } - - if (queryBlock.getSelectList().size() == 1 - && queryBlock.getSelectList().get(0).getExpr() instanceof SQLAllColumnExpr) { - if (from instanceof SQLSubqueryTableSource) { - SQLSelectQuery subQuery = ((SQLSubqueryTableSource) from) - .getSelect().getQuery(); - if (queryBlockFromIsNull(subQuery)) { - return true; - } - } - } - - boolean allIsConst = true; - for (SQLSelectItem item : queryBlock.getSelectList()) { - if (getValue(item.getExpr()) == null) { - allIsConst = false; - break; - } - } - if (allIsConst) { - return true; - } - } - - return false; - } - - public static String form(String name) { - if (name.startsWith("\"") && name.endsWith("\"")) { - name = name.substring(1, name.length() - 1); - } - if (name.startsWith("`") && name.endsWith("`")) { - name = name.substring(1, name.length() - 1); - } - - name = name.toLowerCase(); - return name; - } - - public static void loadResource(Set names, String resource) { - try { - Enumeration e = Thread.currentThread().getContextClassLoader() - .getResources(resource); - while (e.hasMoreElements()) { - URL url = e.nextElement(); - InputStream in = null; - BufferedReader reader = null; - try { - in = url.openStream(); - reader = new BufferedReader(new InputStreamReader(in)); - for (;;) { - String line = reader.readLine(); - if (line == null) { - break; - } - line = line.trim(); - if (line.length() > 0) { - line = line.toLowerCase(); - names.add(line); - } - } - - url.openStream(); - } finally { - JdbcUtils.close(reader); - JdbcUtils.close(in); - } - } - } catch (IOException e) { - LOG.error("load oracle permit tables errror", e); - } - } + private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class); + + public static void check(WallVisitor visitor, SQLInListExpr x) { + + } + + public static void check(WallVisitor visitor, SQLBinaryOpExpr x) { + + } + + public static void check(WallVisitor visitor, SQLPropertyExpr x) { + checkSchema(visitor, x.getOwner()); + } + + public static void checkInsert(WallVisitor visitor, SQLInsertInto x) { + checkReadOnly(visitor, x.getTableSource()); + + if (!visitor.getConfig().isInsertAllow()) { + addViolation(visitor, x); + } + } + + public static void checkSelelct(WallVisitor visitor, SQLSelectQueryBlock x) { + if (x.getInto() != null) { + checkReadOnly(visitor, x.getInto()); + } + + if (!visitor.getConfig().isSelectIntoAllow() && x.getInto() != null) { + addViolation(visitor, x); + return; + } + + if (!visitor.getConfig().isSelectWhereAlwayTrueCheck()) { + return; + } + + SQLExpr where = x.getWhere(); + + if (where != null) { + x.getWhere().setParent(x); + checkCondition(visitor, x.getWhere()); + + if (Boolean.TRUE == getValue(where)) { + if (where instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) where; + if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality + || binaryOpExpr.getOperator() == SQLBinaryOperator.NotEqual) { + if (binaryOpExpr.getLeft() instanceof SQLIntegerExpr + && binaryOpExpr.getRight() instanceof SQLIntegerExpr) { + return; + } + } + } + + addViolation(visitor, x); + } + + } + checkConditionForMultiTenant(visitor, x.getWhere(), x); + } + + public static void checkHaving(WallVisitor visitor, SQLExpr x) { + if (x == null) { + return; + } + + if (!visitor.getConfig().isSelectHavingAlwayTrueCheck()) { + return; + } + + if (Boolean.TRUE == getValue(x)) { + addViolation(visitor, x); + } + } + + public static void checkDelete(WallVisitor visitor, SQLDeleteStatement x) { + checkReadOnly(visitor, x.getExprTableSource()); + + if (!visitor.getConfig().isDeleteAllow()) { + addViolation(visitor, x); + return; + } + + if (!visitor.getConfig().isDeleteWhereAlwayTrueCheck()) { + return; + } + + if (x.getWhere() == null || Boolean.TRUE == getValue(x.getWhere())) { + addViolation(visitor, x); + return; + } + + x.getWhere().setParent(x); + checkCondition(visitor, x.getWhere()); + checkConditionForMultiTenant(visitor, x.getWhere(), x); + } + + private static void checkCondition(WallVisitor visitor, SQLExpr x) { + if (x == null) { + return; + } + + if (visitor.getConfig().isMustParameterized()) { + ExportParameterVisitor exportParameterVisitor = visitor.getProvider().createExportParameterVisitor(); + x.accept(exportParameterVisitor); + + if (exportParameterVisitor.getParameters().size() > 0) { + addViolation(visitor, x); + return; + } + } + + } + + public static void checkConditionForMultiTenant(WallVisitor visitor, SQLExpr x, SQLObject parent) { + String tenantTablePattern = visitor.getConfig().getTenantTablePattern(); + if (tenantTablePattern == null || tenantTablePattern.length() == 0) { + return; + } + + if (parent == null) { + throw new IllegalStateException("parent is null"); + } + + String alias = null; + SQLTableSource tableSource; + if (parent instanceof SQLDeleteStatement) { + tableSource = ((SQLDeleteStatement) parent).getTableSource(); + } else if (parent instanceof SQLUpdateStatement) { + tableSource = ((SQLUpdateStatement) parent).getTableSource(); + } else if (parent instanceof SQLSelectQueryBlock) { + tableSource = ((SQLSelectQueryBlock) parent).getFrom(); + } else { + throw new IllegalStateException("not support parent : " + parent.getClass()); + } + + String matchTableName = null; + if (tableSource instanceof SQLExprTableSource) { + SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr(); + + if (tableExpr instanceof SQLIdentifierExpr) { + String tableName = ((SQLIdentifierExpr) tableExpr).getName(); + if (ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) { + matchTableName = tableName; + alias = tableSource.getAlias(); + } + } + } else if (tableSource instanceof SQLJoinTableSource) { + SQLJoinTableSource join = (SQLJoinTableSource) tableSource; + if (join.getLeft() instanceof SQLExprTableSource) { + SQLExpr tableExpr = ((SQLExprTableSource) join.getLeft()).getExpr(); + + if (tableExpr instanceof SQLIdentifierExpr) { + String tableName = ((SQLIdentifierExpr) tableExpr).getName(); + if (ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) { + matchTableName = tableName; + alias = join.getLeft().getAlias(); + } + } + + checkJoinConditionForMultiTenant(visitor, join, false); + } else { + checkJoinConditionForMultiTenant(visitor, join, true); + } + } + + if (matchTableName == null) { + return; + } + + SQLBinaryOpExpr tenantCondition = cretateTenantCondition(visitor, alias); + + SQLExpr condition; + if (x == null) { + condition = tenantCondition; + } else { + condition = new SQLBinaryOpExpr(tenantCondition, SQLBinaryOperator.BooleanAnd, x); + } + + if (parent instanceof SQLDeleteStatement) { + ((SQLDeleteStatement) parent).setWhere(condition); + } else if (parent instanceof SQLUpdateStatement) { + ((SQLUpdateStatement) parent).setWhere(condition); + } else if (parent instanceof SQLSelectQueryBlock) { + ((SQLSelectQueryBlock) parent).setWhere(condition); + } + } + + public static void checkJoinConditionForMultiTenant(WallVisitor visitor, SQLJoinTableSource join, boolean checkLeft) { + String tenantTablePattern = visitor.getConfig().getTenantTablePattern(); + if (tenantTablePattern == null || tenantTablePattern.length() == 0) { + return; + } + + SQLExpr condition = join.getCondition(); + + if (checkLeft) { + + } + + SQLTableSource right = join.getRight(); + if (right instanceof SQLExprTableSource) { + SQLExpr tableExpr = ((SQLExprTableSource) right).getExpr(); + + if (tableExpr instanceof SQLIdentifierExpr) { + String tableName = ((SQLIdentifierExpr) tableExpr).getName(); + if (ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) { + String alias = right.getAlias(); + if (alias == null) { + alias = tableName; + } + SQLBinaryOpExpr tenantCondition = cretateTenantCondition(visitor, alias); + + if (condition == null) { + condition = tenantCondition; + } else { + condition = new SQLBinaryOpExpr(tenantCondition, SQLBinaryOperator.BooleanAnd, condition); + } + } + } + } + + if (condition != join.getCondition()) { + join.setCondition(condition); + } + } + + private static SQLBinaryOpExpr cretateTenantCondition(WallVisitor visitor, String alias) { + SQLExpr left, right; + if (alias != null) { + left = new SQLPropertyExpr(new SQLIdentifierExpr(alias), visitor.getConfig().getTenantColumn()); + } else { + left = new SQLIdentifierExpr(visitor.getConfig().getTenantColumn()); + } + + Object tenantValue = WallProvider.getTenantValue(); + if (tenantValue instanceof Number) { + right = new SQLNumberExpr((Number) tenantValue); + } else if (tenantValue instanceof String) { + right = new SQLCharExpr((String) tenantValue); + } else { + throw new IllegalStateException("tenant value not support type " + tenantValue); + } + + SQLBinaryOpExpr tenantCondition = new SQLBinaryOpExpr(left, SQLBinaryOperator.Equality, right); + return tenantCondition; + } + + public static void checkReadOnly(WallVisitor visitor, SQLTableSource tableSource) { + if (tableSource instanceof SQLExprTableSource) { + String tableName = null; + SQLExpr tableNameExpr = ((SQLExprTableSource) tableSource).getExpr(); + if (tableNameExpr instanceof SQLName) { + tableName = ((SQLName) tableNameExpr).getSimleName(); + } + + if (tableName != null) { + tableName = form(tableName); + if (visitor.getConfig().getReadOnlyTables().contains(tableName)) { + addViolation(visitor, tableSource); + } + } + } else if (tableSource instanceof SQLJoinTableSource) { + SQLJoinTableSource join = (SQLJoinTableSource) tableSource; + + checkReadOnly(visitor, join.getLeft()); + checkReadOnly(visitor, join.getRight()); + } + } + + public static void checkUpdate(WallVisitor visitor, SQLUpdateStatement x) { + checkReadOnly(visitor, x.getTableSource()); + + if (!visitor.getConfig().isUpdateAllow()) { + addViolation(visitor, x); + return; + } + + if (!visitor.getConfig().isUpdateWhereAlayTrueCheck()) { + return; + } + + if (x.getWhere() == null || Boolean.TRUE == getValue(x.getWhere())) { + addViolation(visitor, x); + return; + } + + x.getWhere().setParent(x); + checkCondition(visitor, x.getWhere()); + checkConditionForMultiTenant(visitor, x.getWhere(), x); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Object getValue(SQLBinaryOpExpr x) { + x.getLeft().setParent(x); + x.getRight().setParent(x); + + if (x.getLeft() instanceof SQLName && x.getRight() instanceof SQLName) { + if (x.getLeft().toString().equalsIgnoreCase(x.getRight().toString())) { + if (x.getOperator() == SQLBinaryOperator.Equality) { + return Boolean.TRUE; + } else if (x.getOperator() == SQLBinaryOperator.NotEqual) { + return Boolean.FALSE; + } + + switch (x.getOperator()) { + case Equality: + case Like: + return Boolean.TRUE; + case NotEqual: + case GreaterThan: + case GreaterThanOrEqual: + case LessThan: + case LessThanOrEqual: + case LessThanOrGreater: + case NotLike: + return Boolean.FALSE; + default: + break; + } + } + } + + if (x.getOperator() == SQLBinaryOperator.BooleanOr) { + List groupList = new ArrayList(); + SQLExpr left = x.getLeft(); + for (;;) { + if (left instanceof SQLBinaryOpExpr && ((SQLBinaryOpExpr) left).getOperator() == x.getOperator()) { + SQLBinaryOpExpr binaryLeft = (SQLBinaryOpExpr) left; + groupList.add(binaryLeft.getRight()); + left = binaryLeft.getLeft(); + } else { + groupList.add(left); + break; + } + } + groupList.add(x.getRight()); + + boolean allFalse = true; + for (int i = groupList.size() - 1; i >= 0; --i) { + Object result = getValue(groupList.get(i)); + if (Boolean.TRUE == result) { + return true; + } + + if (Boolean.FALSE != result) { + allFalse = false; + } + } + + if (allFalse) { + return false; + } + + return null; + } + + Object leftResult = getValue(x.getLeft()); + Object rightResult = getValue(x.getRight()); + + if (x.getOperator() == SQLBinaryOperator.BooleanAnd) { + if (Boolean.FALSE == leftResult || Boolean.FALSE == rightResult) { + return false; + } + + if (Boolean.TRUE == leftResult && Boolean.TRUE == rightResult) { + return true; + } + } + + if (x.getOperator() == SQLBinaryOperator.Like) { + if (x.getRight() instanceof SQLCharExpr) { + String text = ((SQLCharExpr) x.getRight()).getText(); + + if (text.length() >= 0) { + for (char ch : text.toCharArray()) { + if (ch != '%') { + return null; + } + } + + return true; + } + + } + } + + if (leftResult == null || rightResult == null) { + return null; + } + + if (x.getOperator() == SQLBinaryOperator.Equality) { + if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { + return true; + } + + return leftResult.equals(rightResult); + } + + if (x.getOperator() == SQLBinaryOperator.NotEqual || x.getOperator() == SQLBinaryOperator.LessThanOrGreater) { + if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { + return false; + } + + if (leftResult == null || rightResult == null) { + return null; + } + + return !leftResult.equals(rightResult); + } + + if (x.getOperator() == SQLBinaryOperator.GreaterThan) { + if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { + return false; + } + + if (leftResult == null || rightResult == null) { + return null; + } + + if (leftResult instanceof Comparable) { + return (((Comparable) leftResult).compareTo(rightResult) > 0); + } + } + + if (x.getOperator() == SQLBinaryOperator.GreaterThanOrEqual) { + if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { + return false; + } + + if (leftResult == null || rightResult == null) { + return null; + } + + if (leftResult instanceof Comparable) { + return ((Comparable) leftResult).compareTo(rightResult) >= 0; + } + } + + if (x.getOperator() == SQLBinaryOperator.LessThan) { + if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { + return false; + } + + if (leftResult == null || rightResult == null) { + return null; + } + + if (leftResult instanceof Comparable) { + return (((Comparable) leftResult).compareTo(rightResult) < 0); + } + } + + if (x.getOperator() == SQLBinaryOperator.LessThanOrEqual) { + if (x.getLeft() instanceof SQLNullExpr && x.getRight() instanceof SQLNullExpr) { + return false; + } + + if (leftResult == null || rightResult == null) { + return null; + } + + if (leftResult instanceof Comparable) { + return ((Comparable) leftResult).compareTo(rightResult) <= 0; + } + } + + if (x.getOperator() == SQLBinaryOperator.Concat) { + return leftResult.toString() + rightResult.toString(); + } + + if (x.getOperator() == SQLBinaryOperator.Add) { + if (leftResult == null || rightResult == null) { + return null; + } + + if (leftResult instanceof String || rightResult instanceof String) { + return leftResult.toString() + rightResult.toString(); + } + + if (leftResult instanceof Number || rightResult instanceof Number) { + return add((Number) leftResult, (Number) rightResult); + } + } + + return null; + } + + private static Number add(Number a, Number b) { + if (a instanceof BigDecimal) { + return ((BigDecimal) a).add(new BigDecimal(b.toString())); + } + + return a.longValue() + b.longValue(); + } + + public static Object getValue(SQLExpr x) { + if (x instanceof SQLBinaryOpExpr) { + return getValue((SQLBinaryOpExpr) x); + } + + if (x instanceof MySqlBooleanExpr) { + return ((MySqlBooleanExpr) x).getValue(); + } + + if (x instanceof SQLNumericLiteralExpr) { + return ((SQLNumericLiteralExpr) x).getNumber(); + } + + if (x instanceof SQLCharExpr) { + return ((SQLCharExpr) x).getText(); + } + + if (x instanceof SQLNCharExpr) { + return ((SQLNCharExpr) x).getText(); + } + + if (x instanceof SQLNotExpr) { + Object result = getValue(((SQLNotExpr) x).getExpr()); + if (result instanceof Boolean) { + return !((Boolean) result).booleanValue(); + } + } + + if (x instanceof SQLQueryExpr) { + if (isSimpleCountTableSource(((SQLQueryExpr) x).getSubQuery())) { + return Integer.valueOf(1); + } + } + + if (x instanceof SQLMethodInvokeExpr) { + return getValue((SQLMethodInvokeExpr) x); + } + + return null; + } + + public static Object getValue(SQLMethodInvokeExpr x) { + String methodName = x.getMethodName(); + if ("len".equalsIgnoreCase(methodName) || "length".equalsIgnoreCase(methodName)) { + Object firstValue = null; + if (x.getParameters().size() > 0) { + firstValue = (getValue(x.getParameters().get(0))); + } + + if (firstValue instanceof String) { + return ((String) firstValue).length(); + } + } + + if ("if".equalsIgnoreCase(methodName) && x.getParameters().size() == 3) { + SQLExpr first = x.getParameters().get(0); + Object firstResult = getValue(first); + + if (Boolean.TRUE == firstResult) { + return getValue(x.getParameters().get(1)); + } + + if (Boolean.FALSE == firstResult) { + getValue(x.getParameters().get(2)); + } + } + + if ("chr".equalsIgnoreCase(methodName) && x.getParameters().size() == 1) { + SQLExpr first = x.getParameters().get(0); + Object firstResult = getValue(first); + if (firstResult instanceof Number) { + int intValue = ((Number) firstResult).intValue(); + char ch = (char) intValue; + + return "" + ch; + } + } + + if ("concat".equalsIgnoreCase(methodName)) { + StringBuffer buf = new StringBuffer(); + for (SQLExpr expr : x.getParameters()) { + Object value = getValue(expr); + if (value == null) { + return null; + } + + buf.append(value.toString()); + } + return buf.toString(); + } + + return null; + } + + public static boolean isSimpleCountTableSource(SQLTableSource tableSource) { + if (!(tableSource instanceof SQLSubqueryTableSource)) { + return false; + } + + SQLSubqueryTableSource subQuery = (SQLSubqueryTableSource) tableSource; + + return isSimpleCountTableSource(subQuery.getSelect()); + } + + public static boolean isSimpleCountTableSource(SQLSelect select) { + SQLSelectQuery query = select.getQuery(); + + if (query instanceof SQLSelectQueryBlock) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; + + boolean allawTrueWhere = false; + + if (queryBlock.getWhere() == null) { + allawTrueWhere = true; + } else { + Object whereValue = getValue(queryBlock.getWhere()); + if (whereValue == Boolean.TRUE) { + allawTrueWhere = true; + } else if (whereValue == Boolean.FALSE) { + return false; + } + } + boolean simpleCount = false; + if (queryBlock.getSelectList().size() == 1) { + SQLExpr selectItemExpr = queryBlock.getSelectList().get(0).getExpr(); + if (selectItemExpr instanceof SQLAggregateExpr) { + if (((SQLAggregateExpr) selectItemExpr).getMethodName().equalsIgnoreCase("COUNT")) { + simpleCount = true; + } + } + } + + if (allawTrueWhere && simpleCount) { + return true; + } + } + + return false; + } + + public static void checkFunction(WallVisitor visitor, SQLMethodInvokeExpr x) { + checkSchema(visitor, x.getOwner()); + + if (!visitor.getConfig().isFunctionCheck()) { + return; + } + + String methodName = x.getMethodName(); + + if (visitor.getConfig().isPermitFunction(methodName.toLowerCase())) { + addViolation(visitor, x); + } + + } + + private static void checkSchema(WallVisitor visitor, SQLExpr x) { + if (x instanceof SQLName) { + String owner = ((SQLName) x).getSimleName(); + owner = WallVisitorUtils.form(owner); + if (visitor.getConfig().isPermitSchema(owner)) { + addViolation(visitor, x); + } + + if (visitor.getConfig().isPermitObjects(owner)) { + addViolation(visitor, x); + } + } + + // if (ownerExpr instanceof SQLPropertyExpr) { + if (x instanceof SQLPropertyExpr) { + checkSchema(visitor, ((SQLPropertyExpr) x).getOwner()); + } + } + + public static void check(WallVisitor visitor, SQLExprTableSource x) { + SQLExpr expr = x.getExpr(); + + if (expr instanceof SQLPropertyExpr) { + checkSchema(visitor, ((SQLPropertyExpr) expr).getOwner()); + } + + if (expr instanceof SQLName) { + String tableName = ((SQLName) expr).getSimleName(); + if (visitor.isPermitTable(tableName)) { + addViolation(visitor, x); + } + } + } + + private static void addViolation(WallVisitor visitor, SQLObject x) { + visitor.addViolation(new IllegalSQLObjectViolation(visitor.toSQL(x))); + } + + public static void checkUnion(WallVisitor visitor, SQLUnionQuery x) { + if (!visitor.getConfig().isSelectUnionCheck()) { + return; + } + + if (WallVisitorUtils.queryBlockFromIsNull(x.getLeft()) || WallVisitorUtils.queryBlockFromIsNull(x.getRight())) { + addViolation(visitor, x); + } + } + + public static boolean queryBlockFromIsNull(SQLSelectQuery query) { + if (query instanceof SQLSelectQueryBlock) { + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; + SQLTableSource from = queryBlock.getFrom(); + + if (from == null) { + return true; + } + + if (from instanceof SQLExprTableSource) { + SQLExpr fromExpr = ((SQLExprTableSource) from).getExpr(); + if (fromExpr instanceof SQLName) { + String name = fromExpr.toString(); + + name = form(name); + + if (name.equalsIgnoreCase("DUAL")) { + return true; + } + } + } + + if (queryBlock.getSelectList().size() == 1 + && queryBlock.getSelectList().get(0).getExpr() instanceof SQLAllColumnExpr) { + if (from instanceof SQLSubqueryTableSource) { + SQLSelectQuery subQuery = ((SQLSubqueryTableSource) from).getSelect().getQuery(); + if (queryBlockFromIsNull(subQuery)) { + return true; + } + } + } + + boolean allIsConst = true; + for (SQLSelectItem item : queryBlock.getSelectList()) { + if (getValue(item.getExpr()) == null) { + allIsConst = false; + break; + } + } + if (allIsConst) { + return true; + } + } + + return false; + } + + public static String form(String name) { + if (name.startsWith("\"") && name.endsWith("\"")) { + name = name.substring(1, name.length() - 1); + } + if (name.startsWith("`") && name.endsWith("`")) { + name = name.substring(1, name.length() - 1); + } + + name = name.toLowerCase(); + return name; + } + + public static void loadResource(Set names, String resource) { + try { + Enumeration e = Thread.currentThread().getContextClassLoader().getResources(resource); + while (e.hasMoreElements()) { + URL url = e.nextElement(); + InputStream in = null; + BufferedReader reader = null; + try { + in = url.openStream(); + reader = new BufferedReader(new InputStreamReader(in)); + for (;;) { + String line = reader.readLine(); + if (line == null) { + break; + } + line = line.trim(); + if (line.length() > 0) { + line = line.toLowerCase(); + names.add(line); + } + } + + url.openStream(); + } finally { + JdbcUtils.close(reader); + JdbcUtils.close(in); + } + } + } catch (IOException e) { + LOG.error("load oracle permit tables errror", e); + } + } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantDeleteTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantDeleteTest.java new file mode 100644 index 0000000000..7b0d2f5216 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantDeleteTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class TenantDeleteTest extends TestCase { + + private String sql = "DELETE FROM orders WHERE FID = ?"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setTenantTablePattern("*"); + config.setTenantColumn("tenant"); + } + + public void testMySql() throws Exception { + WallProvider.setTenantValue(123); + MySqlWallProvider provider = new MySqlWallProvider(config); + WallCheckResult checkResult = provider.check(sql); + Assert.assertEquals(0, checkResult.getViolations().size()); + + String resultSql = SQLUtils.toSQLString(checkResult.getStatementList(), JdbcConstants.MYSQL); + Assert.assertEquals("DELETE FROM orders" + // + "\nWHERE tenant = 123" + // + "\n\tAND FID = ?", resultSql); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest.java new file mode 100644 index 0000000000..0b0bc4d051 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class TenantSelectTest extends TestCase { + + private String sql = "SELECT ID, NAME FROM orders WHERE FID = ?"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setTenantTablePattern("*"); + config.setTenantColumn("tenant"); + } + + public void testMySql() throws Exception { + WallProvider.setTenantValue(123); + MySqlWallProvider provider = new MySqlWallProvider(config); + WallCheckResult checkResult = provider.check(sql); + Assert.assertEquals(0, checkResult.getViolations().size()); + + String resultSql = SQLUtils.toSQLString(checkResult.getStatementList(), JdbcConstants.MYSQL); + Assert.assertEquals("SELECT ID, NAME" + // + "\nFROM orders" + // + "\nWHERE tenant = 123" + // + "\n\tAND FID = ?", resultSql); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest2.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest2.java new file mode 100644 index 0000000000..5d04795fa5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest2.java @@ -0,0 +1,53 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class TenantSelectTest2 extends TestCase { + + private String sql = "SELECT ID, NAME FROM orders WHERE FID = ? OR FID = ?"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setTenantTablePattern("*"); + config.setTenantColumn("tenant"); + } + + public void testMySql() throws Exception { + WallProvider.setTenantValue(123); + MySqlWallProvider provider = new MySqlWallProvider(config); + WallCheckResult checkResult = provider.check(sql); + Assert.assertEquals(0, checkResult.getViolations().size()); + + String resultSql = SQLUtils.toSQLString(checkResult.getStatementList(), JdbcConstants.MYSQL); + Assert.assertEquals("SELECT ID, NAME" + // + "\nFROM orders" + // + "\nWHERE tenant = 123" + // + "\n\tAND (FID = ?" + + "\n\t\t\tOR FID = ?)", resultSql); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest3.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest3.java new file mode 100644 index 0000000000..b303ec384a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantSelectTest3.java @@ -0,0 +1,57 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed 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 com.alibaba.druid.bvt.filter.wall; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.WallConfig; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; + +public class TenantSelectTest3 extends TestCase { + + private String sql = "SELECT ID, NAME " + // + "FROM orders o inner join users u ON o.userid = u.id " + // + "WHERE FID = ? OR FID = ?"; + + private WallConfig config = new WallConfig(); + + protected void setUp() throws Exception { + config.setTenantTablePattern("*"); + config.setTenantColumn("tenant"); + } + + public void testMySql() throws Exception { + WallProvider.setTenantValue(123); + MySqlWallProvider provider = new MySqlWallProvider(config); + WallCheckResult checkResult = provider.check(sql); + Assert.assertEquals(0, checkResult.getViolations().size()); + + String resultSql = SQLUtils.toSQLString(checkResult.getStatementList(), JdbcConstants.MYSQL); + Assert.assertEquals("SELECT ID, NAME" + // + "\nFROM orders o" + // + "\n\tINNER JOIN users u ON u.tenant = 123" + // + "\n\t\tAND o.userid = u.id" + // + "\nWHERE o.tenant = 123" + // + "\n\tAND (FID = ?" + // + "\n\t\t\tOR FID = ?)", resultSql); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantUpdateTest.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantUpdateTest.java index 8d2d6a8b89..307d033d9d 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantUpdateTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/TenantUpdateTest.java @@ -47,7 +47,7 @@ public class TenantUpdateTest extends TestCase { JdbcConstants.MYSQL); Assert.assertEquals("UPDATE T_USER" + // "\nSET FNAME = ?" + // - "\nWHERE T_USER.tenant = 123" + // + "\nWHERE tenant = 123" + // "\n\tAND FID = ?", resultSql); } }