This is an automated email from the ASF dual-hosted git repository.
HTHou 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 c6afaf54957 Fix table model set configuration audit logging (#18412)
c6afaf54957 is described below
commit c6afaf549571e8a9900a39197336251b3f03e8d6
Author: libo <[email protected]>
AuthorDate: Thu Aug 6 16:43:55 2026 +0800
Fix table model set configuration audit logging (#18412)
---
.../execution/config/TableConfigTaskVisitor.java | 3 +
.../relational/security/AccessControlImpl.java | 22 +++-
.../relational/security/AccessControlImplTest.java | 119 +++++++++++++++++++++
3 files changed, 143 insertions(+), 1 deletion(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
index 5f0ff823972..1ff61937f4b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
@@ -1074,6 +1074,9 @@ public class TableConfigTaskVisitor implements
AstVisitor<IConfigTask, MPPQueryC
setConfigurationStatement.getNeededPrivileges(),
context);
} catch (IOException e) {
+ DNAuditLogger.getInstance()
+ .recordObjectAuthenticationAuditLog(
+
context.setResult(false).setAuditLogOperation(AuditLogOperation.CONTROL), () ->
"");
throw new
AccessDeniedException(DataNodeQueryMessages.FAILED_TO_CHECK_CONFIG_ITEM_PERMISSION);
}
setConfigurationStatement.checkSomeParametersKeepConsistentInCluster();
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 bc20a7d972f..0db343b44d9 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
@@ -40,6 +40,7 @@ import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.tsfile.file.metadata.IDeviceID;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -569,10 +570,29 @@ public class AccessControlImpl implements AccessControl {
@Override
public void checkMissingPrivileges(
String username, Collection<PrivilegeType> privilegeTypes, IAuditEntity
auditEntity) {
+ List<PrivilegeType> relatedPrivileges = new ArrayList<>(privilegeTypes);
if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) {
+ recordMissingPrivilegesAuditLog(auditEntity, relatedPrivileges, true);
return;
}
- authChecker.checkGlobalPrivileges(username, privilegeTypes, auditEntity);
+ try {
+ authChecker.checkGlobalPrivileges(username, privilegeTypes, auditEntity);
+ recordMissingPrivilegesAuditLog(auditEntity, relatedPrivileges, true);
+ } catch (AccessDeniedException e) {
+ recordMissingPrivilegesAuditLog(auditEntity, relatedPrivileges, false);
+ throw e;
+ }
+ }
+
+ private static void recordMissingPrivilegesAuditLog(
+ IAuditEntity auditEntity, List<PrivilegeType> privilegeTypes, boolean
result) {
+ DNAuditLogger.getInstance()
+ .recordObjectAuthenticationAuditLog(
+ auditEntity
+ .setResult(result)
+ .setAuditLogOperation(AuditLogOperation.CONTROL)
+ .setPrivilegeTypes(privilegeTypes),
+ () -> "");
}
@Override
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImplTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImplTest.java
new file mode 100644
index 00000000000..73e3fe6f6a0
--- /dev/null
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImplTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.queryengine.plan.relational.security;
+
+import org.apache.iotdb.commons.audit.AuditEventType;
+import org.apache.iotdb.commons.audit.AuditLogOperation;
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.commons.auth.entity.User;
+import org.apache.iotdb.commons.exception.auth.AccessDeniedException;
+import org.apache.iotdb.db.auth.AuthorityChecker;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class AccessControlImplTest {
+
+ private static final List<PrivilegeType> AUDIT_PRIVILEGE =
+ Collections.singletonList(PrivilegeType.AUDIT);
+ private static final long USER_ID = User.INTERNAL_USER_END_ID + 1;
+ private static final String USER_NAME = "user";
+
+ @Before
+ public void setUp() {
+ AuthorityChecker.getAuthorityFetcher().getAuthorCache().invalidAllCache();
+ }
+
+ @After
+ public void tearDown() {
+ AuthorityChecker.getAuthorityFetcher().getAuthorCache().invalidAllCache();
+ }
+
+ @Test
+ public void testSuperUserMissingPrivilegeCheckIsAudited() {
+ ITableAuthChecker authChecker = mock(ITableAuthChecker.class);
+ AccessControlImpl accessControl =
+ new AccessControlImpl(authChecker, new TreeAccessCheckVisitor());
+ TreeAccessCheckContext auditContext =
+ new TreeAccessCheckContext(AuthorityChecker.SUPER_USER_ID,
AuthorityChecker.SUPER_USER, "");
+
+ accessControl.checkMissingPrivileges(
+ AuthorityChecker.SUPER_USER, AUDIT_PRIVILEGE, auditContext);
+
+ assertAuditContext(auditContext, true);
+ verify(authChecker, never()).checkGlobalPrivileges(anyString(),
anyCollection(), any());
+ }
+
+ @Test
+ public void testUserWithAuditPrivilegeCheckIsAudited() {
+ User user = new User(USER_NAME, "password", USER_ID);
+ user.grantSysPrivilege(PrivilegeType.AUDIT, false);
+
AuthorityChecker.getAuthorityFetcher().getAuthorCache().putUserCache(USER_NAME,
user);
+ AccessControlImpl accessControl =
+ new AccessControlImpl(new ITableAuthCheckerImpl(), new
TreeAccessCheckVisitor());
+ TreeAccessCheckContext auditContext = new TreeAccessCheckContext(USER_ID,
USER_NAME, "");
+
+ accessControl.checkMissingPrivileges(USER_NAME, AUDIT_PRIVILEGE,
auditContext);
+
+ assertAuditContext(auditContext, true);
+ }
+
+ @Test
+ public void testMissingPrivilegeFailureIsAudited() {
+ User user = new User(USER_NAME, "password", USER_ID);
+
AuthorityChecker.getAuthorityFetcher().getAuthorCache().putUserCache(USER_NAME,
user);
+ AccessControlImpl accessControl =
+ new AccessControlImpl(new ITableAuthCheckerImpl(), new
TreeAccessCheckVisitor());
+ TreeAccessCheckContext auditContext = new TreeAccessCheckContext(USER_ID,
USER_NAME, "");
+
+ assertThrows(
+ AccessDeniedException.class,
+ () -> accessControl.checkMissingPrivileges(USER_NAME, AUDIT_PRIVILEGE,
auditContext));
+
+ assertAuditContext(auditContext, false);
+ }
+
+ private static void assertAuditContext(
+ TreeAccessCheckContext auditContext, boolean expectedResult) {
+ assertEquals(AuditEventType.OBJECT_AUTHENTICATION,
auditContext.getAuditEventType());
+ assertEquals(AuditLogOperation.CONTROL,
auditContext.getAuditLogOperation());
+ assertEquals(AUDIT_PRIVILEGE, auditContext.getPrivilegeTypes());
+ if (expectedResult) {
+ assertTrue(auditContext.getResult());
+ } else {
+ assertFalse(auditContext.getResult());
+ }
+ }
+}