This is an automated email from the ASF dual-hosted git repository.
yongzao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 2ed021362c7 Audit log patch for both tree and table models (#16497)
2ed021362c7 is described below
commit 2ed021362c7068f6cf710e850f5db50cbcd36db8
Author: Yongzao <[email protected]>
AuthorDate: Sat Sep 27 21:25:10 2025 +0800
Audit log patch for both tree and table models (#16497)
---
.../iotdb/db/it/audit/IoTDBAuditLogBasicIT.java | 579 ++++++++++++++++++++-
.../org/apache/iotdb/db/audit/DNAuditLogger.java | 20 +-
.../org/apache/iotdb/db/auth/AuthorityChecker.java | 24 +-
.../protocol/thrift/IoTDBDataNodeReceiver.java | 8 +-
.../sink/protocol/writeback/WriteBackSink.java | 7 +-
.../PipePlanTreePrivilegeParseVisitor.java | 5 +-
.../db/protocol/client/DataNodeInternalClient.java | 7 +-
.../iotdb/db/protocol/mqtt/MPPPublishHandler.java | 7 +-
.../rest/handler/AuthorizationHandler.java | 12 +-
.../protocol/thrift/impl/ClientRPCServiceImpl.java | 219 +++++++-
.../analyze/schema/AutoCreateSchemaExecutor.java | 3 +-
.../relational/analyzer/StatementAnalyzer.java | 37 +-
.../plan/relational/security/AccessControl.java | 3 +-
.../relational/security/AccessControlImpl.java | 86 ++-
.../relational/security/AllowAllAccessControl.java | 4 +-
.../security/TreeAccessCheckContext.java | 21 +-
.../security/TreeAccessCheckVisitor.java | 39 +-
.../iotdb/commons/audit/AbstractAuditLogger.java | 2 +-
18 files changed, 926 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 0f831ad8a74..4d96a41406c 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
@@ -27,9 +27,9 @@ import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
import org.apache.iotdb.itbase.env.BaseEnv;
-import org.junit.AfterClass;
+import org.junit.After;
import org.junit.Assert;
-import org.junit.BeforeClass;
+import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -43,18 +43,20 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+/**
+ * This test class ensures the audit log behave exactly the same as we
expected, including the
+ * number, sequence and content of the audit logs.
+ */
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class})
public class IoTDBAuditLogBasicIT {
private static final Logger LOGGER =
LoggerFactory.getLogger(IoTDBAuditLogBasicIT.class);
-
- /**
- * Ensure the Audit log behave exactly the same as we expected, including
number, sequence and
- * content.
- */
private static final List<String> AUDIT_TABLE_COLUMNS =
Arrays.asList(
AbstractAuditLogger.AUDIT_LOG_NODE_ID,
@@ -93,8 +95,8 @@ public class IoTDBAuditLogBasicIT {
private static final String AUDITABLE_OPERATION_RESULT = "SUCCESS,FAIL";
- @BeforeClass
- public static void setUp() throws SQLException {
+ @Before
+ public void setUp() throws SQLException {
EnvFactory.getEnv()
.getConfig()
.getCommonConfig()
@@ -130,8 +132,8 @@ public class IoTDBAuditLogBasicIT {
}
}
- @AfterClass
- public static void tearDown() {
+ @After
+ public void tearDown() {
EnvFactory.getEnv().cleanClusterEnvironment();
}
@@ -145,13 +147,22 @@ public class IoTDBAuditLogBasicIT {
"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",
"INSERT INTO table1(time, t1, a1, s1) values(1, 't1', 'a1', 's1')",
+ "SELECT * FROM table1",
"DELETE FROM table1",
"DROP TABLE table1",
"DROP DATABASE IF EXISTS test");
private static final List<List<String>> TABLE_MODEL_AUDIT_FIELDS =
Arrays.asList(
- // Start DataNode
+ // Start audit service
Arrays.asList(
"node_1",
"u_none",
@@ -165,7 +176,7 @@ public class IoTDBAuditLogBasicIT {
"null",
"null",
"Successfully start the Audit service with configurations
(auditableOperationType [DDL, DML, QUERY, CONTROL], auditableOperationLevel
GLOBAL, auditableOperationResult SUCCESS,FAIL)"),
- // Show audit database TODO: Fix typo in tree model
+ // Show audit database
Arrays.asList(
"node_1",
"u_0",
@@ -174,10 +185,10 @@ public class IoTDBAuditLogBasicIT {
"OBJECT_AUTHENTICATION",
"QUERY",
"[MANAGE_DATABASE]",
- "GLOBAL",
+ "OBJECT",
"true",
"[root.__audit]",
- "null",
+ "SHOW DATABASES root.__audit",
"User root (ID=0) requests authority on object root.__audit with
result true"),
// Desc audit table
Arrays.asList(
@@ -262,7 +273,7 @@ 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 TODO: Find out why twice
+ // Use database, twice for both read and write connections
Arrays.asList(
"node_1",
"u_0",
@@ -297,8 +308,8 @@ public class IoTDBAuditLogBasicIT {
"127.0.0.1",
"OBJECT_AUTHENTICATION",
"DDL",
- "[SYSTEM]",
- "GLOBAL",
+ "[CREATE]",
+ "OBJECT",
"true",
"test",
"CREATE TABLE table1(t1 STRING TAG, a1 STRING ATTRIBUTE, s1 TEXT
FIELD)",
@@ -331,6 +342,118 @@ public class IoTDBAuditLogBasicIT {
"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 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 role
+ 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 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 user1",
+ "User root (ID=0) requests authority on object user: user1,
role: role1 with result true"),
+ // List user TODO: whether to include user object?
+ 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 TODO: whether to include role object?
+ 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"),
+ // 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"),
+ // 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"),
// Insert into table
Arrays.asList(
"node_1",
@@ -343,9 +466,36 @@ public class IoTDBAuditLogBasicIT {
"OBJECT",
"true",
"test",
- "INSERT INTO table1(time, t1, a1, s1) values(1, 't1', 'a1',
's1')",
+ "INSERT INTO table1(time, t1, a1, s1) values(...)",
"User root (ID=0) requests authority on object table1 with
result true"),
- // Delete table TODO: find the delete SQL
+ // Select from table, including fetch device
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "SELECT * FROM table1",
+ "User root (ID=0) requests authority on object table1 with
result true"),
+ Arrays.asList(
+ "node_1",
+ "u_0",
+ "root",
+ "127.0.0.1",
+ "OBJECT_AUTHENTICATION",
+ "QUERY",
+ "[SELECT]",
+ "OBJECT",
+ "true",
+ "test",
+ "fetch device for query",
+ "User root (ID=0) requests authority on object table1 with
result true"),
+ // Delete table
Arrays.asList(
"node_1",
"u_0",
@@ -357,7 +507,21 @@ public class IoTDBAuditLogBasicIT {
"OBJECT",
"true",
"test",
- "null",
+ "DELETE FROM table1",
+ "User root (ID=0) requests authority on object table1 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(
@@ -373,7 +537,7 @@ public class IoTDBAuditLogBasicIT {
"test",
"DROP DATABASE IF EXISTS test",
"User root (ID=0) requests authority on object test with result
true"),
- // Select audit log TODO: find out why twice
+ // Select audit log
Arrays.asList(
"node_1",
"u_0",
@@ -385,7 +549,7 @@ public class IoTDBAuditLogBasicIT {
"OBJECT",
"true",
"__audit",
- "null",
+ "SELECT * FROM __audit.audit_log ORDER BY TIME",
"User root (ID=0) requests authority on object __audit with
result true"),
Arrays.asList(
"node_1",
@@ -398,8 +562,10 @@ public class IoTDBAuditLogBasicIT {
"OBJECT",
"true",
"__audit",
- "null",
+ "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());
@Test
public void basicAuditLogTestForTableModel() throws SQLException {
@@ -409,7 +575,7 @@ public class IoTDBAuditLogBasicIT {
statement.execute(sql);
}
int count = 0;
- ResultSet resultSet = statement.executeQuery("SELECT * FROM
__audit.audit_log");
+ 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<>();
@@ -418,13 +584,372 @@ public class IoTDBAuditLogBasicIT {
}
LOGGER.info("Actual audit log: {}", actualFields);
List<String> expectedFields = TABLE_MODEL_AUDIT_FIELDS.get(count);
- for (int i = 1; i <= 11; i++) {
+ 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));
}
-
Assert.assertTrue(resultSet.getString(13).contains(expectedFields.get(11)));
+
count++;
}
Assert.assertEquals(TABLE_MODEL_AUDIT_FIELDS.size(), count);
}
}
+
+ private static final List<String> TREE_MODEL_AUDIT_SQLS =
+ 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",
+ "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",
+ "DELETE DATABASE root.test");
+ private static final List<List<String>> TREE_MODEL_AUDIT_FIELDS =
+ Arrays.asList(
+ // Start audit service
+ Arrays.asList(
+ "root.__audit.log.node_1.u_none",
+ "true",
+ "GLOBAL",
+ "[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"),
+ // 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"),
+ // 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"),
+ // Create database
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[MANAGE_DATABASE]",
+ "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"),
+ // 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.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.d2.s1,
root.test.d2.s2] with result true",
+ "CREATE ALIGNED TIMESERIES root.test.d2(s1 BOOLEAN, s2 INT64)",
+ "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.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"),
+ // 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 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_DATA, WRITE_DATA 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: user1,
role: role1 with result true",
+ "GRANT ROLE role1 TO user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // List user TODO: whether to include user object?
+ 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 TODO: whether to include role object?
+ 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"),
+ // Drop 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",
+ "DROP ROLE role1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Drop 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",
+ "DROP USER user1",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Insert into (aligned) timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d1.s2]
with result true",
+ "INSERT INTO root.test.d1(timestamp,s2) VALUES(...)",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d2.s1,
root.test.d2.s2] with result true",
+ "INSERT INTO root.test.d2(timestamp,s1,s2) ALIGNED VALUES(...)",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Select all timeseries
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[READ_DATA]",
+ "null",
+ "QUERY",
+ "User root (ID=0) requests authority on object [root.test.**]
with result true",
+ "SELECT ** FROM root.test",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Delete timeseries data
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[WRITE_DATA]",
+ "null",
+ "DML",
+ "User root (ID=0) requests authority on object [root.test.d2]
with result true",
+ "DELETE FROM root.test.d2",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Drop 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.s2]
with result true",
+ "DROP TIMESERIES root.test.d1.s2",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Set TTL to devices
+ 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.** 360000",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Delete database
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[MANAGE_DATABASE]",
+ "[root.test]",
+ "DDL",
+ "User root (ID=0) requests authority on object [root.test] with
result true",
+ "DELETE DATABASE root.test",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"),
+ // Select audit log
+ Arrays.asList(
+ "root.__audit.log.node_1.u_0",
+ "true",
+ "OBJECT",
+ "[READ_DATA]",
+ "null",
+ "QUERY",
+ "User root (ID=0) requests authority on object
[root.__audit.log.**.*] with result true",
+ "SELECT * FROM root.__audit.log.** ORDER BY TIME ALIGN BY
DEVICE",
+ "OBJECT_AUTHENTICATION",
+ "127.0.0.1",
+ "root"));
+ private static final Set<Integer> TREE_INDEX_FOR_CONTAIN =
+ 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) {
+ 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;
+ }
+ Assert.assertEquals(expectedFields.get(i - 1), resultSet.getString(i
+ 1));
+ }
+
+ 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 c26bbb1a38d..1fdb138592f 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
@@ -77,6 +77,8 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import static
org.apache.iotdb.db.pipe.receiver.protocol.legacy.loader.ILoader.SCHEMA_FETCHER;
@@ -159,6 +161,20 @@ public class DNAuditLogger extends AbstractAuditLogger {
AUDIT_LOG_LOG
});
insertStatement.setAligned(false);
+ String sqlString = auditLogFields.getSqlString();
+ if (sqlString != null) {
+ if (sqlString.toUpperCase().startsWith("CREATE USER")) {
+ sqlString = String.join(" ", Arrays.asList(sqlString.split("
")).subList(0, 3)) + " ...";
+ }
+ Pattern pattern = Pattern.compile("(?i)(values)\\([^)]*\\)");
+ Matcher matcher = pattern.matcher(sqlString);
+ StringBuffer sb = new StringBuffer();
+ while (matcher.find()) {
+ matcher.appendReplacement(sb, matcher.group(1) + "(...)");
+ }
+ matcher.appendTail(sb);
+ sqlString = sb.toString();
+ }
insertStatement.setValues(
new Object[] {
new Binary(username == null ? "null" : username,
TSFileConfig.STRING_CHARSET),
@@ -178,9 +194,7 @@ public class DNAuditLogger extends AbstractAuditLogger {
new Binary(
auditLogFields.getDatabase() == null ? "null" :
auditLogFields.getDatabase(),
TSFileConfig.STRING_CHARSET),
- new Binary(
- auditLogFields.getSqlString() == null ? "null" :
auditLogFields.getSqlString(),
- TSFileConfig.STRING_CHARSET),
+ new Binary(sqlString == null ? "null" : sqlString,
TSFileConfig.STRING_CHARSET),
new Binary(log == null ? "null" : log, TSFileConfig.STRING_CHARSET)
});
insertStatement.setDataTypes(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
index 31a7ffe3a11..bbd9ada2b9e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
@@ -45,6 +45,7 @@ import
org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult;
import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
import
org.apache.iotdb.db.queryengine.plan.relational.security.AccessControlImpl;
import
org.apache.iotdb.db.queryengine.plan.relational.security.ITableAuthCheckerImpl;
+import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckContext;
import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckVisitor;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.RelationalAuthorStatement;
import org.apache.iotdb.db.queryengine.plan.statement.Statement;
@@ -176,22 +177,21 @@ public class AuthorityChecker {
}
}
- /** Check whether specific Session has the authorization to given plan. */
- public static TSStatus checkAuthority(Statement statement, IClientSession
session) {
+ public static TSStatus checkAuthority(Statement statement, IAuditEntity
auditEntity) {
long startTime = System.nanoTime();
try {
+ if (auditEntity instanceof TreeAccessCheckContext) {
+ return accessControl.checkPermissionBeforeProcess(
+ statement, (TreeAccessCheckContext) auditEntity);
+ }
return accessControl.checkPermissionBeforeProcess(
statement,
- new UserEntity(session.getUserId(), session.getUsername(),
session.getClientAddress()));
- } finally {
- PERFORMANCE_OVERVIEW_METRICS.recordAuthCost(System.nanoTime() -
startTime);
- }
- }
-
- public static TSStatus checkAuthority(Statement statement, UserEntity
userEntity) {
- long startTime = System.nanoTime();
- try {
- return accessControl.checkPermissionBeforeProcess(statement, userEntity);
+ (TreeAccessCheckContext)
+ new TreeAccessCheckContext(
+ auditEntity.getUserId(),
+ auditEntity.getUsername(),
+ auditEntity.getCliHostname())
+ .setSqlString(auditEntity.getSqlString()));
} finally {
PERFORMANCE_OVERVIEW_METRICS.recordAuthCost(System.nanoTime() -
startTime);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
index 3544e6736f6..1511933ad35 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
@@ -86,6 +86,7 @@ import
org.apache.iotdb.db.queryengine.plan.execution.config.executor.ClusterCon
import
org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.CreateDBTask;
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.view.AlterLogicalViewNode;
+import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckContext;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.PipeEnriched;
import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
import org.apache.iotdb.db.queryengine.plan.statement.Statement;
@@ -880,7 +881,12 @@ public class IoTDBDataNodeReceiver extends
IoTDBFileReceiver {
// For table model, the authority check is done in inner execution. No
need to check here
if (!isTableModelStatement) {
final TSStatus permissionCheckStatus =
- AuthorityChecker.checkAuthority(statement, clientSession);
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (permissionCheckStatus.getCode() !=
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
PipeLogger.log(
LOGGER::warn,
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/writeback/WriteBackSink.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/writeback/WriteBackSink.java
index 53af1bed26a..fddb9f2f1a9 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/writeback/WriteBackSink.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/writeback/WriteBackSink.java
@@ -45,6 +45,7 @@ import
org.apache.iotdb.db.queryengine.plan.execution.config.executor.ClusterCon
import
org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.CreateDBTask;
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertNode;
+import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckContext;
import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
import org.apache.iotdb.db.queryengine.plan.statement.Statement;
import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertBaseStatement;
@@ -481,7 +482,11 @@ public class WriteBackSink implements PipeConnector {
if (useEventUserName && userName != null) {
session.setUsername(userName);
}
- final TSStatus permissionCheckStatus =
AuthorityChecker.checkAuthority(statement, session);
+ final TSStatus permissionCheckStatus =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ session.getUserId(), session.getUsername(),
session.getClientAddress()));
if (permissionCheckStatus.getCode() !=
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
PipeLogger.log(
LOGGER::warn,
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/schemaregion/PipePlanTreePrivilegeParseVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/schemaregion/PipePlanTreePrivilegeParseVisitor.java
index 260f6bd1d37..5967097418d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/schemaregion/PipePlanTreePrivilegeParseVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/schemaregion/PipePlanTreePrivilegeParseVisitor.java
@@ -20,7 +20,6 @@
package org.apache.iotdb.db.pipe.source.schemaregion;
import org.apache.iotdb.commons.audit.IAuditEntity;
-import org.apache.iotdb.commons.audit.UserEntity;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.exception.auth.AccessDeniedException;
import org.apache.iotdb.commons.path.MeasurementPath;
@@ -328,7 +327,9 @@ public class PipePlanTreePrivilegeParseVisitor
final DeleteDataNode node, final IAuditEntity auditEntity) {
final List<MeasurementPath> intersectedPaths =
TreeAccessCheckVisitor.getIntersectedPaths4Pipe(
- node.getPathList(), new TreeAccessCheckContext((UserEntity)
auditEntity));
+ node.getPathList(),
+ new TreeAccessCheckContext(
+ auditEntity.getUserId(), auditEntity.getUsername(),
auditEntity.getCliHostname()));
if (!skip && !intersectedPaths.equals(node.getPathList())) {
throw new AccessDeniedException("Not has privilege to transfer plan: " +
node);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/DataNodeInternalClient.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/DataNodeInternalClient.java
index d96151b2e93..227f8731cae 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/DataNodeInternalClient.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/DataNodeInternalClient.java
@@ -38,6 +38,7 @@ import
org.apache.iotdb.db.queryengine.plan.analyze.schema.ISchemaFetcher;
import org.apache.iotdb.db.queryengine.plan.execution.ExecutionResult;
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
+import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckContext;
import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
import org.apache.iotdb.db.queryengine.plan.statement.StatementType;
import
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertMultiTabletsStatement;
@@ -98,7 +99,11 @@ public class DataNodeInternalClient {
public TSStatus insertTablets(InsertMultiTabletsStatement statement) {
try {
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement, session);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ session.getUserId(), session.getUsername(),
session.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/mqtt/MPPPublishHandler.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/mqtt/MPPPublishHandler.java
index a6464a56c49..c993da93b73 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/mqtt/MPPPublishHandler.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/mqtt/MPPPublishHandler.java
@@ -37,6 +37,7 @@ import
org.apache.iotdb.db.queryengine.plan.analyze.schema.ISchemaFetcher;
import org.apache.iotdb.db.queryengine.plan.execution.ExecutionResult;
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
+import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckContext;
import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowStatement;
import
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertTabletStatement;
@@ -279,7 +280,11 @@ public class MPPPublishHandler extends
AbstractInterceptHandler {
}
statement.setAligned(false);
- tsStatus = AuthorityChecker.checkAuthority(statement, session);
+ tsStatus =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ session.getUserId(), session.getUsername(),
session.getClientAddress()));
if (tsStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
LOG.warn(tsStatus.message);
} else {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/handler/AuthorizationHandler.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/handler/AuthorizationHandler.java
index 989f5211670..3c30e3e95a9 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/handler/AuthorizationHandler.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/handler/AuthorizationHandler.java
@@ -19,29 +19,19 @@ package org.apache.iotdb.db.protocol.rest.handler;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.audit.UserEntity;
-import org.apache.iotdb.commons.auth.entity.User;
import org.apache.iotdb.db.auth.AuthorityChecker;
-import org.apache.iotdb.db.auth.BasicAuthorityCache;
-import org.apache.iotdb.db.auth.ClusterAuthorityFetcher;
-import org.apache.iotdb.db.auth.IAuthorityFetcher;
import org.apache.iotdb.db.protocol.rest.model.ExecutionStatus;
import org.apache.iotdb.db.queryengine.plan.statement.Statement;
import org.apache.iotdb.rpc.TSStatusCode;
-import org.apache.ratis.util.MemoizedSupplier;
-
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
public class AuthorizationHandler {
- private static final MemoizedSupplier<IAuthorityFetcher> authorityFetcher =
- MemoizedSupplier.valueOf(() -> new ClusterAuthorityFetcher(new
BasicAuthorityCache()));
-
public Response checkAuthority(SecurityContext securityContext, Statement
statement) {
String userName = securityContext.getUserPrincipal().getName();
- User user = authorityFetcher.get().getUser(userName);
- long userId = user == null ? -1 : user.getUserId();
+ long userId = AuthorityChecker.getUserId(userName).orElse(-1L);
TSStatus status =
AuthorityChecker.checkAuthority(statement, new UserEntity(userId,
userName, ""));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
index fb7a0813002..74c2f6eda6b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/ClientRPCServiceImpl.java
@@ -88,6 +88,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.Ta
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableDeviceSchemaCache;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableId;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TreeDeviceSchemaCacheManager;
+import
org.apache.iotdb.db.queryengine.plan.relational.security.TreeAccessCheckContext;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SetSqlDialect;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Use;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.parser.ParsingException;
@@ -346,7 +347,14 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
false);
} else {
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(s, clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ s,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress())
+ .setSqlString(statement));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode())
{
return RpcUtils.getTSExecuteStatementResp(status);
}
@@ -521,7 +529,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
Statement s = StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(s, clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ s,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return RpcUtils.getTSExecuteStatementResp(status);
}
@@ -610,7 +624,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
try {
Statement s = StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(s, clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ s,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return RpcUtils.getTSExecuteStatementResp(status);
}
@@ -701,7 +721,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
try {
Statement s = StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(s, clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ s,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return RpcUtils.getTSExecuteStatementResp(status);
}
@@ -1145,7 +1171,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
// cache miss
Statement s = StatementGenerator.createStatement(convert(req));
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(s, clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ s,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return RpcUtils.getTSExecuteStatementResp(status);
}
@@ -1540,7 +1572,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
// Step 1: Create SetStorageGroupStatement
DatabaseSchemaStatement statement =
StatementGenerator.createStatement(storageGroup);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -1578,7 +1616,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
// Step 1: transfer from TSCreateTimeseriesReq to Statement
CreateTimeSeriesStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -1622,7 +1666,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
// Step 1: transfer from CreateAlignedTimeSeriesReq to Statement
CreateAlignedTimeSeriesStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -1666,7 +1716,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
// Step 1: transfer from CreateMultiTimeSeriesReq to Statement
CreateMultiTimeSeriesStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -1706,7 +1762,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
StatementGenerator.createDeleteTimeSeriesStatement(path);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -1745,7 +1807,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
DeleteDatabaseStatement statement =
StatementGenerator.createStatement(storageGroups);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -1825,7 +1893,14 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
false);
} else {
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(s,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ s,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress())
+ .setSqlString(statement));
if (status.getCode() !=
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2015,7 +2090,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
}
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2075,7 +2156,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
}
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2137,7 +2224,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
}
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2201,7 +2294,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
}
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2270,7 +2369,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
}
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2333,7 +2438,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
// permission check for tree model, table model does this in the
analysis stage
if (!req.isWriteToTable()) {
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2404,7 +2515,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
}
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2494,7 +2611,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
DeleteDataStatement statement = StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2554,7 +2677,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
CreateSchemaTemplateStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2717,7 +2846,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
try {
IClientSession clientSession =
SESSION_MANAGER.getCurrSessionAndUpdateIdleTime();
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
resp.setStatus(status);
return resp;
@@ -2796,7 +2931,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
SetSchemaTemplateStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2837,7 +2978,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
UnsetSchemaTemplateStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2878,7 +3025,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
DropSchemaTemplateStatement statement =
StatementGenerator.createStatement(req);
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2917,7 +3070,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
StatementGenerator.createBatchActivateTemplateStatement(req.getDevicePathList());
// permission check
- TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -3007,7 +3166,13 @@ public class ClientRPCServiceImpl implements
IClientRPCServiceWithHandler {
final InsertRowStatement statement =
StatementGenerator.createStatement(req);
// Permission check
- final TSStatus status = AuthorityChecker.checkAuthority(statement,
clientSession);
+ final TSStatus status =
+ AuthorityChecker.checkAuthority(
+ statement,
+ new TreeAccessCheckContext(
+ clientSession.getUserId(),
+ clientSession.getUsername(),
+ clientSession.getClientAddress()));
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
index 37be5691ee5..6806b224778 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/AutoCreateSchemaExecutor.java
@@ -495,8 +495,7 @@ class AutoCreateSchemaExecutor {
// Auto create timeseries and return the existing timeseries info
private List<MeasurementPath> executeInternalCreateTimeseriesStatement(
final Statement statement, final MPPQueryContext context) {
- final TSStatus status =
- AuthorityChecker.checkAuthority(statement,
context.getSession().getUserEntity());
+ final TSStatus status = AuthorityChecker.checkAuthority(statement,
context);
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
throw new IoTDBRuntimeException(status.getMessage(), status.getCode());
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 58e3e510418..408c52909e7 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -19,7 +19,6 @@
package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
-import org.apache.iotdb.commons.audit.UserEntity;
import org.apache.iotdb.commons.schema.table.TsTable;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
@@ -503,10 +502,7 @@ public class StatementAnalyzer {
accessControl.checkCanInsertIntoTable(
sessionContext.getUserName(),
new QualifiedObjectName(node.getDatabase(), node.getTableName()),
- new UserEntity(
- sessionContext.getUserId(),
- sessionContext.getUserName(),
- sessionContext.getCliHostname()));
+ queryContext);
final TranslationMap translationMap = analyzeTraverseDevice(node,
context, true);
final TsTable table =
DataNodeTableCache.getInstance().getTable(node.getDatabase(),
node.getTableName());
@@ -567,10 +563,7 @@ public class StatementAnalyzer {
accessControl.checkCanDeleteFromTable(
sessionContext.getUserName(),
new QualifiedObjectName(node.getDatabase(), node.getTableName()),
- new UserEntity(
- sessionContext.getUserId(),
- sessionContext.getUserName(),
- sessionContext.getCliHostname()));
+ queryContext);
final TsTable table =
DataNodeTableCache.getInstance().getTable(node.getDatabase(),
node.getTableName());
DataNodeTreeViewSchemaUtils.checkTableInWrite(node.getDatabase(), table);
@@ -645,12 +638,7 @@ public class StatementAnalyzer {
}
// verify access privileges
accessControl.checkCanInsertIntoTable(
- sessionContext.getUserName(),
- targetTable,
- new UserEntity(
- sessionContext.getUserId(),
- sessionContext.getUserName(),
- sessionContext.getCliHostname()));
+ sessionContext.getUserName(), targetTable, queryContext);
// verify the insert destination columns match the query
Optional<TableSchema> tableSchema =
metadata.getTableSchema(sessionContext, targetTable);
@@ -773,10 +761,7 @@ public class StatementAnalyzer {
new QualifiedObjectName(
AnalyzeUtils.getDatabaseName(node, queryContext),
node.getTable().getName().getSuffix()),
- new UserEntity(
- sessionContext.getUserId(),
- sessionContext.getUserName(),
- sessionContext.getCliHostname()));
+ queryContext);
AnalyzeUtils.analyzeDelete(node, queryContext);
analysis.setScope(node, ret);
@@ -3071,17 +3056,10 @@ public class StatementAnalyzer {
return resultScope;
}
}
-
QualifiedObjectName name = createQualifiedObjectName(sessionContext,
table.getName());
// access control
- accessControl.checkCanSelectFromTable(
- sessionContext.getUserName(),
- name,
- new UserEntity(
- sessionContext.getUserId(),
- sessionContext.getUserName(),
- sessionContext.getCliHostname()));
+ accessControl.checkCanSelectFromTable(sessionContext.getUserName(),
name, queryContext);
analysis.setRelationName(
table, QualifiedName.of(name.getDatabaseName(),
name.getObjectName()));
@@ -4505,10 +4483,7 @@ public class StatementAnalyzer {
accessControl.checkCanSelectFromTable(
sessionContext.getUserName(),
new QualifiedObjectName(node.getDatabase(), node.getTableName()),
- new UserEntity(
- sessionContext.getUserId(),
- sessionContext.getUserName(),
- sessionContext.getCliHostname()));
+ queryContext);
analyzeTraverseDevice(node, context, node.getWhere().isPresent());
final TsTable table =
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControl.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControl.java
index 6a1cf27d98a..35c04bf4c18 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControl.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControl.java
@@ -21,7 +21,6 @@ package
org.apache.iotdb.db.queryengine.plan.relational.security;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.audit.IAuditEntity;
-import org.apache.iotdb.commons.audit.UserEntity;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.exception.auth.AccessDeniedException;
import org.apache.iotdb.commons.path.PartialPath;
@@ -218,7 +217,7 @@ public interface AccessControl {
// ====================================== TREE
=============================================
- TSStatus checkPermissionBeforeProcess(Statement statement, UserEntity
userEntity);
+ TSStatus checkPermissionBeforeProcess(Statement statement,
TreeAccessCheckContext context);
/** called by load */
TSStatus checkFullPathWriteDataPermission(
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 bfffb794335..af1dec2f68a 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
@@ -22,7 +22,6 @@ package
org.apache.iotdb.db.queryengine.plan.relational.security;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.audit.AuditLogOperation;
import org.apache.iotdb.commons.audit.IAuditEntity;
-import org.apache.iotdb.commons.audit.UserEntity;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.exception.auth.AccessDeniedException;
@@ -107,7 +106,9 @@ public class AccessControlImpl implements AccessControl {
@Override
public void checkCanCreateTable(
String userName, QualifiedObjectName tableName, IAuditEntity
auditEntity) {
- auditEntity.setAuditLogOperation(AuditLogOperation.DDL);
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setDatabase(tableName.getDatabaseName());
InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
if (userName.equals(AuthorityChecker.INTERNAL_AUDIT_USER)
&& tableName.getDatabaseName().equals(TABLE_MODEL_AUDIT_DATABASE)) {
@@ -117,7 +118,7 @@ public class AccessControlImpl implements AccessControl {
checkAuditDatabase(tableName.getDatabaseName());
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity.setPrivilegeType(PrivilegeType.SYSTEM).setResult(true),
+ auditEntity.setPrivilegeType(PrivilegeType.CREATE).setResult(true),
tableName::getObjectName);
return;
}
@@ -127,10 +128,15 @@ public class AccessControlImpl implements AccessControl {
@Override
public void checkCanDropTable(
String userName, QualifiedObjectName tableName, IAuditEntity
auditEntity) {
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setDatabase(tableName.getDatabaseName());
InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
checkAuditDatabase(tableName.getDatabaseName());
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) {
- ITableAuthCheckerImpl.recordAuditLog(auditEntity,
tableName::getObjectName);
+ ITableAuthCheckerImpl.recordAuditLog(
+ auditEntity.setPrivilegeType(PrivilegeType.DROP).setResult(true),
+ tableName::getObjectName);
return;
}
authChecker.checkTablePrivilege(userName, tableName,
TableModelPrivilege.DROP, auditEntity);
@@ -246,58 +252,82 @@ public class AccessControlImpl implements AccessControl {
switch (type) {
case CREATE_USER:
case DROP_USER:
+ case UPDATE_USER:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
- ITableAuthCheckerImpl.recordAuditLog(auditEntity,
statement::getUserName);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getUserName);
return;
}
authChecker.checkGlobalPrivilege(userName,
TableModelPrivilege.MANAGE_USER, auditEntity);
return;
- case UPDATE_USER:
case LIST_USER_PRIV:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()
|| statement.getUserName().equals(userName)) {
- ITableAuthCheckerImpl.recordAuditLog(auditEntity,
statement::getUserName);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getUserName);
return;
}
authChecker.checkGlobalPrivilege(userName,
TableModelPrivilege.MANAGE_USER, auditEntity);
return;
case LIST_USER:
+ auditEntity.setAuditLogOperation(AuditLogOperation.QUERY);
if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_USER)) {
statement.setUserName(userName);
+ } else {
+ auditEntity.setPrivilegeType(PrivilegeType.SECURITY);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getUserName);
}
return;
case CREATE_ROLE:
case DROP_ROLE:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
- ITableAuthCheckerImpl.recordAuditLog(auditEntity,
statement::getRoleName);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getRoleName);
return;
}
authChecker.checkGlobalPrivilege(userName,
TableModelPrivilege.MANAGE_ROLE, auditEntity);
return;
case GRANT_USER_ROLE:
case REVOKE_USER_ROLE:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity,
+ auditEntity.setResult(true),
() -> "user: " + statement.getUserName() + ", role: " +
statement.getRoleName());
return;
}
authChecker.checkGlobalPrivilege(userName,
TableModelPrivilege.MANAGE_ROLE, auditEntity);
return;
case LIST_ROLE:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (statement.getUserName() != null &&
!statement.getUserName().equals(userName)) {
authChecker.checkGlobalPrivilege(userName,
TableModelPrivilege.MANAGE_ROLE, auditEntity);
- ITableAuthCheckerImpl.recordAuditLog(auditEntity,
statement::getRoleName);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getRoleName);
return;
}
if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_ROLE)) {
statement.setUserName(userName);
+ } else {
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getRoleName);
}
return;
case LIST_ROLE_PRIV:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()
|| AuthorityChecker.checkRole(userName, statement.getRoleName())) {
- ITableAuthCheckerImpl.recordAuditLog(auditEntity,
statement::getRoleName);
+ ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true),
statement::getRoleName);
return;
}
authChecker.checkGlobalPrivilege(userName,
TableModelPrivilege.MANAGE_ROLE, auditEntity);
@@ -306,9 +336,13 @@ public class AccessControlImpl implements AccessControl {
case GRANT_USER_ANY:
case REVOKE_ROLE_ANY:
case REVOKE_USER_ANY:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY)
+ .setDatabase(statement.getDatabase());
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity, () -> statement.getUserName() +
statement.getRoleName());
+ auditEntity.setResult(true), () -> statement.getUserName() +
statement.getRoleName());
return;
}
for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -320,9 +354,13 @@ public class AccessControlImpl implements AccessControl {
case REVOKE_ROLE_ALL:
case GRANT_USER_ALL:
case REVOKE_USER_ALL:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY)
+ .setDatabase(statement.getDatabase());
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity, () -> statement.getUserName() +
statement.getRoleName());
+ auditEntity.setResult(true), () -> statement.getUserName() +
statement.getRoleName());
return;
}
for (TableModelPrivilege privilege : TableModelPrivilege.values()) {
@@ -339,9 +377,13 @@ public class AccessControlImpl implements AccessControl {
case GRANT_ROLE_DB:
case REVOKE_USER_DB:
case REVOKE_ROLE_DB:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY)
+ .setDatabase(statement.getDatabase());
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity, () -> statement.getUserName() +
statement.getRoleName());
+ auditEntity.setResult(true), () -> statement.getUserName() +
statement.getRoleName());
return;
}
for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -356,9 +398,13 @@ public class AccessControlImpl implements AccessControl {
case GRANT_ROLE_TB:
case REVOKE_USER_TB:
case REVOKE_ROLE_TB:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY)
+ .setDatabase(statement.getDatabase());
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity, () -> statement.getUserName() +
statement.getRoleName());
+ auditEntity.setResult(true), () -> statement.getUserName() +
statement.getRoleName());
return;
}
for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -374,9 +420,12 @@ public class AccessControlImpl implements AccessControl {
case GRANT_ROLE_SYS:
case REVOKE_USER_SYS:
case REVOKE_ROLE_SYS:
+ auditEntity
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) {
ITableAuthCheckerImpl.recordAuditLog(
- auditEntity, () -> statement.getUserName() +
statement.getRoleName());
+ auditEntity.setResult(true), () -> statement.getUserName() +
statement.getRoleName());
return;
}
for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) {
@@ -420,8 +469,9 @@ public class AccessControlImpl implements AccessControl {
}
@Override
- public TSStatus checkPermissionBeforeProcess(Statement statement, UserEntity
userEntity) {
- return treeAccessCheckVisitor.process(statement, new
TreeAccessCheckContext(userEntity));
+ public TSStatus checkPermissionBeforeProcess(
+ Statement statement, TreeAccessCheckContext context) {
+ return treeAccessCheckVisitor.process(statement, context);
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AllowAllAccessControl.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AllowAllAccessControl.java
index 3ce14c2fd47..11b20883dbb 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AllowAllAccessControl.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AllowAllAccessControl.java
@@ -21,7 +21,6 @@ package
org.apache.iotdb.db.queryengine.plan.relational.security;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.audit.IAuditEntity;
-import org.apache.iotdb.commons.audit.UserEntity;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.path.PartialPath;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
@@ -116,7 +115,8 @@ public class AllowAllAccessControl implements AccessControl
{
String username, Collection<PrivilegeType> privilegeTypes, IAuditEntity
auditEntity) {}
@Override
- public TSStatus checkPermissionBeforeProcess(Statement statement, UserEntity
userEntity) {
+ public TSStatus checkPermissionBeforeProcess(
+ Statement statement, TreeAccessCheckContext context) {
return SUCCEED;
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckContext.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckContext.java
index dc92249a0bb..5dbb91cdbe6 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckContext.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckContext.java
@@ -22,7 +22,6 @@ package
org.apache.iotdb.db.queryengine.plan.relational.security;
import org.apache.iotdb.commons.audit.AuditEventType;
import org.apache.iotdb.commons.audit.AuditLogOperation;
import org.apache.iotdb.commons.audit.IAuditEntity;
-import org.apache.iotdb.commons.audit.UserEntity;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import java.util.Collections;
@@ -30,25 +29,29 @@ import java.util.List;
public class TreeAccessCheckContext implements IAuditEntity {
- private final UserEntity userEntity;
+ private final long userId;
+ private final String username;
+ private final String cliHostname;
- public TreeAccessCheckContext(UserEntity userEntity) {
- this.userEntity = userEntity;
+ public TreeAccessCheckContext(long userId, String username, String
cliHostname) {
+ this.userId = userId;
+ this.username = username;
+ this.cliHostname = cliHostname;
}
@Override
public long getUserId() {
- return userEntity.getUserId();
+ return userId;
}
@Override
public String getUsername() {
- return userEntity.getUsername();
+ return username;
}
@Override
public String getCliHostname() {
- return userEntity.getCliHostname();
+ return cliHostname;
}
private AuditEventType auditEventType;
@@ -134,8 +137,4 @@ public class TreeAccessCheckContext implements IAuditEntity
{
this.sqlString = sqlString;
return this;
}
-
- public UserEntity getUserEntity() {
- return userEntity;
- }
}
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 76761aab42f..6d8a63d6a83 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
@@ -530,9 +530,13 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
@Override
public TSStatus visitAuthor(AuthorStatement statement,
TreeAccessCheckContext context) {
AuthorType authorType = statement.getAuthorType();
+ Supplier<String> auditObject;
switch (authorType) {
case CREATE_USER:
case DROP_USER:
+ context
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.DDL),
PrivilegeType.MANAGE_USER,
@@ -542,22 +546,31 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
if (statement.getUserName().equals(context.getUsername())) {
return RpcUtils.SUCCESS_STATUS;
}
+ context
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.DDL),
PrivilegeType.MANAGE_USER,
statement::getUserName);
case LIST_USER:
+ context
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (checkHasGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
PrivilegeType.MANAGE_USER,
- null)) {
+ statement::getUserName)) {
return RpcUtils.SUCCESS_STATUS;
}
statement.setUserName(context.getUsername());
return RpcUtils.SUCCESS_STATUS;
case LIST_USER_PRIVILEGE:
+ context
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (context.getUsername().equals(statement.getUserName())) {
return RpcUtils.SUCCESS_STATUS;
}
@@ -567,6 +580,9 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
statement::getUserName);
case LIST_ROLE_PRIVILEGE:
+ context
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (!AuthorityChecker.checkRole(context.getUsername(),
statement.getRoleName())) {
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
@@ -577,10 +593,13 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
}
case LIST_ROLE:
+ context
+ .setAuditLogOperation(AuditLogOperation.QUERY)
+ .setPrivilegeType(PrivilegeType.SECURITY);
if (checkHasGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.QUERY),
PrivilegeType.MANAGE_ROLE,
- null)) {
+ statement::getRoleName)) {
return SUCCEED;
}
// list roles of other user is not allowed
@@ -595,17 +614,27 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
case DROP_ROLE:
case GRANT_USER_ROLE:
case REVOKE_USER_ROLE:
+ context
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
+ auditObject =
+ authorType == AuthorType.CREATE_ROLE || authorType ==
AuthorType.DROP_ROLE
+ ? statement::getRoleName
+ : () -> "user: " + statement.getUserName() + ", role: " +
statement.getRoleName();
return checkGlobalAuth(
context.setAuditLogOperation(AuditLogOperation.DDL),
PrivilegeType.MANAGE_ROLE,
- statement::getRoleName);
+ auditObject);
case REVOKE_USER:
case GRANT_USER:
case GRANT_ROLE:
case REVOKE_ROLE:
+ context
+ .setAuditLogOperation(AuditLogOperation.DDL)
+ .setPrivilegeType(PrivilegeType.SECURITY);
context.setAuditLogOperation(AuditLogOperation.DDL);
- Supplier<String> auditObject =
+ auditObject =
() ->
authorType == AuthorType.REVOKE_USER || authorType ==
AuthorType.GRANT_USER
? statement.getUserName()
@@ -1383,6 +1412,7 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
@Override
public TSStatus visitAlterTimeSeries(
AlterTimeSeriesStatement statement, TreeAccessCheckContext context) {
+ context.setAuditLogOperation(AuditLogOperation.DDL);
// audit db is read-only
if (includeByAuditTreeDB(statement.getPath())
&&
!context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
@@ -1398,6 +1428,7 @@ public class TreeAccessCheckVisitor extends
StatementVisitor<TSStatus, TreeAcces
@Override
public TSStatus visitDeleteTimeSeries(
DeleteTimeSeriesStatement statement, TreeAccessCheckContext context) {
+ context.setAuditLogOperation(AuditLogOperation.DDL);
// audit db is read-only
for (PartialPath path : statement.getPathPatternList()) {
if (includeByAuditTreeDB(path)
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/audit/AbstractAuditLogger.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/audit/AbstractAuditLogger.java
index 82eac3606d0..d2d8ce6046c 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/audit/AbstractAuditLogger.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/audit/AbstractAuditLogger.java
@@ -94,6 +94,7 @@ public abstract class AbstractAuditLogger {
case DELETE:
case INSERT:
case SELECT:
+ case MANAGE_DATABASE:
case WRITE_DATA:
case READ_SCHEMA:
case WRITE_SCHEMA:
@@ -106,7 +107,6 @@ public abstract class AbstractAuditLogger {
case MANAGE_ROLE:
case MANAGE_USER:
case USE_TRIGGER:
- case MANAGE_DATABASE:
case EXTEND_TEMPLATE:
default:
return PrivilegeLevel.GLOBAL;