This is an automated email from the ASF dual-hosted git repository. shuwenwei pushed a commit to branch AuthEnhance in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/AuthEnhance by this push: new 450d50dd5eb tree model show queries 450d50dd5eb is described below commit 450d50dd5ebf39ca0e120fc3fb17c5f1e1ce3567 Author: shuwenwei <s13979062...@gmail.com> AuthorDate: Wed Sep 17 12:05:28 2025 +0800 tree model show queries --- .../org/apache/iotdb/db/auth/AuthorityChecker.java | 9 +++++++ .../operator/source/ShowQueriesOperator.java | 10 ++++++- .../plan/planner/LogicalPlanBuilder.java | 13 +++++---- .../plan/planner/LogicalPlanVisitor.java | 3 ++- .../plan/planner/OperatorTreeGenerator.java | 5 +++- .../planner/plan/node/source/ShowQueriesNode.java | 31 +++++++++++++++++++--- .../security/TreeAccessCheckVisitor.java | 23 +++++++++++++--- .../plan/statement/sys/ShowQueriesStatement.java | 9 +++++++ .../operator/MergeTreeSortOperatorTest.java | 4 +-- 9 files changed, 91 insertions(+), 16 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java index c30a47c205d..1c4c29c5234 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java @@ -358,6 +358,15 @@ public class AuthorityChecker { PrivilegeType.MAINTAIN); } + public static TSStatus checkSuperUserOrSystemAdmin(String userName) { + if (AuthorityChecker.SUPER_USER.equals(userName)) { + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + } + return AuthorityChecker.getTSStatus( + AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM), + PrivilegeType.SYSTEM); + } + public static void buildTSBlock( TAuthorizerResp authResp, SettableFuture<ConfigTaskResult> future) { List<TSDataType> types = new ArrayList<>(); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowQueriesOperator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowQueriesOperator.java index 14159f1de63..b23906f00a1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowQueriesOperator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/ShowQueriesOperator.java @@ -50,6 +50,7 @@ public class ShowQueriesOperator implements SourceOperator { private boolean hasConsumed; private final Coordinator coordinator; + private final String allowedUsername; private static final int DEFAULT_MAX_TSBLOCK_SIZE_IN_BYTES = TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(); @@ -58,10 +59,14 @@ public class ShowQueriesOperator implements SourceOperator { RamUsageEstimator.shallowSizeOfInstance(ShowQueriesOperator.class); public ShowQueriesOperator( - OperatorContext operatorContext, PlanNodeId sourceId, Coordinator coordinator) { + OperatorContext operatorContext, + PlanNodeId sourceId, + Coordinator coordinator, + String allowedUsername) { this.operatorContext = operatorContext; this.sourceId = sourceId; this.coordinator = coordinator; + this.allowedUsername = allowedUsername; } @Override @@ -132,6 +137,9 @@ public class ShowQueriesOperator implements SourceOperator { int dataNodeId = Integer.parseInt(splits[splits.length - 1]); for (IQueryExecution queryExecution : queryExecutions) { + if (allowedUsername != null && !allowedUsername.equals(queryExecution.getUser())) { + continue; + } if (queryExecution.getSQLDialect().equals(IClientSession.SqlDialect.TREE)) { timeColumnBuilder.writeLong( TimestampPrecisionUtils.convertToCurrPrecision( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java index 9dbb0b8274d..af965ba60c3 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java @@ -1230,11 +1230,11 @@ public class LogicalPlanBuilder { return this; } - public LogicalPlanBuilder planShowQueries(Analysis analysis) { + public LogicalPlanBuilder planShowQueries(Analysis analysis, String allowedUsername) { List<TDataNodeLocation> dataNodeLocations = analysis.getReadableDataNodeLocations(); if (dataNodeLocations.size() == 1) { this.root = - planSingleShowQueries(dataNodeLocations.get(0)) + planSingleShowQueries(dataNodeLocations.get(0), allowedUsername) .planFilterAndTransform( analysis.getWhereExpression(), analysis.getSourceExpressions(), @@ -1254,7 +1254,7 @@ public class LogicalPlanBuilder { dataNodeLocations.forEach( dataNodeLocation -> mergeSortNode.addChild( - this.planSingleShowQueries(dataNodeLocation) + this.planSingleShowQueries(dataNodeLocation, allowedUsername) .planFilterAndTransform( analysis.getWhereExpression(), analysis.getSourceExpressions(), @@ -1275,8 +1275,11 @@ public class LogicalPlanBuilder { return this; } - private LogicalPlanBuilder planSingleShowQueries(TDataNodeLocation dataNodeLocation) { - this.root = new ShowQueriesNode(context.getQueryId().genPlanNodeId(), dataNodeLocation); + private LogicalPlanBuilder planSingleShowQueries( + TDataNodeLocation dataNodeLocation, String allowedUsername) { + this.root = + new ShowQueriesNode( + context.getQueryId().genPlanNodeId(), dataNodeLocation, allowedUsername); return this; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java index 5a49e6d0d98..fa39b3ba7dc 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java @@ -948,7 +948,8 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context); planBuilder = planBuilder - .planShowQueries(analysis) // push Filter down + .planShowQueries( + analysis, showQueriesStatement.getAllowedUsername()) // push Filter down .planOffset(showQueriesStatement.getRowOffset()) .planLimit(showQueriesStatement.getRowLimit()); return planBuilder.getRoot(); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java index 4668b25c4c1..2bc2c419412 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java @@ -2584,7 +2584,10 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP ShowQueriesOperator.class.getSimpleName()); return new ShowQueriesOperator( - operatorContext, node.getPlanNodeId(), Coordinator.getInstance()); + operatorContext, + node.getPlanNodeId(), + Coordinator.getInstance(), + node.getAllowedUsername()); } private List<OutputColumn> generateOutputColumnsFromChildren(MultiChildProcessNode node) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/ShowQueriesNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/ShowQueriesNode.java index 92cec4c91e3..4010264f3fd 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/ShowQueriesNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/ShowQueriesNode.java @@ -26,6 +26,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeType; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor; import com.google.common.collect.ImmutableList; +import org.apache.tsfile.utils.ReadWriteIOUtils; import java.io.DataOutputStream; import java.io.IOException; @@ -42,8 +43,12 @@ public class ShowQueriesNode extends VirtualSourceNode { ColumnHeaderConstant.ELAPSED_TIME, ColumnHeaderConstant.STATEMENT); - public ShowQueriesNode(PlanNodeId id, TDataNodeLocation dataNodeLocation) { + private final String allowedUsername; + + public ShowQueriesNode( + PlanNodeId id, TDataNodeLocation dataNodeLocation, String allowedUsername) { super(id, dataNodeLocation); + this.allowedUsername = allowedUsername; } @Override @@ -63,7 +68,11 @@ public class ShowQueriesNode extends VirtualSourceNode { @Override public PlanNode clone() { - return new ShowQueriesNode(getPlanNodeId(), getDataNodeLocation()); + return new ShowQueriesNode(getPlanNodeId(), getDataNodeLocation(), allowedUsername); + } + + public String getAllowedUsername() { + return allowedUsername; } @Override @@ -86,16 +95,32 @@ public class ShowQueriesNode extends VirtualSourceNode { @Override protected void serializeAttributes(ByteBuffer byteBuffer) { PlanNodeType.SHOW_QUERIES.serialize(byteBuffer); + if (this.allowedUsername != null) { + ReadWriteIOUtils.write(true, byteBuffer); + ReadWriteIOUtils.write(this.allowedUsername, byteBuffer); + } else { + ReadWriteIOUtils.write(false, byteBuffer); + } } @Override protected void serializeAttributes(DataOutputStream stream) throws IOException { PlanNodeType.SHOW_QUERIES.serialize(stream); + if (this.allowedUsername != null) { + ReadWriteIOUtils.write(true, stream); + ReadWriteIOUtils.write(this.allowedUsername, stream); + } else { + ReadWriteIOUtils.write(false, stream); + } } public static ShowQueriesNode deserialize(ByteBuffer byteBuffer) { PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer); - return new ShowQueriesNode(planNodeId, null); + String allowedUsername = null; + if (ReadWriteIOUtils.readBoolean(byteBuffer)) { + allowedUsername = ReadWriteIOUtils.readString(byteBuffer); + } + return new ShowQueriesNode(planNodeId, null, allowedUsername); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java index 8bb0c7e2075..e33f75e666f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java @@ -121,7 +121,9 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.view.DeleteLogica import org.apache.iotdb.db.queryengine.plan.statement.metadata.view.RenameLogicalViewStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.view.ShowLogicalViewStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.AuthorStatement; +import org.apache.iotdb.db.queryengine.plan.statement.sys.ClearCacheStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ExplainAnalyzeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.sys.FlushStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.KillQueryStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.SetSqlDialectStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowCurrentSqlDialectStatement; @@ -906,6 +908,17 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces return AuthorityChecker.checkSuperUserOrMaintain(context.userName); } + @Override + public TSStatus visitFlush(FlushStatement flushStatement, TreeAccessCheckContext context) { + return AuthorityChecker.checkSuperUserOrSystemAdmin(context.userName); + } + + @Override + public TSStatus visitClearCache( + ClearCacheStatement clearCacheStatement, TreeAccessCheckContext context) { + return AuthorityChecker.checkSuperUserOrSystemAdmin(context.userName); + } + @Override public TSStatus visitMigrateRegion( MigrateRegionStatement statement, TreeAccessCheckContext context) { @@ -990,7 +1003,11 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces @Override public TSStatus visitShowQueries(ShowQueriesStatement statement, TreeAccessCheckContext context) { - return AuthorityChecker.checkSuperUserOrMaintain(context.userName); + if (AuthorityChecker.checkSuperUserOrMaintain(context.userName).getCode() + != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + statement.setAllowedUsername(context.userName); + } + return SUCCEED; } @Override @@ -1001,12 +1018,12 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces @Override public TSStatus visitShowVariables( ShowVariablesStatement statement, TreeAccessCheckContext context) { - return SUCCEED; + return AuthorityChecker.checkSuperUserOrMaintain(context.userName); } @Override public TSStatus visitShowVersion(ShowVersionStatement statement, TreeAccessCheckContext context) { - return SUCCEED; + return AuthorityChecker.checkSuperUserOrMaintain(context.userName); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowQueriesStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowQueriesStatement.java index 1baca6e07b9..0f176f24d3d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowQueriesStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowQueriesStatement.java @@ -39,6 +39,7 @@ public class ShowQueriesStatement extends ShowStatement { private long rowLimit; private long rowOffset; + private String allowedUsername; public ShowQueriesStatement() { this.statementType = StatementType.SHOW_QUERIES; @@ -49,6 +50,14 @@ public class ShowQueriesStatement extends ShowStatement { return true; } + public String getAllowedUsername() { + return allowedUsername; + } + + public void setAllowedUsername(String allowedUsername) { + this.allowedUsername = allowedUsername; + } + @Override public <R, C> R accept(StatementVisitor<R, C> visitor, C context) { return visitor.visitShowQueries(this, context); diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java index 7a2bee23d32..4ca38a5c8d9 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java @@ -1618,9 +1618,9 @@ public class MergeTreeSortOperatorTest { new FakeQueryExecution(1, "20221229_000000_00001_2", "sql1_node2"))); ShowQueriesOperator showQueriesOperator1 = - new ShowQueriesOperator(operatorContexts.get(0), planNodeId0, coordinator1); + new ShowQueriesOperator(operatorContexts.get(0), planNodeId0, coordinator1, null); ShowQueriesOperator showQueriesOperator2 = - new ShowQueriesOperator(operatorContexts.get(1), planNodeId1, coordinator2); + new ShowQueriesOperator(operatorContexts.get(1), planNodeId1, coordinator2, null); TreeSortOperator treeSortOperator1 = new TreeSortOperator( operatorContexts.get(2), showQueriesOperator1, dataTypes, "", comparator);