/*
* Copyright 1999-2017 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.wall;
import com.alibaba.druid.wall.spi.WallVisitorUtils;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
import static com.alibaba.druid.util.Utils.getBoolean;
import static com.alibaba.druid.util.Utils.getInteger;
import static com.alibaba.druid.wall.spi.WallVisitorUtils.loadResource;
public class WallConfig implements WallConfigMBean {
private boolean noneBaseStatementAllow = false;
private boolean callAllow = true;
private boolean selelctAllow = true;
private boolean selectIntoAllow = true;
private boolean selectIntoOutfileAllow = false;
private boolean selectWhereAlwayTrueCheck = true;
private boolean selectHavingAlwayTrueCheck = true;
private boolean selectUnionCheck = true;
private boolean selectMinusCheck = true;
private boolean selectExceptCheck = true;
private boolean selectIntersectCheck = true;
private boolean createTableAllow = true;
private boolean dropTableAllow = true;
private boolean alterTableAllow = true;
private boolean renameTableAllow = true;
private boolean hintAllow = true;
private boolean lockTableAllow = true;
private boolean startTransactionAllow = true;
private boolean blockAllow = true;
private boolean conditionAndAlwayTrueAllow = false;
private boolean conditionAndAlwayFalseAllow = false;
private boolean conditionDoubleConstAllow = false;
private boolean conditionLikeTrueAllow = true;
private boolean selectAllColumnAllow = true;
private boolean deleteAllow = true;
private boolean deleteWhereAlwayTrueCheck = true;
private boolean deleteWhereNoneCheck = false;
private boolean updateAllow = true;
private boolean updateWhereAlayTrueCheck = true;
private boolean updateWhereNoneCheck = false;
private boolean insertAllow = true;
private boolean mergeAllow = true;
private boolean minusAllow = true;
private boolean intersectAllow = true;
private boolean replaceAllow = true;
private boolean setAllow = true;
private boolean commitAllow = true;
private boolean rollbackAllow = true;
private boolean useAllow = true;
private boolean multiStatementAllow = false;
private boolean truncateAllow = true;
private boolean commentAllow = false;
private boolean strictSyntaxCheck = true;
private boolean constArithmeticAllow = true;
private boolean limitZeroAllow = false;
private boolean describeAllow = true;
private boolean showAllow = true;
private boolean schemaCheck = true;
private boolean tableCheck = true;
private boolean functionCheck = true;
private boolean objectCheck = true;
private boolean variantCheck = true;
private boolean mustParameterized = false;
private boolean doPrivilegedAllow = false;
protected final Set<String> denyFunctions = new ConcurrentSkipListSet<String>();
protected final Set<String> denyTables = new ConcurrentSkipListSet<String>();
protected final Set<String> denySchemas = new ConcurrentSkipListSet<String>();
protected final Set<String> denyVariants = new ConcurrentSkipListSet<String>();
protected final Set<String> denyObjects = new ConcurrentSkipListSet<String>();
protected final Set<String> permitFunctions = new ConcurrentSkipListSet<String>();
protected final Set<String> permitTables = new ConcurrentSkipListSet<String>();
protected final Set<String> permitSchemas = new ConcurrentSkipListSet<String>();
protected final Set<String> permitVariants = new ConcurrentSkipListSet<String>();
protected final Set<String> readOnlyTables = new ConcurrentSkipListSet<String>();
private String dir;
private boolean inited;
private String tenantTablePattern;
private String tenantColumn;
private TenantCallBack tenantCallBack;
private boolean wrapAllow = true;
private boolean metadataAllow = true;
private boolean conditionOpXorAllow = false;
private boolean conditionOpBitwseAllow = true;
private boolean caseConditionConstAllow = false;
private boolean completeInsertValuesCheck = false;
private int insertValuesCheckSize = 3;
private int selectLimit = -1;
public WallConfig(){
this.configFromProperties(System.getProperties());
}
public boolean isCaseConditionConstAllow() {
return caseConditionConstAllow;
}
public void setCaseConditionConstAllow(boolean caseConditionConstAllow) {
this.caseConditionConstAllow = caseConditionConstAllow;
}
public boolean isConditionDoubleConstAllow() {
return conditionDoubleConstAllow;
}
public void setConditionDoubleConstAllow(boolean conditionDoubleConstAllow) {
this.conditionDoubleConstAllow = conditionDoubleConstAllow;
}
public boolean isConditionLikeTrueAllow() {
return conditionLikeTrueAllow;
}
public void setConditionLikeTrueAllow(boolean conditionLikeTrueAllow) {
this.conditionLikeTrueAllow = conditionLikeTrueAllow;
}
public boolean isLimitZeroAllow() {
return limitZeroAllow;
}
public void setLimitZeroAllow(boolean limitZero) {
this.limitZeroAllow = limitZero;
}
public boolean isUseAllow() {
return useAllow;
}
public void setUseAllow(boolean useAllow) {
this.useAllow = useAllow;
}
public boolean isCommitAllow() {
return commitAllow;
}
public void setCommitAllow(boolean commitAllow) {
this.commitAllow = commitAllow;
}
public boolean isRollbackAllow() {
return rollbackAllow;
}
public void setRollbackAllow(boolean rollbackAllow) {
this.rollbackAllow = rollbackAllow;
}
public boolean isIntersectAllow() {
return intersectAllow;
}
public void setIntersectAllow(boolean intersectAllow) {
this.intersectAllow = intersectAllow;
}
public boolean isMinusAllow() {
return minusAllow;
}
public void setMinusAllow(boolean minusAllow) {
this.minusAllow = minusAllow;
}
public boolean isConditionOpXorAllow() {
return conditionOpXorAllow;
}
public void setConditionOpXorAllow(boolean conditionOpXorAllow) {
this.conditionOpXorAllow = conditionOpXorAllow;
}
public String getTenantTablePattern() {
return tenantTablePattern;
}
public void setTenantTablePattern(String tenantTablePattern) {
this.tenantTablePattern = tenantTablePattern;
}
public String getTenantColumn() {
return tenantColumn;
}
public void setTenantColumn(String tenantColumn) {
this.tenantColumn = tenantColumn;
}
public TenantCallBack getTenantCallBack() {
return tenantCallBack;
}
public void setTenantCallBack(TenantCallBack tenantCallBack) {
this.tenantCallBack = tenantCallBack;
}
public boolean isMetadataAllow() {
return metadataAllow;
}
public void setMetadataAllow(boolean metadataAllow) {
this.metadataAllow = metadataAllow;
}
public boolean isWrapAllow() {
return wrapAllow;
}
public void setWrapAllow(boolean wrapAllow) {
this.wrapAllow = wrapAllow;
}
public boolean isDoPrivilegedAllow() {
return doPrivilegedAllow;
}
public void setDoPrivilegedAllow(boolean doPrivilegedAllow) {
this.doPrivilegedAllow = doPrivilegedAllow;
}
public boolean isSelectAllColumnAllow() {
return selectAllColumnAllow;
}
public void setSelectAllColumnAllow(boolean selectAllColumnAllow) {
this.selectAllColumnAllow = selectAllColumnAllow;
}
public boolean isInited() {
return inited;
}
public WallConfig(String dir){
this.dir = dir;
this.init();
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public final void init() {
loadConfig(dir);
}
public void loadConfig(String dir) {
if (dir.endsWith("/")) {
dir = dir.substring(0, dir.length() - 1);
}
loadResource(this.denyVariants, dir + "/deny-variant.txt");
loadResource(this.denySchemas, dir + "/deny-schema.txt");
loadResource(this.denyFunctions, dir + "/deny-function.txt");
loadResource(this.denyTables, dir + "/deny-table.txt");
loadResource(this.denyObjects, dir + "/deny-object.txt");
loadResource(this.readOnlyTables, dir + "/readonly-table.txt");
loadResource(this.permitFunctions, dir + "/permit-function.txt");
loadResource(this.permitTables, dir + "/permit-table.txt");
loadResource(this.permitSchemas, dir + "/permit-schema.txt");
loadResource(this.permitVariants, dir + "/permit-variant.txt");
}
public boolean isNoneBaseStatementAllow() {
return noneBaseStatementAllow;
}
public void setNoneBaseStatementAllow(boolean noneBaseStatementAllow) {
this.noneBaseStatementAllow = noneBaseStatementAllow;
}
/**
* allow mysql describe statement
*
* @since 0.2.10
* @return
*/
public boolean isDescribeAllow() {
return describeAllow;
}
/**
* set allow mysql describe statement
*
* @since 0.2.10
*/
public void setDescribeAllow(boolean describeAllow) {
this.describeAllow = describeAllow;
}
public boolean isShowAllow() {
return showAllow;
}
public void setShowAllow(boolean showAllow) {
this.showAllow = showAllow;
}
public boolean isTruncateAllow() {
return truncateAllow;
}
public void setTruncateAllow(boolean truncateAllow) {
this.truncateAllow = truncateAllow;
}
public boolean isSelectIntoAllow() {
return selectIntoAllow;
}
public void setSelectIntoAllow(boolean selectIntoAllow) {
this.selectIntoAllow = selectIntoAllow;
}
public boolean isSelectIntoOutfileAllow() {
return selectIntoOutfileAllow;
}
public void setSelectIntoOutfileAllow(boolean selectIntoOutfileAllow) {
this.selectIntoOutfileAllow = selectIntoOutfileAllow;
}
public boolean isCreateTableAllow() {
return createTableAllow;
}
public void setCreateTableAllow(boolean createTableAllow) {
this.createTableAllow = createTableAllow;
}
public boolean isDropTableAllow() {
return dropTableAllow;
}
public void setDropTableAllow(boolean dropTableAllow) {
this.dropTableAllow = dropTableAllow;
}
public boolean isAlterTableAllow() {
return alterTableAllow;
}
public void setAlterTableAllow(boolean alterTableAllow) {
this.alterTableAllow = alterTableAllow;
}
public boolean isRenameTableAllow() {
return renameTableAllow;
}
public void setRenameTableAllow(boolean renameTableAllow) {
this.renameTableAllow = renameTableAllow;
}
public boolean isSelectUnionCheck() {
return selectUnionCheck;
}
public void setSelectUnionCheck(boolean selectUnionCheck) {
this.selectUnionCheck = selectUnionCheck;
}
public boolean isSelectMinusCheck() {
return selectMinusCheck;
}
public void setSelectMinusCheck(boolean selectMinusCheck) {
this.selectMinusCheck = selectMinusCheck;
}
public boolean isSelectExceptCheck() {
return selectExceptCheck;
}
public void setSelectExceptCheck(boolean selectExceptCheck) {
this.selectExceptCheck = selectExceptCheck;
}
public boolean isSelectIntersectCheck() {
return selectIntersectCheck;
}
public void setSelectIntersectCheck(boolean selectIntersectCheck) {
this.selectIntersectCheck = selectIntersectCheck;
}
public boolean isDeleteAllow() {
return deleteAllow;
}
public void setDeleteAllow(boolean deleteAllow) {
this.deleteAllow = deleteAllow;
}
public boolean isDeleteWhereNoneCheck() {
return deleteWhereNoneCheck;
}
public void setDeleteWhereNoneCheck(boolean deleteWhereNoneCheck) {
this.deleteWhereNoneCheck = deleteWhereNoneCheck;
}
public boolean isUpdateAllow() {
return updateAllow;
}
public void setUpdateAllow(boolean updateAllow) {
this.updateAllow = updateAllow;
}
public boolean isUpdateWhereNoneCheck() {
return updateWhereNoneCheck;
}
public void setUpdateWhereNoneCheck(boolean updateWhereNoneCheck) {
this.updateWhereNoneCheck = updateWhereNoneCheck;
}
public boolean isInsertAllow() {
return insertAllow;
}
public void setInsertAllow(boolean insertAllow) {
this.insertAllow = insertAllow;
}
public boolean isReplaceAllow() {
return replaceAllow;
}
public void setReplaceAllow(boolean replaceAllow) {
this.replaceAllow = replaceAllow;
}
public boolean isSetAllow() {
return setAllow;
}
public void setSetAllow(boolean value) {
this.setAllow = value;
}
public boolean isMergeAllow() {
return mergeAllow;
}
public void setMergeAllow(boolean mergeAllow) {
this.mergeAllow = mergeAllow;
}
public boolean isMultiStatementAllow() {
return multiStatementAllow;
}
public void setMultiStatementAllow(boolean multiStatementAllow) {
this.multiStatementAllow = multiStatementAllow;
}
public boolean isSchemaCheck() {
return schemaCheck;
}
public void setSchemaCheck(boolean schemaCheck) {
this.schemaCheck = schemaCheck;
}
public boolean isTableCheck() {
return tableCheck;
}
public void setTableCheck(boolean tableCheck) {
this.tableCheck = tableCheck;
}
public boolean isFunctionCheck() {
return functionCheck;
}
public void setFunctionCheck(boolean functionCheck) {
this.functionCheck = functionCheck;
}
public boolean isVariantCheck() {
return variantCheck;
}
public void setVariantCheck(boolean variantCheck) {
this.variantCheck = variantCheck;
}
public boolean isObjectCheck() {
return objectCheck;
}
public void setObjectCheck(boolean objectCheck) {
this.objectCheck = objectCheck;
}
// ///////////////////
public boolean isCommentAllow() {
return commentAllow;
}
public void setCommentAllow(boolean commentAllow) {
this.commentAllow = commentAllow;
}
public boolean isStrictSyntaxCheck() {
return strictSyntaxCheck;
}
public void setStrictSyntaxCheck(boolean strictSyntaxCheck) {
this.strictSyntaxCheck = strictSyntaxCheck;
}
public boolean isConstArithmeticAllow() {
return constArithmeticAllow;
}
public void setConstArithmeticAllow(boolean constArithmeticAllow) {
this.constArithmeticAllow = constArithmeticAllow;
}
public Set<String> getDenyFunctions() {
return denyFunctions;
}
public Set<String> getDenyTables() {
return denyTables;
}
public Set<String> getDenySchemas() {
return denySchemas;
}
public Set<String> getDenyVariants() {
return denyVariants;
}
public Set<String> getDenyObjects() {
return denyObjects;
}
public Set<String> getReadOnlyTables() {
return readOnlyTables;
}
public void addReadOnlyTable(String tableName) {
this.readOnlyTables.add(tableName);
}
public boolean isReadOnly(String tableName) {
return this.readOnlyTables.contains(tableName);
}
public Set<String> getPermitFunctions() {
return permitFunctions;
}
public Set<String> getPermitTables() {
return permitTables;
}
public Set<String> getPermitSchemas() {
return permitSchemas;
}
public Set<String> getPermitVariants() {
return permitVariants;
}
public boolean isMustParameterized() {
return mustParameterized;
}
public void setMustParameterized(boolean mustParameterized) {
this.mustParameterized = mustParameterized;
}
public boolean isDenyObjects(String name) {
if (!objectCheck) {
return false;
}
name = WallVisitorUtils.form(name);
return denyObjects.contains(name);
}
public boolean isDenySchema(String name) {
if (!schemaCheck) {
return false;
}
name = WallVisitorUtils.form(name);
return this.denySchemas.contains(name);
}
public boolean isDenyFunction(String name) {
if (!functionCheck) {
return false;
}
name = WallVisitorUtils.form(name);
return this.denyFunctions.contains(name);
}
public boolean isCallAllow() {
return callAllow;
}
public void setCallAllow(boolean callAllow) {
this.callAllow = callAllow;
}
public boolean isHintAllow() {
return hintAllow;
}
public void setHintAllow(boolean hintAllow) {
this.hintAllow = hintAllow;
}
public static abstract interface TenantCallBack {
public static enum StatementType {
SELECT, UPDATE, INSERT, DELETE
}
Object getTenantValue(StatementType statementType, String tableName);
String getTenantColumn(StatementType statementType, String tableName);
/**
* 返回resultset隐藏列名
*
* @param tableName
*/
String getHiddenColumn(String tableName);
/**
* resultset返回值中如果包含tenantColumn的回调函数
*
* @param value tenantColumn对应的值
*/
void filterResultsetTenantColumn(Object value);
}
public boolean isSelelctAllow() {
return selelctAllow;
}
public void setSelelctAllow(boolean selelctAllow) {
this.selelctAllow = selelctAllow;
}
public boolean isSelectWhereAlwayTrueCheck() {
return selectWhereAlwayTrueCheck;
}
public void setSelectWhereAlwayTrueCheck(boolean selectWhereAlwayTrueCheck) {
this.selectWhereAlwayTrueCheck = selectWhereAlwayTrueCheck;
}
public boolean isSelectHavingAlwayTrueCheck() {
return selectHavingAlwayTrueCheck;
}
public void setSelectHavingAlwayTrueCheck(boolean selectHavingAlwayTrueCheck) {
this.selectHavingAlwayTrueCheck = selectHavingAlwayTrueCheck;
}
public boolean isConditionAndAlwayTrueAllow() {
return conditionAndAlwayTrueAllow;
}
public void setConditionAndAlwayTrueAllow(boolean conditionAndAlwayTrueAllow) {
this.conditionAndAlwayTrueAllow = conditionAndAlwayTrueAllow;
}
public boolean isConditionAndAlwayFalseAllow() {
return conditionAndAlwayFalseAllow;
}
public void setConditionAndAlwayFalseAllow(boolean conditionAndAlwayFalseAllow) {
this.conditionAndAlwayFalseAllow = conditionAndAlwayFalseAllow;
}
public boolean isDeleteWhereAlwayTrueCheck() {
return deleteWhereAlwayTrueCheck;
}
public void setDeleteWhereAlwayTrueCheck(boolean deleteWhereAlwayTrueCheck) {
this.deleteWhereAlwayTrueCheck = deleteWhereAlwayTrueCheck;
}
public boolean isUpdateWhereAlayTrueCheck() {
return updateWhereAlayTrueCheck;
}
public void setUpdateWhereAlayTrueCheck(boolean updateWhereAlayTrueCheck) {
this.updateWhereAlayTrueCheck = updateWhereAlayTrueCheck;
}
public boolean isConditionOpBitwseAllow() {
return conditionOpBitwseAllow;
}
public void setConditionOpBitwseAllow(boolean conditionOpBitwseAllow) {
this.conditionOpBitwseAllow = conditionOpBitwseAllow;
}
public void setInited(boolean inited) {
this.inited = inited;
}
public boolean isLockTableAllow() {
return lockTableAllow;
}
public void setLockTableAllow(boolean lockTableAllow) {
this.lockTableAllow = lockTableAllow;
}
public boolean isStartTransactionAllow() {
return startTransactionAllow;
}
public void setStartTransactionAllow(boolean startTransactionAllow) {
this.startTransactionAllow = startTransactionAllow;
}
public boolean isCompleteInsertValuesCheck() {
return completeInsertValuesCheck;
}
public void setCompleteInsertValuesCheck(boolean completeInsertValuesCheck) {
this.completeInsertValuesCheck = completeInsertValuesCheck;
}
public int getInsertValuesCheckSize() {
return insertValuesCheckSize;
}
public void setInsertValuesCheckSize(int insertValuesCheckSize) {
this.insertValuesCheckSize = insertValuesCheckSize;
}
public boolean isBlockAllow() {
return blockAllow;
}
public void setBlockAllow(boolean blockAllow) {
this.blockAllow = blockAllow;
}
public int getSelectLimit() {
return selectLimit;
}
public void setSelectLimit(int selectLimit) {
this.selectLimit = selectLimit;
}
public void configFromProperties(Properties properties) {
{
String propertyValue = properties.getProperty("druid.wall.tenantColumn");
if (propertyValue != null) {
this.setTenantColumn(propertyValue);
}
}
{
Boolean propertyValue = getBoolean(properties, "druid.wall.selelctAllow");
if (propertyValue != null) {
this.setSelelctAllow(propertyValue);
}
}
{
Boolean propertyValue = getBoolean(properties, "druid.wall.updateAllow");
if (propertyValue != null) {
this.setUpdateAllow(propertyValue);
}
}
{
Boolean propertyValue = getBoolean(properties, "druid.wall.deleteAllow");
if (propertyValue != null) {
this.setDeleteAllow(propertyValue);
}
}
{
Boolean propertyValue = getBoolean(properties, "druid.wall.insertAllow");
if (propertyValue != null) {
this.setInsertAllow(propertyValue);
}
}
{
Boolean propertyValue = getBoolean(properties, "druid.wall.multiStatementAllow");
if (propertyValue != null) {
this.setMultiStatementAllow(propertyValue);
}
}
{
Integer propertyValue = getInteger(properties, "druid.wall.selectLimit");
if (propertyValue != null) {
this.setSelectLimit(propertyValue);
}
}
}
}