jt2594838 commented on code in PR #18418:
URL: https://github.com/apache/iotdb/pull/18418#discussion_r3734126683


##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/subscription/agent/SubscriptionTopicAgent.java:
##########
@@ -369,6 +375,105 @@ public TSStatus checkTopicOwners(
     return RpcUtils.SUCCESS_STATUS;
   }
 
+  /**
+   * Check that the authenticated session can read all data covered by the 
requested topics.
+   * ConsumerConfig is client-controlled and therefore must not be used as the 
authorization
+   * identity.
+   */
+  public TSStatus checkTopicReadPermissions(
+      final String username,
+      final ConsumerConfig consumerConfig,
+      final Iterable<String> topicNames) {
+    if (Objects.isNull(username)) {
+      return RpcUtils.getStatus(TSStatusCode.NO_PERMISSION);
+    }
+
+    acquireReadLock();
+    try {
+      for (final String topicName : topicNames) {
+        final TopicMeta topicMeta =
+            topicMetaKeeper.getTopicMeta(topicName, 
isTableModel(consumerConfig));
+        if (Objects.isNull(topicMeta)) {
+          continue;
+        }
+
+        final TSStatus status =
+            topicMeta.getConfig().isTableTopic()
+                ? checkTableTopicReadPermission(username, topicMeta)
+                : checkTreeTopicReadPermission(username, topicMeta);
+        if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+          return status;
+        }
+      }
+      return RpcUtils.SUCCESS_STATUS;
+    } finally {
+      releaseReadLock();
+    }
+  }
+
+  private TSStatus checkTreeTopicReadPermission(final String username, final 
TopicMeta topicMeta) {
+    final TopicConfig topicConfig = topicMeta.getConfig();
+    final TreePattern treePattern =
+        topicConfig.getAttribute().containsKey(TopicConstant.PATTERN_KEY)
+            ? new 
PrefixTreePattern(topicConfig.getAttribute().get(TopicConstant.PATTERN_KEY))
+            : new IoTDBTreePattern(
+                topicConfig.getStringOrDefault(
+                    TopicConstant.PATH_KEY, TopicConstant.PATH_DEFAULT_VALUE));
+    for (final PartialPath path : treePattern.getBaseInclusionPaths()) {
+      if (!AuthorityChecker.checkFullPathOrPatternPermission(
+          username, path, PrivilegeType.READ_DATA)) {
+        return AuthorityChecker.getTSStatus(false, path, 
PrivilegeType.READ_DATA);
+      }
+    }
+    return RpcUtils.SUCCESS_STATUS;
+  }
+
+  private TSStatus checkTableTopicReadPermission(final String username, final 
TopicMeta topicMeta) {
+    if (AuthorityChecker.SUPER_USER.equals(username)) {
+      return RpcUtils.SUCCESS_STATUS;
+    }
+    final TopicConfig topicConfig = topicMeta.getConfig();
+    final String database =
+        topicConfig.getStringOrDefault(
+            TopicConstant.DATABASE_KEY, TopicConstant.DATABASE_DEFAULT_VALUE);
+    final String table =
+        topicConfig.getStringOrDefault(TopicConstant.TABLE_KEY, 
TopicConstant.TABLE_DEFAULT_VALUE);
+
+    // A database-level SELECT grant covers all tables in one database. For a 
topic whose
+    // database/table is a regular expression, only an any-scope SELECT grant 
is broad enough to
+    // cover every object matched by the topic.
+    final boolean databasePattern = isRegexPattern(database);
+    final boolean tablePattern = isRegexPattern(table);
+    final boolean allowed =
+        (databasePattern
+            ? AuthorityChecker.checkDBPermission(
+                username, AuthorityChecker.ANY_SCOPE, PrivilegeType.SELECT)
+            : AuthorityChecker.checkDBPermission(username, database, 
PrivilegeType.SELECT)
+                || (!tablePattern
+                    && AuthorityChecker.checkTablePermission(
+                        username, database, table, PrivilegeType.SELECT)));
+    return allowed
+        ? RpcUtils.SUCCESS_STATUS
+        : AuthorityChecker.getTSStatus(false, PrivilegeType.SELECT, database, 
table);
+  }
+
+  private static boolean isRegexPattern(final String value) {
+    return value.indexOf('.') >= 0
+        || value.indexOf('*') >= 0
+        || value.indexOf('+') >= 0
+        || value.indexOf('?') >= 0
+        || value.indexOf('[') >= 0
+        || value.indexOf(']') >= 0
+        || value.indexOf('(') >= 0
+        || value.indexOf(')') >= 0
+        || value.indexOf('{') >= 0
+        || value.indexOf('}') >= 0
+        || value.indexOf('|') >= 0
+        || value.indexOf('^') >= 0
+        || value.indexOf('$') >= 0
+        || value.indexOf('\\') >= 0;
+  }

Review Comment:
   Is it possible that the table name contains these chars?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to