This is an automated email from the ASF dual-hosted git repository.
CRZbulabula pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 165cd4cafd2 Improve error messages for unsupported __audit database
operations (#18309)
165cd4cafd2 is described below
commit 165cd4cafd28409234fcd119e787a5da44c7d00c
Author: Yongzao <[email protected]>
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 92242b62aa7..7959e032f39 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 9ce80200a7b..093bbc1d534 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();
+ }
+ }
}