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 <[email protected]> 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;
