You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2026/08/24 08:22:58 UTC
(iotdb) 12/17: Improve error messages for unsupported __audit database operations (#18309)
This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch rc/2.0.11
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 83d683d38509702f15b2642a1384a5999948b6b5
Author: Yongzao <yo...@apache.org>
AuthorDate: Sat Jul 25 23:05:57 2026 +0800
Improve error messages for unsupported __audit database operations (#18309)
---
.../iotdb/db/it/auth/IoTDBSeriesPermissionIT.java | 2 +-
.../iotdb/db/it/auth/IoTDBTemplateAuthIT.java | 7 ++-
.../it/db/it/IoTDBAuthenticationTableIT.java | 9 +++
.../iotdb/db/i18n/DataNodeQueryMessages.java | 5 +-
.../iotdb/db/i18n/DataNodeQueryMessages.java | 5 +-
.../relational/security/AccessControlImpl.java | 13 ++--
.../relational/security/ITableAuthCheckerImpl.java | 3 +-
.../security/TreeAccessCheckVisitor.java | 71 +++++++++++-----------
.../org/apache/iotdb/db/auth/TreeAccessTest.java | 28 +++++++++
9 files changed, 96 insertions(+), 47 deletions(-)
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
index 509d9dac808..a0feb9712da 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
@@ -383,7 +383,7 @@ public class IoTDBSeriesPermissionIT {
assertNonQueryTestFail(
statement,
"set ttl to root.__audit.** 1",
- "803: The database 'root.__audit' is read-only.");
+ "803: Apache IoTDB does not support this operation on database 'root.__audit'.");
} catch (SQLException e) {
e.printStackTrace();
fail(e.getMessage());
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBTemplateAuthIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBTemplateAuthIT.java
index a535e8774bf..2c874030ae7 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBTemplateAuthIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBTemplateAuthIT.java
@@ -85,10 +85,15 @@ public class IoTDBTemplateAuthIT {
"create database root.__audit",
"803: The database name \"root.__audit\" is reserved, please use another valid database name.");
+ assertNonQueryTestFail(
+ adminStmt,
+ "delete database root.__audit",
+ "803: Apache IoTDB does not support this operation on database 'root.__audit'.");
+
assertNonQueryTestFail(
adminStmt,
"set device template t1 to root.__audit",
- "803: The database 'root.__audit' is read-only");
+ "803: Apache IoTDB does not support this operation on database 'root.__audit'.");
Set<String> retSet = new HashSet<>(Arrays.asList("t1", "t2", "t3"));
diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBAuthenticationTableIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBAuthenticationTableIT.java
index 77a3be13edb..cdda20ab728 100644
--- a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBAuthenticationTableIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBAuthenticationTableIT.java
@@ -106,6 +106,15 @@ public class IoTDBAuthenticationTableIT {
e.getMessage());
}
+ try {
+ sessionRoot.executeNonQueryStatement("DROP DATABASE __audit");
+ fail("Should have thrown an exception");
+ } catch (StatementExecutionException e) {
+ assertEquals(
+ "803: Access Denied: Apache IoTDB does not support this operation on database '__audit'.",
+ e.getMessage());
+ }
+
sessionRoot.executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS \"汉化\"");
sessionRoot.executeNonQueryStatement("USE \"汉化\"");
diff --git a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
index b540ebb2540..cfca303060b 100644
--- a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
+++ b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
@@ -3050,8 +3050,9 @@ public final class DataNodeQueryMessages {
"getOutputColumnNames of CreateMultiTimeSeriesNode is not implemented";
public static final String QUERY_EXCEPTION_GETOUTPUTCOLUMNNAMES_OF_ALTERLOGICALVIEWNODE_IS_NOT_IMPLEMENTED_D2294789 =
"getOutputColumnNames of AlterLogicalViewNode is not implemented";
- public static final String QUERY_EXCEPTION_THE_DATABASE_S_IS_READ_ONLY_CB6732CE =
- "The database '%s' is read-only.";
+ public static final String
+ EXCEPTION_APACHE_IOTDB_DOES_NOT_SUPPORT_THIS_OPERATION_ON_DATABASE_ARG_B09ADFD7 =
+ "Apache IoTDB does not support this operation on database '%s'.";
public static final String QUERY_EXCEPTION_THE_DATABASE_S_CAN_ONLY_BE_QUERIED_BY_AUDIT_ADMIN_4A510F66 =
"The database '%s' can only be queried by AUDIT admin.";
public static final String QUERY_EXCEPTION_UNEXPECTED_WINDOW_FRAME_TYPE_S_F06F81B8 =
diff --git a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
index 0e73bd1dd96..304d22a6e7d 100644
--- a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
+++ b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java
@@ -3683,9 +3683,10 @@ public final class DataNodeQueryMessages {
public static final String QUERY_EXCEPTION_GETOUTPUTCOLUMNNAMES_OF_ALTERLOGICALVIEWNODE_IS_NOT_IMPLEMENTED_D2294789 =
"AlterLogicalViewNode 的 getOutputColumnNames 尚未实现";
- public static final String QUERY_EXCEPTION_THE_DATABASE_S_IS_READ_ONLY_CB6732CE =
+ public static final String
+ EXCEPTION_APACHE_IOTDB_DOES_NOT_SUPPORT_THIS_OPERATION_ON_DATABASE_ARG_B09ADFD7 =
- "数据库 '%s' 为只读。";
+ "Apache IoTDB 不支持对数据库 '%s' 执行此操作。";
public static final String QUERY_EXCEPTION_THE_DATABASE_S_CAN_ONLY_BE_QUERIED_BY_AUDIT_ADMIN_4A510F66 =
"数据库 '%s' 仅允许 AUDIT admin 查询。";
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 55b0b6cc248..1a50f15e9cd 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
@@ -58,7 +58,12 @@ import static org.apache.iotdb.db.queryengine.plan.relational.security.TreeAcces
public class AccessControlImpl implements AccessControl {
- public static final String READ_ONLY_DB_ERROR_MSG = "The database '%s' is read-only.";
+ static String getUnsupportedAuditDatabaseOperationMessage(String databaseName) {
+ return String.format(
+ DataNodeQueryMessages
+ .EXCEPTION_APACHE_IOTDB_DOES_NOT_SUPPORT_THIS_OPERATION_ON_DATABASE_ARG_B09ADFD7,
+ databaseName);
+ }
protected final ITableAuthChecker authChecker;
@@ -72,7 +77,7 @@ public class AccessControlImpl implements AccessControl {
private void checkAuditDatabase(String databaseName) {
if (TABLE_MODEL_AUDIT_DATABASE.equalsIgnoreCase(databaseName)) {
throw new AccessDeniedException(
- String.format(READ_ONLY_DB_ERROR_MSG, TABLE_MODEL_AUDIT_DATABASE));
+ getUnsupportedAuditDatabaseOperationMessage(TABLE_MODEL_AUDIT_DATABASE));
}
}
@@ -567,11 +572,11 @@ public class AccessControlImpl implements AccessControl {
IAuditEntity auditEntity, IDeviceID device, String measurementId) {
try {
PartialPath path = new MeasurementPath(device, measurementId);
- // audit db is read-only
+ // Apache IoTDB does not support external writes to the audit database.
if (includeByAuditTreeDB(path)
&& !auditEntity.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(
auditEntity, () -> Collections.singletonList(path), PrivilegeType.WRITE_DATA);
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 6be70384fc7..7d10285b2a6 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
@@ -167,8 +167,7 @@ public class ITableAuthCheckerImpl implements ITableAuthChecker {
.setResult(false),
() -> databaseName);
throw new AccessDeniedException(
- String.format(
- DataNodeQueryMessages.QUERY_EXCEPTION_THE_DATABASE_S_IS_READ_ONLY_CB6732CE,
+ AccessControlImpl.getUnsupportedAuditDatabaseOperationMessage(
TABLE_MODEL_AUDIT_DATABASE));
}
}
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 a4d20b9b7c7..4381cdc5729 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
@@ -191,7 +191,7 @@ import static org.apache.iotdb.commons.schema.table.Audit.includeByAuditTreeDB;
import static org.apache.iotdb.commons.schema.table.Audit.isAuditTreeDatabase;
import static org.apache.iotdb.db.auth.AuthorityChecker.SUCCEED;
import static org.apache.iotdb.db.auth.AuthorityChecker.getAuthorizedPathTree;
-import static org.apache.iotdb.db.queryengine.plan.relational.security.AccessControlImpl.READ_ONLY_DB_ERROR_MSG;
+import static org.apache.iotdb.db.queryengine.plan.relational.security.AccessControlImpl.getUnsupportedAuditDatabaseOperationMessage;
public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAccessCheckContext> {
@@ -276,7 +276,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context.setAuditLogOperation(AuditLogOperation.DDL);
// root.__audit can never be set template
TSStatus status =
- checkWriteOnReadOnlyPath(
+ checkUnsupportedAuditDatabaseWrite(
context.setPrivilegeType(PrivilegeType.WRITE_DATA),
setSchemaTemplateStatement.getPath());
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -424,13 +424,13 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
.getIntoDevice()
.concatNode(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD));
for (PartialPath path : paths) {
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(path)
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
@@ -537,14 +537,14 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitRenameLogicalView(
RenameLogicalViewStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getNewName())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
AUDIT_LOGGER.recordObjectAuthenticationAuditLog(
context.setPrivilegeType(PrivilegeType.WRITE_SCHEMA).setResult(false),
() -> statement.getOldName().toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(
context,
@@ -930,7 +930,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTriggerManagement(
context.setAuditLogOperation(AuditLogOperation.DDL),
@@ -1073,7 +1073,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context.setPrivilegeType(PrivilegeType.MANAGE_DATABASE).setResult(false),
() -> prefixPath);
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
if (AuthorityChecker.SUPER_USER.equals(context.getUsername())) {
@@ -1100,7 +1100,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
if (AuthorityChecker.SUPER_USER.equals(auditEntity.getUsername())) {
@@ -1137,12 +1137,12 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitInsertBase(InsertBaseStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DML).setPrivilegeType(PrivilegeType.WRITE_DATA);
for (PartialPath path : statement.getDevicePaths()) {
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(path)
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
@@ -1161,13 +1161,13 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
@Override
public TSStatus visitInsert(InsertStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DML).setPrivilegeType(PrivilegeType.WRITE_DATA);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getDevice())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_DATA);
}
@@ -1182,12 +1182,12 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitDeleteData(DeleteDataStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DML).setPrivilegeType(PrivilegeType.WRITE_DATA);
for (PartialPath path : statement.getPaths()) {
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(path)
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_DATA);
@@ -1280,14 +1280,14 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context
.setPrivilegeType(PrivilegeType.WRITE_SCHEMA)
.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getPath())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
AUDIT_LOGGER.recordObjectAuthenticationAuditLog(
context.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
}
@@ -1298,14 +1298,14 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context
.setPrivilegeType(PrivilegeType.WRITE_SCHEMA)
.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getDevicePath())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
AUDIT_LOGGER.recordObjectAuthenticationAuditLog(
context.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
}
@@ -1316,12 +1316,12 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context
.setPrivilegeType(PrivilegeType.WRITE_SCHEMA)
.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
for (PartialPath path : statement.getPaths()) {
if (includeByAuditTreeDB(path)
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
@@ -1334,13 +1334,13 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context
.setPrivilegeType(PrivilegeType.WRITE_SCHEMA)
.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
for (PartialPath path : statement.getDeviceMap().keySet()) {
if (includeByAuditTreeDB(path)
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
@@ -1350,14 +1350,14 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitInternalCreateTimeseries(
InternalCreateTimeSeriesStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getDevicePath())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
AUDIT_LOGGER.recordObjectAuthenticationAuditLog(
context.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
}
@@ -1602,14 +1602,14 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitAlterTimeSeries(
AlterTimeSeriesStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getPath())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
AUDIT_LOGGER.recordObjectAuthenticationAuditLog(
context.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
}
@@ -1618,14 +1618,14 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitAlterTimeSeries(
AlterTimeSeriesDataTypeStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
if (includeByAuditTreeDB(statement.getPath())
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
AUDIT_LOGGER.recordObjectAuthenticationAuditLog(
context.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
}
@@ -1685,7 +1685,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
public TSStatus visitDeleteTimeSeries(
DeleteTimeSeriesStatement statement, TreeAccessCheckContext context) {
context.setAuditLogOperation(AuditLogOperation.DDL);
- // audit db is read-only
+ // External users cannot modify the audit database.
for (PartialPath path : statement.getPathPatternList()) {
if (includeByAuditTreeDB(path)
&& !context.getUsername().equals(AuthorityChecker.INTERNAL_AUDIT_USER)) {
@@ -1693,7 +1693,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
context.setResult(false),
() -> statement.getPaths().stream().distinct().collect(Collectors.toList()).toString());
return new TSStatus(TSStatusCode.NO_PERMISSION.getStatusCode())
- .setMessage(String.format(READ_ONLY_DB_ERROR_MSG, TREE_MODEL_AUDIT_DATABASE));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
}
return checkTimeSeriesPermission(context, statement::getPaths, PrivilegeType.WRITE_SCHEMA);
@@ -2007,7 +2007,7 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
boolean[] pathsNotEndWithMultiLevelWildcard = null;
for (int i = 0; i < checkedPaths.size(); i++) {
PartialPath checkedPath = checkedPaths.get(i);
- TSStatus status = checkWriteOnReadOnlyPath(context, checkedPath);
+ TSStatus status = checkUnsupportedAuditDatabaseWrite(context, checkedPath);
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return status;
}
@@ -2294,12 +2294,13 @@ public class TreeAccessCheckVisitor extends StatementVisitor<TSStatus, TreeAcces
return status;
}
- protected TSStatus checkWriteOnReadOnlyPath(IAuditEntity auditEntity, PartialPath path) {
+ protected TSStatus checkUnsupportedAuditDatabaseWrite(
+ IAuditEntity auditEntity, PartialPath path) {
if (includeByAuditTreeDB(path)
- && !AuthorityChecker.INTERNAL_AUDIT_USER.equals(path.getFullPath())) {
+ && !AuthorityChecker.INTERNAL_AUDIT_USER.equals(auditEntity.getUsername())) {
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));
+ .setMessage(getUnsupportedAuditDatabaseOperationMessage(TREE_MODEL_AUDIT_DATABASE));
}
return SUCCEED;
}
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/TreeAccessTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/TreeAccessTest.java
index dd1826982c9..0e83cc5b477 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/TreeAccessTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/TreeAccessTest.java
@@ -214,4 +214,32 @@ public class TreeAccessTest {
.getAllPathPatterns()
.contains(new PartialPath("root.__audit.**")));
}
+
+ @Test
+ public void testUnsupportedAuditDatabaseWrite() throws Exception {
+ TestTreeAccessCheckVisitor treeAccessCheckVisitor = new TestTreeAccessCheckVisitor();
+
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(),
+ treeAccessCheckVisitor.checkUnsupportedAuditDatabaseWriteStatus(
+ new TreeAccessCheckContext(
+ AuthorityChecker.INTERNAL_AUDIT_USER_ID, AuthorityChecker.INTERNAL_AUDIT_USER, ""),
+ new PartialPath("root.__audit")));
+ Assert.assertEquals(
+ TSStatusCode.NO_PERMISSION.getStatusCode(),
+ treeAccessCheckVisitor.checkUnsupportedAuditDatabaseWriteStatus(
+ new TreeAccessCheckContext(10000L, "user1", ""), new PartialPath("root.__audit")));
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(),
+ treeAccessCheckVisitor.checkUnsupportedAuditDatabaseWriteStatus(
+ new TreeAccessCheckContext(10000L, "user1", ""), new PartialPath("root.sg")));
+ }
+
+ private static class TestTreeAccessCheckVisitor extends TreeAccessCheckVisitor {
+
+ private int checkUnsupportedAuditDatabaseWriteStatus(
+ TreeAccessCheckContext context, PartialPath path) {
+ return checkUnsupportedAuditDatabaseWrite(context, path).getCode();
+ }
+ }
}