You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by yo...@apache.org on 2025/10/11 11:06:04 UTC
(iotdb) branch audit-log-patch-again created (now 4653b93d236)
This is an automated email from the ASF dual-hosted git repository.
yongzao pushed a change to branch audit-log-patch-again
in repository https://gitbox.apache.org/repos/asf/iotdb.git
at 4653b93d236 reconstruct audit CI
This branch includes the following new commits:
new 6216b2add61 Fix table model bugs
new 4653b93d236 reconstruct audit CI
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(iotdb) 02/02: reconstruct audit CI
Posted by yo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
yongzao pushed a commit to branch audit-log-patch-again
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 4653b93d236c434a498d2f51b2d65d954df06c68
Author: Yongzao <53...@qq.com>
AuthorDate: Sat Oct 11 19:05:51 2025 +0800
reconstruct audit CI
---
.../org/apache/iotdb/db/it/audit/AuditLogSet.java | 86 +
.../iotdb/db/it/audit/IoTDBAuditLogBasicIT.java | 2873 ++++++++++++--------
.../org/apache/iotdb/db/audit/DNAuditLogger.java | 2 +-
.../relational/security/AccessControlImpl.java | 13 +-
.../security/TreeAccessCheckVisitor.java | 32 +-
5 files changed, 1827 insertions(+), 1179 deletions(-)
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/audit/AuditLogSet.java b/integration-test/src/test/java/org/apache/iotdb/db/it/audit/AuditLogSet.java
new file mode 100644
index 00000000000..b21b46582d5
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/audit/AuditLogSet.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it.audit;
+
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class AuditLogSet {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AuditLogSet.class);
+
+ private final int logCnt;
+ private final Set<List<String>> auditLogSet;
+
+ @SafeVarargs
+ public AuditLogSet(List<String>... auditLogs) {
+ logCnt = auditLogs.length;
+ auditLogSet = Stream.of(auditLogs).collect(Collectors.toSet());
+ }
+
+ public void containAuditLog(ResultSet resultSet, Set<Integer> indexForContain, int columnCnt)
+ throws SQLException {
+ LOGGER.info("===========================================================");
+ for (List<String> auditLog : auditLogSet) {
+ LOGGER.info("Expected audit log: {}", auditLog);
+ }
+ for (int curLog = 0; curLog < logCnt; curLog++) {
+ resultSet.next();
+ List<String> actualFields = new ArrayList<>();
+ for (int i = 1; i <= columnCnt; i++) {
+ actualFields.add(resultSet.getString(i + 1));
+ }
+ LOGGER.info("Actual audit log: {}", actualFields);
+ boolean match = false;
+ for (List<String> expectedFields : auditLogSet) {
+ match = true;
+ for (int i = 1; i <= columnCnt; i++) {
+ if (indexForContain.contains(i)) {
+ if (resultSet.getString(i + 1).contains(expectedFields.get(i - 1))) {
+ continue;
+ } else {
+ match = false;
+ break;
+ }
+ }
+ if (!expectedFields.get(i - 1).equals(resultSet.getString(i + 1))) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ auditLogSet.remove(expectedFields);
+ break;
+ }
+ }
+ Assert.assertTrue(match);
+ }
+ Assert.assertTrue(auditLogSet.isEmpty());
+ }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java
index 372e1e6176c..d1493ee8ed5 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java
@@ -182,6 +182,7 @@ public class IoTDBAuditLogBasicIT {
"LIST PRIVILEGES OF USER user2",
"LIST PRIVILEGES OF ROLE role1",
"list user",
+ "list role",
"USE test",
"INSERT INTO table1(time, t1, a1, s1) values(1, 't1', 'a1', 's1')",
"SELECT * FROM table1",
@@ -197,1026 +198,1069 @@ public class IoTDBAuditLogBasicIT {
"DROP USER user1",
"DROP USER user2",
"DROP ROLE role1");
- private static final List<List<String>> TABLE_MODEL_AUDIT_FIELDS =
+ private static final List<AuditLogSet> TABLE_MODEL_AUDIT_FIELDS =
Arrays.asList(
// Start audit service
- Arrays.asList(
- "node_1",
- "u_none",
- "null",
- "null",
- "CHANGE_AUDIT_OPTION",
- "CONTROL",
- "[AUDIT]",
- "GLOBAL",
- "true",
- "null",
- "null",
- "Successfully start the Audit service with configurations (auditableOperationType [DDL, DML, QUERY, CONTROL], auditableOperationLevel GLOBAL, auditableOperationResult SUCCESS,FAIL)"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_none",
+ "null",
+ "null",
+ "CHANGE_AUDIT_OPTION",
+ "CONTROL",
+ "[AUDIT]",
+ "GLOBAL",
+ "true",
+ "null",
+ "null",
+ "Successfully start the Audit service with configurations (auditableOperationType [DDL, DML, QUERY, CONTROL], auditableOperationLevel GLOBAL, auditableOperationResult SUCCESS,FAIL)")),
// Environment init login/logout
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[MANAGE_DATABASE]",
- "OBJECT",
- "true",
- "[root.__audit]",
- "SHOW DATABASES root.__audit",
- "User root (ID=0) requests authority on object root.__audit with result true"),
- // Setup logout through tree model dialect, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- // Setup login through table model dialect, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- // Desc audit table
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "__audit",
- "DESC __audit.audit_log",
- "User root (ID=0) requests authority on object audit_log with result true"),
- // Setup logout through table model dialect, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing")),
+ // Show audit log database
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[MANAGE_DATABASE]",
+ "OBJECT",
+ "true",
+ "[root.__audit]",
+ "SHOW DATABASES root.__audit",
+ "User root (ID=0) requests authority on object root.__audit with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing")),
+ // Desc audit log table view
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "__audit",
+ "DESC __audit.audit_log",
+ "User root (ID=0) requests authority on object audit_log with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing")),
// =============================Audit user root=============================
// Root login, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session")),
// Create database
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[CREATE]",
- "OBJECT",
- "true",
- "test",
- "CREATE DATABASE test",
- "User root (ID=0) requests authority on object test with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[CREATE]",
+ "OBJECT",
+ "true",
+ "test",
+ "CREATE DATABASE test",
+ "User root (ID=0) requests authority on object test with result true")),
// Use database, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User root (ID=0) requests authority on object test with result true"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User root (ID=0) requests authority on object test with result true"),
- // Show database TODO: Enable only when the order of show databases authentication fixed
- // Arrays.asList(
- // "node_1",
- // "u_0",
- // "root",
- // "127.0.0.1",
- // "OBJECT_AUTHENTICATION",
- // "QUERY",
- // "[READ_SCHEMA]",
- // "OBJECT",
- // "true",
- // "test",
- // "SHOW DATABASES",
- // "User root (ID=0) requests authority on object test with result true"),
- // Arrays.asList(
- // "node_1",
- // "u_0",
- // "root",
- // "127.0.0.1",
- // "OBJECT_AUTHENTICATION",
- // "QUERY",
- // "[READ_SCHEMA]",
- // "OBJECT",
- // "true",
- // "information_schema",
- // "SHOW DATABASES",
- // "User root (ID=0) requests authority on object information_schema with
- // result true"),
- // Arrays.asList(
- // "node_1",
- // "u_0",
- // "root",
- // "127.0.0.1",
- // "OBJECT_AUTHENTICATION",
- // "QUERY",
- // "[READ_SCHEMA]",
- // "OBJECT",
- // "true",
- // "__audit",
- // "SHOW DATABASES",
- // "User root (ID=0) requests authority on object test with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true")),
+ // Show database
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "SHOW DATABASES",
+ "User root (ID=0) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "information_schema",
+ "SHOW DATABASES",
+ "User root (ID=0) requests authority on object information_schema with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "__audit",
+ "SHOW DATABASES",
+ "User root (ID=0) requests authority on object test with result true")),
// Alter database
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[ALTER]",
- "OBJECT",
- "true",
- "test",
- "ALTER DATABASE test SET PROPERTIES TTL='INF'",
- "User root (ID=0) requests authority on object test with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[ALTER]",
+ "OBJECT",
+ "true",
+ "test",
+ "ALTER DATABASE test SET PROPERTIES TTL='INF'",
+ "User root (ID=0) requests authority on object test with result true")),
// Create table
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[CREATE]",
- "OBJECT",
- "true",
- "test",
- "CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 STRING FIELD)",
- "User root (ID=0) requests authority on object table1 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[CREATE]",
+ "OBJECT",
+ "true",
+ "test",
+ "CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 STRING FIELD)",
+ "User root (ID=0) requests authority on object table1 with result true")),
// Show table
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "SHOW TABLES",
- "User root (ID=0) requests authority on object table1 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "SHOW TABLES",
+ "User root (ID=0) requests authority on object table1 with result true")),
// Desc table
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "DESC table1",
- "User root (ID=0) requests authority on object table1 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "DESC table1",
+ "User root (ID=0) requests authority on object table1 with result true")),
// Create user
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "CREATE USER user1 ...",
- "User root (ID=0) requests authority on object user1 with result true"),
- // Create user
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "CREATE USER user2 ...",
- "User root (ID=0) requests authority on object user2 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "CREATE USER user1 ...",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "CREATE USER user2 ...",
+ "User root (ID=0) requests authority on object user2 with result true")),
// Create role
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "CREATE ROLE role1",
- "User root (ID=0) requests authority on object role1 with result true"),
- // Grant privileges to user
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "test",
- "GRANT SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 TO USER user1",
- "User root (ID=0) requests authority on object user1 with result true"),
- // Grant privileges to role
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "GRANT SELECT ON ANY TO ROLE role1",
- "User root (ID=0) requests authority on object role1 with result true"),
- // Grant role to user
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "GRANT ROLE role1 TO user2",
- "User root (ID=0) requests authority on object user: user2, role: role1 with result true"),
- // List user, the user object is null since the root can list all users
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "list user",
- "User root (ID=0) requests authority on object null with result true"),
- // List role, the role object is null since the root can list all roles
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "list role",
- "User root (ID=0) requests authority on object null with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "CREATE ROLE role1",
+ "User root (ID=0) requests authority on object role1 with result true")),
+ // Grant privileges: pri->user, pri->role, role->user
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "test",
+ "GRANT SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 TO USER user1",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "GRANT SELECT ON ANY TO ROLE role1",
+ "User root (ID=0) requests authority on object role1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "GRANT ROLE role1 TO user2",
+ "User root (ID=0) requests authority on object user: user2, role: role1 with result true")),
+ // List user/role, the authentication object is null since the root can list all
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "list user",
+ "User root (ID=0) requests authority on object null with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "list role",
+ "User root (ID=0) requests authority on object null with result true")),
// Root logout, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing")),
// =============================Audit user user1=============================
// User1 login, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session"),
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session")),
// List privileges of user1
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "null",
- "GLOBAL",
- "true",
- "null",
- "LIST PRIVILEGES OF USER user1",
- "User user1 (ID=10000) requests authority on object user1 with result true"),
- // Use database, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User user1 (ID=10000) requests authority on object test with result true"),
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User user1 (ID=10000) requests authority on object test with result true"),
- // Insert into table
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DML",
- "[INSERT]",
- "OBJECT",
- "true",
- "test",
- "INSERT INTO table1(time, t1, a1, s1) values(...)",
- "User user1 (ID=10000) requests authority on object table1 with result true"),
- // Select from table, including fetch device
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
- "true",
- "test",
- "SELECT * FROM table1",
- "User user1 (ID=10000) requests authority on object table1 with result true"),
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
- "true",
- "test",
- "fetch device for query",
- "User user1 (ID=10000) requests authority on object table1 with result true"),
- // Update table
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DML",
- "[INSERT]",
- "OBJECT",
- "true",
- "test",
- "UPDATE table1 SET a1 = t1",
- "User user1 (ID=10000) requests authority on object table1 with result true"),
- // Delete from table
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DML",
- "[DELETE]",
- "OBJECT",
- "true",
- "test",
- "DELETE FROM table1",
- "User user1 (ID=10000) requests authority on object table1 with result true"),
- // User1 logout, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- Arrays.asList(
- "node_1",
- "u_10000",
- "user1",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- // =============================Audit user user2=============================
- // User2 login, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session"),
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session"),
- // List privileges of user2
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "null",
- "GLOBAL",
- "true",
- "null",
- "LIST PRIVILEGES OF USER user2",
- "User user2 (ID=10001) requests authority on object user2 with result true"),
- // List privileges of role1
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "null",
- "GLOBAL",
- "true",
- "null",
- "LIST PRIVILEGES OF ROLE role1",
- "User user2 (ID=10001) requests authority on object role1 with result true"),
- // List user, only him/herself
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "null",
- "GLOBAL",
- "true",
- "null",
- "list user",
- "User user2 (ID=10001) requests authority on object user2 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "LIST PRIVILEGES OF USER user1",
+ "User user1 (ID=10000) requests authority on object user1 with result true")),
// Use database, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User user2 (ID=10001) requests authority on object test with result true"),
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User user2 (ID=10001) requests authority on object test with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user1 (ID=10000) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user1 (ID=10000) requests authority on object test with result true")),
+ // Insert into table
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[INSERT]",
+ "OBJECT",
+ "true",
+ "test",
+ "INSERT INTO table1(time, t1, a1, s1) values(...)",
+ "User user1 (ID=10000) requests authority on object table1 with result true")),
+ // Select from table, including fetch device
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "SELECT * FROM table1",
+ "User user1 (ID=10000) requests authority on object table1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "fetch device for query",
+ "User user1 (ID=10000) requests authority on object table1 with result true")),
+ // Update table
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[INSERT]",
+ "OBJECT",
+ "true",
+ "test",
+ "UPDATE table1 SET a1 = t1",
+ "User user1 (ID=10000) requests authority on object table1 with result true")),
+ // Delete from table
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[DELETE]",
+ "OBJECT",
+ "true",
+ "test",
+ "DELETE FROM table1",
+ "User user1 (ID=10000) requests authority on object table1 with result true")),
+ // User1 logout, twice for both read and write connections
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing")),
+ // =============================Audit user user2=============================
+ // User2 login, twice for both read and write connections
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session")),
+ // List privileges of user2, role1
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "LIST PRIVILEGES OF USER user2",
+ "User user2 (ID=10001) requests authority on object user2 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "LIST PRIVILEGES OF ROLE role1",
+ "User user2 (ID=10001) requests authority on object role1 with result true")),
+ // List user and role, only him/herself
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "list user",
+ "User user2 (ID=10001) requests authority on object user2 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "list role",
+ "User user2 (ID=10001) requests authority on object null with result true")),
+ // Use database, twice for both read and write connections
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user2 (ID=10001) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user2 (ID=10001) requests authority on object test with result true")),
// Failed to insert since no privilege
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DML",
- "[INSERT]",
- "OBJECT",
- "false",
- "test",
- "INSERT INTO table1(time, t1, a1, s1) values(...)",
- "User user2 (ID=10001) requests authority on object table1 with result false"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[INSERT]",
+ "OBJECT",
+ "false",
+ "test",
+ "INSERT INTO table1(time, t1, a1, s1) values(...)",
+ "User user2 (ID=10001) requests authority on object table1 with result false")),
// Select from table1, including fetch device
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
- "true",
- "test",
- "SELECT * FROM table1",
- "User user2 (ID=10001) requests authority on object table1 with result true"),
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
- "true",
- "test",
- "fetch device for query",
- "User user2 (ID=10001) requests authority on object table1 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "SELECT * FROM table1",
+ "User user2 (ID=10001) requests authority on object table1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "fetch device for query",
+ "User user2 (ID=10001) requests authority on object table1 with result true")),
// Update table
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DML",
- "[INSERT]",
- "OBJECT",
- "false",
- "test",
- "UPDATE table1 SET a1 = t1",
- "User user2 (ID=10001) requests authority on object table1 with result false"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[INSERT]",
+ "OBJECT",
+ "false",
+ "test",
+ "UPDATE table1 SET a1 = t1",
+ "User user2 (ID=10001) requests authority on object table1 with result false")),
// Delete from table
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DML",
- "[DELETE]",
- "OBJECT",
- "false",
- "test",
- "DELETE FROM table1",
- "User user2 (ID=10001) requests authority on object table1 with result false"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[DELETE]",
+ "OBJECT",
+ "false",
+ "test",
+ "DELETE FROM table1",
+ "User user2 (ID=10001) requests authority on object table1 with result false")),
// User2 logout, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
- Arrays.asList(
- "node_1",
- "u_10001",
- "user2",
- "127.0.0.1",
- "LOGOUT",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "is closing"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing")),
// =============================Audit user root=============================
// Root login, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "LOGIN",
- "CONTROL",
- "null",
- "GLOBAL",
- "true",
- "",
- "",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session")),
// Use database, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User root (ID=0) requests authority on object test with result true"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User root (ID=0) requests authority on object test with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true")),
// Drop table
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[DROP]",
- "OBJECT",
- "true",
- "test",
- "DROP TABLE table1",
- "User root (ID=0) requests authority on object table1 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[DROP]",
+ "OBJECT",
+ "true",
+ "test",
+ "DROP TABLE table1",
+ "User root (ID=0) requests authority on object table1 with result true")),
// Drop database
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[DROP]",
- "OBJECT",
- "true",
- "test",
- "DROP DATABASE IF EXISTS test",
- "User root (ID=0) requests authority on object test with result true"),
- // Revoke user privilege
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "test",
- "REVOKE SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 FROM USER user1",
- "User root (ID=0) requests authority on object user1 with result true"),
- // Revoke role privilege
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "REVOKE SELECT ON ANY FROM ROLE role1",
- "User root (ID=0) requests authority on object role1 with result true"),
- // Drop user
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "DROP USER user1",
- "User root (ID=0) requests authority on object user1 with result true"),
- // Drop user
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "DROP USER user2",
- "User root (ID=0) requests authority on object user2 with result true"),
- // Drop role
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
- "GLOBAL",
- "true",
- "null",
- "DROP ROLE role1",
- "User root (ID=0) requests authority on object role1 with result true"),
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[DROP]",
+ "OBJECT",
+ "true",
+ "test",
+ "DROP DATABASE IF EXISTS test",
+ "User root (ID=0) requests authority on object test with result true")),
+ // Revoke user/role privilege
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "test",
+ "REVOKE SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 FROM USER user1",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "REVOKE SELECT ON ANY FROM ROLE role1",
+ "User root (ID=0) requests authority on object role1 with result true")),
+ // Drop user, role
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "DROP USER user1",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "DROP USER user2",
+ "User root (ID=0) requests authority on object user2 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "DROP ROLE role1",
+ "User root (ID=0) requests authority on object role1 with result true")),
// Select audit log
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
- "true",
- "__audit",
- "SELECT * FROM __audit.audit_log ORDER BY TIME",
- "User root (ID=0) requests authority on object __audit with result true"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
- "true",
- "__audit",
- "fetch device for query",
- "User root (ID=0) requests authority on object __audit with result true"));
+ new AuditLogSet(
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "__audit",
+ "SELECT * FROM __audit.audit_log ORDER BY TIME",
+ "User root (ID=0) requests authority on object __audit with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "__audit",
+ "fetch device for query",
+ "User root (ID=0) requests authority on object __audit with result true")));
private static final Set<Integer> TABLE_INDEX_FOR_CONTAIN =
Stream.of(11, 12).collect(Collectors.toSet());
@@ -1251,48 +1295,69 @@ public class IoTDBAuditLogBasicIT {
for (String sql : TABLE_MODEL_AUDIT_SQLS_USER_ROOT_FINAL) {
statement.execute(sql);
}
- int count = 0;
ResultSet resultSet = statement.executeQuery("SELECT * FROM __audit.audit_log ORDER BY TIME");
- while (resultSet.next()) {
- LOGGER.info("Expected audit log: {}", TABLE_MODEL_AUDIT_FIELDS.get(count));
- List<String> actualFields = new ArrayList<>();
- for (int i = 1; i <= 12; i++) {
- actualFields.add(resultSet.getString(i + 1));
- }
- LOGGER.info("Actual audit log: {}", actualFields);
- List<String> expectedFields = TABLE_MODEL_AUDIT_FIELDS.get(count);
- for (int i = 1; i <= 12; i++) {
- if (TABLE_INDEX_FOR_CONTAIN.contains(i)) {
- Assert.assertTrue(resultSet.getString(i + 1).contains(expectedFields.get(i - 1)));
- continue;
- }
- Assert.assertEquals(expectedFields.get(i - 1), resultSet.getString(i + 1));
- }
- count++;
+ for (AuditLogSet expectedAuditLogSet : TABLE_MODEL_AUDIT_FIELDS) {
+ expectedAuditLogSet.containAuditLog(resultSet, TABLE_INDEX_FOR_CONTAIN, 12);
}
- Assert.assertEquals(TABLE_MODEL_AUDIT_FIELDS.size(), count);
+ Assert.assertFalse(resultSet.next());
}
- private static final List<String> TREE_MODEL_AUDIT_SQLS =
+ private static final List<String> TREE_MODEL_AUDIT_SQLS_USER_ROOT =
Arrays.asList(
"CREATE DATABASE root.test",
- "CREATE TIMESERIES root.test.d1.s2 WITH DATATYPE=INT64",
- "CREATE ALIGNED TIMESERIES root.test.d2(s1 BOOLEAN, s2 INT64)",
- "ALTER TIMESERIES root.test.d2.s1 ADD TAGS tag3=v3, tag4=v4",
- "CREATE USER user1 'IoTDB@2021abc'",
- "CREATE role role1",
- "GRANT READ_DATA, WRITE_DATA ON root.test TO ROLE role1",
- "GRANT ROLE role1 TO user1",
- "LIST USER",
- "LIST ROLE",
- "DROP ROLE role1",
+ // "show databases",
+ // "COUNT databases",
+ "set ttl to root.test.** INF",
+ "create timeseries root.test.d1.s1 with datatype=BOOLEAN",
+ "create timeseries root.test.d1.s2 with datatype=INT64",
+ "create timeseries root.test.d1.s3 with datatype=TEXT",
+ "CREATE ALIGNED TIMESERIES root.test.d2(s1 BOOLEAN, s2 INT64, s3 TEXT)",
+ "show timeseries",
+ "COUNT TIMESERIES root.test",
+ "ALTER timeseries root.test.d1.s1 ADD TAGS tag3=v3, tag4=v4",
+ "ALTER timeseries root.test.d2.s1 ADD TAGS tag3=v3, tag4=v4",
+ "CREATE USER user1 'IoTDB@2025abc'",
+ "CREATE USER user2 'IoTDB@2025abc'",
+ "CREATE ROLE role1",
+ "GRANT READ_DATA, WRITE_DATA ON root.test.** TO USER user1",
+ "GRANT READ ON root.test.** TO ROLE role1",
+ "GRANT ROLE role1 TO user2",
+ "list user",
+ "list role");
+ private static final List<String> TREE_MODEL_AUDIT_SQLS_USER_USER1 =
+ Arrays.asList(
+ "LIST PRIVILEGES OF USER user1",
+ "insert into root.test.d1(timestamp,s1,s2,s3) values(1,true,1,'1')",
+ "insert into root.test.d2(timestamp,s1,s2,s3) aligned values(1,true,1,'1')",
+ // TODO: Enable testing select for normal user
+ // "select * from root.test.d1 order by time",
+ // "select * from root.test.d2 order by time",
+ "delete from root.test.d1.s3",
+ "delete from root.test.d2.s3");
+ private static final List<String> TREE_MODEL_AUDIT_SQLS_USER_USER2 =
+ Arrays.asList(
+ "LIST PRIVILEGES OF USER user2",
+ "LIST PRIVILEGES OF ROLE role1",
+ "list user",
+ "list role",
+ "insert into root.test.d1(timestamp,s1,s2,s3) values(1,true,1,'1')",
+ "insert into root.test.d2(timestamp,s1,s2,s3) aligned values(1,true,1,'1')",
+ "insert into root.test.d1(timestamp,s1,s2,s3) values(1,false,2,'2')",
+ "insert into root.test.d2(timestamp,s1,s2,s3) aligned values(1,false,2,'2')",
+ // TODO: Enable testing select for normal user
+ // "select * from root.test.d1 order by time",
+ // "select * from root.test.d2 order by time",
+ "delete from root.test.d1.s3",
+ "delete from root.test.d2.s3");
+ private static final List<String> TREE_MODEL_AUDIT_SQLS_USER_ROOT_FINAL =
+ Arrays.asList(
+ "delete timeseries root.test.d1.s3",
+ "drop timeseries root.test.d1.*",
+ "REVOKE READ_DATA, WRITE_DATA ON root.test.** FROM USER user1",
+ "REVOKE READ ON root.test.** FROM ROLE role1",
"DROP USER user1",
- "INSERT INTO root.test.d1(timestamp,s2) VALUES(1,1)",
- "INSERT INTO root.test.d2(timestamp,s1,s2) ALIGNED VALUES(1,true,1)",
- "SELECT ** FROM root.test",
- "DELETE FROM root.test.d2",
- "DROP TIMESERIES root.test.d1.s2",
- "set ttl to root.test.** 360000",
+ "DROP USER user2",
+ "DROP ROLE role1",
"DELETE DATABASE root.test");
private static final List<List<String>> TREE_MODEL_AUDIT_FIELDS =
Arrays.asList(
@@ -1301,14 +1366,111 @@ public class IoTDBAuditLogBasicIT {
"root.__audit.log.node_1.u_none",
"true",
"GLOBAL",
- "[AUDIT]",
+ "[AUDIT]",
+ "null",
+ "CONTROL",
+ "Successfully start the Audit service with configurations (auditableOperationType [DDL, DML, QUERY, CONTROL], auditableOperationLevel GLOBAL, auditableOperationResult SUCCESS,FAIL)",
+ "null",
+ "CHANGE_AUDIT_OPTION",
+ "null",
+ "null"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "null",
+ "",
+ "CONTROL",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "",
+ "LOGIN",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "null",
+ "",
+ "CONTROL",
+ "is closing",
+ "",
+ "LOGOUT",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "null",
+ "",
+ "CONTROL",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "",
+ "LOGIN",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "null",
+ "",
+ "CONTROL",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "",
+ "LOGIN",
+ "127.0.0.1",
+ "root"),
+ // Show audit database
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[MANAGE_DATABASE]",
+ "[root.__audit]",
+ "QUERY",
+ "User root (ID=0) requests authority on object root.__audit with result true",
+ "SHOW DATABASES root.__audit",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
"null",
+ "",
"CONTROL",
- "Successfully start the Audit service with configurations (auditableOperationType [DDL, DML, QUERY, CONTROL], auditableOperationLevel GLOBAL, auditableOperationResult SUCCESS,FAIL)",
+ "is closing",
+ "",
+ "LOGOUT",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
"null",
- "CHANGE_AUDIT_OPTION",
+ "",
+ "CONTROL",
+ "is closing",
+ "",
+ "LOGOUT",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
"null",
- "null"),
+ "",
+ "CONTROL",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "",
+ "LOGIN",
+ "127.0.0.1",
+ "root"),
Arrays.asList(
"root.__audit.log.node_1.u_0",
"true",
@@ -1321,6 +1483,31 @@ public class IoTDBAuditLogBasicIT {
"LOGIN",
"127.0.0.1",
"root"),
+ // Desc audit table
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[READ_SCHEMA]",
+ "__audit",
+ "QUERY",
+ "User root (ID=0) requests authority on object audit_log with result true",
+ "DESC __audit.audit_log",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "null",
+ "",
+ "CONTROL",
+ "is closing",
+ "",
+ "LOGOUT",
+ "127.0.0.1",
+ "root"),
Arrays.asList(
"root.__audit.log.node_1.u_0",
"true",
@@ -1333,6 +1520,8 @@ public class IoTDBAuditLogBasicIT {
"LOGOUT",
"127.0.0.1",
"root"),
+ // =============================Audit user root=============================
+ // Root login, twice for both read and write connections
Arrays.asList(
"root.__audit.log.node_1.u_0",
"true",
@@ -1357,19 +1546,236 @@ public class IoTDBAuditLogBasicIT {
"LOGIN",
"127.0.0.1",
"root"),
- // Show audit database
+ // Create database
Arrays.asList(
"root.__audit.log.node_1.u_0",
"true",
"OBJECT",
"[MANAGE_DATABASE]",
- "[root.__audit]",
+ "root.test",
+ "DDL",
+ "User root (ID=0) requests authority on object root.test with result true",
+ "CREATE DATABASE root.test",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Set TTL to database
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[SYSTEM]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.**] with result true",
+ "set ttl to root.test.** INF",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Create (aligned) timeseries TODO: fill database if necessary, same as follows
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_SCHEMA]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.d1.s1] with result true",
+ "create timeseries root.test.d1.s1 with datatype=BOOLEAN",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_SCHEMA]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.d1.s2] with result true",
+ "create timeseries root.test.d1.s2 with datatype=INT64",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_SCHEMA]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.d1.s3] with result true",
+ "create timeseries root.test.d1.s3 with datatype=TEXT",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_SCHEMA]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.d2.s1, root.test.d2.s2, root.test.d2.s3] with result true",
+ "CREATE ALIGNED TIMESERIES root.test.d2(s1 BOOLEAN, s2 INT64, s3 TEXT)",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Show timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[READ_DATA, READ_SCHEMA]",
+ "null",
"QUERY",
- "User root (ID=0) requests authority on object root.__audit with result true",
- "SHOW DATABASES root.__audit",
+ "User root (ID=0) requests authority on object [root.**] with result true",
+ "show timeseries",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Count timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[READ_SCHEMA]",
+ "null",
+ "QUERY",
+ "User root (ID=0) requests authority on object [root.test] with result true",
+ "COUNT TIMESERIES root.test",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Alter timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_SCHEMA]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.d1.s1] with result true",
+ "ALTER timeseries root.test.d1.s1 ADD TAGS tag3=v3, tag4=v4",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_SCHEMA]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test.d2.s1] with result true",
+ "ALTER timeseries root.test.d2.s1 ADD TAGS tag3=v3, tag4=v4",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Create user
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[MANAGE_USER]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object user1 with result true",
+ "CREATE USER user1 ...",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[MANAGE_USER]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object user2 with result true",
+ "CREATE USER user2 ...",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Create role
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[MANAGE_ROLE]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object role1 with result true",
+ "CREATE ROLE role1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Grant privileges to user
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[SECURITY]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object user1 with result true",
+ "GRANT READ_DATA, WRITE_DATA ON root.test.** TO USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Grant privileges to role
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[SECURITY]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object role1 with result true",
+ "GRANT READ ON root.test.** TO ROLE role1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Grant role to user
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[MANAGE_ROLE]",
+ "null",
+ "DDL",
+ "User root (ID=0) requests authority on object user: user2, role: role1 with result true",
+ "GRANT ROLE role1 TO user2",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // List user, the target object is null since the root can list all
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[MANAGE_USER]",
+ "null",
+ "QUERY",
+ "User root (ID=0) requests authority on object null with result true",
+ "list user",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // List role, the target object is null since the root can list all
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "GLOBAL",
+ "[MANAGE_ROLE]",
+ "null",
+ "QUERY",
+ "User root (ID=0) requests authority on object null with result true",
+ "list role",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
"root"),
+ // Root logout, twice for both read and write connections
Arrays.asList(
"root.__audit.log.node_1.u_0",
"true",
@@ -1394,46 +1800,123 @@ public class IoTDBAuditLogBasicIT {
"LOGOUT",
"127.0.0.1",
"root"),
+ // =============================Audit user user1=============================
+ // User1 login, twice for both read and write connections
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"GLOBAL",
"null",
"",
"CONTROL",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session",
"",
"LOGIN",
"127.0.0.1",
- "root"),
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"GLOBAL",
"null",
"",
"CONTROL",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session",
"",
"LOGIN",
"127.0.0.1",
- "root"),
-
- // Desc audit table
+ "user1"),
+ // List privilege of user1
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "GLOBAL",
+ "null",
+ "null",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object user1 with result true",
+ "LIST PRIVILEGES OF USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // Insert into (aligned) timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
"true",
"OBJECT",
- "[READ_SCHEMA]",
- "__audit",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User user1 (ID=10000) requests authority on object [root.test.d1.s1, root.test.d1.s2, root.test.d1.s3] with result true",
+ "insert into root.test.d1(timestamp,s1,s2,s3) values(...)",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "OBJECT",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User user1 (ID=10000) requests authority on object [root.test.d2.s1, root.test.d2.s2, root.test.d2.s3] with result true",
+ "insert into root.test.d2(timestamp,s1,s2,s3) aligned values(...)",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // Select timeseries data
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "OBJECT",
+ "[READ_DATA]",
+ "null",
"QUERY",
- "User root (ID=0) requests authority on object audit_log with result true",
- "DESC __audit.audit_log",
+ "User user1 (ID=10000) requests authority on object [root.test.d1.*] with result true",
+ "select * from root.test.d1 order by time",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "OBJECT",
+ "[READ_DATA]",
+ "null",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object [root.test.d2.*] with result true",
+ "select * from root.test.d2 order by time",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // Delete timeseries data
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "OBJECT",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d1.s3] with result true",
+ "delete from root.test.d1.s3",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "OBJECT",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d2.s3] with result true",
+ "delete from root.test.d2.s3",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // user1 logout, twice for both read and write connections
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
"true",
"GLOBAL",
"null",
@@ -1443,9 +1926,9 @@ public class IoTDBAuditLogBasicIT {
"",
"LOGOUT",
"127.0.0.1",
- "root"),
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"GLOBAL",
"null",
@@ -1455,160 +1938,211 @@ public class IoTDBAuditLogBasicIT {
"",
"LOGOUT",
"127.0.0.1",
- "root"),
+ "user1"),
+ // =============================Audit user user2=============================
+ // User2 login, twice for both read and write connections
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10001",
"true",
"GLOBAL",
"null",
"",
"CONTROL",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session",
"",
"LOGIN",
"127.0.0.1",
- "root"),
+ "user2"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10001",
"true",
"GLOBAL",
"null",
"",
"CONTROL",
- "IoTDB: Login status: Login successfully. User root (ID=0), opens Session",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session",
"",
"LOGIN",
"127.0.0.1",
- "root"),
- // Create database
+ "user2"),
+ // List privilege of user2
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "GLOBAL",
+ "null",
+ "null",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object user1 with result true",
+ "LIST PRIVILEGES OF USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // List privilege of role1
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "GLOBAL",
+ "null",
+ "null",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object user1 with result true",
+ "LIST PRIVILEGES OF USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // List user, can only see him/herself
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "GLOBAL",
+ "null",
+ "null",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object user1 with result true",
+ "LIST PRIVILEGES OF USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // List role, can only see his/hers roles
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
+ "true",
+ "GLOBAL",
+ "null",
+ "null",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object user1 with result true",
+ "LIST PRIVILEGES OF USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "user1"),
+ // Insert into (aligned) timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_10000",
"true",
"OBJECT",
- "[MANAGE_DATABASE]",
- "root.test",
- "DDL",
- "User root (ID=0) requests authority on object root.test with result true",
- "CREATE DATABASE root.test",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User user1 (ID=10000) requests authority on object [root.test.d1.s1, root.test.d1.s2, root.test.d1.s3] with result true",
+ "insert into root.test.d1(timestamp,s1,s2,s3) values(...)",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
- // Create (aligned) timeseries TODO: fill database if necessary, same as follows
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"OBJECT",
- "[WRITE_SCHEMA]",
+ "[WRITE_DATA]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object [root.test.d1.s2] with result true",
- "CREATE TIMESERIES root.test.d1.s2 WITH DATATYPE=INT64",
+ "DML",
+ "User user1 (ID=10000) requests authority on object [root.test.d2.s1, root.test.d2.s2, root.test.d2.s3] with result true",
+ "insert into root.test.d2(timestamp,s1,s2,s3) aligned values(...)",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
+ "user1"),
+ // Select timeseries data
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"OBJECT",
- "[WRITE_SCHEMA]",
+ "[READ_DATA]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object [root.test.d2.s1, root.test.d2.s2] with result true",
- "CREATE ALIGNED TIMESERIES root.test.d2(s1 BOOLEAN, s2 INT64)",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object [root.test.d1.*] with result true",
+ "select * from root.test.d1 order by time",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
- // Alter timeseries
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"OBJECT",
- "[WRITE_SCHEMA]",
+ "[READ_DATA]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object [root.test.d2.s1] with result true",
- "ALTER TIMESERIES root.test.d2.s1 ADD TAGS tag3=v3, tag4=v4",
+ "QUERY",
+ "User user1 (ID=10000) requests authority on object [root.test.d2.*] with result true",
+ "select * from root.test.d2 order by time",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
- // Create user
+ "user1"),
+ // Delete timeseries data
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
- "GLOBAL",
- "[MANAGE_USER]",
+ "OBJECT",
+ "[WRITE_DATA]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object user1 with result true",
- "CREATE USER user1 ...",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d1.s3] with result true",
+ "delete from root.test.d1.s3",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
- // Create role
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
- "GLOBAL",
- "[MANAGE_ROLE]",
+ "OBJECT",
+ "[WRITE_DATA]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object role1 with result true",
- "CREATE role role1",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d2.s3] with result true",
+ "delete from root.test.d2.s3",
"OBJECT_AUTHENTICATION",
"127.0.0.1",
- "root"),
- // Grant privileges to role
+ "user1"),
+ // user1 logout, twice for both read and write connections
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"GLOBAL",
- "[SECURITY]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object role1 with result true",
- "GRANT READ_DATA, WRITE_DATA ON root.test TO ROLE role1",
- "OBJECT_AUTHENTICATION",
+ "",
+ "CONTROL",
+ "is closing",
+ "",
+ "LOGOUT",
"127.0.0.1",
- "root"),
- // Grant role to user
+ "user1"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10000",
"true",
"GLOBAL",
- "[MANAGE_ROLE]",
"null",
- "DDL",
- "User root (ID=0) requests authority on object user: user1, role: role1 with result true",
- "GRANT ROLE role1 TO user1",
- "OBJECT_AUTHENTICATION",
+ "",
+ "CONTROL",
+ "is closing",
+ "",
+ "LOGOUT",
"127.0.0.1",
- "root"),
- // List user TODO: whether to include user object?
+ "user1"),
+ // =============================Audit user user2=============================
+ // User2 login, twice for both read and write connections
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10001",
"true",
"GLOBAL",
- "[MANAGE_USER]",
"null",
- "QUERY",
- "User root (ID=0) requests authority on object null with result true",
- "LIST USER",
- "OBJECT_AUTHENTICATION",
+ "",
+ "CONTROL",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session",
+ "",
+ "LOGIN",
"127.0.0.1",
- "root"),
- // List role TODO: whether to include role object?
+ "user2"),
Arrays.asList(
- "root.__audit.log.node_1.u_0",
+ "root.__audit.log.node_1.u_10001",
"true",
"GLOBAL",
- "[MANAGE_ROLE]",
"null",
- "QUERY",
- "User root (ID=0) requests authority on object null with result true",
- "LIST ROLE",
- "OBJECT_AUTHENTICATION",
+ "",
+ "CONTROL",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session",
+ "",
+ "LOGIN",
"127.0.0.1",
- "root"),
+ "user2"),
// Drop role
Arrays.asList(
"root.__audit.log.node_1.u_0",
@@ -1742,34 +2276,57 @@ public class IoTDBAuditLogBasicIT {
Stream.of(7).collect(Collectors.toSet());
@Test
- public void basicAuditLogTestForTreeModel() throws SQLException {
- try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TREE_SQL_DIALECT);
- Statement statement = connection.createStatement()) {
- for (String sql : TREE_MODEL_AUDIT_SQLS) {
+ public void basicAuditLogTestForTreeModel() throws SQLException, InterruptedException {
+ Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TREE_SQL_DIALECT);
+ Statement statement = connection.createStatement();
+ for (String sql : TREE_MODEL_AUDIT_SQLS_USER_ROOT) {
+ statement.execute(sql);
+ }
+ closeConnectionCompletely(connection);
+ connection =
+ EnvFactory.getEnv().getConnection("user1", "IoTDB@2025abc", BaseEnv.TREE_SQL_DIALECT);
+ statement = connection.createStatement();
+ for (String sql : TREE_MODEL_AUDIT_SQLS_USER_USER1) {
+ statement.execute(sql);
+ }
+ closeConnectionCompletely(connection);
+ connection =
+ EnvFactory.getEnv().getConnection("user2", "IoTDB@2025abc", BaseEnv.TREE_SQL_DIALECT);
+ statement = connection.createStatement();
+ for (String sql : TREE_MODEL_AUDIT_SQLS_USER_USER2) {
+ try {
statement.execute(sql);
+ } catch (SQLException e) {
+ // Ignore, only record audit log
}
- int count = 0;
- ResultSet resultSet =
- statement.executeQuery("SELECT * FROM root.__audit.log.** ORDER BY TIME ALIGN BY DEVICE");
- while (resultSet.next()) {
- LOGGER.info("Expected audit log: {}", TREE_MODEL_AUDIT_FIELDS.get(count));
- List<String> actualFields = new ArrayList<>();
- for (int i = 1; i <= 11; i++) {
- actualFields.add(resultSet.getString(i + 1));
- }
- LOGGER.info("Actual audit log: {}", actualFields);
- List<String> expectedFields = TREE_MODEL_AUDIT_FIELDS.get(count);
- for (int i = 1; i <= 11; i++) {
- if (TREE_INDEX_FOR_CONTAIN.contains(i)) {
- Assert.assertTrue(resultSet.getString(i + 1).contains(expectedFields.get(i - 1)));
- continue;
- }
- Assert.assertEquals(expectedFields.get(i - 1), resultSet.getString(i + 1));
+ }
+ closeConnectionCompletely(connection);
+ connection = EnvFactory.getEnv().getConnection(BaseEnv.TREE_SQL_DIALECT);
+ statement = connection.createStatement();
+ for (String sql : TREE_MODEL_AUDIT_SQLS_USER_ROOT_FINAL) {
+ statement.execute(sql);
+ }
+ int count = 0;
+ ResultSet resultSet =
+ statement.executeQuery("SELECT * FROM root.__audit.log.** ORDER BY TIME ALIGN BY DEVICE");
+ while (resultSet.next()) {
+ LOGGER.info("Expected audit log: {}", TREE_MODEL_AUDIT_FIELDS.get(count));
+ List<String> actualFields = new ArrayList<>();
+ for (int i = 1; i <= 11; i++) {
+ actualFields.add(resultSet.getString(i + 1));
+ }
+ LOGGER.info("Actual audit log: {}", actualFields);
+ List<String> expectedFields = TREE_MODEL_AUDIT_FIELDS.get(count);
+ for (int i = 1; i <= 11; i++) {
+ if (TREE_INDEX_FOR_CONTAIN.contains(i)) {
+ Assert.assertTrue(resultSet.getString(i + 1).contains(expectedFields.get(i - 1)));
+ continue;
}
-
- count++;
+ Assert.assertEquals(expectedFields.get(i - 1), resultSet.getString(i + 1));
}
- Assert.assertEquals(TREE_MODEL_AUDIT_FIELDS.size(), count);
+
+ count++;
}
+ Assert.assertEquals(TREE_MODEL_AUDIT_FIELDS.size(), count);
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java
index a8a5280b444..938263616e4 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java
@@ -354,7 +354,7 @@ public class DNAuditLogger extends AbstractAuditLogger {
}
@Override
- public void log(IAuditEntity auditLogFields, Supplier<String> log) {
+ public synchronized void log(IAuditEntity auditLogFields, Supplier<String> log) {
if (!IS_AUDIT_LOG_ENABLED) {
return;
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
index 8c3fbb2253d..4d720bc0ddc 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
@@ -336,18 +336,21 @@ public class AccessControlImpl implements AccessControl {
authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity);
return;
case LIST_ROLE:
- auditEntity
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
+ auditEntity.setAuditLogOperation(AuditLogOperation.QUERY);
if (statement.getUserName() != null && !statement.getUserName().equals(userName)) {
+ // Require SECURITY privilege to list other users' roles
authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity);
- ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getRoleName);
return;
}
if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_ROLE)) {
+ // No need to check privilege to list his/hers own role
statement.setUserName(userName);
- } else {
ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getRoleName);
+ } else {
+ // Require SECURITY privilege to list all roles
+ ITableAuthCheckerImpl.recordAuditLog(
+ auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true),
+ statement::getRoleName);
}
return;
case LIST_ROLE_PRIV:
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 cd6cbe31336..aa999677075 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
@@ -540,47 +540,45 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
PrivilegeType.MANAGE_USER,
statement::getUserName);
case LIST_USER:
- context
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
+ context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true);
if (checkHasGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
PrivilegeType.MANAGE_USER,
statement::getUserName)) {
+ // MANAGE_USER privilege can list all users
return RpcUtils.SUCCESS_STATUS;
}
+ // Can only list him/herself without MANAGE_USER privilege
statement.setUserName(context.getUsername());
+ recordObjectAuthenticationAuditLog(
+ context.setPrivilegeType(null).setResult(true), context::getUsername);
return RpcUtils.SUCCESS_STATUS;
-
case LIST_USER_PRIVILEGE:
- context
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
+ context.setAuditLogOperation(AuditLogOperation.QUERY);
if (context.getUsername().equals(statement.getUserName())) {
+ // No need any privilege to list his/her own privileges
+ recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername);
return RpcUtils.SUCCESS_STATUS;
}
+ // Require MANAGE_USER privilege to list other users' privileges
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
PrivilegeType.MANAGE_USER,
statement::getUserName);
-
case LIST_ROLE_PRIVILEGE:
- context
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
+ context.setAuditLogOperation(AuditLogOperation.QUERY);
if (!AuthorityChecker.checkRole(context.getUsername(), statement.getRoleName())) {
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
PrivilegeType.MANAGE_ROLE,
statement::getRoleName);
} else {
+ // No need any privilege to list his/her own role's privileges
+ recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername);
return SUCCEED;
}
-
case LIST_ROLE:
- context
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
+ context.setAuditLogOperation(AuditLogOperation.QUERY);
if (checkHasGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
PrivilegeType.MANAGE_ROLE,
@@ -590,8 +588,12 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
// list roles of other user is not allowed
if (statement.getUserName() != null
&& !statement.getUserName().equals(context.getUsername())) {
+ recordObjectAuthenticationAuditLog(
+ context.setPrivilegeType(PrivilegeType.MANAGE_ROLE).setResult(false),
+ context::getUsername);
return AuthorityChecker.getTSStatus(false, PrivilegeType.MANAGE_ROLE);
}
+ recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername);
statement.setUserName(context.getUsername());
return RpcUtils.SUCCESS_STATUS;
(iotdb) 01/02: Fix table model bugs
Posted by yo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
yongzao pushed a commit to branch audit-log-patch-again
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 6216b2add615305a568f70a62432ff8ecbb7ff87
Author: Yongzao <53...@qq.com>
AuthorDate: Sat Oct 11 13:52:25 2025 +0800
Fix table model bugs
---
.../iotdb/db/it/audit/IoTDBAuditLogBasicIT.java | 791 +++++++++++++++++----
.../relational/security/AccessControlImpl.java | 39 +-
2 files changed, 673 insertions(+), 157 deletions(-)
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java
index 39a51468082..372e1e6176c 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/audit/IoTDBAuditLogBasicIT.java
@@ -115,14 +115,7 @@ public class IoTDBAuditLogBasicIT {
ResultSet resultSet = statement.executeQuery("SHOW DATABASES root.__audit");
Assert.assertTrue(resultSet.next());
Assert.assertEquals("root.__audit", resultSet.getString(1));
- Thread.sleep(1000);
- ((ClusterTestConnection) connection).writeConnection.close();
- Thread.sleep(1000);
- for (NodeConnection conn : ((ClusterTestConnection) connection).readConnections) {
- Thread.sleep(1000);
- conn.close();
- Thread.sleep(1000);
- }
+ closeConnectionCompletely(connection);
connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
statement = connection.createStatement();
resultSet = statement.executeQuery("DESC __audit.audit_log");
@@ -135,6 +128,18 @@ public class IoTDBAuditLogBasicIT {
cnt++;
}
Assert.assertEquals(AUDIT_TABLE_COLUMNS.size(), cnt);
+ closeConnectionCompletely(connection);
+ }
+
+ @After
+ public void tearDown() {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ private static void closeConnectionCompletely(Connection connection) throws InterruptedException {
+ // Ensure the session conns in test env are closed completely,
+ // in order to generate logout audit log
+ // TODO: Optimize this func after the close func of connection is optimized
Thread.sleep(1000);
((ClusterTestConnection) connection).writeConnection.close();
Thread.sleep(1000);
@@ -145,34 +150,53 @@ public class IoTDBAuditLogBasicIT {
}
}
- @After
- public void tearDown() {
- EnvFactory.getEnv().cleanClusterEnvironment();
- }
-
- private static final List<String> TABLE_MODEL_AUDIT_SQLS =
+ private static final List<String> TABLE_MODEL_AUDIT_SQLS_USER_ROOT =
Arrays.asList(
"CREATE DATABASE test",
- // "SHOW DATABASES",
- "ALTER DATABASE test SET PROPERTIES TTL='INF'",
"USE test",
- "CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 TEXT FIELD)",
+ // "SHOW CURRENT_DATABASE",
+ // "SHOW DATABASES",
+ "ALTER DATABASE test SET PROPERTIES TTL='INF'",
+ "CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 STRING FIELD)",
"SHOW TABLES",
"DESC table1",
"ALTER TABLE table1 set properties TTL='INF'",
- "CREATE USER user1 'IoTDB@2021abc'",
- "CREATE role role1",
- "GRANT SELECT, ALTER, INSERT, DELETE ON test.table1 TO ROLE role1",
- "GRANT ROLE role1 TO user1",
- "LIST USER",
- "LIST ROLE",
- "DROP ROLE role1",
- "DROP USER user1",
+ "CREATE USER user1 'IoTDB@2025abc'",
+ "CREATE USER user2 'IoTDB@2025abc'",
+ "CREATE ROLE role1",
+ "GRANT SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 TO USER user1",
+ "GRANT SELECT ON ANY TO ROLE role1",
+ "GRANT ROLE role1 TO user2",
+ "list user",
+ "list role");
+ private static final List<String> TABLE_MODEL_AUDIT_SQLS_USER_USER1 =
+ Arrays.asList(
+ "LIST PRIVILEGES OF USER user1",
+ "USE test",
"INSERT INTO table1(time, t1, a1, s1) values(1, 't1', 'a1', 's1')",
"SELECT * FROM table1",
- "DELETE FROM table1",
+ "UPDATE table1 SET a1 = t1",
+ "DELETE FROM table1");
+ private static final List<String> TABLE_MODEL_AUDIT_SQLS_USER_USER2 =
+ Arrays.asList(
+ "LIST PRIVILEGES OF USER user2",
+ "LIST PRIVILEGES OF ROLE role1",
+ "list user",
+ "USE test",
+ "INSERT INTO table1(time, t1, a1, s1) values(1, 't1', 'a1', 's1')",
+ "SELECT * FROM table1",
+ "UPDATE table1 SET a1 = t1",
+ "DELETE FROM table1");
+ private static final List<String> TABLE_MODEL_AUDIT_SQLS_USER_ROOT_FINAL =
+ Arrays.asList(
+ "USE test",
"DROP TABLE table1",
- "DROP DATABASE IF EXISTS test");
+ "DROP DATABASE IF EXISTS test",
+ "REVOKE SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 FROM USER user1",
+ "REVOKE SELECT ON ANY FROM ROLE role1",
+ "DROP USER user1",
+ "DROP USER user2",
+ "DROP ROLE role1");
private static final List<List<String>> TABLE_MODEL_AUDIT_FIELDS =
Arrays.asList(
// Start audit service
@@ -189,7 +213,6 @@ public class IoTDBAuditLogBasicIT {
"null",
"null",
"Successfully start the Audit service with configurations (auditableOperationType [DDL, DML, QUERY, CONTROL], auditableOperationLevel GLOBAL, auditableOperationResult SUCCESS,FAIL)"),
-
// Environment init login/logout
Arrays.asList(
"node_1",
@@ -324,6 +347,7 @@ public class IoTDBAuditLogBasicIT {
"__audit",
"DESC __audit.audit_log",
"User root (ID=0) requests authority on object audit_log with result true"),
+ // Setup logout through table model dialect, twice for both read and write connections
Arrays.asList(
"node_1",
"u_0",
@@ -337,6 +361,8 @@ public class IoTDBAuditLogBasicIT {
"",
"",
"is closing"),
+ // =============================Audit user root=============================
+ // Root login, twice for both read and write connections
Arrays.asList(
"node_1",
"u_0",
@@ -390,6 +416,33 @@ public class IoTDBAuditLogBasicIT {
"test",
"CREATE DATABASE test",
"User root (ID=0) requests authority on object test with result true"),
+ // Use database, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true"),
// Show database TODO: Enable only when the order of show databases authentication fixed
// Arrays.asList(
// "node_1",
@@ -445,33 +498,6 @@ public class IoTDBAuditLogBasicIT {
"test",
"ALTER DATABASE test SET PROPERTIES TTL='INF'",
"User root (ID=0) requests authority on object test with result true"),
- // Use database, twice for both read and write connections
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User root (ID=0) requests authority on object test with result true"),
- Arrays.asList(
- "node_1",
- "u_0",
- "root",
- "127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[READ_SCHEMA]",
- "OBJECT",
- "true",
- "test",
- "USE test",
- "User root (ID=0) requests authority on object test with result true"),
// Create table
Arrays.asList(
"node_1",
@@ -484,7 +510,7 @@ public class IoTDBAuditLogBasicIT {
"OBJECT",
"true",
"test",
- "CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 TEXT FIELD)",
+ "CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 STRING FIELD)",
"User root (ID=0) requests authority on object table1 with result true"),
// Show table
Arrays.asList(
@@ -528,6 +554,20 @@ public class IoTDBAuditLogBasicIT {
"null",
"CREATE USER user1 ...",
"User root (ID=0) requests authority on object user1 with result true"),
+ // Create user
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "CREATE USER user2 ...",
+ "User root (ID=0) requests authority on object user2 with result true"),
// Create role
Arrays.asList(
"node_1",
@@ -540,9 +580,9 @@ public class IoTDBAuditLogBasicIT {
"GLOBAL",
"true",
"null",
- "CREATE role role1",
+ "CREATE ROLE role1",
"User root (ID=0) requests authority on object role1 with result true"),
- // Grant privileges to role
+ // Grant privileges to user
Arrays.asList(
"node_1",
"u_0",
@@ -554,7 +594,21 @@ public class IoTDBAuditLogBasicIT {
"GLOBAL",
"true",
"test",
- "GRANT SELECT, ALTER, INSERT, DELETE ON test.table1 TO ROLE role1",
+ "GRANT SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 TO USER user1",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ // Grant privileges to role
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "GRANT SELECT ON ANY TO ROLE role1",
"User root (ID=0) requests authority on object role1 with result true"),
// Grant role to user
Arrays.asList(
@@ -568,9 +622,9 @@ public class IoTDBAuditLogBasicIT {
"GLOBAL",
"true",
"null",
- "GRANT ROLE role1 TO user1",
- "User root (ID=0) requests authority on object user: user1, role: role1 with result true"),
- // List user TODO: whether to include user object?
+ "GRANT ROLE role1 TO user2",
+ "User root (ID=0) requests authority on object user: user2, role: role1 with result true"),
+ // List user, the user object is null since the root can list all users
Arrays.asList(
"node_1",
"u_0",
@@ -582,9 +636,9 @@ public class IoTDBAuditLogBasicIT {
"GLOBAL",
"true",
"null",
- "LIST USER",
+ "list user",
"User root (ID=0) requests authority on object null with result true"),
- // List role TODO: whether to include role object?
+ // List role, the role object is null since the root can list all roles
Arrays.asList(
"node_1",
"u_0",
@@ -596,41 +650,109 @@ public class IoTDBAuditLogBasicIT {
"GLOBAL",
"true",
"null",
- "LIST ROLE",
+ "list role",
"User root (ID=0) requests authority on object null with result true"),
- // Drop role
+ // Root logout, twice for both read and write connections
Arrays.asList(
"node_1",
"u_0",
"root",
"127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
+ "LOGOUT",
+ "CONTROL",
+ "null",
"GLOBAL",
"true",
- "null",
- "DROP ROLE role1",
- "User root (ID=0) requests authority on object role1 with result true"),
- // Drop user
+ "",
+ "",
+ "is closing"),
Arrays.asList(
"node_1",
"u_0",
"root",
"127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ // =============================Audit user user1=============================
+ // User1 login, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user1 (ID=10000), opens Session"),
+ // List privileges of user1
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
"OBJECT_AUTHENTICATION",
- "DDL",
- "[SECURITY]",
+ "QUERY",
+ "null",
"GLOBAL",
"true",
"null",
- "DROP USER user1",
- "User root (ID=0) requests authority on object user1 with result true"),
+ "LIST PRIVILEGES OF USER user1",
+ "User user1 (ID=10000) requests authority on object user1 with result true"),
+ // Use database, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user1 (ID=10000) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10000",
+ "user1",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user1 (ID=10000) requests authority on object test with result true"),
// Insert into table
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
"OBJECT_AUTHENTICATION",
"DML",
@@ -639,12 +761,12 @@ public class IoTDBAuditLogBasicIT {
"true",
"test",
"INSERT INTO table1(time, t1, a1, s1) values(...)",
- "User root (ID=0) requests authority on object table1 with result true"),
+ "User user1 (ID=10000) requests authority on object table1 with result true"),
// Select from table, including fetch device
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
"OBJECT_AUTHENTICATION",
"QUERY",
@@ -653,11 +775,11 @@ public class IoTDBAuditLogBasicIT {
"true",
"test",
"SELECT * FROM table1",
- "User root (ID=0) requests authority on object table1 with result true"),
+ "User user1 (ID=10000) requests authority on object table1 with result true"),
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
"OBJECT_AUTHENTICATION",
"QUERY",
@@ -666,65 +788,424 @@ public class IoTDBAuditLogBasicIT {
"true",
"test",
"fetch device for query",
- "User root (ID=0) requests authority on object table1 with result true"),
- // Delete table
+ "User user1 (ID=10000) requests authority on object table1 with result true"),
+ // Update table
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
"OBJECT_AUTHENTICATION",
"DML",
- "[DELETE]",
+ "[INSERT]",
"OBJECT",
"true",
"test",
- "DELETE FROM table1",
- "User root (ID=0) requests authority on object table1 with result true"),
- // Drop table
+ "UPDATE table1 SET a1 = t1",
+ "User user1 (ID=10000) requests authority on object table1 with result true"),
+ // Delete from table
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
"OBJECT_AUTHENTICATION",
- "DDL",
- "[DROP]",
+ "DML",
+ "[DELETE]",
"OBJECT",
"true",
"test",
- "DROP TABLE table1",
- "User root (ID=0) requests authority on object table1 with result true"),
- // Drop database
+ "DELETE FROM table1",
+ "User user1 (ID=10000) requests authority on object table1 with result true"),
+ // User1 logout, twice for both read and write connections
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "DDL",
- "[DROP]",
- "OBJECT",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
"true",
- "test",
- "DROP DATABASE IF EXISTS test",
- "User root (ID=0) requests authority on object test with result true"),
- // Select audit log
+ "",
+ "",
+ "is closing"),
Arrays.asList(
"node_1",
- "u_0",
- "root",
+ "u_10000",
+ "user1",
"127.0.0.1",
- "OBJECT_AUTHENTICATION",
- "QUERY",
- "[SELECT]",
- "OBJECT",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
"true",
- "__audit",
- "SELECT * FROM __audit.audit_log ORDER BY TIME",
- "User root (ID=0) requests authority on object __audit with result true"),
- Arrays.asList(
- "node_1",
+ "",
+ "",
+ "is closing"),
+ // =============================Audit user user2=============================
+ // User2 login, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User user2 (ID=10001), opens Session"),
+ // List privileges of user2
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "LIST PRIVILEGES OF USER user2",
+ "User user2 (ID=10001) requests authority on object user2 with result true"),
+ // List privileges of role1
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "LIST PRIVILEGES OF ROLE role1",
+ "User user2 (ID=10001) requests authority on object role1 with result true"),
+ // List user, only him/herself
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "null",
+ "GLOBAL",
+ "true",
+ "null",
+ "list user",
+ "User user2 (ID=10001) requests authority on object user2 with result true"),
+ // Use database, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user2 (ID=10001) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User user2 (ID=10001) requests authority on object test with result true"),
+ // Failed to insert since no privilege
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[INSERT]",
+ "OBJECT",
+ "false",
+ "test",
+ "INSERT INTO table1(time, t1, a1, s1) values(...)",
+ "User user2 (ID=10001) requests authority on object table1 with result false"),
+ // Select from table1, including fetch device
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "SELECT * FROM table1",
+ "User user2 (ID=10001) requests authority on object table1 with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "fetch device for query",
+ "User user2 (ID=10001) requests authority on object table1 with result true"),
+ // Update table
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[INSERT]",
+ "OBJECT",
+ "false",
+ "test",
+ "UPDATE table1 SET a1 = t1",
+ "User user2 (ID=10001) requests authority on object table1 with result false"),
+ // Delete from table
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DML",
+ "[DELETE]",
+ "OBJECT",
+ "false",
+ "test",
+ "DELETE FROM table1",
+ "User user2 (ID=10001) requests authority on object table1 with result false"),
+ // User2 logout, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ Arrays.asList(
+ "node_1",
+ "u_10001",
+ "user2",
+ "127.0.0.1",
+ "LOGOUT",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "is closing"),
+ // =============================Audit user root=============================
+ // Root login, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "LOGIN",
+ "CONTROL",
+ "null",
+ "GLOBAL",
+ "true",
+ "",
+ "",
+ "IoTDB: Login status: Login successfully. User root (ID=0), opens Session"),
+ // Use database, twice for both read and write connections
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[READ_SCHEMA]",
+ "OBJECT",
+ "true",
+ "test",
+ "USE test",
+ "User root (ID=0) requests authority on object test with result true"),
+ // Drop table
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[DROP]",
+ "OBJECT",
+ "true",
+ "test",
+ "DROP TABLE table1",
+ "User root (ID=0) requests authority on object table1 with result true"),
+ // Drop database
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[DROP]",
+ "OBJECT",
+ "true",
+ "test",
+ "DROP DATABASE IF EXISTS test",
+ "User root (ID=0) requests authority on object test with result true"),
+ // Revoke user privilege
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "test",
+ "REVOKE SELECT,ALTER,INSERT,DELETE ON TEST.TABLE1 FROM USER user1",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ // Revoke role privilege
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "REVOKE SELECT ON ANY FROM ROLE role1",
+ "User root (ID=0) requests authority on object role1 with result true"),
+ // Drop user
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "DROP USER user1",
+ "User root (ID=0) requests authority on object user1 with result true"),
+ // Drop user
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "DROP USER user2",
+ "User root (ID=0) requests authority on object user2 with result true"),
+ // Drop role
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "DDL",
+ "[SECURITY]",
+ "GLOBAL",
+ "true",
+ "null",
+ "DROP ROLE role1",
+ "User root (ID=0) requests authority on object role1 with result true"),
+ // Select audit log
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "__audit",
+ "SELECT * FROM __audit.audit_log ORDER BY TIME",
+ "User root (ID=0) requests authority on object __audit with result true"),
+ Arrays.asList(
+ "node_1",
"u_0",
"root",
"127.0.0.1",
@@ -740,34 +1221,56 @@ public class IoTDBAuditLogBasicIT {
Stream.of(11, 12).collect(Collectors.toSet());
@Test
- public void basicAuditLogTestForTableModel() throws SQLException {
- try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
- Statement statement = connection.createStatement()) {
- for (String sql : TABLE_MODEL_AUDIT_SQLS) {
+ public void basicAuditLogTestForTableModel() throws SQLException, InterruptedException {
+ Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement();
+ for (String sql : TABLE_MODEL_AUDIT_SQLS_USER_ROOT) {
+ statement.execute(sql);
+ }
+ closeConnectionCompletely(connection);
+ connection =
+ EnvFactory.getEnv().getConnection("user1", "IoTDB@2025abc", BaseEnv.TABLE_SQL_DIALECT);
+ statement = connection.createStatement();
+ for (String sql : TABLE_MODEL_AUDIT_SQLS_USER_USER1) {
+ statement.execute(sql);
+ }
+ closeConnectionCompletely(connection);
+ connection =
+ EnvFactory.getEnv().getConnection("user2", "IoTDB@2025abc", BaseEnv.TABLE_SQL_DIALECT);
+ statement = connection.createStatement();
+ for (String sql : TABLE_MODEL_AUDIT_SQLS_USER_USER2) {
+ try {
statement.execute(sql);
+ } catch (SQLException e) {
+ // Ignore, only record audit log
}
- int count = 0;
- ResultSet resultSet = statement.executeQuery("SELECT * FROM __audit.audit_log ORDER BY TIME");
- while (resultSet.next()) {
- LOGGER.info("Expected audit log: {}", TABLE_MODEL_AUDIT_FIELDS.get(count));
- List<String> actualFields = new ArrayList<>();
- for (int i = 1; i <= 12; i++) {
- actualFields.add(resultSet.getString(i + 1));
- }
- LOGGER.info("Actual audit log: {}", actualFields);
- List<String> expectedFields = TABLE_MODEL_AUDIT_FIELDS.get(count);
- for (int i = 1; i <= 12; i++) {
- if (TABLE_INDEX_FOR_CONTAIN.contains(i)) {
- Assert.assertTrue(resultSet.getString(i + 1).contains(expectedFields.get(i - 1)));
- continue;
- }
- Assert.assertEquals(expectedFields.get(i - 1), resultSet.getString(i + 1));
+ }
+ closeConnectionCompletely(connection);
+ connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ statement = connection.createStatement();
+ for (String sql : TABLE_MODEL_AUDIT_SQLS_USER_ROOT_FINAL) {
+ statement.execute(sql);
+ }
+ int count = 0;
+ ResultSet resultSet = statement.executeQuery("SELECT * FROM __audit.audit_log ORDER BY TIME");
+ while (resultSet.next()) {
+ LOGGER.info("Expected audit log: {}", TABLE_MODEL_AUDIT_FIELDS.get(count));
+ List<String> actualFields = new ArrayList<>();
+ for (int i = 1; i <= 12; i++) {
+ actualFields.add(resultSet.getString(i + 1));
+ }
+ LOGGER.info("Actual audit log: {}", actualFields);
+ List<String> expectedFields = TABLE_MODEL_AUDIT_FIELDS.get(count);
+ for (int i = 1; i <= 12; i++) {
+ if (TABLE_INDEX_FOR_CONTAIN.contains(i)) {
+ Assert.assertTrue(resultSet.getString(i + 1).contains(expectedFields.get(i - 1)));
+ continue;
}
-
- count++;
+ Assert.assertEquals(expectedFields.get(i - 1), resultSet.getString(i + 1));
}
- Assert.assertEquals(TABLE_MODEL_AUDIT_FIELDS.size(), count);
+ count++;
}
+ Assert.assertEquals(TABLE_MODEL_AUDIT_FIELDS.size(), count);
}
private static final List<String> TREE_MODEL_AUDIT_SQLS =
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
index d7a35f39913..8c3fbb2253d 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
@@ -284,23 +284,31 @@ public class AccessControlImpl implements AccessControl {
authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity);
return;
case LIST_USER_PRIV:
- auditEntity
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
- if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()
- || statement.getUserName().equals(userName)) {
+ auditEntity.setAuditLogOperation(AuditLogOperation.QUERY);
+ if (statement.getUserName().equals(userName)) {
+ // No need any privilege to list him/herself
ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName);
return;
}
+ // Require SECURITY privilege to list other users' privileges
+ if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
+ ITableAuthCheckerImpl.recordAuditLog(
+ auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true),
+ statement::getUserName);
+ return;
+ }
authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity);
return;
case LIST_USER:
- auditEntity.setAuditLogOperation(AuditLogOperation.QUERY);
+ auditEntity.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true);
if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_USER)) {
+ // No need to check privilege to list himself/herself
statement.setUserName(userName);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity, statement::getUserName);
} else {
- auditEntity.setPrivilegeType(PrivilegeType.SECURITY);
- ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName);
+ // Require SECURITY privilege to list other users
+ ITableAuthCheckerImpl.recordAuditLog(
+ auditEntity.setPrivilegeType(PrivilegeType.SECURITY), statement::getUserName);
}
return;
case CREATE_ROLE:
@@ -343,14 +351,19 @@ public class AccessControlImpl implements AccessControl {
}
return;
case LIST_ROLE_PRIV:
- auditEntity
- .setAuditLogOperation(AuditLogOperation.QUERY)
- .setPrivilegeType(PrivilegeType.SECURITY);
- if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()
- || AuthorityChecker.checkRole(userName, statement.getRoleName())) {
+ auditEntity.setAuditLogOperation(AuditLogOperation.QUERY);
+ if (AuthorityChecker.checkRole(userName, statement.getRoleName())) {
+ // No need any privilege to list his/hers own role
ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getRoleName);
return;
}
+ // Require SECURITY privilege to list other roles' privileges
+ if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
+ ITableAuthCheckerImpl.recordAuditLog(
+ auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true),
+ statement::getRoleName);
+ return;
+ }
authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity);
return;
case GRANT_ROLE_ANY: