From 7614e14717849476cefa4cb5ecabfb4bb19e1e4e Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Thu, 25 Dec 2025 18:23:36 +0800 Subject: [PATCH 01/19] fix --- .../security/AccessControlImpl.java | 120 +++++++------ .../security/ITableAuthCheckerImpl.java | 68 +++----- .../security/TreeAccessCheckVisitor.java | 159 ++++++++---------- .../commons/audit/AbstractAuditLogger.java | 15 +- 4 files changed, 186 insertions(+), 176 deletions(-) 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 94323f30c96c6..dfb97f0287f5c 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 @@ -28,6 +28,7 @@ import org.apache.iotdb.commons.path.MeasurementPath; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.commons.schema.table.InformationSchema; +import org.apache.iotdb.db.audit.DNAuditLogger; import org.apache.iotdb.db.auth.AuthorityChecker; import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.RelationalAuthorStatement; @@ -117,9 +118,10 @@ public void checkCanCreateTable( } checkAuditDatabase(tableName.getDatabaseName()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setPrivilegeType(PrivilegeType.CREATE).setResult(true), - tableName::getObjectName); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setPrivilegeType(PrivilegeType.CREATE).setResult(true), + tableName::getObjectName); return; } authChecker.checkTablePrivilege(userName, tableName, TableModelPrivilege.CREATE, auditEntity); @@ -134,9 +136,10 @@ public void checkCanDropTable( InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName()); checkAuditDatabase(tableName.getDatabaseName()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setPrivilegeType(PrivilegeType.DROP).setResult(true), - tableName::getObjectName); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setPrivilegeType(PrivilegeType.DROP).setResult(true), + tableName::getObjectName); return; } authChecker.checkTablePrivilege(userName, tableName, TableModelPrivilege.DROP, auditEntity); @@ -148,7 +151,7 @@ public void checkCanAlterTable( InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName()); checkAuditDatabase(tableName.getDatabaseName()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) { - ITableAuthCheckerImpl.recordAuditLog(auditEntity, tableName::getObjectName); + DNAuditLogger.getInstance().recordAuditLog(auditEntity, tableName::getObjectName); return; } authChecker.checkTablePrivilege(userName, tableName, TableModelPrivilege.ALTER, auditEntity); @@ -256,7 +259,8 @@ public void checkUserCanRunRelationalAuthorStatement( .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.SECURITY); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getUserName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); @@ -266,19 +270,21 @@ public void checkUserCanRunRelationalAuthorStatement( auditEntity.setAuditLogOperation(AuditLogOperation.DDL); if (statement.getUserName().equals(userName)) { // users can change the username and password of themselves - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getUserName); return; } if (AuthorityChecker.SUPER_USER_ID == AuthorityChecker.getUserId(statement.getUserName()).orElse(-1L)) { // Only the superuser can alter him/herself - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(false), statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(false), statement::getUserName); throw new AccessDeniedException("Only the superuser can alter him/herself."); } if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { // the superuser can alter anyone - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getUserName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); @@ -287,14 +293,16 @@ public void checkUserCanRunRelationalAuthorStatement( auditEntity.setAuditLogOperation(AuditLogOperation.QUERY); if (statement.getUserName().equals(userName)) { // No need any privilege to list him/herself - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getUserName); return; } // Require SECURITY privilege to list other users' privileges if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), - statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + statement::getUserName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); @@ -304,11 +312,12 @@ public void checkUserCanRunRelationalAuthorStatement( if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_USER)) { // No need to check privilege to list himself/herself statement.setUserName(userName); - ITableAuthCheckerImpl.recordAuditLog(auditEntity, statement::getUserName); + DNAuditLogger.getInstance().recordAuditLog(auditEntity, statement::getUserName); } else { // Require SECURITY privilege to list other users - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setPrivilegeType(PrivilegeType.SECURITY), statement::getUserName); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setPrivilegeType(PrivilegeType.SECURITY), statement::getUserName); } return; case CREATE_ROLE: @@ -317,7 +326,8 @@ public void checkUserCanRunRelationalAuthorStatement( .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.SECURITY); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getRoleName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getRoleName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity); @@ -328,9 +338,10 @@ public void checkUserCanRunRelationalAuthorStatement( .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.SECURITY); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(true), - () -> "user: " + statement.getUserName() + ", role: " + statement.getRoleName()); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setResult(true), + () -> "user: " + statement.getUserName() + ", role: " + statement.getRoleName()); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity); @@ -345,26 +356,30 @@ public void checkUserCanRunRelationalAuthorStatement( if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_ROLE)) { // No need to check privilege to list his/hers own role statement.setUserName(userName); - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getRoleName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getRoleName); } else { // Require SECURITY privilege to list all roles - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), - statement::getRoleName); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + statement::getRoleName); } return; case LIST_ROLE_PRIV: auditEntity.setAuditLogOperation(AuditLogOperation.QUERY); if (AuthorityChecker.checkRole(userName, statement.getRoleName())) { // No need any privilege to list his/hers own role - ITableAuthCheckerImpl.recordAuditLog(auditEntity.setResult(true), statement::getRoleName); + DNAuditLogger.getInstance() + .recordAuditLog(auditEntity.setResult(true), statement::getRoleName); return; } // Require SECURITY privilege to list other roles' privileges if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), - statement::getRoleName); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + statement::getRoleName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity); @@ -378,8 +393,10 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY) .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setResult(true), + () -> statement.getUserName() + statement.getRoleName()); return; } for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) { @@ -396,8 +413,10 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY) .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setResult(true), + () -> statement.getUserName() + statement.getRoleName()); return; } for (TableModelPrivilege privilege : TableModelPrivilege.values()) { @@ -419,8 +438,10 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY) .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setResult(true), + () -> statement.getUserName() + statement.getRoleName()); return; } for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) { @@ -440,8 +461,10 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY) .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setResult(true), + () -> statement.getUserName() + statement.getRoleName()); return; } for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) { @@ -462,8 +485,10 @@ public void checkUserCanRunRelationalAuthorStatement( .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.SECURITY); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { - ITableAuthCheckerImpl.recordAuditLog( - auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); + DNAuditLogger.getInstance() + .recordAuditLog( + auditEntity.setResult(true), + () -> statement.getUserName() + statement.getRoleName()); return; } for (PrivilegeType privilegeType : statement.getPrivilegeTypes()) { @@ -545,12 +570,13 @@ public TSStatus checkCanAlterTemplate(IAuditEntity entity, Supplier audi public TSStatus checkCanAlterView( IAuditEntity entity, List sourcePaths, List targetPaths) { if (AuthorityChecker.SUPER_USER_ID == entity.getUserId()) { - ITableAuthCheckerImpl.recordAuditLog( - entity - .setPrivilegeTypes( - Arrays.asList(PrivilegeType.READ_SCHEMA, PrivilegeType.WRITE_SCHEMA)) - .setResult(true), - () -> "source: " + sourcePaths + ", target: " + targetPaths); + DNAuditLogger.getInstance() + .recordAuditLog( + entity + .setPrivilegeTypes( + Arrays.asList(PrivilegeType.READ_SCHEMA, PrivilegeType.WRITE_SCHEMA)) + .setResult(true), + () -> "source: " + sourcePaths + ", target: " + targetPaths); return SUCCEED; } TSStatus status = new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java index d1f60445295ee..8eca0f9b33408 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java @@ -33,20 +33,18 @@ import java.util.Collection; import java.util.function.Supplier; +import static org.apache.iotdb.commons.audit.AbstractAuditLogger.OBJECT_AUTHENTICATION_AUDIT_STR; import static org.apache.iotdb.commons.schema.table.Audit.TABLE_MODEL_AUDIT_DATABASE; public class ITableAuthCheckerImpl implements ITableAuthChecker { private static final DNAuditLogger AUDIT_LOGGER = DNAuditLogger.getInstance(); - private static final String OBJECT_AUTHENTICATION_AUDIT_STR = - "User %s (ID=%d) requests authority on object %s with result %s"; - @Override public void checkDatabaseVisibility( String userName, String databaseName, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -56,7 +54,7 @@ public void checkDatabaseVisibility( } // Information_schema is visible to any user if (databaseName.equals(InformationSchema.INFORMATION_DATABASE)) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -69,7 +67,7 @@ public void checkDatabaseVisibility( // The audit database only requires audit privilege boolean hasAuditPrivilege = AuthorityChecker.checkSystemPermission(userName, PrivilegeType.AUDIT); - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.AUDIT) @@ -82,7 +80,7 @@ public void checkDatabaseVisibility( } if (AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM)) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -91,7 +89,7 @@ public void checkDatabaseVisibility( return; } if (!AuthorityChecker.checkDBVisible(userName, databaseName)) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -99,7 +97,7 @@ public void checkDatabaseVisibility( () -> databaseName); throw new AccessDeniedException("DATABASE " + databaseName); } - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -121,7 +119,7 @@ public void checkDatabasePrivilege( } if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -131,7 +129,7 @@ public void checkDatabasePrivilege( } if (AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM)) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -161,7 +159,7 @@ private static void checkAuditDatabase( if (privilege == TableModelPrivilege.SELECT) { checkCanSelectAuditTable(auditEntity); } else { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -177,7 +175,7 @@ public static void checkCanSelectAuditTable(IAuditEntity auditEntity) { String userName = auditEntity.getUsername(); if (AuthorityChecker.SUPER_USER_ID != auditEntity.getUserId() && !AuthorityChecker.checkSystemPermission(userName, PrivilegeType.AUDIT)) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.SELECT) @@ -201,7 +199,7 @@ public static void checkCanSelectAuditTable(IAuditEntity auditEntity) { String.format( "The database '%s' can only be queried by AUDIT admin.", TABLE_MODEL_AUDIT_DATABASE)); } - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.SELECT) @@ -216,7 +214,7 @@ public void checkDatabasePrivilegeGrantOption( TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -241,7 +239,7 @@ public void checkTablePrivilege( IAuditEntity auditEntity) { auditEntity.setDatabase(tableName.getDatabaseName()); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -269,7 +267,7 @@ public void checkTablePrivilegeGrantOption( TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -305,7 +303,7 @@ public boolean checkTablePrivilege4Pipe( tableName.getObjectName()) .getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.CONTROL) .setPrivilegeType(PrivilegeType.SYSTEM) @@ -313,7 +311,7 @@ public boolean checkTablePrivilege4Pipe( tableName::getObjectName); return true; } - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.CONTROL) .setPrivilegeType(PrivilegeType.SYSTEM) @@ -327,7 +325,7 @@ public void checkTableVisibility( String userName, QualifiedObjectName tableName, IAuditEntity auditEntity) { auditEntity.setDatabase(tableName.getDatabaseName()); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -341,7 +339,7 @@ public void checkTableVisibility( // The audit table only requires audit privilege boolean hasAuditPrivilege = AuthorityChecker.checkSystemPermission(userName, PrivilegeType.AUDIT); - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.AUDIT) @@ -354,7 +352,7 @@ public void checkTableVisibility( } if (AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM)) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -364,7 +362,7 @@ public void checkTableVisibility( } if (!AuthorityChecker.checkTableVisible( userName, tableName.getDatabaseName(), tableName.getObjectName())) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -378,7 +376,7 @@ public void checkTableVisibility( public void checkGlobalPrivilege( String userName, TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -398,7 +396,7 @@ public void checkGlobalPrivileges( String username, Collection privileges, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { for (PrivilegeType privilege : privileges) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege) @@ -419,7 +417,7 @@ public void checkGlobalPrivileges( public void checkGlobalPrivilegeGrantOption( String userName, TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -440,7 +438,7 @@ public void checkGlobalPrivilegeGrantOption( public void checkAnyScopePrivilegeGrantOption( String userName, TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -463,7 +461,7 @@ private void recordAuditLogViaAuthenticationResult( IAuditEntity auditEntity, TSStatus result) { if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -471,23 +469,11 @@ private void recordAuditLogViaAuthenticationResult( auditObject); throw new AccessDeniedException(result.getMessage()); } - recordAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) .setResult(true), auditObject); } - - public static void recordAuditLog(IAuditEntity auditEntity, Supplier auditObject) { - AUDIT_LOGGER.log( - auditEntity.setAuditEventType(AuditEventType.OBJECT_AUTHENTICATION), - () -> - String.format( - OBJECT_AUTHENTICATION_AUDIT_STR, - auditEntity.getUsername(), - auditEntity.getUserId(), - auditObject.get(), - auditEntity.getResult())); - } } 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 e63b63f850e57..5631bc0051f8d 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 @@ -20,7 +20,6 @@ package org.apache.iotdb.db.queryengine.plan.relational.security; import org.apache.iotdb.common.rpc.thrift.TSStatus; -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.auth.AuthException; @@ -196,7 +195,7 @@ public TSStatus visitAuthorityInformation( .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -205,12 +204,12 @@ public TSStatus visitAuthorityInformation( statement.setAuthorityScope( AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_SCHEMA)); } catch (AuthException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -220,7 +219,7 @@ public static List getIntersectedPaths4Pipe( final List paths, final TreeAccessCheckContext context) { context.setAuditLogOperation(AuditLogOperation.QUERY).setPrivilegeType(PrivilegeType.READ_DATA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> paths.stream().distinct().collect(Collectors.toList()).toString()); return paths; @@ -231,12 +230,12 @@ public static List getIntersectedPaths4Pipe( originalTree.constructTree(); final PathPatternTree tree = AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_DATA); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> paths.stream().distinct().collect(Collectors.toList()).toString()); return originalTree.intersectWithFullPathPrefixTree(tree).getAllPathPatterns(true); } catch (AuthException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> paths.stream().distinct().collect(Collectors.toList()).toString()); return Collections.emptyList(); @@ -299,7 +298,7 @@ private TSStatus checkTemplateShowRelated( ShowSchemaTemplateStatement statement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAll(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.SYSTEM) @@ -379,7 +378,7 @@ public TSStatus visitAlterSchemaTemplate( public TSStatus checkCanAlterTemplate(IAuditEntity entity, Supplier auditObject) { if (AuthorityChecker.SUPER_USER.equals(entity.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( entity .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.EXTEND_TEMPLATE) @@ -410,7 +409,7 @@ public TSStatus visitCreateLogicalView( // audit db is read-only if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.AUDIT).setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); @@ -422,7 +421,7 @@ public TSStatus visitCreateLogicalView( if (statement.getQueryStatement() != null) { statement.getQueryStatement().setCanSeeAuditDB(true); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setPrivilegeTypes( Arrays.asList(PrivilegeType.WRITE_SCHEMA, PrivilegeType.READ_SCHEMA)) @@ -480,7 +479,7 @@ public TSStatus visitAlterLogicalView( if (statement.getQueryStatement() != null) { statement.getQueryStatement().setCanSeeAuditDB(true); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setPrivilegeTypes( Arrays.asList(PrivilegeType.READ_SCHEMA, PrivilegeType.WRITE_SCHEMA)) @@ -523,7 +522,7 @@ public TSStatus visitRenameLogicalView( // audit db is read-only if (includeByAuditTreeDB(statement.getNewName()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.WRITE_SCHEMA).setResult(false), () -> statement.getOldName().toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -555,13 +554,13 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co context.setAuditLogOperation(AuditLogOperation.DDL); if (statement.getUserName().equals(context.getUsername())) { // users can change the username and password of themselves - recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername); + AUDIT_LOGGER.recordAuditLog(context.setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; } if (AuthorityChecker.SUPER_USER_ID == AuthorityChecker.getUserId(statement.getUserName()).orElse(-1L)) { // Only the superuser can alter him/herself - recordObjectAuthenticationAuditLog(context.setResult(false), context::getUsername); + AUDIT_LOGGER.recordAuditLog(context.setResult(false), context::getUsername); return AuthorityChecker.getTSStatus( false, "Has no permission to execute " @@ -584,14 +583,14 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co } // Can only list him/herself without MANAGE_USER privilege statement.setUserName(context.getUsername()); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(null).setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; case LIST_USER_PRIVILEGE: 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); + AUDIT_LOGGER.recordAuditLog(context.setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; } // Require MANAGE_USER privilege to list other users' privileges @@ -608,7 +607,7 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co statement::getRoleName); } else { // No need any privilege to list his/her own role's privileges - recordObjectAuthenticationAuditLog(context.setResult(true), context::getUsername); + AUDIT_LOGGER.recordAuditLog(context.setResult(true), context::getUsername); return SUCCEED; } case LIST_ROLE: @@ -622,12 +621,12 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co // list roles of other user is not allowed if (statement.getUserName() != null && !statement.getUserName().equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.MANAGE_ROLE).setResult(false), context::getUsername); return AuthorityChecker.getTSStatus(false, PrivilegeType.MANAGE_ROLE); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(null).setResult(true), context::getUsername); statement.setUserName(context.getUsername()); return RpcUtils.SUCCESS_STATUS; @@ -723,7 +722,7 @@ public TSStatus visitShowContinuousQueries( private TSStatus checkCQManagement(IAuditEntity auditEntity, Supplier auditObject) { if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity.setPrivilegeType(PrivilegeType.USE_CQ).setResult(true), auditObject); return SUCCEED; } @@ -749,7 +748,7 @@ public TSStatus visitDropFunction( public TSStatus visitShowFunctions( ShowFunctionsStatement statement, TreeAccessCheckContext context) { // anyone can show functions - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), null); return SUCCEED; } @@ -917,7 +916,7 @@ public TSStatus visitDropSubscription( public TSStatus visitCreateTrigger( CreateTriggerStatement statement, TreeAccessCheckContext context) { if (TREE_MODEL_AUDIT_DATABASE_PATH.include(statement.getPathPattern())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.USE_TRIGGER) @@ -945,7 +944,7 @@ public TSStatus visitShowTriggers( private TSStatus checkTriggerManagement(IAuditEntity auditEntity, Supplier auditObject) { if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( auditEntity.setPrivilegeType(PrivilegeType.USE_TRIGGER).setResult(true), auditObject); return SUCCEED; } @@ -979,7 +978,7 @@ public TSStatus visitShowDatabase( .collect(Collectors.toList()) .toString()); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.SYSTEM).setResult(true), context::getDatabase); return SUCCEED; } @@ -998,7 +997,7 @@ public TSStatus visitCountDatabase( .collect(Collectors.toList()) .toString()); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.SYSTEM).setResult(true), context::getDatabase); return SUCCEED; } @@ -1015,7 +1014,7 @@ public TSStatus visitDeleteDatabase( for (String prefixPath : statement.getPrefixPath()) { // root.__audit can never be deleted if (TREE_MODEL_AUDIT_DATABASE.equals(prefixPath)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.MANAGE_DATABASE).setResult(false), () -> prefixPath); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1023,7 +1022,7 @@ public TSStatus visitDeleteDatabase( } } if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(PrivilegeType.MANAGE_DATABASE).setResult(true), () -> statement.getPrefixPath().toString()); return SUCCEED; @@ -1043,13 +1042,13 @@ protected TSStatus checkCreateOrAlterDatabasePermission( // root.__audit can never be created or alter by other users return SUCCEED; } - recordObjectAuthenticationAuditLog(auditEntity.setResult(false), databaseName::getFullPath); + AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(false), databaseName::getFullPath); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - recordObjectAuthenticationAuditLog(auditEntity.setResult(true), databaseName::getFullPath); + AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(true), databaseName::getFullPath); return SUCCEED; } @@ -1066,7 +1065,7 @@ private TSStatus checkShowOrCountDatabasePermission( () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString())) { return visitAuthorityInformation(statement, context); } else { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.MANAGE_DATABASE) @@ -1084,14 +1083,14 @@ public TSStatus visitInsertBase(InsertBaseStatement statement, TreeAccessCheckCo // audit db is read-only if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog(context.setResult(false), path::toString); + AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } } if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1108,8 +1107,7 @@ public TSStatus visitInsert(InsertStatement statement, TreeAccessCheckContext co // audit db is read-only if (includeByAuditTreeDB(statement.getDevice()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( - context.setResult(false), () -> statement.getDevice().toString()); + AUDIT_LOGGER.recordAuditLog(context.setResult(false), () -> statement.getDevice().toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -1129,7 +1127,7 @@ public TSStatus visitDeleteData(DeleteDataStatement statement, TreeAccessCheckCo // audit db is read-only if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog(context.setResult(false), path::toString); + AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -1142,7 +1140,7 @@ public TSStatus visitQuery(QueryStatement statement, TreeAccessCheckContext cont context.setAuditLogOperation(AuditLogOperation.QUERY).setPrivilegeType(PrivilegeType.READ_DATA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1153,12 +1151,12 @@ public TSStatus visitQuery(QueryStatement statement, TreeAccessCheckContext cont statement.setAuthorityScope( AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_DATA)); } catch (AuthException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1182,7 +1180,7 @@ public static TSStatus checkTimeSeriesPermission( PrivilegeType permission) { context.setPrivilegeType(permission); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> checkedPathsSupplier.get().toString()); return SUCCEED; } @@ -1195,7 +1193,7 @@ public static TSStatus checkTimeSeriesPermission( permission); if (!AuthorityChecker.INTERNAL_AUDIT_USER.equals(context.getUsername())) { // Internal auditor no needs audit log - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), checkedPaths::toString); } @@ -1206,13 +1204,13 @@ public static List checkTimeSeriesPermission4Pipe( IAuditEntity context, List checkedPaths, PrivilegeType permission) { context.setPrivilegeType(permission); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog(context.setResult(true), checkedPaths::toString); + AUDIT_LOGGER.recordAuditLog(context.setResult(true), checkedPaths::toString); return Collections.emptyList(); } final List results = AuthorityChecker.checkFullPathOrPatternListPermission( context.getUsername(), checkedPaths, permission); - recordObjectAuthenticationAuditLog(context.setResult(true), checkedPaths::toString); + AUDIT_LOGGER.recordAuditLog(context.setResult(true), checkedPaths::toString); return results; } @@ -1225,7 +1223,7 @@ public TSStatus visitCreateTimeseries( // audit db is read-only if (includeByAuditTreeDB(statement.getPath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1243,7 +1241,7 @@ public TSStatus visitCreateAlignedTimeseries( // audit db is read-only if (includeByAuditTreeDB(statement.getDevicePath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1280,7 +1278,7 @@ public TSStatus visitInternalCreateMultiTimeSeries( for (PartialPath path : statement.getDeviceMap().keySet()) { if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog(context.setResult(false), path::toString); + AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -1295,7 +1293,7 @@ public TSStatus visitInternalCreateTimeseries( // audit db is read-only if (includeByAuditTreeDB(statement.getDevicePath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1312,7 +1310,7 @@ public TSStatus visitShowTimeSeries( .setPrivilegeTypes(Arrays.asList(PrivilegeType.READ_DATA, PrivilegeType.READ_SCHEMA)); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1329,7 +1327,7 @@ public TSStatus visitShowTimeSeries( } catch (AuthException e) { return new TSStatus(e.getCode().getStatusCode()); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1346,7 +1344,7 @@ public TSStatus visitCountTimeSeries( .setPrivilegeType(PrivilegeType.READ_SCHEMA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1361,12 +1359,12 @@ public TSStatus visitCountTimeSeries( AuthorityChecker.getAuthorizedPathTree( context.getUsername(), PrivilegeType.READ_DATA))); } catch (AuthException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1380,7 +1378,7 @@ public TSStatus visitCountLevelTimeSeries( CountLevelTimeSeriesStatement countStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { countStatement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> countStatement.getPaths().stream() @@ -1398,7 +1396,7 @@ public TSStatus visitCountNodes( CountNodesStatement countStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { countStatement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> countStatement.getPaths().stream() @@ -1416,7 +1414,7 @@ public TSStatus visitShowChildNodes( ShowChildNodesStatement showChildNodesStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { showChildNodesStatement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> showChildNodesStatement.getPaths().stream() @@ -1434,7 +1432,7 @@ public TSStatus visitShowChildPaths( ShowChildPathsStatement showChildPathsStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { showChildPathsStatement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> showChildPathsStatement.getPaths().stream() @@ -1454,7 +1452,7 @@ public TSStatus visitAlterTimeSeries( // audit db is read-only if (includeByAuditTreeDB(statement.getPath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1487,7 +1485,7 @@ public TSStatus visitAlterEncodingCompressor( alterEncodingCompressorStatement.getPatternTree(), authTree)); return StatusUtils.OK; } catch (final AuthException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> alterEncodingCompressorStatement.getPaths().stream() @@ -1521,7 +1519,7 @@ public TSStatus visitDeleteTimeSeries( for (PartialPath path : statement.getPathPatternList()) { if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1606,7 +1604,7 @@ public TSStatus visitSetConfiguration( AuthorityChecker.getTSStatus( AuthorityChecker.checkUserMissingSystemPermissions( context.getUsername(), relatedPrivileges)); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) .setAuditLogOperation(AuditLogOperation.CONTROL) @@ -1614,7 +1612,7 @@ public TSStatus visitSetConfiguration( () -> ""); return result; } catch (IOException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false).setAuditLogOperation(AuditLogOperation.CONTROL), () -> ""); return AuthorityChecker.getTSStatus(false, "Failed to check config item permission"); } @@ -1707,7 +1705,7 @@ public TSStatus visitShowCluster(ShowClusterStatement statement, TreeAccessCheck @Override public TSStatus visitShowAvailableUrls( ShowAvailableUrlsStatement showAvailableUrlsStatement, TreeAccessCheckContext context) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), () -> ""); return SUCCEED; } @@ -1845,7 +1843,7 @@ public TSStatus visitSetTTL(SetTTLStatement statement, TreeAccessCheckContext co context.getUsername(), pathsForCheckingPermissions, PrivilegeType.WRITE_SCHEMA), pathsForCheckingPermissions, PrivilegeType.WRITE_SCHEMA); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context .setPrivilegeType(PrivilegeType.WRITE_SCHEMA) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), @@ -1876,7 +1874,7 @@ public TSStatus visitShowTTL(ShowTTLStatement showTTLStatement, TreeAccessCheckC context.getUsername(), path.concatNode(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD), PrivilegeType.READ_SCHEMA)) { - recordObjectAuthenticationAuditLog(context.setResult(false), path::getFullPath); + AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::getFullPath); return AuthorityChecker.getTSStatus(false, path, PrivilegeType.READ_SCHEMA); } } @@ -1897,7 +1895,7 @@ public TSStatus visitShowDevices(ShowDevicesStatement statement, TreeAccessCheck .setPrivilegeTypes(Arrays.asList(PrivilegeType.READ_DATA, PrivilegeType.READ_SCHEMA)); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1912,12 +1910,12 @@ public TSStatus visitShowDevices(ShowDevicesStatement statement, TreeAccessCheck AuthorityChecker.getAuthorizedPathTree( context.getUsername(), PrivilegeType.READ_DATA))); } catch (AuthException e) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1933,7 +1931,7 @@ public TSStatus visitCountDevices( .setPrivilegeTypes(Arrays.asList(PrivilegeType.READ_DATA, PrivilegeType.READ_SCHEMA)) .setAuditLogOperation(AuditLogOperation.QUERY); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1966,7 +1964,7 @@ protected TSStatus checkGlobalAuth( return SUCCEED; } TSStatus result = AuthorityChecker.getTSStatus(false, requiredPrivilege); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), auditObject); return result; @@ -1983,7 +1981,7 @@ protected boolean checkHasGlobalAuth( Supplier auditObject, boolean checkGrantOption) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(requiredPrivilege).setResult(true), auditObject); return true; } @@ -1992,7 +1990,7 @@ protected boolean checkHasGlobalAuth( ? AuthorityChecker.checkSystemPermissionGrantOption( context.getUsername(), requiredPrivilege) : AuthorityChecker.checkSystemPermission(context.getUsername(), requiredPrivilege); - recordObjectAuthenticationAuditLog( + AUDIT_LOGGER.recordAuditLog( context.setPrivilegeType(requiredPrivilege).setResult(result), auditObject); return result; } @@ -2000,7 +1998,7 @@ protected boolean checkHasGlobalAuth( protected TSStatus checkWriteOnReadOnlyPath(IAuditEntity auditEntity, PartialPath path) { if (includeByAuditTreeDB(path) && !AuthorityChecker.INTERNAL_AUDIT_USER.equals(path.getFullPath())) { - recordObjectAuthenticationAuditLog(auditEntity, path::getFullPath); + AUDIT_LOGGER.recordAuditLog(auditEntity, path::getFullPath); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -2018,23 +2016,10 @@ private TSStatus checkOnlySuperUser( IAuditEntity auditEntity, PrivilegeType privilegeType, Supplier auditObject) { auditEntity.setPrivilegeType(privilegeType); if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - recordObjectAuthenticationAuditLog(auditEntity.setResult(true), auditObject); + AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(true), auditObject); return SUCCEED; } - recordObjectAuthenticationAuditLog(auditEntity.setResult(false), auditObject); + AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(false), auditObject); return AuthorityChecker.getTSStatus(false, "Only the admin user can perform this operation"); } - - protected static void recordObjectAuthenticationAuditLog( - IAuditEntity auditEntity, Supplier auditObject) { - AUDIT_LOGGER.log( - auditEntity.setAuditEventType(AuditEventType.OBJECT_AUTHENTICATION), - () -> - String.format( - OBJECT_AUTHENTICATION_AUDIT_STR, - auditEntity.getUsername(), - auditEntity.getUserId(), - auditObject.get(), - auditEntity.getResult())); - } } 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 cec0336632100..4e94574accf36 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 @@ -25,7 +25,8 @@ import java.util.function.Supplier; public abstract class AbstractAuditLogger { - + public static final String OBJECT_AUTHENTICATION_AUDIT_STR = + "User %s (ID=%d) requests authority on object %s with result %s"; public static final String AUDIT_LOG_NODE_ID = "node_id"; public static final String AUDIT_LOG_USER_ID = "user_id"; public static final String AUDIT_LOG_USERNAME = "username"; @@ -47,4 +48,16 @@ public abstract class AbstractAuditLogger { public boolean noNeedInsertAuditLog(IAuditEntity auditLogFields) { return true; } + + public void recordAuditLog(final IAuditEntity auditEntity, final Supplier auditObject) { + log( + auditEntity.setAuditEventType(AuditEventType.OBJECT_AUTHENTICATION), + () -> + String.format( + OBJECT_AUTHENTICATION_AUDIT_STR, + auditEntity.getUsername(), + auditEntity.getUserId(), + auditObject.get(), + auditEntity.getResult())); + } } From c53722a0ec32d1b7800fc8fdc1187dd6e2e5c72c Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 10:00:17 +0800 Subject: [PATCH 02/19] permission-change --- .../pipe/source/IoTDBConfigRegionSource.java | 3 +- .../PipeConfigTreePrivilegeParseVisitor.java | 251 ++++++++++-------- .../config/TableConfigTaskVisitor.java | 7 +- .../security/TreeAccessCheckVisitor.java | 4 - .../commons/pipe/source/IoTDBSource.java | 2 + 5 files changed, 142 insertions(+), 125 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java index 86a10d16f1b22..8515dee97f6b3 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java @@ -246,7 +246,8 @@ protected Optional trimRealtimeEventByPrivilege( ((PipeConfigRegionWritePlanEvent) event).getConfigPhysicalPlan(); final Boolean isTableDatabasePlan = isTableDatabasePlan(plan); if (!Boolean.TRUE.equals(isTableDatabasePlan)) { - final Optional result = treePrivilegeParseVisitor.process(plan, userName); + final Optional result = + treePrivilegeParseVisitor.process(plan, userEntity); if (result.isPresent()) { return Optional.of( new PipeConfigRegionWritePlanEvent(result.get(), event.isGeneratedByPipe())); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 0d5f331bc3994..925ba9ef952ad 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -19,6 +19,7 @@ package org.apache.iotdb.confignode.manager.pipe.source; +import org.apache.iotdb.commons.audit.IAuditEntity; import org.apache.iotdb.commons.auth.AuthException; import org.apache.iotdb.commons.auth.entity.PrivilegeType; import org.apache.iotdb.commons.auth.entity.PrivilegeUnion; @@ -27,6 +28,7 @@ import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.commons.path.PathPatternTree; import org.apache.iotdb.commons.schema.template.Template; +import org.apache.iotdb.confignode.audit.CNAuditLogger; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor; import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan; @@ -40,6 +42,7 @@ import org.apache.iotdb.confignode.consensus.request.write.template.CommitSetSchemaTemplatePlan; import org.apache.iotdb.confignode.consensus.request.write.template.CreateSchemaTemplatePlan; import org.apache.iotdb.confignode.consensus.request.write.template.ExtendSchemaTemplatePlan; +import org.apache.iotdb.confignode.manager.ConfigManager; import org.apache.iotdb.confignode.service.ConfigNode; import org.apache.iotdb.rpc.TSStatusCode; @@ -57,7 +60,7 @@ import static org.apache.iotdb.commons.schema.SchemaConstant.ALL_MATCH_SCOPE; public class PipeConfigTreePrivilegeParseVisitor - extends ConfigPhysicalPlanVisitor, String> { + extends ConfigPhysicalPlanVisitor, IAuditEntity> { private static final Logger LOGGER = LoggerFactory.getLogger(PipeConfigTreePrivilegeParseVisitor.class); private final boolean skip; @@ -68,102 +71,79 @@ public class PipeConfigTreePrivilegeParseVisitor @Override public Optional visitPlan( - final ConfigPhysicalPlan plan, final String context) { + final ConfigPhysicalPlan plan, final IAuditEntity context) { return Optional.of(plan); } @Override public Optional visitCreateDatabase( - final DatabaseSchemaPlan createDatabasePlan, final String userName) { - return canReadSysSchema(createDatabasePlan.getSchema().getName(), userName, true) + final DatabaseSchemaPlan createDatabasePlan, final IAuditEntity userEntity) { + return canReadSysSchema(createDatabasePlan.getSchema().getName(), userEntity, true) ? Optional.of(createDatabasePlan) : Optional.empty(); } @Override public Optional visitAlterDatabase( - final DatabaseSchemaPlan alterDatabasePlan, final String userName) { - return canReadSysSchema(alterDatabasePlan.getSchema().getName(), userName, true) + final DatabaseSchemaPlan alterDatabasePlan, final IAuditEntity userEntity) { + return canReadSysSchema(alterDatabasePlan.getSchema().getName(), userEntity, true) ? Optional.of(alterDatabasePlan) : Optional.empty(); } @Override public Optional visitDeleteDatabase( - final DeleteDatabasePlan deleteDatabasePlan, final String userName) { - return canReadSysSchema(deleteDatabasePlan.getName(), userName, true) + final DeleteDatabasePlan deleteDatabasePlan, final IAuditEntity userEntity) { + return canReadSysSchema(deleteDatabasePlan.getName(), userEntity, true) ? Optional.of(deleteDatabasePlan) : Optional.empty(); } @Override public Optional visitCreateSchemaTemplate( - final CreateSchemaTemplatePlan createSchemaTemplatePlan, final String userName) { - return canShowSchemaTemplate(createSchemaTemplatePlan.getTemplate().getName(), userName) + final CreateSchemaTemplatePlan createSchemaTemplatePlan, final IAuditEntity userEntity) { + return canShowSchemaTemplate(createSchemaTemplatePlan.getTemplate().getName(), userEntity) ? Optional.of(createSchemaTemplatePlan) : Optional.empty(); } @Override public Optional visitCommitSetSchemaTemplate( - final CommitSetSchemaTemplatePlan commitSetSchemaTemplatePlan, final String userName) { - return canReadSysSchema(commitSetSchemaTemplatePlan.getPath(), userName, false) + final CommitSetSchemaTemplatePlan commitSetSchemaTemplatePlan, + final IAuditEntity userEntity) { + return canReadSysSchema(commitSetSchemaTemplatePlan.getPath(), userEntity, false) ? Optional.of(commitSetSchemaTemplatePlan) : Optional.empty(); } @Override public Optional visitPipeUnsetSchemaTemplate( - final PipeUnsetSchemaTemplatePlan pipeUnsetSchemaTemplatePlan, final String userName) { - return canReadSysSchema(pipeUnsetSchemaTemplatePlan.getPath(), userName, false) + final PipeUnsetSchemaTemplatePlan pipeUnsetSchemaTemplatePlan, + final IAuditEntity userEntity) { + return canReadSysSchema(pipeUnsetSchemaTemplatePlan.getPath(), userEntity, false) ? Optional.of(pipeUnsetSchemaTemplatePlan) : Optional.empty(); } @Override public Optional visitExtendSchemaTemplate( - final ExtendSchemaTemplatePlan extendSchemaTemplatePlan, final String userName) { + final ExtendSchemaTemplatePlan extendSchemaTemplatePlan, final IAuditEntity userEntity) { return canShowSchemaTemplate( - extendSchemaTemplatePlan.getTemplateExtendInfo().getTemplateName(), userName) + extendSchemaTemplatePlan.getTemplateExtendInfo().getTemplateName(), userEntity) ? Optional.of(extendSchemaTemplatePlan) : Optional.empty(); } - public boolean canShowSchemaTemplate(final String templateName, final String userName) { + public boolean canShowSchemaTemplate(final String templateName, final IAuditEntity userEntity) { try { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.SYSTEM)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() + return hasGlobalPrivilege(userEntity, PrivilegeType.SYSTEM, templateName, false) || ConfigNode.getInstance() .getConfigManager() .getClusterSchemaManager() .getPathsSetTemplate(templateName, ALL_MATCH_SCOPE) .getPathList() .stream() - .anyMatch( - path -> { - try { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges( - userName, - new PrivilegeUnion( - Collections.singletonList( - new PartialPath(path) - .concatNode(MULTI_LEVEL_PATH_WILDCARD)), - PrivilegeType.READ_SCHEMA)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode(); - } catch (final IllegalPathException e) { - throw new RuntimeException(e); - } - }); + .anyMatch(path -> hasReadPrivilege(userEntity, path, true, true)); } catch (final Exception e) { LOGGER.warn( "Un-parse-able path name encountered during template privilege trimming, please check", @@ -173,103 +153,83 @@ public boolean canShowSchemaTemplate(final String templateName, final String use } public boolean canReadSysSchema( - final String path, final String userName, final boolean canSkipMulti) { - try { - return canSkipMulti - && ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges( - userName, - new PrivilegeUnion( - Collections.singletonList(new PartialPath(path)), - PrivilegeType.READ_SCHEMA)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - || ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges( - userName, - new PrivilegeUnion( - Collections.singletonList( - new PartialPath(path).concatNode(MULTI_LEVEL_PATH_WILDCARD)), - PrivilegeType.READ_SCHEMA)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - || ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.SYSTEM)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode(); - } catch (final IllegalPathException e) { - LOGGER.warn("Un-parse-able path name encountered during privilege trimming, please check", e); - return false; - } + final String path, final IAuditEntity userEntity, final boolean canSkipMulti) { + return canSkipMulti && hasReadPrivilege(userEntity, path, false, false) + || hasReadPrivilege(userEntity, path, true, false) + || hasGlobalPrivilege(userEntity, PrivilegeType.SYSTEM, path, true); } @Override public Optional visitGrantUser( - final AuthorTreePlan grantUserPlan, final String userName) { - return visitUserPlan(grantUserPlan, userName); + final AuthorTreePlan grantUserPlan, final IAuditEntity userEntity) { + return visitUserPlan(grantUserPlan, userEntity); } @Override public Optional visitRevokeUser( - final AuthorTreePlan revokeUserPlan, final String userName) { - return visitUserPlan(revokeUserPlan, userName); + final AuthorTreePlan revokeUserPlan, final IAuditEntity userEntity) { + return visitUserPlan(revokeUserPlan, userEntity); } @Override public Optional visitGrantRole( - final AuthorTreePlan grantRolePlan, final String userName) { - return visitRolePlan(grantRolePlan, userName); + final AuthorTreePlan grantRolePlan, final IAuditEntity userEntity) { + return visitRolePlan(grantRolePlan, userEntity); } @Override public Optional visitRevokeRole( - final AuthorTreePlan revokeRolePlan, final String userName) { - return visitRolePlan(revokeRolePlan, userName); + final AuthorTreePlan revokeRolePlan, final IAuditEntity userEntity) { + return visitRolePlan(revokeRolePlan, userEntity); } private Optional visitUserPlan( - final AuthorTreePlan plan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.MANAGE_USER)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() + final AuthorTreePlan plan, final IAuditEntity userEntity) { + final String auditObject = plan.getUserName(); + if (userEntity.getUsername().equals(plan.getUserName())) { + ConfigNode.getInstance() + .getConfigManager() + .getAuditLogger() + .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); + return Optional.of(plan); + } + return hasGlobalPrivilege(userEntity, PrivilegeType.MANAGE_USER, plan.getUserName(), true) ? Optional.of(plan) : Optional.empty(); } private Optional visitRolePlan( - final AuthorTreePlan plan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.MANAGE_ROLE)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() + final AuthorTreePlan plan, final IAuditEntity userEntity) { + final String auditObject = plan.getRoleName(); + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + try { + if (configManager + .getPermissionManager() + .checkRoleOfUser(userEntity.getUsername(), plan.getRoleName()) + .getStatus() + .getCode() + == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + configManager + .getAuditLogger() + .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); + return Optional.of(plan); + } + } catch (final Exception ignore) { + // Check manage role + } + return hasGlobalPrivilege(userEntity, PrivilegeType.MANAGE_ROLE, plan.getRoleName(), true) ? Optional.of(plan) : Optional.empty(); } @Override public Optional visitPipeDeleteTimeSeries( - final PipeDeleteTimeSeriesPlan pipeDeleteTimeSeriesPlan, final String userName) { + final PipeDeleteTimeSeriesPlan pipeDeleteTimeSeriesPlan, final IAuditEntity userEntity) { try { final PathPatternTree originalTree = PathPatternTree.deserialize(pipeDeleteTimeSeriesPlan.getPatternTreeBytes()); final PathPatternTree intersectedTree = - originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userName)); + originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !originalTree.equals(intersectedTree)) { throw new AccessDeniedException( "Not has privilege to transfer plan: " + pipeDeleteTimeSeriesPlan); @@ -294,12 +254,12 @@ public Optional visitPipeDeleteTimeSeries( @Override public Optional visitPipeDeleteLogicalView( - final PipeDeleteLogicalViewPlan pipeDeleteLogicalViewPlan, final String userName) { + final PipeDeleteLogicalViewPlan pipeDeleteLogicalViewPlan, final IAuditEntity userEntity) { try { final PathPatternTree originalTree = PathPatternTree.deserialize(pipeDeleteLogicalViewPlan.getPatternTreeBytes()); final PathPatternTree intersectedTree = - originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userName)); + originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !originalTree.equals(intersectedTree)) { throw new AccessDeniedException( "Not has privilege to transfer plan: " + pipeDeleteLogicalViewPlan); @@ -324,14 +284,14 @@ public Optional visitPipeDeleteLogicalView( @Override public Optional visitPipeDeactivateTemplate( - final PipeDeactivateTemplatePlan pipeDeactivateTemplatePlan, final String userName) { + final PipeDeactivateTemplatePlan pipeDeactivateTemplatePlan, final IAuditEntity userEntity) { try { final Map> newTemplateSetInfo = new HashMap<>(); for (final Map.Entry> templateEntry : pipeDeactivateTemplatePlan.getTemplateSetInfo().entrySet()) { for (final PartialPath intersectedPath : getAllIntersectedPatterns( - templateEntry.getKey(), userName, pipeDeactivateTemplatePlan)) { + templateEntry.getKey(), userEntity, pipeDeactivateTemplatePlan)) { // root.db.device2.measurement -> root.db.device.** = root.db // Note that we cannot take this circumstance into account if (intersectedPath.getNodeLength() == templateEntry.getKey().getNodeLength()) { @@ -353,11 +313,12 @@ public Optional visitPipeDeactivateTemplate( } @Override - public Optional visitTTL(final SetTTLPlan setTTLPlan, final String userName) { + public Optional visitTTL( + final SetTTLPlan setTTLPlan, final IAuditEntity userEntity) { try { final List paths = getAllIntersectedPatterns( - new PartialPath(setTTLPlan.getPathPattern()), userName, setTTLPlan); + new PartialPath(setTTLPlan.getPathPattern()), userEntity, setTTLPlan); // The intersectionList is either a singleton list or an empty list, because the pipe // pattern and TTL path are each either a prefix path or a full path return !paths.isEmpty() && paths.get(0).getNodeLength() == setTTLPlan.getPathPattern().length @@ -373,23 +334,79 @@ public Optional visitTTL(final SetTTLPlan setTTLPlan, final } private List getAllIntersectedPatterns( - final PartialPath partialPath, final String userName, final ConfigPhysicalPlan plan) + final PartialPath partialPath, final IAuditEntity userEntity, final ConfigPhysicalPlan plan) throws AuthException { final PathPatternTree thisPatternTree = new PathPatternTree(); thisPatternTree.appendPathPattern(partialPath); thisPatternTree.constructTree(); final PathPatternTree intersectedTree = - thisPatternTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userName)); + thisPatternTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !thisPatternTree.equals(intersectedTree)) { throw new AccessDeniedException("Not has privilege to transfer plan: " + plan); } return intersectedTree.getAllPathPatterns(); } - private PathPatternTree getAuthorizedPTree(final String userName) throws AuthException { + private PathPatternTree getAuthorizedPTree(final IAuditEntity userEntity) throws AuthException { return ConfigNode.getInstance() .getConfigManager() .getPermissionManager() - .fetchRawAuthorizedPTree(userName, PrivilegeType.READ_SCHEMA); + .fetchRawAuthorizedPTree(userEntity, PrivilegeType.READ_SCHEMA); + } + + private boolean hasGlobalPrivilege( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String auditObject, + final boolean isLastCheck) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + final boolean result = + configManager + .getPermissionManager() + .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(privilegeType)) + .getStatus() + .getCode() + == TSStatusCode.SUCCESS_STATUS.getStatusCode(); + if (result || isLastCheck) { + logger.recordAuditLog( + userEntity.setPrivilegeType(privilegeType).setResult(result), () -> auditObject); + } + return result; + } + + private boolean hasReadPrivilege( + final IAuditEntity userEntity, + final String path, + final boolean withWildcard, + final boolean isLastCheck) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + PartialPath partialPath; + try { + partialPath = new PartialPath(path); + } catch (final IllegalPathException e) { + LOGGER.warn("Unable to parse path when checking READ privilege, path: {}", path); + return false; + } + if (withWildcard) { + partialPath = partialPath.concatNode(MULTI_LEVEL_PATH_WILDCARD); + } + final boolean result = + ConfigNode.getInstance() + .getConfigManager() + .getPermissionManager() + .checkUserPrivileges( + userEntity.getUsername(), + new PrivilegeUnion( + Collections.singletonList(partialPath), PrivilegeType.READ_SCHEMA)) + .getStatus() + .getCode() + == TSStatusCode.SUCCESS_STATUS.getStatusCode(); + if (result || isLastCheck) { + logger.recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA).setResult(result), () -> path); + } + return result; } } 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 1de3643cabe55..60be9a4655441 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 @@ -41,6 +41,7 @@ import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory; import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema; import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema; +import org.apache.iotdb.db.audit.DNAuditLogger; import org.apache.iotdb.db.auth.AuthorityChecker; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.exception.sql.SemanticException; @@ -134,7 +135,6 @@ import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName; import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableHeaderSchemaValidator; import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl; -import org.apache.iotdb.db.queryengine.plan.relational.security.ITableAuthCheckerImpl; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AddColumn; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterPipe; @@ -500,8 +500,9 @@ protected IConfigTask visitShowDataNodes( protected IConfigTask visitShowAvailableUrls( final ShowAvailableUrls showAvailableUrls, final MPPQueryContext context) { context.setQueryType(QueryType.READ); - ITableAuthCheckerImpl.recordAuditLog( - context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), () -> ""); + DNAuditLogger.getInstance() + .recordAuditLog( + context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), () -> ""); return new ShowAvailableUrlsTask(); } 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 5631bc0051f8d..d53b52d2e9378 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 @@ -652,10 +652,6 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co case GRANT_ROLE: case REVOKE_ROLE: case ACCOUNT_UNLOCK: - context - .setAuditLogOperation(AuditLogOperation.DDL) - .setPrivilegeType(PrivilegeType.SECURITY); - context.setAuditLogOperation(AuditLogOperation.DDL); auditObject = () -> authorType == AuthorType.REVOKE_USER || authorType == AuthorType.GRANT_USER diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/source/IoTDBSource.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/source/IoTDBSource.java index 6640fde7f4a62..91a149c9f6690 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/source/IoTDBSource.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/source/IoTDBSource.java @@ -19,6 +19,7 @@ package org.apache.iotdb.commons.pipe.source; +import org.apache.iotdb.commons.audit.AuditLogOperation; import org.apache.iotdb.commons.audit.UserEntity; import org.apache.iotdb.commons.pipe.agent.task.meta.PipeTaskMeta; import org.apache.iotdb.commons.pipe.config.constant.PipeSourceConstant; @@ -195,6 +196,7 @@ public void customize( PipeSourceConstant.EXTRACTOR_IOTDB_CLI_HOSTNAME, PipeSourceConstant.SOURCE_IOTDB_CLI_HOSTNAME); userEntity = new UserEntity(Long.parseLong(userId), userName, cliHostname); + userEntity.setAuditLogOperation(AuditLogOperation.QUERY); skipIfNoPrivileges = getSkipIfNoPrivileges(parameters); } From 857e0b576531d0aa996843376896acc09d2e73f8 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 11:10:09 +0800 Subject: [PATCH 03/19] user_role --- .../PipeConfigTablePrivilegeParseVisitor.java | 287 ++++++++---------- .../PipeConfigTreePrivilegeParseVisitor.java | 25 +- 2 files changed, 154 insertions(+), 158 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java index bf0871f003232..3ae3b3ed9fe71 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java @@ -19,8 +19,10 @@ package org.apache.iotdb.confignode.manager.pipe.source; +import org.apache.iotdb.commons.audit.IAuditEntity; import org.apache.iotdb.commons.auth.entity.PrivilegeType; import org.apache.iotdb.commons.auth.entity.PrivilegeUnion; +import org.apache.iotdb.confignode.audit.CNAuditLogger; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor; import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan; @@ -37,353 +39,334 @@ import org.apache.iotdb.confignode.consensus.request.write.table.SetTableColumnCommentPlan; import org.apache.iotdb.confignode.consensus.request.write.table.SetTableCommentPlan; import org.apache.iotdb.confignode.consensus.request.write.table.SetTablePropertiesPlan; +import org.apache.iotdb.confignode.manager.ConfigManager; import org.apache.iotdb.confignode.service.ConfigNode; import org.apache.iotdb.rpc.TSStatusCode; import java.util.Optional; public class PipeConfigTablePrivilegeParseVisitor - extends ConfigPhysicalPlanVisitor, String> { + extends ConfigPhysicalPlanVisitor, IAuditEntity> { @Override public Optional visitPlan( - final ConfigPhysicalPlan plan, final String userName) { + final ConfigPhysicalPlan plan, final IAuditEntity userEntity) { return Optional.of(plan); } @Override public Optional visitCreateDatabase( - final DatabaseSchemaPlan createDatabasePlan, final String userName) { - return visitDatabaseSchemaPlan(createDatabasePlan, userName); + final DatabaseSchemaPlan createDatabasePlan, final IAuditEntity userEntity) { + return visitDatabaseSchemaPlan(createDatabasePlan, userEntity); } @Override public Optional visitAlterDatabase( - final DatabaseSchemaPlan alterDatabasePlan, final String userName) { - return visitDatabaseSchemaPlan(alterDatabasePlan, userName); + final DatabaseSchemaPlan alterDatabasePlan, final IAuditEntity userEntity) { + return visitDatabaseSchemaPlan(alterDatabasePlan, userEntity); } public Optional visitDatabaseSchemaPlan( - final DatabaseSchemaPlan databaseSchemaPlan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges( - userName, new PrivilegeUnion(databaseSchemaPlan.getSchema().getName(), null)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() + final DatabaseSchemaPlan databaseSchemaPlan, final IAuditEntity userEntity) { + return isDatabaseVisible(userEntity, databaseSchemaPlan.getSchema().getName()) ? Optional.of(databaseSchemaPlan) : Optional.empty(); } @Override public Optional visitDeleteDatabase( - final DeleteDatabasePlan deleteDatabasePlan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges( - userName, new PrivilegeUnion(deleteDatabasePlan.getName(), null)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() + final DeleteDatabasePlan deleteDatabasePlan, final IAuditEntity userEntity) { + return isDatabaseVisible(userEntity, deleteDatabasePlan.getName()) ? Optional.of(deleteDatabasePlan) : Optional.empty(); } - @Override - public Optional visitPipeCreateTableOrView( - final PipeCreateTableOrViewPlan pipeCreateTableOrViewPlan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() + private boolean isDatabaseVisible(final IAuditEntity userEntity, final String database) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + boolean result = + configManager .getPermissionManager() - .checkUserPrivileges( - userName, - new PrivilegeUnion( - pipeCreateTableOrViewPlan.getDatabase(), - pipeCreateTableOrViewPlan.getTable().getTableName(), - null)) + .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(database, null)) .getStatus() .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() + == TSStatusCode.SUCCESS_STATUS.getStatusCode(); + if (result) { + logger.recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA).setResult(true), () -> database); + return true; + } + return PipeConfigTreePrivilegeParseVisitor.hasGlobalPrivilege( + userEntity, PrivilegeType.SYSTEM, database, true); + } + + @Override + public Optional visitPipeCreateTableOrView( + final PipeCreateTableOrViewPlan pipeCreateTableOrViewPlan, final IAuditEntity userEntity) { + return isTableVisible( + userEntity, + pipeCreateTableOrViewPlan.getDatabase(), + pipeCreateTableOrViewPlan.getTable().getTableName()) ? Optional.of(pipeCreateTableOrViewPlan) : Optional.empty(); } @Override public Optional visitAddTableColumn( - final AddTableColumnPlan addTableColumnPlan, final String userName) { - return visitAbstractTablePlan(addTableColumnPlan, userName); + final AddTableColumnPlan addTableColumnPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(addTableColumnPlan, userEntity); } @Override public Optional visitSetTableProperties( - final SetTablePropertiesPlan setTablePropertiesPlan, final String userName) { - return visitAbstractTablePlan(setTablePropertiesPlan, userName); + final SetTablePropertiesPlan setTablePropertiesPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(setTablePropertiesPlan, userEntity); } @Override public Optional visitCommitDeleteColumn( - final CommitDeleteColumnPlan commitDeleteColumnPlan, final String userName) { - return visitAbstractTablePlan(commitDeleteColumnPlan, userName); + final CommitDeleteColumnPlan commitDeleteColumnPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(commitDeleteColumnPlan, userEntity); } @Override public Optional visitRenameTableColumn( - final RenameTableColumnPlan renameTableColumnPlan, final String userName) { - return visitAbstractTablePlan(renameTableColumnPlan, userName); + final RenameTableColumnPlan renameTableColumnPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(renameTableColumnPlan, userEntity); } @Override public Optional visitCommitDeleteTable( - final CommitDeleteTablePlan commitDeleteTablePlan, final String userName) { - return visitAbstractTablePlan(commitDeleteTablePlan, userName); + final CommitDeleteTablePlan commitDeleteTablePlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(commitDeleteTablePlan, userEntity); } @Override public Optional visitPipeDeleteDevices( - final PipeDeleteDevicesPlan pipeDeleteDevicesPlan, final String userName) { - return visitAbstractTablePlan(pipeDeleteDevicesPlan, userName); + final PipeDeleteDevicesPlan pipeDeleteDevicesPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(pipeDeleteDevicesPlan, userEntity); } @Override public Optional visitSetTableComment( - final SetTableCommentPlan setTableCommentPlan, final String userName) { - return visitAbstractTablePlan(setTableCommentPlan, userName); + final SetTableCommentPlan setTableCommentPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(setTableCommentPlan, userEntity); } @Override public Optional visitSetTableColumnComment( - final SetTableColumnCommentPlan setTableColumnCommentPlan, final String userName) { - return visitAbstractTablePlan(setTableColumnCommentPlan, userName); + final SetTableColumnCommentPlan setTableColumnCommentPlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(setTableColumnCommentPlan, userEntity); } @Override public Optional visitRenameTable( - final RenameTablePlan renameTablePlan, final String userName) { - return visitAbstractTablePlan(renameTablePlan, userName); + final RenameTablePlan renameTablePlan, final IAuditEntity userEntity) { + return visitAbstractTablePlan(renameTablePlan, userEntity); } private Optional visitAbstractTablePlan( - final AbstractTablePlan plan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() + final AbstractTablePlan plan, final IAuditEntity userEntity) { + return isTableVisible(userEntity, plan.getDatabase(), plan.getTableName()) + ? Optional.of(plan) + : Optional.empty(); + } + + private boolean isTableVisible( + final IAuditEntity userEntity, final String database, final String tableName) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + boolean result = + configManager .getPermissionManager() .checkUserPrivileges( - userName, new PrivilegeUnion(plan.getDatabase(), plan.getTableName(), null)) + userEntity.getUsername(), new PrivilegeUnion(database, tableName, null)) .getStatus() .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - ? Optional.of(plan) - : Optional.empty(); + == TSStatusCode.SUCCESS_STATUS.getStatusCode(); + if (result) { + logger.recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA).setResult(true), () -> database); + return true; + } + return PipeConfigTreePrivilegeParseVisitor.hasGlobalPrivilege( + userEntity, PrivilegeType.SYSTEM, tableName, true); } @Override public Optional visitRCreateUser( - final AuthorRelationalPlan rCreateUserPlan, final String userName) { - return visitUserPlan(rCreateUserPlan, userName); + final AuthorRelationalPlan rCreateUserPlan, final IAuditEntity userEntity) { + return visitUserPlan(rCreateUserPlan, userEntity); } @Override public Optional visitRCreateRole( - final AuthorRelationalPlan rCreateRolePlan, final String userName) { - return visitRolePlan(rCreateRolePlan, userName); + final AuthorRelationalPlan rCreateRolePlan, final IAuditEntity userEntity) { + return visitRolePlan(rCreateRolePlan, userEntity); } @Override public Optional visitRUpdateUser( - final AuthorRelationalPlan rUpdateUserPlan, final String userName) { - return visitUserPlan(rUpdateUserPlan, userName); + final AuthorRelationalPlan rUpdateUserPlan, final IAuditEntity userEntity) { + return visitUserPlan(rUpdateUserPlan, userEntity); } @Override public Optional visitRDropUserPlan( - final AuthorRelationalPlan rDropUserPlan, final String userName) { - return visitUserPlan(rDropUserPlan, userName); + final AuthorRelationalPlan rDropUserPlan, final IAuditEntity userEntity) { + return visitUserPlan(rDropUserPlan, userEntity); } @Override public Optional visitRDropRolePlan( - final AuthorRelationalPlan rDropRolePlan, final String userName) { - return visitRolePlan(rDropRolePlan, userName); + final AuthorRelationalPlan rDropRolePlan, final IAuditEntity userEntity) { + return visitRolePlan(rDropRolePlan, userEntity); } @Override public Optional visitRGrantUserRole( - final AuthorRelationalPlan rGrantUserRolePlan, final String userName) { - return visitUserRolePlan(rGrantUserRolePlan, userName); + final AuthorRelationalPlan rGrantUserRolePlan, final IAuditEntity userEntity) { + return visitUserRolePlan(rGrantUserRolePlan, userEntity); } @Override public Optional visitRRevokeUserRole( - final AuthorRelationalPlan rRevokeUserRolePlan, final String userName) { - return visitUserRolePlan(rRevokeUserRolePlan, userName); + final AuthorRelationalPlan rRevokeUserRolePlan, final IAuditEntity userEntity) { + return visitUserRolePlan(rRevokeUserRolePlan, userEntity); } @Override public Optional visitRGrantUserAny( - final AuthorRelationalPlan rGrantUserAnyPlan, final String userName) { - return visitUserPlan(rGrantUserAnyPlan, userName); + final AuthorRelationalPlan rGrantUserAnyPlan, final IAuditEntity userEntity) { + return visitUserPlan(rGrantUserAnyPlan, userEntity); } @Override public Optional visitRGrantRoleAny( - final AuthorRelationalPlan rGrantRoleAnyPlan, final String userName) { - return visitRolePlan(rGrantRoleAnyPlan, userName); + final AuthorRelationalPlan rGrantRoleAnyPlan, final IAuditEntity userEntity) { + return visitRolePlan(rGrantRoleAnyPlan, userEntity); } @Override public Optional visitRGrantUserAll( - final AuthorRelationalPlan rGrantUserAllPlan, final String userName) { - return visitUserPlan(rGrantUserAllPlan, userName); + final AuthorRelationalPlan rGrantUserAllPlan, final IAuditEntity userEntity) { + return visitUserPlan(rGrantUserAllPlan, userEntity); } @Override public Optional visitRGrantRoleAll( - final AuthorRelationalPlan rGrantRoleAllPlan, final String userName) { - return visitRolePlan(rGrantRoleAllPlan, userName); + final AuthorRelationalPlan rGrantRoleAllPlan, final IAuditEntity userEntity) { + return visitRolePlan(rGrantRoleAllPlan, userEntity); } @Override public Optional visitRGrantUserDB( - final AuthorRelationalPlan rGrantUserDBPlan, final String userName) { - return visitUserPlan(rGrantUserDBPlan, userName); + final AuthorRelationalPlan rGrantUserDBPlan, final IAuditEntity userEntity) { + return visitUserPlan(rGrantUserDBPlan, userEntity); } @Override public Optional visitRGrantUserTB( - final AuthorRelationalPlan rGrantUserTBPlan, final String userName) { - return visitUserPlan(rGrantUserTBPlan, userName); + final AuthorRelationalPlan rGrantUserTBPlan, final IAuditEntity userEntity) { + return visitUserPlan(rGrantUserTBPlan, userEntity); } @Override public Optional visitRGrantRoleDB( - final AuthorRelationalPlan rGrantRoleDBPlan, final String userName) { - return visitRolePlan(rGrantRoleDBPlan, userName); + final AuthorRelationalPlan rGrantRoleDBPlan, final IAuditEntity userEntity) { + return visitRolePlan(rGrantRoleDBPlan, userEntity); } @Override public Optional visitRGrantRoleTB( - final AuthorRelationalPlan rGrantRoleTBPlan, final String userName) { - return visitRolePlan(rGrantRoleTBPlan, userName); + final AuthorRelationalPlan rGrantRoleTBPlan, final IAuditEntity userEntity) { + return visitRolePlan(rGrantRoleTBPlan, userEntity); } @Override public Optional visitRRevokeUserAny( - final AuthorRelationalPlan rRevokeUserAnyPlan, final String userName) { - return visitUserPlan(rRevokeUserAnyPlan, userName); + final AuthorRelationalPlan rRevokeUserAnyPlan, final IAuditEntity userEntity) { + return visitUserPlan(rRevokeUserAnyPlan, userEntity); } @Override public Optional visitRRevokeRoleAny( - final AuthorRelationalPlan rRevokeRoleAnyPlan, final String userName) { - return visitRolePlan(rRevokeRoleAnyPlan, userName); + final AuthorRelationalPlan rRevokeRoleAnyPlan, final IAuditEntity userEntity) { + return visitRolePlan(rRevokeRoleAnyPlan, userEntity); } @Override public Optional visitRRevokeUserAll( - final AuthorRelationalPlan rRevokeUserAllPlan, final String userName) { - return visitUserPlan(rRevokeUserAllPlan, userName); + final AuthorRelationalPlan rRevokeUserAllPlan, final IAuditEntity userEntity) { + return visitUserPlan(rRevokeUserAllPlan, userEntity); } @Override public Optional visitRRevokeRoleAll( - final AuthorRelationalPlan rRevokeRoleAllPlan, final String userName) { - return visitRolePlan(rRevokeRoleAllPlan, userName); + final AuthorRelationalPlan rRevokeRoleAllPlan, final IAuditEntity userEntity) { + return visitRolePlan(rRevokeRoleAllPlan, userEntity); } @Override public Optional visitRRevokeUserDBPrivilege( - final AuthorRelationalPlan rRevokeUserDBPrivilegePlan, final String userName) { - return visitUserPlan(rRevokeUserDBPrivilegePlan, userName); + final AuthorRelationalPlan rRevokeUserDBPrivilegePlan, final IAuditEntity userEntity) { + return visitUserPlan(rRevokeUserDBPrivilegePlan, userEntity); } @Override public Optional visitRRevokeUserTBPrivilege( - final AuthorRelationalPlan rRevokeUserTBPrivilegePlan, final String userName) { - return visitUserPlan(rRevokeUserTBPrivilegePlan, userName); + final AuthorRelationalPlan rRevokeUserTBPrivilegePlan, final IAuditEntity userEntity) { + return visitUserPlan(rRevokeUserTBPrivilegePlan, userEntity); } @Override public Optional visitRRevokeRoleDBPrivilege( - final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final String userName) { - return visitRolePlan(rRevokeRoleTBPrivilegePlan, userName); + final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final IAuditEntity userEntity) { + return visitRolePlan(rRevokeRoleTBPrivilegePlan, userEntity); } @Override public Optional visitRRevokeRoleTBPrivilege( - final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final String userName) { - return visitRolePlan(rRevokeRoleTBPrivilegePlan, userName); + final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final IAuditEntity userEntity) { + return visitRolePlan(rRevokeRoleTBPrivilegePlan, userEntity); } @Override public Optional visitRGrantUserSysPrivilege( - final AuthorRelationalPlan rGrantUserSysPrivilegePlan, final String userName) { - return visitUserPlan(rGrantUserSysPrivilegePlan, userName); + final AuthorRelationalPlan rGrantUserSysPrivilegePlan, final IAuditEntity userEntity) { + return visitUserPlan(rGrantUserSysPrivilegePlan, userEntity); } @Override public Optional visitRGrantRoleSysPrivilege( - final AuthorRelationalPlan rGrantRoleSysPrivilegePlan, final String userName) { - return visitRolePlan(rGrantRoleSysPrivilegePlan, userName); + final AuthorRelationalPlan rGrantRoleSysPrivilegePlan, final IAuditEntity userEntity) { + return visitRolePlan(rGrantRoleSysPrivilegePlan, userEntity); } @Override public Optional visitRRevokeUserSysPrivilege( - final AuthorRelationalPlan rRevokeUserSysPrivilegePlan, final String userName) { - return visitUserPlan(rRevokeUserSysPrivilegePlan, userName); + final AuthorRelationalPlan rRevokeUserSysPrivilegePlan, final IAuditEntity userEntity) { + return visitUserPlan(rRevokeUserSysPrivilegePlan, userEntity); } @Override public Optional visitRRevokeRoleSysPrivilege( - final AuthorRelationalPlan rRevokeRoleSysPrivilegePlan, final String userName) { - return visitRolePlan(rRevokeRoleSysPrivilegePlan, userName); + final AuthorRelationalPlan rRevokeRoleSysPrivilegePlan, final IAuditEntity userEntity) { + return visitRolePlan(rRevokeRoleSysPrivilegePlan, userEntity); } private Optional visitUserPlan( - final AuthorRelationalPlan plan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.MANAGE_USER)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - ? Optional.of(plan) - : Optional.empty(); + final AuthorRelationalPlan plan, final IAuditEntity userEntity) { + return PipeConfigTreePrivilegeParseVisitor.visitUserPlan(plan, userEntity); } private Optional visitRolePlan( - final AuthorRelationalPlan plan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.MANAGE_ROLE)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - ? Optional.of(plan) - : Optional.empty(); + final AuthorRelationalPlan plan, final IAuditEntity userEntity) { + return PipeConfigTreePrivilegeParseVisitor.visitRolePlan(plan, userEntity); } private Optional visitUserRolePlan( - final AuthorRelationalPlan plan, final String userName) { - return ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.MANAGE_ROLE)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - || ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges(userName, new PrivilegeUnion(PrivilegeType.MANAGE_USER)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode() - ? Optional.of(plan) - : Optional.empty(); + final AuthorRelationalPlan plan, final IAuditEntity userEntity) { + return PipeConfigTreePrivilegeParseVisitor.visitUserRolePlan(plan, userEntity); } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 925ba9ef952ad..4fe00a92ab00b 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -31,6 +31,7 @@ import org.apache.iotdb.confignode.audit.CNAuditLogger; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor; +import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan; import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan; import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan; import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan; @@ -183,8 +184,19 @@ public Optional visitRevokeRole( return visitRolePlan(revokeRolePlan, userEntity); } - private Optional visitUserPlan( - final AuthorTreePlan plan, final IAuditEntity userEntity) { + public static Optional visitUserRolePlan( + final AuthorPlan plan, final IAuditEntity userEntity) { + final Optional result = visitUserPlan(plan, userEntity, false); + return result.isPresent() ? result : visitRolePlan(plan, userEntity); + } + + public static Optional visitUserPlan( + final AuthorPlan plan, final IAuditEntity userEntity) { + return visitUserPlan(plan, userEntity, true); + } + + public static Optional visitUserPlan( + final AuthorPlan plan, final IAuditEntity userEntity, final boolean isLastCheck) { final String auditObject = plan.getUserName(); if (userEntity.getUsername().equals(plan.getUserName())) { ConfigNode.getInstance() @@ -193,13 +205,14 @@ private Optional visitUserPlan( .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); return Optional.of(plan); } - return hasGlobalPrivilege(userEntity, PrivilegeType.MANAGE_USER, plan.getUserName(), true) + return hasGlobalPrivilege( + userEntity, PrivilegeType.MANAGE_USER, plan.getUserName(), isLastCheck) ? Optional.of(plan) : Optional.empty(); } - private Optional visitRolePlan( - final AuthorTreePlan plan, final IAuditEntity userEntity) { + public static Optional visitRolePlan( + final AuthorPlan plan, final IAuditEntity userEntity) { final String auditObject = plan.getRoleName(); final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); try { @@ -354,7 +367,7 @@ private PathPatternTree getAuthorizedPTree(final IAuditEntity userEntity) throws .fetchRawAuthorizedPTree(userEntity, PrivilegeType.READ_SCHEMA); } - private boolean hasGlobalPrivilege( + public static boolean hasGlobalPrivilege( final IAuditEntity userEntity, final PrivilegeType privilegeType, final String auditObject, From f2f92b5d7af425f443f1af7f3e4eb5d2fb8ce7f8 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 11:26:48 +0800 Subject: [PATCH 04/19] part --- .../PipeConfigTreePrivilegeParseVisitor.java | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 4fe00a92ab00b..e86981acffb43 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -184,6 +184,18 @@ public Optional visitRevokeRole( return visitRolePlan(revokeRolePlan, userEntity); } + @Override + public Optional visitGrantRoleToUser( + final AuthorTreePlan grantRoleToUserPlan, final IAuditEntity userEntity) { + return visitUserRolePlan(grantRoleToUserPlan, userEntity); + } + + @Override + public Optional visitRevokeRoleFromUser( + final AuthorTreePlan revokeRoleFromUserPlan, final IAuditEntity userEntity) { + return visitUserRolePlan(revokeRoleFromUserPlan, userEntity); + } + public static Optional visitUserRolePlan( final AuthorPlan plan, final IAuditEntity userEntity) { final Optional result = visitUserPlan(plan, userEntity, false); @@ -238,24 +250,32 @@ public static Optional visitRolePlan( @Override public Optional visitPipeDeleteTimeSeries( final PipeDeleteTimeSeriesPlan pipeDeleteTimeSeriesPlan, final IAuditEntity userEntity) { + final CNAuditLogger logger = ConfigNode.getInstance().getConfigManager().getAuditLogger(); + final PathPatternTree originalTree = + PathPatternTree.deserialize(pipeDeleteTimeSeriesPlan.getPatternTreeBytes()); + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA); + final String auditObject = originalTree.getAllPathPatterns().toString(); try { - final PathPatternTree originalTree = - PathPatternTree.deserialize(pipeDeleteTimeSeriesPlan.getPatternTreeBytes()); final PathPatternTree intersectedTree = originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !originalTree.equals(intersectedTree)) { + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); throw new AccessDeniedException( "Not has privilege to transfer plan: " + pipeDeleteTimeSeriesPlan); } - return !intersectedTree.isEmpty() + final boolean result = !intersectedTree.isEmpty(); + logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + return result ? Optional.of(new PipeDeleteTimeSeriesPlan(intersectedTree.serialize())) : Optional.empty(); } catch (final IOException e) { LOGGER.warn( "Serialization failed for the delete time series plan in pipe transmission, skip transfer", e); + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); return Optional.empty(); } catch (final AuthException e) { + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -268,24 +288,32 @@ public Optional visitPipeDeleteTimeSeries( @Override public Optional visitPipeDeleteLogicalView( final PipeDeleteLogicalViewPlan pipeDeleteLogicalViewPlan, final IAuditEntity userEntity) { + final CNAuditLogger logger = ConfigNode.getInstance().getConfigManager().getAuditLogger(); + final PathPatternTree originalTree = + PathPatternTree.deserialize(pipeDeleteLogicalViewPlan.getPatternTreeBytes()); + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA); + final String auditObject = originalTree.getAllPathPatterns().toString(); try { - final PathPatternTree originalTree = - PathPatternTree.deserialize(pipeDeleteLogicalViewPlan.getPatternTreeBytes()); final PathPatternTree intersectedTree = originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !originalTree.equals(intersectedTree)) { + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); throw new AccessDeniedException( "Not has privilege to transfer plan: " + pipeDeleteLogicalViewPlan); } - return !intersectedTree.isEmpty() + final boolean result = !intersectedTree.isEmpty(); + logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + return result ? Optional.of(new PipeDeleteLogicalViewPlan(intersectedTree.serialize())) : Optional.empty(); } catch (final IOException e) { LOGGER.warn( "Serialization failed for the delete time series plan in pipe transmission, skip transfer", e); + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); return Optional.empty(); } catch (final AuthException e) { + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -298,6 +326,9 @@ public Optional visitPipeDeleteLogicalView( @Override public Optional visitPipeDeactivateTemplate( final PipeDeactivateTemplatePlan pipeDeactivateTemplatePlan, final IAuditEntity userEntity) { + final CNAuditLogger logger = ConfigNode.getInstance().getConfigManager().getAuditLogger(); + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA); + final String auditObject = pipeDeactivateTemplatePlan.getTemplateSetInfo().toString(); try { final Map> newTemplateSetInfo = new HashMap<>(); for (final Map.Entry> templateEntry : @@ -312,10 +343,13 @@ public Optional visitPipeDeactivateTemplate( } } } + final boolean result = !newTemplateSetInfo.isEmpty(); + logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); return !newTemplateSetInfo.isEmpty() ? Optional.of(new PipeDeactivateTemplatePlan(newTemplateSetInfo)) : Optional.empty(); } catch (final AuthException e) { + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -364,7 +398,7 @@ private PathPatternTree getAuthorizedPTree(final IAuditEntity userEntity) throws return ConfigNode.getInstance() .getConfigManager() .getPermissionManager() - .fetchRawAuthorizedPTree(userEntity, PrivilegeType.READ_SCHEMA); + .fetchRawAuthorizedPTree(userEntity.getUsername(), PrivilegeType.READ_SCHEMA); } public static boolean hasGlobalPrivilege( From b895cd074e0b772fba99306d0f083d4d0f7e3249 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 12:28:03 +0800 Subject: [PATCH 05/19] fix --- .../source/PipeConfigTreePrivilegeParseVisitor.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index e86981acffb43..2f1ca01e13bdd 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -51,6 +51,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -362,16 +363,23 @@ public Optional visitPipeDeactivateTemplate( @Override public Optional visitTTL( final SetTTLPlan setTTLPlan, final IAuditEntity userEntity) { + final CNAuditLogger logger = ConfigNode.getInstance().getConfigManager().getAuditLogger(); + userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA); + final String auditObject = Arrays.toString(setTTLPlan.getPathPattern()); try { final List paths = getAllIntersectedPatterns( new PartialPath(setTTLPlan.getPathPattern()), userEntity, setTTLPlan); // The intersectionList is either a singleton list or an empty list, because the pipe // pattern and TTL path are each either a prefix path or a full path - return !paths.isEmpty() && paths.get(0).getNodeLength() == setTTLPlan.getPathPattern().length + final boolean result = + !paths.isEmpty() && paths.get(0).getNodeLength() == setTTLPlan.getPathPattern().length; + logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + return result ? Optional.of(new SetTTLPlan(paths.get(0).getNodes(), setTTLPlan.getTTL())) : Optional.empty(); } catch (final AuthException e) { + logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { From 3d29c5119f44c2011dac855b61e9d16c7cee7a20 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 12:31:10 +0800 Subject: [PATCH 06/19] f --- .../plan/relational/security/TreeAccessCheckVisitor.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 d53b52d2e9378..147fcd71e01af 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 @@ -841,8 +841,9 @@ public TSStatus visitCreatePipe(CreatePipeStatement statement, TreeAccessCheckCo @Override public TSStatus visitShowPipes(ShowPipesStatement statement, TreeAccessCheckContext context) { - return checkPipeManagement( - context.setAuditLogOperation(AuditLogOperation.DDL), statement::getPipeName); + // This query cannot be rejected, but will be filtered at configNode + // Does not need auth check here + return StatusUtils.OK; } @Override From d4da677de730a2c14d304a049add9228ecdaeea8 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 14:24:59 +0800 Subject: [PATCH 07/19] fix --- .../treemodel/manual/IoTDBPipePermissionIT.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java index 1bb6acb35f2d4..5ecff397e129c 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java @@ -22,7 +22,6 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus; import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient; import org.apache.iotdb.confignode.rpc.thrift.TCreatePipeReq; -import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq; import org.apache.iotdb.consensus.ConsensusFactory; import org.apache.iotdb.db.it.utils.TestUtils; import org.apache.iotdb.it.env.MultiEnvFactory; @@ -39,6 +38,7 @@ import org.junit.runner.RunWith; import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; @@ -414,15 +414,17 @@ public void testSourcePermission() { fail("Create pipe without user shall succeed if use the current session"); } - TestUtils.executeNonQuery(senderEnv, "revoke SYSTEM on root.** from user thulab"); - // A user shall only see its own pipe - try (final SyncConfigNodeIServiceClient client = - (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) { - Assert.assertEquals( - 1, client.showPipe(new TShowPipeReq().setUserName("thulab")).pipeInfoList.size()); + try (final Connection connection = senderEnv.getConnection("thulab", "passwD@123456"); + final Statement statement = connection.createStatement()) { + // Will not throw any exception + final ResultSet resultSet = statement.executeQuery("show pipes"); + Assert.assertTrue(resultSet.next()); + Assert.assertFalse(resultSet.next()); } catch (Exception e) { fail(e.getMessage()); } + + TestUtils.executeNonQuery(senderEnv, "revoke SYSTEM on root.** from user thulab"); } } From 83becc03e1588afe45bc3b2e07328b1c1ca4da71 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 14:26:20 +0800 Subject: [PATCH 08/19] fix --- .../pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java index 5ecff397e129c..ac75b5f19cce8 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java @@ -414,6 +414,8 @@ public void testSourcePermission() { fail("Create pipe without user shall succeed if use the current session"); } + TestUtils.executeNonQuery(senderEnv, "revoke SYSTEM on root.** from user thulab"); + // A user shall only see its own pipe try (final Connection connection = senderEnv.getConnection("thulab", "passwD@123456"); final Statement statement = connection.createStatement()) { @@ -424,7 +426,5 @@ public void testSourcePermission() { } catch (Exception e) { fail(e.getMessage()); } - - TestUtils.executeNonQuery(senderEnv, "revoke SYSTEM on root.** from user thulab"); } } From d6931f768171bbd659ede84e01921988a083aead Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 14:27:05 +0800 Subject: [PATCH 09/19] fix --- .../confignode/manager/pipe/source/IoTDBConfigRegionSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java index 8515dee97f6b3..60512887703ff 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/IoTDBConfigRegionSource.java @@ -255,7 +255,7 @@ protected Optional trimRealtimeEventByPrivilege( } if (!Boolean.FALSE.equals(isTableDatabasePlan)) { final Optional result = - TABLE_PRIVILEGE_PARSE_VISITOR.process(plan, userName); + TABLE_PRIVILEGE_PARSE_VISITOR.process(plan, userEntity); if (result.isPresent()) { return Optional.of( new PipeConfigRegionWritePlanEvent(result.get(), event.isGeneratedByPipe())); From 59263be8ca3031d5b124793a371220295ff830a5 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 16:41:48 +0800 Subject: [PATCH 10/19] no-excep --- .../dual/treemodel/auto/basic/IoTDBPipeLifeCycleIT.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeLifeCycleIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeLifeCycleIT.java index b4519ca950090..03fbac5955ce8 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeLifeCycleIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeLifeCycleIT.java @@ -833,12 +833,8 @@ public void testPermission() { "803: No permissions for this operation, please add privilege SYSTEM", "test", "test123123456"); - assertTestFail( - senderEnv, - "show pipes", - "803: No permissions for this operation, please add privilege SYSTEM", - "test", - "test123123456"); + // Will not throw exception + executeQueryWithRetry(senderEnv, "show pipes", "test", "test123123456"); assertNonQueryTestFail( senderEnv, "start pipe testPipe", From b9820f3d4eea22e7af80e7a84e7163c7d0f441e5 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 15:51:09 +0800 Subject: [PATCH 11/19] pw-args --- .../cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java index 17587cf8811a2..8fd0a179063c7 100644 --- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java +++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java @@ -321,9 +321,7 @@ static String[] removePasswordArgs(String[] args) { } } if (index >= 0) { - if (index + 1 >= args.length - || args[index + 1].startsWith("-") - || (keywordSet.contains(args[index + 1]))) { + if (index + 1 >= args.length || keywordSet.contains(args[index + 1])) { return ArrayUtils.remove(args, index); } } From 3f515d7cf9275ab647005a2159e41791e24d3310 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 17:43:12 +0800 Subject: [PATCH 12/19] fix --- ...peConfigTreePrivilegeParseVisitorTest.java | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java index 7823513bf26e1..1ffc41dd3bb70 100644 --- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java +++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java @@ -20,6 +20,7 @@ package org.apache.iotdb.confignode.manager.pipe.source; import org.apache.iotdb.common.rpc.thrift.TSStatus; +import org.apache.iotdb.commons.audit.UserEntity; import org.apache.iotdb.commons.auth.entity.PrivilegeType; import org.apache.iotdb.commons.auth.entity.PrivilegeUnion; import org.apache.iotdb.commons.exception.MetadataException; @@ -57,7 +58,7 @@ import java.util.function.BiFunction; public class PipeConfigTreePrivilegeParseVisitorTest { - + private static final UserEntity FAKE_USER_ENTITY = new UserEntity(0L, "", ""); private final PipeConfigTreePrivilegeParseVisitor skipVisitor = new PipeConfigTreePrivilegeParseVisitor(true); private final PipeConfigTreePrivilegeParseVisitor throwVisitor = @@ -85,28 +86,28 @@ public void tearDown() throws IOException, StorageEngineException { public void testCanReadSysSchema() { permissionManager.setUserPrivilege( (userName, privilegeUnion) -> privilegeUnion.getPrivilegeType() == PrivilegeType.SYSTEM); - Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", null, true)); + Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", FAKE_USER_ENTITY, true)); permissionManager.setUserPrivilege( (userName, privilegeUnion) -> privilegeUnion.getPrivilegeType() == PrivilegeType.READ_SCHEMA && privilegeUnion.getPaths().stream().allMatch(path -> path.equals("root.db"))); - Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", null, true)); - Assert.assertFalse(skipVisitor.canReadSysSchema("root.db", null, false)); + Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", FAKE_USER_ENTITY, true)); + Assert.assertFalse(skipVisitor.canReadSysSchema("root.db", FAKE_USER_ENTITY, false)); Assert.assertFalse( throwVisitor .visitCreateDatabase( new DatabaseSchemaPlan( ConfigPhysicalPlanType.CreateDatabase, new TDatabaseSchema("root.db1")), - null) + FAKE_USER_ENTITY) .isPresent()); permissionManager.setUserPrivilege( (userName, privilegeUnion) -> privilegeUnion.getPrivilegeType() == PrivilegeType.READ_SCHEMA && privilegeUnion.getPaths().stream().allMatch(path -> path.equals("root.db.**"))); - Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", null, true)); - Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", null, false)); + Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", FAKE_USER_ENTITY, true)); + Assert.assertTrue(skipVisitor.canReadSysSchema("root.db", FAKE_USER_ENTITY, false)); } @Test @@ -116,19 +117,21 @@ public void testAuthPrivilege() { privilegeUnion.getPrivilegeType() == PrivilegeType.MANAGE_USER); Assert.assertTrue( skipVisitor - .visitGrantUser(new AuthorTreePlan(ConfigPhysicalPlanType.GrantUser), null) + .visitGrantUser(new AuthorTreePlan(ConfigPhysicalPlanType.GrantUser), FAKE_USER_ENTITY) .isPresent()); Assert.assertTrue( skipVisitor - .visitRevokeUser(new AuthorTreePlan(ConfigPhysicalPlanType.RevokeUser), null) + .visitRevokeUser( + new AuthorTreePlan(ConfigPhysicalPlanType.RevokeUser), FAKE_USER_ENTITY) .isPresent()); Assert.assertFalse( skipVisitor - .visitGrantRole(new AuthorTreePlan(ConfigPhysicalPlanType.GrantRole), null) + .visitGrantRole(new AuthorTreePlan(ConfigPhysicalPlanType.GrantRole), FAKE_USER_ENTITY) .isPresent()); Assert.assertFalse( skipVisitor - .visitRevokeRole(new AuthorTreePlan(ConfigPhysicalPlanType.RevokeRole), null) + .visitRevokeRole( + new AuthorTreePlan(ConfigPhysicalPlanType.RevokeRole), FAKE_USER_ENTITY) .isPresent()); permissionManager.setUserPrivilege( @@ -136,19 +139,21 @@ public void testAuthPrivilege() { privilegeUnion.getPrivilegeType() == PrivilegeType.MANAGE_ROLE); Assert.assertFalse( skipVisitor - .visitGrantUser(new AuthorTreePlan(ConfigPhysicalPlanType.GrantUser), null) + .visitGrantUser(new AuthorTreePlan(ConfigPhysicalPlanType.GrantUser), FAKE_USER_ENTITY) .isPresent()); Assert.assertFalse( skipVisitor - .visitRevokeUser(new AuthorTreePlan(ConfigPhysicalPlanType.RevokeUser), null) + .visitRevokeUser( + new AuthorTreePlan(ConfigPhysicalPlanType.RevokeUser), FAKE_USER_ENTITY) .isPresent()); Assert.assertTrue( skipVisitor - .visitGrantRole(new AuthorTreePlan(ConfigPhysicalPlanType.GrantRole), null) + .visitGrantRole(new AuthorTreePlan(ConfigPhysicalPlanType.GrantRole), FAKE_USER_ENTITY) .isPresent()); Assert.assertTrue( skipVisitor - .visitRevokeRole(new AuthorTreePlan(ConfigPhysicalPlanType.RevokeRole), null) + .visitRevokeRole( + new AuthorTreePlan(ConfigPhysicalPlanType.RevokeRole), FAKE_USER_ENTITY) .isPresent()); } @@ -172,7 +177,8 @@ public void testPatternRelatedPrivilege() throws IOException { PathPatternTree.deserialize( ((PipeDeleteTimeSeriesPlan) skipVisitor - .visitPipeDeleteTimeSeries(new PipeDeleteTimeSeriesPlan(buffer), null) + .visitPipeDeleteTimeSeries( + new PipeDeleteTimeSeriesPlan(buffer), FAKE_USER_ENTITY) .get()) .getPatternTreeBytes()) .getAllPathPatterns()); @@ -181,16 +187,21 @@ public void testPatternRelatedPrivilege() throws IOException { PathPatternTree.deserialize( ((PipeDeleteLogicalViewPlan) skipVisitor - .visitPipeDeleteLogicalView(new PipeDeleteLogicalViewPlan(buffer), null) + .visitPipeDeleteLogicalView( + new PipeDeleteLogicalViewPlan(buffer), FAKE_USER_ENTITY) .get()) .getPatternTreeBytes()) .getAllPathPatterns()); Assert.assertThrows( AccessDeniedException.class, - () -> throwVisitor.visitPipeDeleteTimeSeries(new PipeDeleteTimeSeriesPlan(buffer), null)); + () -> + throwVisitor.visitPipeDeleteTimeSeries( + new PipeDeleteTimeSeriesPlan(buffer), FAKE_USER_ENTITY)); Assert.assertThrows( AccessDeniedException.class, - () -> throwVisitor.visitPipeDeleteLogicalView(new PipeDeleteLogicalViewPlan(buffer), null)); + () -> + throwVisitor.visitPipeDeleteLogicalView( + new PipeDeleteLogicalViewPlan(buffer), FAKE_USER_ENTITY)); Assert.assertEquals( Collections.singleton(matchedPath), @@ -204,7 +215,7 @@ public void testPatternRelatedPrivilege() throws IOException { put(unmatchedPath, Collections.singletonList(new Template())); } }), - null) + FAKE_USER_ENTITY) .get()) .getTemplateSetInfo() .keySet()); @@ -215,13 +226,14 @@ public void testPatternRelatedPrivilege() throws IOException { skipVisitor .visitTTL( new SetTTLPlan(new String[] {"root", "*", "device", "measurement"}, 100), - null) + FAKE_USER_ENTITY) .get()) .getPathPattern()); Assert.assertFalse( skipVisitor .visitTTL( - new SetTTLPlan(new String[] {"root", "db2", "device", "measurement"}, 100), null) + new SetTTLPlan(new String[] {"root", "db2", "device", "measurement"}, 100), + FAKE_USER_ENTITY) .isPresent()); } From 47429d0f206483c6086612dc5dd0c15567d70855 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 17:56:40 +0800 Subject: [PATCH 13/19] test --- ...peConfigTreePrivilegeParseVisitorTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java index 1ffc41dd3bb70..4d8c295a7a47a 100644 --- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java +++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitorTest.java @@ -55,6 +55,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Objects; import java.util.function.BiFunction; public class PipeConfigTreePrivilegeParseVisitorTest { @@ -134,6 +135,15 @@ public void testAuthPrivilege() { new AuthorTreePlan(ConfigPhysicalPlanType.RevokeRole), FAKE_USER_ENTITY) .isPresent()); + permissionManager.setUserPrivilege((userName, privilegeUnion) -> false); + AuthorTreePlan plan = new AuthorTreePlan(ConfigPhysicalPlanType.GrantUser); + plan.setUserName(""); + Assert.assertTrue(skipVisitor.visitGrantUser(plan, FAKE_USER_ENTITY).isPresent()); + Assert.assertTrue(skipVisitor.visitRevokeUser(plan, FAKE_USER_ENTITY).isPresent()); + plan.setUserName("another"); + Assert.assertFalse(skipVisitor.visitGrantUser(plan, FAKE_USER_ENTITY).isPresent()); + Assert.assertFalse(skipVisitor.visitRevokeUser(plan, FAKE_USER_ENTITY).isPresent()); + permissionManager.setUserPrivilege( (userName, privilegeUnion) -> privilegeUnion.getPrivilegeType() == PrivilegeType.MANAGE_ROLE); @@ -155,6 +165,15 @@ public void testAuthPrivilege() { .visitRevokeRole( new AuthorTreePlan(ConfigPhysicalPlanType.RevokeRole), FAKE_USER_ENTITY) .isPresent()); + + permissionManager.setUserPrivilege((userName, privilegeUnion) -> false); + plan = new AuthorTreePlan(ConfigPhysicalPlanType.GrantUser); + plan.setRoleName(""); + Assert.assertTrue(skipVisitor.visitGrantRole(plan, FAKE_USER_ENTITY).isPresent()); + Assert.assertTrue(skipVisitor.visitRevokeRole(plan, FAKE_USER_ENTITY).isPresent()); + plan.setRoleName("another"); + Assert.assertFalse(skipVisitor.visitGrantRole(plan, FAKE_USER_ENTITY).isPresent()); + Assert.assertFalse(skipVisitor.visitRevokeRole(plan, FAKE_USER_ENTITY).isPresent()); } @Test @@ -267,5 +286,12 @@ public PathPatternTree fetchRawAuthorizedPTree( tree.constructTree(); return tree; } + + @Override + public TPermissionInfoResp checkRoleOfUser(String username, String rolename) { + return Objects.equals(username, rolename) + ? new TPermissionInfoResp(StatusUtils.OK) + : new TPermissionInfoResp(new TSStatus(TSStatusCode.USER_NOT_HAS_ROLE.getStatusCode())); + } } } From 18adf5b812291b7e9cdd121a4eb37004a8c8bfa0 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 18:49:18 +0800 Subject: [PATCH 14/19] partial --- .../protocol/IoTDBConfigNodeReceiver.java | 90 ++++++++++++------- .../PipeConfigTablePrivilegeParseVisitor.java | 4 +- .../PipeConfigTreePrivilegeParseVisitor.java | 29 ++++-- .../thrift/IoTDBDataNodeReceiver.java | 4 +- .../pipe/receiver/IoTDBFileReceiver.java | 11 ++- 5 files changed, 90 insertions(+), 48 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java index daf91c51c4c48..ace94259c396f 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java @@ -20,6 +20,7 @@ package org.apache.iotdb.confignode.manager.pipe.receiver.protocol; import org.apache.iotdb.common.rpc.thrift.TSStatus; +import org.apache.iotdb.commons.audit.IAuditEntity; import org.apache.iotdb.commons.auth.entity.PrivilegeType; import org.apache.iotdb.commons.auth.entity.PrivilegeUnion; import org.apache.iotdb.commons.conf.CommonDescriptor; @@ -46,6 +47,7 @@ import org.apache.iotdb.commons.schema.ttl.TTLCache; import org.apache.iotdb.commons.utils.PathUtils; import org.apache.iotdb.commons.utils.StatusUtils; +import org.apache.iotdb.confignode.audit.CNAuditLogger; import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan; import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType; @@ -143,6 +145,8 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.iotdb.confignode.manager.pipe.source.PipeConfigTreePrivilegeParseVisitor.checkGlobalStatus; + public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver { private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBConfigNodeReceiver.class); @@ -157,6 +161,7 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver { new PipeConfigPhysicalPlanExceptionVisitor(); private final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + private final CNAuditLogger auditLogger = configManager.getAuditLogger(); @Override public TPipeTransferResp receive(final TPipeTransferReq req) { @@ -290,43 +295,41 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti return status; } + String database; switch (plan.getType()) { case CreateDatabase: - return PathUtils.isTableModelDatabase(((DatabaseSchemaPlan) plan).getSchema().getName()) - ? configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((DatabaseSchemaPlan) plan).getSchema().getName(), PrivilegeType.CREATE)) - .getStatus() - : configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_DATABASE)) - .getStatus(); + database = ((DatabaseSchemaPlan) plan).getSchema().getName(); + if (PathUtils.isTableModelDatabase(database)) { + status = checkDatabaseStatus(userEntity, PrivilegeType.CREATE, database, false); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, database, true); + } + } + return checkGlobalStatus(userEntity, PrivilegeType.MANAGE_DATABASE, database, true); case AlterDatabase: - return PathUtils.isTableModelDatabase(((DatabaseSchemaPlan) plan).getSchema().getName()) - ? configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((DatabaseSchemaPlan) plan).getSchema().getName(), PrivilegeType.ALTER)) - .getStatus() - : configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_DATABASE)) - .getStatus(); + database = ((DatabaseSchemaPlan) plan).getSchema().getName(); + if (PathUtils.isTableModelDatabase(database)) { + status = checkDatabaseStatus(userEntity, PrivilegeType.ALTER, database, false); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, database, true); + } + } + return checkGlobalStatus(userEntity, PrivilegeType.MANAGE_DATABASE, database, true); case DeleteDatabase: - return PathUtils.isTableModelDatabase(((DeleteDatabasePlan) plan).getName()) - ? configManager - .checkUserPrivileges( - username, - new PrivilegeUnion(((DeleteDatabasePlan) plan).getName(), PrivilegeType.DROP)) - .getStatus() - : configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_DATABASE)) - .getStatus(); + database = ((DeleteDatabasePlan) plan).getName(); + if (PathUtils.isTableModelDatabase(database)) { + status = checkDatabaseStatus(userEntity, PrivilegeType.DELETE, database, false); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, database, true); + } + } + return checkGlobalStatus(userEntity, PrivilegeType.MANAGE_DATABASE, database, true); case ExtendSchemaTemplate: - return configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.EXTEND_TEMPLATE)) - .getStatus(); + return checkGlobalStatus( + userEntity, + PrivilegeType.EXTEND_TEMPLATE, + ((ExtendSchemaTemplatePlan) plan).getTemplateExtendInfo().getTemplateName(), + true); case CreateSchemaTemplate: case CommitSetSchemaTemplate: case PipeUnsetTemplate: @@ -618,6 +621,29 @@ username, new PrivilegeUnion(PrivilegeType.values()[permission], true)) } } + public static TSStatus checkDatabaseStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String database, + final boolean isLastCheck) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + final TSStatus result = + configManager + .getPermissionManager() + .checkUserPrivileges( + userEntity.getUsername(), new PrivilegeUnion(database, privilegeType)) + .getStatus(); + if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { + logger.recordAuditLog( + userEntity + .setPrivilegeType(privilegeType) + .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), + () -> database); + } + return result; + } + private TSStatus executePlan(final ConfigPhysicalPlan plan) throws ConsensusException { final String queryId = generatePseudoQueryId(); switch (plan.getType()) { diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java index 3ae3b3ed9fe71..0f75aa56ae556 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java @@ -84,7 +84,7 @@ public Optional visitDeleteDatabase( private boolean isDatabaseVisible(final IAuditEntity userEntity, final String database) { final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); final CNAuditLogger logger = configManager.getAuditLogger(); - boolean result = + final boolean result = configManager .getPermissionManager() .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(database, null)) @@ -176,7 +176,7 @@ private boolean isTableVisible( final IAuditEntity userEntity, final String database, final String tableName) { final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); final CNAuditLogger logger = configManager.getAuditLogger(); - boolean result = + final boolean result = configManager .getPermissionManager() .checkUserPrivileges( diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 2f1ca01e13bdd..3b98962f64f7e 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -19,6 +19,7 @@ package org.apache.iotdb.confignode.manager.pipe.source; +import org.apache.iotdb.common.rpc.thrift.TSStatus; import org.apache.iotdb.commons.audit.IAuditEntity; import org.apache.iotdb.commons.auth.AuthException; import org.apache.iotdb.commons.auth.entity.PrivilegeType; @@ -409,27 +410,37 @@ private PathPatternTree getAuthorizedPTree(final IAuditEntity userEntity) throws .fetchRawAuthorizedPTree(userEntity.getUsername(), PrivilegeType.READ_SCHEMA); } - public static boolean hasGlobalPrivilege( + public static TSStatus checkGlobalStatus( final IAuditEntity userEntity, final PrivilegeType privilegeType, final String auditObject, final boolean isLastCheck) { final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); final CNAuditLogger logger = configManager.getAuditLogger(); - final boolean result = + final TSStatus result = configManager - .getPermissionManager() - .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(privilegeType)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode(); - if (result || isLastCheck) { + .getPermissionManager() + .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(privilegeType)) + .getStatus(); + if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { logger.recordAuditLog( - userEntity.setPrivilegeType(privilegeType).setResult(result), () -> auditObject); + userEntity + .setPrivilegeType(privilegeType) + .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), + () -> auditObject); } return result; } + public static boolean hasGlobalPrivilege( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String auditObject, + final boolean isLastCheck) { + return checkGlobalStatus(userEntity, privilegeType, auditObject, isLastCheck).getCode() + == TSStatusCode.SUCCESS_STATUS.getStatusCode(); + } + private boolean hasReadPrivilege( final IAuditEntity userEntity, final String path, 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 2efa3abe2f0ab..b012232379947 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 @@ -21,7 +21,6 @@ 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.conf.IoTDBConstant; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.exception.pipe.PipeRuntimeOutOfMemoryCriticalException; @@ -1016,8 +1015,7 @@ private void autoCreateDatabaseIfNecessary(final String database) { return; } - AuthorityChecker.getAccessControl() - .checkCanCreateDatabase(username, database, new UserEntity(userId, username, cliHostname)); + AuthorityChecker.getAccessControl().checkCanCreateDatabase(username, database, userEntity); final TDatabaseSchema schema = new TDatabaseSchema(new TDatabaseSchema(database)); schema.setIsTableModel(true); diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/receiver/IoTDBFileReceiver.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/receiver/IoTDBFileReceiver.java index c0ee96e2b1050..ff8c8dbd293d8 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/receiver/IoTDBFileReceiver.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/receiver/IoTDBFileReceiver.java @@ -20,6 +20,8 @@ package org.apache.iotdb.commons.pipe.receiver; 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.conf.CommonDescriptor; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.pipe.config.PipeConfig; @@ -75,10 +77,9 @@ public abstract class IoTDBFileReceiver implements IoTDBReceiver { // Used to restore the original thread name when the receiver is closed. private String originalThreadName; - protected long userId = -1; protected String username = CONNECTOR_IOTDB_USER_DEFAULT_VALUE; - protected String cliHostname = ""; protected String password = CONNECTOR_IOTDB_PASSWORD_DEFAULT_VALUE; + protected IAuditEntity userEntity; protected long lastSuccessfulLoginTime = Long.MIN_VALUE; @@ -288,6 +289,9 @@ protected TPipeTransferResp handleTransferHandshakeV2(final PipeTransferHandshak return new TPipeTransferResp(status); } + long userId = -1; + String cliHostname = ""; + final String userIdString = req.getParams().get(PipeTransferHandshakeConstant.HANDSHAKE_KEY_USER_ID); if (userIdString != null) { @@ -303,6 +307,9 @@ protected TPipeTransferResp handleTransferHandshakeV2(final PipeTransferHandshak if (cliHostnameString != null) { cliHostname = cliHostnameString; } + + userEntity = new UserEntity(userId, username, cliHostname); + final String passwordString = req.getParams().get(PipeTransferHandshakeConstant.HANDSHAKE_KEY_PASSWORD); if (passwordString != null) { From e39c9c4c5b5d96ea5b90585e16f4f184c1345ae9 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Fri, 26 Dec 2025 19:10:19 +0800 Subject: [PATCH 15/19] hdx --- .../protocol/IoTDBConfigNodeReceiver.java | 79 +++++++++---------- .../PipeConfigTreePrivilegeParseVisitor.java | 50 +++++++----- 2 files changed, 69 insertions(+), 60 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java index ace94259c396f..4204fe60bbefd 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java @@ -82,6 +82,7 @@ import org.apache.iotdb.confignode.consensus.request.write.table.view.SetViewCommentPlan; import org.apache.iotdb.confignode.consensus.request.write.table.view.SetViewPropertiesPlan; import org.apache.iotdb.confignode.consensus.request.write.template.CommitSetSchemaTemplatePlan; +import org.apache.iotdb.confignode.consensus.request.write.template.CreateSchemaTemplatePlan; import org.apache.iotdb.confignode.consensus.request.write.template.ExtendSchemaTemplatePlan; import org.apache.iotdb.confignode.consensus.request.write.trigger.DeleteTriggerInTablePlan; import org.apache.iotdb.confignode.manager.ConfigManager; @@ -146,6 +147,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.apache.iotdb.confignode.manager.pipe.source.PipeConfigTreePrivilegeParseVisitor.checkGlobalStatus; +import static org.apache.iotdb.confignode.manager.pipe.source.PipeConfigTreePrivilegeParseVisitor.checkPathsStatus; public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver { @@ -296,6 +298,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } String database; + String templateName; switch (plan.getType()) { case CreateDatabase: database = ((DatabaseSchemaPlan) plan).getSchema().getName(); @@ -331,23 +334,22 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti ((ExtendSchemaTemplatePlan) plan).getTemplateExtendInfo().getTemplateName(), true); case CreateSchemaTemplate: + templateName = ((CreateSchemaTemplatePlan) plan).getTemplate().getName(); + return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, templateName, true); case CommitSetSchemaTemplate: + templateName = ((CommitSetSchemaTemplatePlan) plan).getName(); + return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, templateName, true); case PipeUnsetTemplate: - return CommonDescriptor.getInstance().getConfig().getDefaultAdminName().equals(username) - ? StatusUtils.OK - : new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) - .setMessage("Only the admin user can perform this operation"); + templateName = ((PipeUnsetSchemaTemplatePlan) plan).getName(); + return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, templateName, true); case PipeDeleteTimeSeries: - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - new ArrayList<>( - PathPatternTree.deserialize( - ((PipeDeleteTimeSeriesPlan) plan).getPatternTreeBytes()) - .getAllPathPatterns()), - PrivilegeType.WRITE_SCHEMA)) - .getStatus(); + return checkPathsStatus( + userEntity, + PrivilegeType.WRITE_SCHEMA, + new ArrayList<>( + PathPatternTree.deserialize(((PipeDeleteTimeSeriesPlan) plan).getPatternTreeBytes()) + .getAllPathPatterns()), + true); case PipeAlterEncodingCompressor: // Judge here in the future if (configManager @@ -376,37 +378,30 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti .serialize()); return StatusUtils.OK; } else { - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - new ArrayList<>( - PathPatternTree.deserialize( - ((PipeAlterEncodingCompressorPlan) plan).getPatternTreeBytes()) - .getAllPathPatterns()), - PrivilegeType.WRITE_SCHEMA)) - .getStatus(); + return checkPathsStatus( + userEntity, + PrivilegeType.WRITE_SCHEMA, + new ArrayList<>( + PathPatternTree.deserialize( + ((PipeAlterEncodingCompressorPlan) plan).getPatternTreeBytes()) + .getAllPathPatterns()), + true); } case PipeDeleteLogicalView: - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - new ArrayList<>( - PathPatternTree.deserialize( - ((PipeDeleteLogicalViewPlan) plan).getPatternTreeBytes()) - .getAllPathPatterns()), - PrivilegeType.WRITE_SCHEMA)) - .getStatus(); + return checkPathsStatus( + userEntity, + PrivilegeType.WRITE_SCHEMA, + new ArrayList<>( + PathPatternTree.deserialize( + ((PipeDeleteLogicalViewPlan) plan).getPatternTreeBytes()) + .getAllPathPatterns()), + true); case PipeDeactivateTemplate: - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - new ArrayList<>( - ((PipeDeactivateTemplatePlan) plan).getTemplateSetInfo().keySet()), - PrivilegeType.WRITE_SCHEMA)) - .getStatus(); + return checkPathsStatus( + userEntity, + PrivilegeType.WRITE_SCHEMA, + new ArrayList<>(((PipeDeactivateTemplatePlan) plan).getTemplateSetInfo().keySet()), + true); case SetTTL: return Objects.equals( configManager diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 3b98962f64f7e..4f886a808a210 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -51,6 +51,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; + import java.io.IOException; import java.util.Arrays; import java.util.Collections; @@ -441,13 +443,34 @@ public static boolean hasGlobalPrivilege( == TSStatusCode.SUCCESS_STATUS.getStatusCode(); } + public static TSStatus checkPathsStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final @Nonnull List paths, + final boolean isLastCheck) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + final TSStatus result = + ConfigNode.getInstance() + .getConfigManager() + .getPermissionManager() + .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(paths, privilegeType)) + .getStatus(); + if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { + logger.recordAuditLog( + userEntity + .setPrivilegeType(PrivilegeType.READ_SCHEMA) + .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), + paths::toString); + } + return result; + } + private boolean hasReadPrivilege( final IAuditEntity userEntity, final String path, final boolean withWildcard, final boolean isLastCheck) { - final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); - final CNAuditLogger logger = configManager.getAuditLogger(); PartialPath partialPath; try { partialPath = new PartialPath(path); @@ -458,21 +481,12 @@ private boolean hasReadPrivilege( if (withWildcard) { partialPath = partialPath.concatNode(MULTI_LEVEL_PATH_WILDCARD); } - final boolean result = - ConfigNode.getInstance() - .getConfigManager() - .getPermissionManager() - .checkUserPrivileges( - userEntity.getUsername(), - new PrivilegeUnion( - Collections.singletonList(partialPath), PrivilegeType.READ_SCHEMA)) - .getStatus() - .getCode() - == TSStatusCode.SUCCESS_STATUS.getStatusCode(); - if (result || isLastCheck) { - logger.recordAuditLog( - userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA).setResult(result), () -> path); - } - return result; + return checkPathsStatus( + userEntity, + PrivilegeType.READ_SCHEMA, + Collections.singletonList(partialPath), + isLastCheck) + .getCode() + == TSStatusCode.SUCCESS_STATUS.getStatusCode(); } } From acc5210baa6831c5cffbef83425af3f18f327ccd Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 29 Dec 2025 10:01:15 +0800 Subject: [PATCH 16/19] Update IoTDBConfigNodeReceiver.java --- .../protocol/IoTDBConfigNodeReceiver.java | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java index 4204fe60bbefd..289933eeafe3d 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java @@ -85,6 +85,7 @@ import org.apache.iotdb.confignode.consensus.request.write.template.CreateSchemaTemplatePlan; import org.apache.iotdb.confignode.consensus.request.write.template.ExtendSchemaTemplatePlan; import org.apache.iotdb.confignode.consensus.request.write.trigger.DeleteTriggerInTablePlan; +import org.apache.iotdb.confignode.consensus.request.write.trigger.UpdateTriggerStateInTablePlan; import org.apache.iotdb.confignode.manager.ConfigManager; import org.apache.iotdb.confignode.manager.pipe.event.PipeConfigRegionSnapshotEvent; import org.apache.iotdb.confignode.manager.pipe.metric.receiver.PipeConfigNodeReceiverMetrics; @@ -297,8 +298,9 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti return status; } - String database; - String templateName; + final String database; + final String templateName; + final String triggerName; switch (plan.getType()) { case CreateDatabase: database = ((DatabaseSchemaPlan) plan).getSchema().getName(); @@ -351,7 +353,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti .getAllPathPatterns()), true); case PipeAlterEncodingCompressor: - // Judge here in the future + // The audit check does not need any if (configManager .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.AUDIT)) .getStatus() @@ -424,10 +426,11 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti PrivilegeType.WRITE_SCHEMA)) .getStatus(); case UpdateTriggerStateInTable: + triggerName = ((UpdateTriggerStateInTablePlan) plan).getTriggerName(); + return checkGlobalStatus(userEntity, PrivilegeType.USE_TRIGGER, triggerName, true); case DeleteTriggerInTable: - return configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.USE_TRIGGER)) - .getStatus(); + triggerName = ((DeleteTriggerInTablePlan) plan).getTriggerName(); + return checkGlobalStatus(userEntity, PrivilegeType.USE_TRIGGER, triggerName, true); case PipeCreateTableOrView: return configManager .checkUserPrivileges( @@ -597,9 +600,8 @@ username, new PrivilegeUnion(PrivilegeType.values()[permission], true)) case DropUserV2: case RDropUser: case RDropUserV2: - return configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_USER)) - .getStatus(); + return checkGlobalStatus( + userEntity, PrivilegeType.MANAGE_USER, ((AuthorPlan) plan).getUserName(), true); case CreateRole: case RCreateRole: case DropRole: @@ -608,9 +610,8 @@ username, new PrivilegeUnion(PrivilegeType.values()[permission], true)) case RGrantUserRole: case RevokeRoleFromUser: case RRevokeUserRole: - return configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_ROLE)) - .getStatus(); + return checkGlobalStatus( + userEntity, PrivilegeType.MANAGE_ROLE, ((AuthorPlan) plan).getRoleName(), true); default: return StatusUtils.OK; } @@ -639,6 +640,30 @@ public static TSStatus checkDatabaseStatus( return result; } + public static TSStatus checkTableStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String database, + final String tableName, + final boolean isLastCheck) { + final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); + final CNAuditLogger logger = configManager.getAuditLogger(); + final TSStatus result = + configManager + .getPermissionManager() + .checkUserPrivileges( + userEntity.getUsername(), new PrivilegeUnion(database, tableName, privilegeType)) + .getStatus(); + if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { + logger.recordAuditLog( + userEntity + .setPrivilegeType(privilegeType) + .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), + () -> tableName); + } + return result; + } + private TSStatus executePlan(final ConfigPhysicalPlan plan) throws ConsensusException { final String queryId = generatePseudoQueryId(); switch (plan.getType()) { From e196254101a072ead4df6e7b345050e83681e982 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 29 Dec 2025 10:35:35 +0800 Subject: [PATCH 17/19] part --- .../protocol/IoTDBConfigNodeReceiver.java | 120 +++++++++--------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java index 289933eeafe3d..ab5a6c983fbbb 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java @@ -139,6 +139,7 @@ import java.nio.ByteBuffer; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -353,7 +354,8 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti .getAllPathPatterns()), true); case PipeAlterEncodingCompressor: - // The audit check does not need any + // The audit check will only filter but not block the plan + // Hence we do not write any audit log here if (configManager .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.AUDIT)) .getStatus() @@ -371,13 +373,20 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti if (((PipeAlterEncodingCompressorPlan) plan).isMayAlterAudit()) { pathPatternTree.appendPathPattern(Audit.TREE_MODEL_AUDIT_DATABASE_PATH_PATTERN, true); } - ((PipeAlterEncodingCompressorPlan) plan) - .setPatternTreeBytes( - PathPatternTreeUtils.intersectWithFullPathPrefixTree( - PathPatternTree.deserialize( - ((PipeAlterEncodingCompressorPlan) plan).getPatternTreeBytes()), - pathPatternTree) - .serialize()); + final String auditObject = pathPatternTree.getAllPathPatterns().toString(); + final PathPatternTree tree = + PathPatternTreeUtils.intersectWithFullPathPrefixTree( + PathPatternTree.deserialize( + ((PipeAlterEncodingCompressorPlan) plan).getPatternTreeBytes()), + pathPatternTree); + ((PipeAlterEncodingCompressorPlan) plan).setPatternTreeBytes(tree.serialize()); + configManager + .getAuditLogger() + .recordAuditLog( + userEntity + .setPrivilegeType(PrivilegeType.WRITE_SCHEMA) + .setResult(!tree.isEmpty()), + () -> auditObject); return StatusUtils.OK; } else { return checkPathsStatus( @@ -405,26 +414,26 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti new ArrayList<>(((PipeDeactivateTemplatePlan) plan).getTemplateSetInfo().keySet()), true); case SetTTL: - return Objects.equals( - configManager - .getTTLManager() - .getAllTTL() - .get( - String.join( - String.valueOf(IoTDBConstant.PATH_SEPARATOR), - ((SetTTLPlan) plan).getPathPattern())), - ((SetTTLPlan) plan).getTTL()) - ? StatusUtils.OK - : configManager - .checkUserPrivileges( - username, - ((SetTTLPlan) plan).isDataBase() - ? new PrivilegeUnion(PrivilegeType.MANAGE_DATABASE) - : new PrivilegeUnion( - Collections.singletonList( - new PartialPath(((SetTTLPlan) plan).getPathPattern())), - PrivilegeType.WRITE_SCHEMA)) - .getStatus(); + if (Objects.equals( + configManager + .getTTLManager() + .getAllTTL() + .get( + String.join( + String.valueOf(IoTDBConstant.PATH_SEPARATOR), + ((SetTTLPlan) plan).getPathPattern())), + ((SetTTLPlan) plan).getTTL())) { + return StatusUtils.OK; + } + final String[] paths = ((SetTTLPlan) plan).getPathPattern(); + return ((SetTTLPlan) plan).isDataBase() + ? checkGlobalStatus( + userEntity, PrivilegeType.MANAGE_DATABASE, Arrays.toString(paths), true) + : checkPathsStatus( + userEntity, + PrivilegeType.WRITE_SCHEMA, + Collections.singletonList(new PartialPath(paths)), + true); case UpdateTriggerStateInTable: triggerName = ((UpdateTriggerStateInTablePlan) plan).getTriggerName(); return checkGlobalStatus(userEntity, PrivilegeType.USE_TRIGGER, triggerName, true); @@ -432,14 +441,12 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti triggerName = ((DeleteTriggerInTablePlan) plan).getTriggerName(); return checkGlobalStatus(userEntity, PrivilegeType.USE_TRIGGER, triggerName, true); case PipeCreateTableOrView: - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((PipeCreateTableOrViewPlan) plan).getDatabase(), - ((PipeCreateTableOrViewPlan) plan).getTable().getTableName(), - PrivilegeType.CREATE)) - .getStatus(); + return checkTableStatus( + userEntity, + PrivilegeType.CREATE, + ((PipeCreateTableOrViewPlan) plan).getDatabase(), + ((PipeCreateTableOrViewPlan) plan).getTable().getTableName(), + true); case AddTableColumn: case AddViewColumn: case SetTableProperties: @@ -453,24 +460,20 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti case RenameViewColumn: case RenameTable: case RenameView: - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((AbstractTablePlan) plan).getDatabase(), - ((AbstractTablePlan) plan).getTableName(), - PrivilegeType.ALTER)) - .getStatus(); + return checkTableStatus( + userEntity, + PrivilegeType.ALTER, + ((AbstractTablePlan) plan).getDatabase(), + ((AbstractTablePlan) plan).getTableName(), + true); case CommitDeleteTable: case CommitDeleteView: - return configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((CommitDeleteTablePlan) plan).getDatabase(), - ((CommitDeleteTablePlan) plan).getTableName(), - PrivilegeType.DROP)) - .getStatus(); + return checkTableStatus( + userEntity, + PrivilegeType.DELETE, + ((CommitDeleteTablePlan) plan).getDatabase(), + ((CommitDeleteTablePlan) plan).getTableName(), + true); case GrantRole: case GrantUser: case RevokeUser: @@ -588,11 +591,14 @@ username, new PrivilegeUnion(PrivilegeType.values()[permission], true)) case UpdateUserV2: case RUpdateUser: case RUpdateUserV2: - return ((AuthorPlan) plan).getUserName().equals(username) - ? StatusUtils.OK - : configManager - .checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_USER)) - .getStatus(); + if (((AuthorPlan) plan).getUserName().equals(username)) { + configManager + .getAuditLogger() + .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> username); + return StatusUtils.OK; + } + return checkGlobalStatus( + userEntity, PrivilegeType.MANAGE_USER, ((AuthorPlan) plan).getUserName(), true); case CreateUser: case RCreateUser: case CreateUserWithRawPassword: From b054a0fd0fbb6811f030f528adf068ddff96fb67 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 29 Dec 2025 11:49:26 +0800 Subject: [PATCH 18/19] fix --- .../confignode/manager/ConfigManager.java | 17 -- .../confignode/manager/PermissionManager.java | 6 - .../protocol/IoTDBConfigNodeReceiver.java | 189 ++++++++++++------ .../PipeConfigTreePrivilegeParseVisitor.java | 40 +++- 4 files changed, 162 insertions(+), 90 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java index 2cd3979861333..ed9210c9ff165 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java @@ -1353,23 +1353,6 @@ public TAuthizedPatternTreeResp fetchAuthizedPatternTree(String username, int pe } } - public TPermissionInfoResp checkUserPrivilegeGrantOpt(String username, PrivilegeUnion union) { - TSStatus status = confirmLeader(); - TPermissionInfoResp resp = new TPermissionInfoResp(); - if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - try { - resp = permissionManager.checkUserPrivilegeGrantOpt(username, union); - } catch (AuthException e) { - status.setCode(e.getCode().getStatusCode()).setMessage(e.getMessage()); - resp.setStatus(status); - return resp; - } - } else { - resp.setStatus(status); - } - return resp; - } - public TPermissionInfoResp checkRoleOfUser(String username, String rolename) { TSStatus status = confirmLeader(); TPermissionInfoResp resp = new TPermissionInfoResp(); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java index f7ee6069e8730..06be2818593ae 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java @@ -134,12 +134,6 @@ public PathPatternTree fetchRawAuthorizedPTree(final String userName, final Priv return authorInfo.generateRawAuthorizedPTree(userName, type); } - public TPermissionInfoResp checkUserPrivilegeGrantOpt(String username, PrivilegeUnion union) - throws AuthException { - union.setGrantOption(true); - return authorInfo.checkUserPrivileges(username, union); - } - public TPermissionInfoResp checkRoleOfUser(String username, String rolename) throws AuthException { return authorInfo.checkRoleOfUser(username, rolename); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java index ab5a6c983fbbb..8e54f46a5ff3e 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java @@ -20,6 +20,7 @@ package org.apache.iotdb.confignode.manager.pipe.receiver.protocol; 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.auth.entity.PrivilegeType; import org.apache.iotdb.commons.auth.entity.PrivilegeUnion; @@ -148,6 +149,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.iotdb.confignode.manager.pipe.source.PipeConfigTreePrivilegeParseVisitor.checkGlobalOrAnyStatus; import static org.apache.iotdb.confignode.manager.pipe.source.PipeConfigTreePrivilegeParseVisitor.checkGlobalStatus; import static org.apache.iotdb.confignode.manager.pipe.source.PipeConfigTreePrivilegeParseVisitor.checkPathsStatus; @@ -193,6 +195,7 @@ public TPipeTransferResp receive(final TPipeTransferReq req) { resp = handleTransferHandshakeV2( PipeTransferConfigNodeHandshakeV2Req.fromTPipeTransferReq(req)); + userEntity.setAuditLogOperation(AuditLogOperation.DDL); PipeConfigNodeReceiverMetrics.getInstance() .recordHandshakeConfigNodeV2Timer(System.nanoTime() - startTime); return resp; @@ -302,11 +305,12 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti final String database; final String templateName; final String triggerName; + final String entityName; switch (plan.getType()) { case CreateDatabase: database = ((DatabaseSchemaPlan) plan).getSchema().getName(); if (PathUtils.isTableModelDatabase(database)) { - status = checkDatabaseStatus(userEntity, PrivilegeType.CREATE, database, false); + status = checkDatabaseStatus(userEntity, PrivilegeType.CREATE, database); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, database, true); } @@ -315,7 +319,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti case AlterDatabase: database = ((DatabaseSchemaPlan) plan).getSchema().getName(); if (PathUtils.isTableModelDatabase(database)) { - status = checkDatabaseStatus(userEntity, PrivilegeType.ALTER, database, false); + status = checkDatabaseStatus(userEntity, PrivilegeType.ALTER, database); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, database, true); } @@ -324,7 +328,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti case DeleteDatabase: database = ((DeleteDatabasePlan) plan).getName(); if (PathUtils.isTableModelDatabase(database)) { - status = checkDatabaseStatus(userEntity, PrivilegeType.DELETE, database, false); + status = checkDatabaseStatus(userEntity, PrivilegeType.DELETE, database); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return checkGlobalStatus(userEntity, PrivilegeType.SYSTEM, database, true); } @@ -445,8 +449,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti userEntity, PrivilegeType.CREATE, ((PipeCreateTableOrViewPlan) plan).getDatabase(), - ((PipeCreateTableOrViewPlan) plan).getTable().getTableName(), - true); + ((PipeCreateTableOrViewPlan) plan).getTable().getTableName()); case AddTableColumn: case AddViewColumn: case SetTableProperties: @@ -464,67 +467,86 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti userEntity, PrivilegeType.ALTER, ((AbstractTablePlan) plan).getDatabase(), - ((AbstractTablePlan) plan).getTableName(), - true); + ((AbstractTablePlan) plan).getTableName()); case CommitDeleteTable: case CommitDeleteView: return checkTableStatus( userEntity, PrivilegeType.DELETE, ((CommitDeleteTablePlan) plan).getDatabase(), - ((CommitDeleteTablePlan) plan).getTableName(), - true); + ((CommitDeleteTablePlan) plan).getTableName()); case GrantRole: case GrantUser: case RevokeUser: case RevokeRole: + entityName = + plan.getType() == ConfigPhysicalPlanType.GrantUser + || plan.getType() == ConfigPhysicalPlanType.RevokeUser + ? ((AuthorPlan) plan).getUserName() + : ((AuthorPlan) plan).getRoleName(); + status = checkGlobalStatus(userEntity, PrivilegeType.SECURITY, entityName, false); + if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return status; + } for (final int permission : ((AuthorTreePlan) plan).getPermissions()) { status = - configManager - .checkUserPrivilegeGrantOpt( - username, - PrivilegeType.values()[permission].isPathPrivilege() - ? new PrivilegeUnion( - ((AuthorTreePlan) plan).getNodeNameList(), - PrivilegeType.values()[permission], - true) - : new PrivilegeUnion(PrivilegeType.values()[permission], true)) - .getStatus(); + PrivilegeType.values()[permission].isPathPrivilege() + ? checkPathsStatus( + userEntity, + PrivilegeType.values()[permission], + ((AuthorTreePlan) plan).getNodeNameList(), + false, + entityName) + : checkGlobalStatus( + userEntity, PrivilegeType.values()[permission], entityName, false, true); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return status; } } + configManager + .getAuditLogger() + .recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + () -> entityName); return StatusUtils.OK; case RGrantUserAny: case RGrantRoleAny: case RRevokeUserAny: case RRevokeRoleAny: + entityName = + plan.getType() == ConfigPhysicalPlanType.RGrantUserAny + || plan.getType() == ConfigPhysicalPlanType.RRevokeUserAny + ? ((AuthorPlan) plan).getUserName() + : ((AuthorPlan) plan).getRoleName(); for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) { status = - configManager - .checkUserPrivileges( - username, new PrivilegeUnion(PrivilegeType.values()[permission], true, true)) - .getStatus(); + checkGlobalOrAnyStatus( + userEntity, PrivilegeType.values()[permission], entityName, false, true, true); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return status; } } + configManager + .getAuditLogger() + .recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + () -> entityName); return StatusUtils.OK; case RGrantUserAll: case RGrantRoleAll: case RRevokeUserAll: case RRevokeRoleAll: + entityName = + plan.getType() == ConfigPhysicalPlanType.RGrantUserAll + || plan.getType() == ConfigPhysicalPlanType.RRevokeUserAll + ? ((AuthorPlan) plan).getUserName() + : ((AuthorPlan) plan).getRoleName(); for (PrivilegeType privilegeType : PrivilegeType.values()) { if (privilegeType.isRelationalPrivilege()) { status = - configManager - .checkUserPrivileges(username, new PrivilegeUnion(privilegeType, true, true)) - .getStatus(); + checkGlobalOrAnyStatus(userEntity, privilegeType, entityName, false, true, true); } else if (privilegeType.forRelationalSys()) { - status = - configManager - .checkUserPrivileges(username, new PrivilegeUnion(privilegeType, true)) - .getStatus(); + status = checkGlobalStatus(userEntity, privilegeType, entityName, false, true); } else { continue; } @@ -532,60 +554,88 @@ username, new PrivilegeUnion(PrivilegeType.values()[permission], true, true)) return status; } } + configManager + .getAuditLogger() + .recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + () -> entityName); return StatusUtils.OK; case RGrantUserDBPriv: case RGrantRoleDBPriv: case RRevokeUserDBPriv: case RRevokeRoleDBPriv: + entityName = + plan.getType() == ConfigPhysicalPlanType.RGrantUserDBPriv + || plan.getType() == ConfigPhysicalPlanType.RRevokeUserDBPriv + ? ((AuthorPlan) plan).getUserName() + : ((AuthorPlan) plan).getRoleName(); for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) { status = - configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((AuthorRelationalPlan) plan).getDatabaseName(), - PrivilegeType.values()[permission], - true)) - .getStatus(); + checkDatabaseStatus( + userEntity, + PrivilegeType.values()[permission], + ((AuthorRelationalPlan) plan).getDatabaseName(), + true); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return status; } } + configManager + .getAuditLogger() + .recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + () -> entityName); return StatusUtils.OK; case RGrantUserTBPriv: case RGrantRoleTBPriv: case RRevokeUserTBPriv: case RRevokeRoleTBPriv: + entityName = + plan.getType() == ConfigPhysicalPlanType.RGrantUserTBPriv + || plan.getType() == ConfigPhysicalPlanType.RRevokeUserTBPriv + ? ((AuthorPlan) plan).getUserName() + : ((AuthorPlan) plan).getRoleName(); for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) { status = - configManager - .checkUserPrivileges( - username, - new PrivilegeUnion( - ((AuthorRelationalPlan) plan).getDatabaseName(), - ((AuthorRelationalPlan) plan).getTableName(), - PrivilegeType.values()[permission], - true)) - .getStatus(); + checkTableStatus( + userEntity, + PrivilegeType.values()[permission], + ((AuthorRelationalPlan) plan).getDatabaseName(), + ((AuthorRelationalPlan) plan).getTableName(), + false, + true); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return status; } } + configManager + .getAuditLogger() + .recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + () -> entityName); return StatusUtils.OK; case RGrantUserSysPri: case RGrantRoleSysPri: case RRevokeUserSysPri: case RRevokeRoleSysPri: + entityName = + plan.getType() == ConfigPhysicalPlanType.RGrantUserSysPri + || plan.getType() == ConfigPhysicalPlanType.RRevokeUserSysPri + ? ((AuthorPlan) plan).getUserName() + : ((AuthorPlan) plan).getRoleName(); for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) { status = - configManager - .checkUserPrivileges( - username, new PrivilegeUnion(PrivilegeType.values()[permission], true)) - .getStatus(); + checkGlobalStatus( + userEntity, PrivilegeType.values()[permission], entityName, false, true); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { return status; } } + configManager + .getAuditLogger() + .recordAuditLog( + userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), + () -> entityName); return StatusUtils.OK; case UpdateUser: case UpdateUserV2: @@ -623,21 +673,24 @@ username, new PrivilegeUnion(PrivilegeType.values()[permission], true)) } } - public static TSStatus checkDatabaseStatus( + private TSStatus checkDatabaseStatus( + final IAuditEntity userEntity, final PrivilegeType privilegeType, final String database) { + return checkDatabaseStatus(userEntity, privilegeType, database, false); + } + + private TSStatus checkDatabaseStatus( final IAuditEntity userEntity, final PrivilegeType privilegeType, final String database, - final boolean isLastCheck) { - final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); - final CNAuditLogger logger = configManager.getAuditLogger(); + final boolean grantOption) { final TSStatus result = configManager .getPermissionManager() .checkUserPrivileges( - userEntity.getUsername(), new PrivilegeUnion(database, privilegeType)) + userEntity.getUsername(), new PrivilegeUnion(database, privilegeType, grantOption)) .getStatus(); - if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { - logger.recordAuditLog( + if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + auditLogger.recordAuditLog( userEntity .setPrivilegeType(privilegeType) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), @@ -646,22 +699,30 @@ public static TSStatus checkDatabaseStatus( return result; } - public static TSStatus checkTableStatus( + private TSStatus checkTableStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String database, + final String tableName) { + return checkTableStatus(userEntity, privilegeType, database, tableName, true, false); + } + + private TSStatus checkTableStatus( final IAuditEntity userEntity, final PrivilegeType privilegeType, final String database, final String tableName, - final boolean isLastCheck) { - final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); - final CNAuditLogger logger = configManager.getAuditLogger(); + final boolean isLastCheck, + final boolean grantOption) { final TSStatus result = configManager .getPermissionManager() .checkUserPrivileges( - userEntity.getUsername(), new PrivilegeUnion(database, tableName, privilegeType)) + userEntity.getUsername(), + new PrivilegeUnion(database, tableName, privilegeType, grantOption)) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { - logger.recordAuditLog( + auditLogger.recordAuditLog( userEntity .setPrivilegeType(privilegeType) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 4f886a808a210..3cfb85cdecd0e 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -52,6 +52,7 @@ import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.IOException; import java.util.Arrays; @@ -59,6 +60,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import static org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD; @@ -417,12 +419,33 @@ public static TSStatus checkGlobalStatus( final PrivilegeType privilegeType, final String auditObject, final boolean isLastCheck) { + return checkGlobalStatus(userEntity, privilegeType, auditObject, isLastCheck, false); + } + + public static TSStatus checkGlobalStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String auditObject, + final boolean isLastCheck, + final boolean grantOption) { + return checkGlobalOrAnyStatus( + userEntity, privilegeType, auditObject, isLastCheck, grantOption, false); + } + + public static TSStatus checkGlobalOrAnyStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final String auditObject, + final boolean isLastCheck, + final boolean grantOption, + final boolean isAny) { final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); final CNAuditLogger logger = configManager.getAuditLogger(); final TSStatus result = configManager .getPermissionManager() - .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(privilegeType)) + .checkUserPrivileges( + userEntity.getUsername(), new PrivilegeUnion(privilegeType, grantOption, isAny)) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { logger.recordAuditLog( @@ -448,20 +471,31 @@ public static TSStatus checkPathsStatus( final PrivilegeType privilegeType, final @Nonnull List paths, final boolean isLastCheck) { + return checkPathsStatus(userEntity, privilegeType, paths, isLastCheck, null); + } + + public static TSStatus checkPathsStatus( + final IAuditEntity userEntity, + final PrivilegeType privilegeType, + final @Nonnull List paths, + final boolean isLastCheck, + final @Nullable String grantName) { final ConfigManager configManager = ConfigNode.getInstance().getConfigManager(); final CNAuditLogger logger = configManager.getAuditLogger(); final TSStatus result = ConfigNode.getInstance() .getConfigManager() .getPermissionManager() - .checkUserPrivileges(userEntity.getUsername(), new PrivilegeUnion(paths, privilegeType)) + .checkUserPrivileges( + userEntity.getUsername(), + new PrivilegeUnion(paths, privilegeType, Objects.nonNull(grantName))) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { logger.recordAuditLog( userEntity .setPrivilegeType(PrivilegeType.READ_SCHEMA) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), - paths::toString); + Objects.nonNull(grantName) ? () -> grantName : paths::toString); } return result; } From 9135ce6cbd130db81eb9efb8f09810304b25b2ab Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:17:56 +0800 Subject: [PATCH 19/19] refactor --- .../protocol/IoTDBConfigNodeReceiver.java | 21 +-- .../PipeConfigTablePrivilegeParseVisitor.java | 4 +- .../PipeConfigTreePrivilegeParseVisitor.java | 34 ++-- .../config/TableConfigTaskVisitor.java | 2 +- .../security/AccessControlImpl.java | 56 ++++--- .../security/ITableAuthCheckerImpl.java | 52 +++--- .../security/TreeAccessCheckVisitor.java | 154 ++++++++++-------- .../commons/audit/AbstractAuditLogger.java | 3 +- 8 files changed, 175 insertions(+), 151 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java index 8e54f46a5ff3e..5044a5b858f75 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java @@ -386,7 +386,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti ((PipeAlterEncodingCompressorPlan) plan).setPatternTreeBytes(tree.serialize()); configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity .setPrivilegeType(PrivilegeType.WRITE_SCHEMA) .setResult(!tree.isEmpty()), @@ -505,7 +505,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), () -> entityName); return StatusUtils.OK; @@ -528,7 +528,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), () -> entityName); return StatusUtils.OK; @@ -556,7 +556,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), () -> entityName); return StatusUtils.OK; @@ -582,7 +582,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), () -> entityName); return StatusUtils.OK; @@ -610,7 +610,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), () -> entityName); return StatusUtils.OK; @@ -633,7 +633,7 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti } configManager .getAuditLogger() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), () -> entityName); return StatusUtils.OK; @@ -644,7 +644,8 @@ private TSStatus checkPermission(final ConfigPhysicalPlan plan) throws IOExcepti if (((AuthorPlan) plan).getUserName().equals(username)) { configManager .getAuditLogger() - .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> username); + .recordObjectAuthenticationAuditLog( + userEntity.setPrivilegeType(null).setResult(true), () -> username); return StatusUtils.OK; } return checkGlobalStatus( @@ -690,7 +691,7 @@ private TSStatus checkDatabaseStatus( userEntity.getUsername(), new PrivilegeUnion(database, privilegeType, grantOption)) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - auditLogger.recordAuditLog( + auditLogger.recordObjectAuthenticationAuditLog( userEntity .setPrivilegeType(privilegeType) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), @@ -722,7 +723,7 @@ private TSStatus checkTableStatus( new PrivilegeUnion(database, tableName, privilegeType, grantOption)) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { - auditLogger.recordAuditLog( + auditLogger.recordObjectAuthenticationAuditLog( userEntity .setPrivilegeType(privilegeType) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java index 0f75aa56ae556..9f3d92e29f1dc 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTablePrivilegeParseVisitor.java @@ -92,7 +92,7 @@ private boolean isDatabaseVisible(final IAuditEntity userEntity, final String da .getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode(); if (result) { - logger.recordAuditLog( + logger.recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA).setResult(true), () -> database); return true; } @@ -185,7 +185,7 @@ private boolean isTableVisible( .getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode(); if (result) { - logger.recordAuditLog( + logger.recordObjectAuthenticationAuditLog( userEntity.setPrivilegeType(PrivilegeType.READ_SCHEMA).setResult(true), () -> database); return true; } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java index 3cfb85cdecd0e..e2599ac20c9bb 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/source/PipeConfigTreePrivilegeParseVisitor.java @@ -220,7 +220,8 @@ public static Optional visitUserPlan( ConfigNode.getInstance() .getConfigManager() .getAuditLogger() - .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); + .recordObjectAuthenticationAuditLog( + userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); return Optional.of(plan); } return hasGlobalPrivilege( @@ -242,7 +243,8 @@ public static Optional visitRolePlan( == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { configManager .getAuditLogger() - .recordAuditLog(userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); + .recordObjectAuthenticationAuditLog( + userEntity.setPrivilegeType(null).setResult(true), () -> auditObject); return Optional.of(plan); } } catch (final Exception ignore) { @@ -265,12 +267,12 @@ public Optional visitPipeDeleteTimeSeries( final PathPatternTree intersectedTree = originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !originalTree.equals(intersectedTree)) { - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); throw new AccessDeniedException( "Not has privilege to transfer plan: " + pipeDeleteTimeSeriesPlan); } final boolean result = !intersectedTree.isEmpty(); - logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(result), () -> auditObject); return result ? Optional.of(new PipeDeleteTimeSeriesPlan(intersectedTree.serialize())) : Optional.empty(); @@ -278,10 +280,10 @@ public Optional visitPipeDeleteTimeSeries( LOGGER.warn( "Serialization failed for the delete time series plan in pipe transmission, skip transfer", e); - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); return Optional.empty(); } catch (final AuthException e) { - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -303,12 +305,12 @@ public Optional visitPipeDeleteLogicalView( final PathPatternTree intersectedTree = originalTree.intersectWithFullPathPrefixTree(getAuthorizedPTree(userEntity)); if (!skip && !originalTree.equals(intersectedTree)) { - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); throw new AccessDeniedException( "Not has privilege to transfer plan: " + pipeDeleteLogicalViewPlan); } final boolean result = !intersectedTree.isEmpty(); - logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(result), () -> auditObject); return result ? Optional.of(new PipeDeleteLogicalViewPlan(intersectedTree.serialize())) : Optional.empty(); @@ -316,10 +318,10 @@ public Optional visitPipeDeleteLogicalView( LOGGER.warn( "Serialization failed for the delete time series plan in pipe transmission, skip transfer", e); - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); return Optional.empty(); } catch (final AuthException e) { - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -350,12 +352,12 @@ public Optional visitPipeDeactivateTemplate( } } final boolean result = !newTemplateSetInfo.isEmpty(); - logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(result), () -> auditObject); return !newTemplateSetInfo.isEmpty() ? Optional.of(new PipeDeactivateTemplatePlan(newTemplateSetInfo)) : Optional.empty(); } catch (final AuthException e) { - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -379,12 +381,12 @@ public Optional visitTTL( // pattern and TTL path are each either a prefix path or a full path final boolean result = !paths.isEmpty() && paths.get(0).getNodeLength() == setTTLPlan.getPathPattern().length; - logger.recordAuditLog(userEntity.setResult(result), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(result), () -> auditObject); return result ? Optional.of(new SetTTLPlan(paths.get(0).getNodes(), setTTLPlan.getTTL())) : Optional.empty(); } catch (final AuthException e) { - logger.recordAuditLog(userEntity.setResult(false), () -> auditObject); + logger.recordObjectAuthenticationAuditLog(userEntity.setResult(false), () -> auditObject); if (skip) { return Optional.empty(); } else { @@ -448,7 +450,7 @@ public static TSStatus checkGlobalOrAnyStatus( userEntity.getUsername(), new PrivilegeUnion(privilegeType, grantOption, isAny)) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { - logger.recordAuditLog( + logger.recordObjectAuthenticationAuditLog( userEntity .setPrivilegeType(privilegeType) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), @@ -491,7 +493,7 @@ public static TSStatus checkPathsStatus( new PrivilegeUnion(paths, privilegeType, Objects.nonNull(grantName))) .getStatus(); if (result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() || isLastCheck) { - logger.recordAuditLog( + logger.recordObjectAuthenticationAuditLog( userEntity .setPrivilegeType(PrivilegeType.READ_SCHEMA) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), 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 60be9a4655441..fc973548ae89b 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 @@ -501,7 +501,7 @@ protected IConfigTask visitShowAvailableUrls( final ShowAvailableUrls showAvailableUrls, final MPPQueryContext context) { context.setQueryType(QueryType.READ); DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), () -> ""); return new ShowAvailableUrlsTask(); } 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 dfb97f0287f5c..c162508d45dca 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 @@ -119,7 +119,7 @@ public void checkCanCreateTable( checkAuditDatabase(tableName.getDatabaseName()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.CREATE).setResult(true), tableName::getObjectName); return; @@ -137,7 +137,7 @@ public void checkCanDropTable( checkAuditDatabase(tableName.getDatabaseName()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.DROP).setResult(true), tableName::getObjectName); return; @@ -151,7 +151,8 @@ public void checkCanAlterTable( InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName()); checkAuditDatabase(tableName.getDatabaseName()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SYSTEM)) { - DNAuditLogger.getInstance().recordAuditLog(auditEntity, tableName::getObjectName); + DNAuditLogger.getInstance() + .recordObjectAuthenticationAuditLog(auditEntity, tableName::getObjectName); return; } authChecker.checkTablePrivilege(userName, tableName, TableModelPrivilege.ALTER, auditEntity); @@ -260,7 +261,8 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getUserName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getUserName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); @@ -271,20 +273,23 @@ public void checkUserCanRunRelationalAuthorStatement( if (statement.getUserName().equals(userName)) { // users can change the username and password of themselves DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getUserName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getUserName); return; } if (AuthorityChecker.SUPER_USER_ID == AuthorityChecker.getUserId(statement.getUserName()).orElse(-1L)) { // Only the superuser can alter him/herself DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(false), statement::getUserName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(false), statement::getUserName); throw new AccessDeniedException("Only the superuser can alter him/herself."); } if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { // the superuser can alter anyone DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getUserName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getUserName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_USER, auditEntity); @@ -294,13 +299,14 @@ public void checkUserCanRunRelationalAuthorStatement( if (statement.getUserName().equals(userName)) { // No need any privilege to list him/herself DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getUserName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getUserName); return; } // Require SECURITY privilege to list other users' privileges if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), statement::getUserName); return; @@ -312,11 +318,12 @@ public void checkUserCanRunRelationalAuthorStatement( if (!hasGlobalPrivilege(auditEntity, PrivilegeType.MANAGE_USER)) { // No need to check privilege to list himself/herself statement.setUserName(userName); - DNAuditLogger.getInstance().recordAuditLog(auditEntity, statement::getUserName); + DNAuditLogger.getInstance() + .recordObjectAuthenticationAuditLog(auditEntity, statement::getUserName); } else { // Require SECURITY privilege to list other users DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.SECURITY), statement::getUserName); } return; @@ -327,7 +334,8 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getRoleName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getRoleName); return; } authChecker.checkGlobalPrivilege(userName, TableModelPrivilege.MANAGE_ROLE, auditEntity); @@ -339,7 +347,7 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setResult(true), () -> "user: " + statement.getUserName() + ", role: " + statement.getRoleName()); return; @@ -357,11 +365,12 @@ public void checkUserCanRunRelationalAuthorStatement( // No need to check privilege to list his/hers own role statement.setUserName(userName); DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getRoleName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getRoleName); } else { // Require SECURITY privilege to list all roles DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), statement::getRoleName); } @@ -371,13 +380,14 @@ public void checkUserCanRunRelationalAuthorStatement( if (AuthorityChecker.checkRole(userName, statement.getRoleName())) { // No need any privilege to list his/hers own role DNAuditLogger.getInstance() - .recordAuditLog(auditEntity.setResult(true), statement::getRoleName); + .recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), statement::getRoleName); return; } // Require SECURITY privilege to list other roles' privileges if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.SECURITY).setResult(true), statement::getRoleName); return; @@ -394,7 +404,7 @@ public void checkUserCanRunRelationalAuthorStatement( .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); return; @@ -414,7 +424,7 @@ public void checkUserCanRunRelationalAuthorStatement( .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); return; @@ -439,7 +449,7 @@ public void checkUserCanRunRelationalAuthorStatement( .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); return; @@ -462,7 +472,7 @@ public void checkUserCanRunRelationalAuthorStatement( .setDatabase(statement.getDatabase()); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); return; @@ -486,7 +496,7 @@ public void checkUserCanRunRelationalAuthorStatement( .setPrivilegeType(PrivilegeType.SECURITY); if (hasGlobalPrivilege(auditEntity, PrivilegeType.SECURITY)) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( auditEntity.setResult(true), () -> statement.getUserName() + statement.getRoleName()); return; @@ -571,7 +581,7 @@ public TSStatus checkCanAlterView( IAuditEntity entity, List sourcePaths, List targetPaths) { if (AuthorityChecker.SUPER_USER_ID == entity.getUserId()) { DNAuditLogger.getInstance() - .recordAuditLog( + .recordObjectAuthenticationAuditLog( entity .setPrivilegeTypes( Arrays.asList(PrivilegeType.READ_SCHEMA, PrivilegeType.WRITE_SCHEMA)) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java index 8eca0f9b33408..16c32880c8e48 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java @@ -44,7 +44,7 @@ public class ITableAuthCheckerImpl implements ITableAuthChecker { public void checkDatabaseVisibility( String userName, String databaseName, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -54,7 +54,7 @@ public void checkDatabaseVisibility( } // Information_schema is visible to any user if (databaseName.equals(InformationSchema.INFORMATION_DATABASE)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -67,7 +67,7 @@ public void checkDatabaseVisibility( // The audit database only requires audit privilege boolean hasAuditPrivilege = AuthorityChecker.checkSystemPermission(userName, PrivilegeType.AUDIT); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.AUDIT) @@ -80,7 +80,7 @@ public void checkDatabaseVisibility( } if (AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -89,7 +89,7 @@ public void checkDatabaseVisibility( return; } if (!AuthorityChecker.checkDBVisible(userName, databaseName)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -97,7 +97,7 @@ public void checkDatabaseVisibility( () -> databaseName); throw new AccessDeniedException("DATABASE " + databaseName); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -119,7 +119,7 @@ public void checkDatabasePrivilege( } if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -129,7 +129,7 @@ public void checkDatabasePrivilege( } if (AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -159,7 +159,7 @@ private static void checkAuditDatabase( if (privilege == TableModelPrivilege.SELECT) { checkCanSelectAuditTable(auditEntity); } else { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -175,7 +175,7 @@ public static void checkCanSelectAuditTable(IAuditEntity auditEntity) { String userName = auditEntity.getUsername(); if (AuthorityChecker.SUPER_USER_ID != auditEntity.getUserId() && !AuthorityChecker.checkSystemPermission(userName, PrivilegeType.AUDIT)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.SELECT) @@ -199,7 +199,7 @@ public static void checkCanSelectAuditTable(IAuditEntity auditEntity) { String.format( "The database '%s' can only be queried by AUDIT admin.", TABLE_MODEL_AUDIT_DATABASE)); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.SELECT) @@ -214,7 +214,7 @@ public void checkDatabasePrivilegeGrantOption( TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -239,7 +239,7 @@ public void checkTablePrivilege( IAuditEntity auditEntity) { auditEntity.setDatabase(tableName.getDatabaseName()); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -267,7 +267,7 @@ public void checkTablePrivilegeGrantOption( TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -303,7 +303,7 @@ public boolean checkTablePrivilege4Pipe( tableName.getObjectName()) .getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.CONTROL) .setPrivilegeType(PrivilegeType.SYSTEM) @@ -311,7 +311,7 @@ public boolean checkTablePrivilege4Pipe( tableName::getObjectName); return true; } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.CONTROL) .setPrivilegeType(PrivilegeType.SYSTEM) @@ -325,7 +325,7 @@ public void checkTableVisibility( String userName, QualifiedObjectName tableName, IAuditEntity auditEntity) { auditEntity.setDatabase(tableName.getDatabaseName()); if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -339,7 +339,7 @@ public void checkTableVisibility( // The audit table only requires audit privilege boolean hasAuditPrivilege = AuthorityChecker.checkSystemPermission(userName, PrivilegeType.AUDIT); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.AUDIT) @@ -352,7 +352,7 @@ public void checkTableVisibility( } if (AuthorityChecker.checkSystemPermission(userName, PrivilegeType.SYSTEM)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -362,7 +362,7 @@ public void checkTableVisibility( } if (!AuthorityChecker.checkTableVisible( userName, tableName.getDatabaseName(), tableName.getObjectName())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA) @@ -376,7 +376,7 @@ public void checkTableVisibility( public void checkGlobalPrivilege( String userName, TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -396,7 +396,7 @@ public void checkGlobalPrivileges( String username, Collection privileges, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { for (PrivilegeType privilege : privileges) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege) @@ -417,7 +417,7 @@ public void checkGlobalPrivileges( public void checkGlobalPrivilegeGrantOption( String userName, TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -438,7 +438,7 @@ public void checkGlobalPrivilegeGrantOption( public void checkAnyScopePrivilegeGrantOption( String userName, TableModelPrivilege privilege, IAuditEntity auditEntity) { if (AuthorityChecker.SUPER_USER_ID == auditEntity.getUserId()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -461,7 +461,7 @@ private void recordAuditLogViaAuthenticationResult( IAuditEntity auditEntity, TSStatus result) { if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) @@ -469,7 +469,7 @@ private void recordAuditLogViaAuthenticationResult( auditObject); throw new AccessDeniedException(result.getMessage()); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity .setAuditLogOperation(privilege.getAuditLogOperation()) .setPrivilegeType(privilege.getPrivilegeType()) 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 147fcd71e01af..219984fc5fdf8 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 @@ -195,7 +195,7 @@ public TSStatus visitAuthorityInformation( .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.READ_SCHEMA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -204,12 +204,12 @@ public TSStatus visitAuthorityInformation( statement.setAuthorityScope( AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_SCHEMA)); } catch (AuthException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -219,7 +219,7 @@ public static List getIntersectedPaths4Pipe( final List paths, final TreeAccessCheckContext context) { context.setAuditLogOperation(AuditLogOperation.QUERY).setPrivilegeType(PrivilegeType.READ_DATA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> paths.stream().distinct().collect(Collectors.toList()).toString()); return paths; @@ -230,12 +230,12 @@ public static List getIntersectedPaths4Pipe( originalTree.constructTree(); final PathPatternTree tree = AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_DATA); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> paths.stream().distinct().collect(Collectors.toList()).toString()); return originalTree.intersectWithFullPathPrefixTree(tree).getAllPathPatterns(true); } catch (AuthException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> paths.stream().distinct().collect(Collectors.toList()).toString()); return Collections.emptyList(); @@ -298,7 +298,7 @@ private TSStatus checkTemplateShowRelated( ShowSchemaTemplateStatement statement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAll(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.SYSTEM) @@ -378,7 +378,7 @@ public TSStatus visitAlterSchemaTemplate( public TSStatus checkCanAlterTemplate(IAuditEntity entity, Supplier auditObject) { if (AuthorityChecker.SUPER_USER.equals(entity.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( entity .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.EXTEND_TEMPLATE) @@ -409,7 +409,7 @@ public TSStatus visitCreateLogicalView( // audit db is read-only if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.AUDIT).setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); @@ -421,7 +421,7 @@ public TSStatus visitCreateLogicalView( if (statement.getQueryStatement() != null) { statement.getQueryStatement().setCanSeeAuditDB(true); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setPrivilegeTypes( Arrays.asList(PrivilegeType.WRITE_SCHEMA, PrivilegeType.READ_SCHEMA)) @@ -479,7 +479,7 @@ public TSStatus visitAlterLogicalView( if (statement.getQueryStatement() != null) { statement.getQueryStatement().setCanSeeAuditDB(true); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setPrivilegeTypes( Arrays.asList(PrivilegeType.READ_SCHEMA, PrivilegeType.WRITE_SCHEMA)) @@ -522,7 +522,7 @@ public TSStatus visitRenameLogicalView( // audit db is read-only if (includeByAuditTreeDB(statement.getNewName()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.WRITE_SCHEMA).setResult(false), () -> statement.getOldName().toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -554,13 +554,15 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co context.setAuditLogOperation(AuditLogOperation.DDL); if (statement.getUserName().equals(context.getUsername())) { // users can change the username and password of themselves - AUDIT_LOGGER.recordAuditLog(context.setResult(true), context::getUsername); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; } if (AuthorityChecker.SUPER_USER_ID == AuthorityChecker.getUserId(statement.getUserName()).orElse(-1L)) { // Only the superuser can alter him/herself - AUDIT_LOGGER.recordAuditLog(context.setResult(false), context::getUsername); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(false), context::getUsername); return AuthorityChecker.getTSStatus( false, "Has no permission to execute " @@ -583,14 +585,15 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co } // Can only list him/herself without MANAGE_USER privilege statement.setUserName(context.getUsername()); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(null).setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; case LIST_USER_PRIVILEGE: context.setAuditLogOperation(AuditLogOperation.QUERY); if (context.getUsername().equals(statement.getUserName())) { // No need any privilege to list his/her own privileges - AUDIT_LOGGER.recordAuditLog(context.setResult(true), context::getUsername); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(true), context::getUsername); return RpcUtils.SUCCESS_STATUS; } // Require MANAGE_USER privilege to list other users' privileges @@ -607,7 +610,8 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co statement::getRoleName); } else { // No need any privilege to list his/her own role's privileges - AUDIT_LOGGER.recordAuditLog(context.setResult(true), context::getUsername); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(true), context::getUsername); return SUCCEED; } case LIST_ROLE: @@ -621,12 +625,12 @@ public TSStatus visitAuthor(AuthorStatement statement, TreeAccessCheckContext co // list roles of other user is not allowed if (statement.getUserName() != null && !statement.getUserName().equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.MANAGE_ROLE).setResult(false), context::getUsername); return AuthorityChecker.getTSStatus(false, PrivilegeType.MANAGE_ROLE); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(null).setResult(true), context::getUsername); statement.setUserName(context.getUsername()); return RpcUtils.SUCCESS_STATUS; @@ -718,7 +722,7 @@ public TSStatus visitShowContinuousQueries( private TSStatus checkCQManagement(IAuditEntity auditEntity, Supplier auditObject) { if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.USE_CQ).setResult(true), auditObject); return SUCCEED; } @@ -744,7 +748,7 @@ public TSStatus visitDropFunction( public TSStatus visitShowFunctions( ShowFunctionsStatement statement, TreeAccessCheckContext context) { // anyone can show functions - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), null); return SUCCEED; } @@ -913,7 +917,7 @@ public TSStatus visitDropSubscription( public TSStatus visitCreateTrigger( CreateTriggerStatement statement, TreeAccessCheckContext context) { if (TREE_MODEL_AUDIT_DATABASE_PATH.include(statement.getPathPattern())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setAuditLogOperation(AuditLogOperation.DDL) .setPrivilegeType(PrivilegeType.USE_TRIGGER) @@ -941,7 +945,7 @@ public TSStatus visitShowTriggers( private TSStatus checkTriggerManagement(IAuditEntity auditEntity, Supplier auditObject) { if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( auditEntity.setPrivilegeType(PrivilegeType.USE_TRIGGER).setResult(true), auditObject); return SUCCEED; } @@ -975,7 +979,7 @@ public TSStatus visitShowDatabase( .collect(Collectors.toList()) .toString()); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.SYSTEM).setResult(true), context::getDatabase); return SUCCEED; } @@ -994,7 +998,7 @@ public TSStatus visitCountDatabase( .collect(Collectors.toList()) .toString()); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.SYSTEM).setResult(true), context::getDatabase); return SUCCEED; } @@ -1011,7 +1015,7 @@ public TSStatus visitDeleteDatabase( for (String prefixPath : statement.getPrefixPath()) { // root.__audit can never be deleted if (TREE_MODEL_AUDIT_DATABASE.equals(prefixPath)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.MANAGE_DATABASE).setResult(false), () -> prefixPath); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1019,7 +1023,7 @@ public TSStatus visitDeleteDatabase( } } if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(PrivilegeType.MANAGE_DATABASE).setResult(true), () -> statement.getPrefixPath().toString()); return SUCCEED; @@ -1039,13 +1043,15 @@ protected TSStatus checkCreateOrAlterDatabasePermission( // root.__audit can never be created or alter by other users return SUCCEED; } - AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(false), databaseName::getFullPath); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + auditEntity.setResult(false), databaseName::getFullPath); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(true), databaseName::getFullPath); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + auditEntity.setResult(true), databaseName::getFullPath); return SUCCEED; } @@ -1062,7 +1068,7 @@ private TSStatus checkShowOrCountDatabasePermission( () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString())) { return visitAuthorityInformation(statement, context); } else { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setAuditLogOperation(AuditLogOperation.QUERY) .setPrivilegeType(PrivilegeType.MANAGE_DATABASE) @@ -1080,14 +1086,14 @@ public TSStatus visitInsertBase(InsertBaseStatement statement, TreeAccessCheckCo // audit db is read-only if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::toString); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog(context.setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } } if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1104,7 +1110,8 @@ public TSStatus visitInsert(InsertStatement statement, TreeAccessCheckContext co // audit db is read-only if (includeByAuditTreeDB(statement.getDevice()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog(context.setResult(false), () -> statement.getDevice().toString()); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(false), () -> statement.getDevice().toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -1124,7 +1131,7 @@ public TSStatus visitDeleteData(DeleteDataStatement statement, TreeAccessCheckCo // audit db is read-only if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::toString); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog(context.setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -1137,7 +1144,7 @@ public TSStatus visitQuery(QueryStatement statement, TreeAccessCheckContext cont context.setAuditLogOperation(AuditLogOperation.QUERY).setPrivilegeType(PrivilegeType.READ_DATA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1148,12 +1155,12 @@ public TSStatus visitQuery(QueryStatement statement, TreeAccessCheckContext cont statement.setAuthorityScope( AuthorityChecker.getAuthorizedPathTree(context.getUsername(), PrivilegeType.READ_DATA)); } catch (AuthException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1177,7 +1184,7 @@ public static TSStatus checkTimeSeriesPermission( PrivilegeType permission) { context.setPrivilegeType(permission); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> checkedPathsSupplier.get().toString()); return SUCCEED; } @@ -1190,7 +1197,7 @@ public static TSStatus checkTimeSeriesPermission( permission); if (!AuthorityChecker.INTERNAL_AUDIT_USER.equals(context.getUsername())) { // Internal auditor no needs audit log - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), checkedPaths::toString); } @@ -1201,13 +1208,15 @@ public static List checkTimeSeriesPermission4Pipe( IAuditEntity context, List checkedPaths, PrivilegeType permission) { context.setPrivilegeType(permission); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog(context.setResult(true), checkedPaths::toString); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(true), checkedPaths::toString); return Collections.emptyList(); } final List results = AuthorityChecker.checkFullPathOrPatternListPermission( context.getUsername(), checkedPaths, permission); - AUDIT_LOGGER.recordAuditLog(context.setResult(true), checkedPaths::toString); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(true), checkedPaths::toString); return results; } @@ -1220,7 +1229,7 @@ public TSStatus visitCreateTimeseries( // audit db is read-only if (includeByAuditTreeDB(statement.getPath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1238,7 +1247,7 @@ public TSStatus visitCreateAlignedTimeseries( // audit db is read-only if (includeByAuditTreeDB(statement.getDevicePath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1275,7 +1284,7 @@ public TSStatus visitInternalCreateMultiTimeSeries( for (PartialPath path : statement.getDeviceMap().keySet()) { if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::toString); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog(context.setResult(false), path::toString); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -1290,7 +1299,7 @@ public TSStatus visitInternalCreateTimeseries( // audit db is read-only if (includeByAuditTreeDB(statement.getDevicePath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1307,7 +1316,7 @@ public TSStatus visitShowTimeSeries( .setPrivilegeTypes(Arrays.asList(PrivilegeType.READ_DATA, PrivilegeType.READ_SCHEMA)); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1324,7 +1333,7 @@ public TSStatus visitShowTimeSeries( } catch (AuthException e) { return new TSStatus(e.getCode().getStatusCode()); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1341,7 +1350,7 @@ public TSStatus visitCountTimeSeries( .setPrivilegeType(PrivilegeType.READ_SCHEMA); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1356,12 +1365,12 @@ public TSStatus visitCountTimeSeries( AuthorityChecker.getAuthorizedPathTree( context.getUsername(), PrivilegeType.READ_DATA))); } catch (AuthException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1375,7 +1384,7 @@ public TSStatus visitCountLevelTimeSeries( CountLevelTimeSeriesStatement countStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { countStatement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> countStatement.getPaths().stream() @@ -1393,7 +1402,7 @@ public TSStatus visitCountNodes( CountNodesStatement countStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { countStatement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> countStatement.getPaths().stream() @@ -1411,7 +1420,7 @@ public TSStatus visitShowChildNodes( ShowChildNodesStatement showChildNodesStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { showChildNodesStatement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> showChildNodesStatement.getPaths().stream() @@ -1429,7 +1438,7 @@ public TSStatus visitShowChildPaths( ShowChildPathsStatement showChildPathsStatement, TreeAccessCheckContext context) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { showChildPathsStatement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> showChildPathsStatement.getPaths().stream() @@ -1449,7 +1458,7 @@ public TSStatus visitAlterTimeSeries( // audit db is read-only if (includeByAuditTreeDB(statement.getPath()) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1482,7 +1491,7 @@ public TSStatus visitAlterEncodingCompressor( alterEncodingCompressorStatement.getPatternTree(), authTree)); return StatusUtils.OK; } catch (final AuthException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> alterEncodingCompressorStatement.getPaths().stream() @@ -1516,7 +1525,7 @@ public TSStatus visitDeleteTimeSeries( for (PartialPath path : statement.getPathPatternList()) { if (includeByAuditTreeDB(path) && !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) @@ -1601,7 +1610,7 @@ public TSStatus visitSetConfiguration( AuthorityChecker.getTSStatus( AuthorityChecker.checkUserMissingSystemPermissions( context.getUsername(), relatedPrivileges)); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) .setAuditLogOperation(AuditLogOperation.CONTROL) @@ -1609,7 +1618,7 @@ public TSStatus visitSetConfiguration( () -> ""); return result; } catch (IOException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false).setAuditLogOperation(AuditLogOperation.CONTROL), () -> ""); return AuthorityChecker.getTSStatus(false, "Failed to check config item permission"); } @@ -1702,7 +1711,7 @@ public TSStatus visitShowCluster(ShowClusterStatement statement, TreeAccessCheck @Override public TSStatus visitShowAvailableUrls( ShowAvailableUrlsStatement showAvailableUrlsStatement, TreeAccessCheckContext context) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setAuditLogOperation(AuditLogOperation.QUERY).setResult(true), () -> ""); return SUCCEED; } @@ -1840,7 +1849,7 @@ public TSStatus visitSetTTL(SetTTLStatement statement, TreeAccessCheckContext co context.getUsername(), pathsForCheckingPermissions, PrivilegeType.WRITE_SCHEMA), pathsForCheckingPermissions, PrivilegeType.WRITE_SCHEMA); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context .setPrivilegeType(PrivilegeType.WRITE_SCHEMA) .setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), @@ -1871,7 +1880,8 @@ public TSStatus visitShowTTL(ShowTTLStatement showTTLStatement, TreeAccessCheckC context.getUsername(), path.concatNode(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD), PrivilegeType.READ_SCHEMA)) { - AUDIT_LOGGER.recordAuditLog(context.setResult(false), path::getFullPath); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( + context.setResult(false), path::getFullPath); return AuthorityChecker.getTSStatus(false, path, PrivilegeType.READ_SCHEMA); } } @@ -1892,7 +1902,7 @@ public TSStatus visitShowDevices(ShowDevicesStatement statement, TreeAccessCheck .setPrivilegeTypes(Arrays.asList(PrivilegeType.READ_DATA, PrivilegeType.READ_SCHEMA)); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { statement.setCanSeeAuditDB(true); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1907,12 +1917,12 @@ public TSStatus visitShowDevices(ShowDevicesStatement statement, TreeAccessCheck AuthorityChecker.getAuthorizedPathTree( context.getUsername(), PrivilegeType.READ_DATA))); } catch (AuthException e) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(false), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(e.getCode().getStatusCode()); } - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); @@ -1928,7 +1938,7 @@ public TSStatus visitCountDevices( .setPrivilegeTypes(Arrays.asList(PrivilegeType.READ_DATA, PrivilegeType.READ_SCHEMA)) .setAuditLogOperation(AuditLogOperation.QUERY); if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(true), () -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString()); return SUCCEED; @@ -1961,7 +1971,7 @@ protected TSStatus checkGlobalAuth( return SUCCEED; } TSStatus result = AuthorityChecker.getTSStatus(false, requiredPrivilege); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setResult(result.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()), auditObject); return result; @@ -1978,7 +1988,7 @@ protected boolean checkHasGlobalAuth( Supplier auditObject, boolean checkGrantOption) { if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) { - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(requiredPrivilege).setResult(true), auditObject); return true; } @@ -1987,7 +1997,7 @@ protected boolean checkHasGlobalAuth( ? AuthorityChecker.checkSystemPermissionGrantOption( context.getUsername(), requiredPrivilege) : AuthorityChecker.checkSystemPermission(context.getUsername(), requiredPrivilege); - AUDIT_LOGGER.recordAuditLog( + AUDIT_LOGGER.recordObjectAuthenticationAuditLog( context.setPrivilegeType(requiredPrivilege).setResult(result), auditObject); return result; } @@ -1995,7 +2005,7 @@ protected boolean checkHasGlobalAuth( protected TSStatus checkWriteOnReadOnlyPath(IAuditEntity auditEntity, PartialPath path) { if (includeByAuditTreeDB(path) && !AuthorityChecker.INTERNAL_AUDIT_USER.equals(path.getFullPath())) { - AUDIT_LOGGER.recordAuditLog(auditEntity, path::getFullPath); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog(auditEntity, path::getFullPath); return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode()) .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE)); } @@ -2013,10 +2023,10 @@ private TSStatus checkOnlySuperUser( IAuditEntity auditEntity, PrivilegeType privilegeType, Supplier auditObject) { auditEntity.setPrivilegeType(privilegeType); if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) { - AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(true), auditObject); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog(auditEntity.setResult(true), auditObject); return SUCCEED; } - AUDIT_LOGGER.recordAuditLog(auditEntity.setResult(false), auditObject); + AUDIT_LOGGER.recordObjectAuthenticationAuditLog(auditEntity.setResult(false), auditObject); return AuthorityChecker.getTSStatus(false, "Only the admin user can perform this operation"); } } 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 4e94574accf36..d7c00c9128b8d 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 @@ -49,7 +49,8 @@ public boolean noNeedInsertAuditLog(IAuditEntity auditLogFields) { return true; } - public void recordAuditLog(final IAuditEntity auditEntity, final Supplier auditObject) { + public void recordObjectAuthenticationAuditLog( + final IAuditEntity auditEntity, final Supplier auditObject) { log( auditEntity.setAuditEventType(AuditEventType.OBJECT_AUTHENTICATION), () ->