You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ch...@apache.org on 2022/04/29 09:46:19 UTC
[iotdb] branch master updated: [IOTDB-3025] add permission check (#5699)
This is an automated email from the ASF dual-hosted git repository.
chaow 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 685ea15ed6 [IOTDB-3025] add permission check (#5699)
685ea15ed6 is described below
commit 685ea15ed64997b7a56a04969311af2c3c6dabd6
Author: 任宇华 <79...@users.noreply.github.com>
AuthorDate: Fri Apr 29 17:46:13 2022 +0800
[IOTDB-3025] add permission check (#5699)
Co-authored-by: renyuhua <ry...@163.com>
Co-authored-by: Jinrui.Zhang <xi...@gmail.com>
---
.../iotdb/confignode/manager/ConfigManager.java | 13 +-
.../apache/iotdb/confignode/manager/Manager.java | 12 ++
.../confignode/manager/PermissionManager.java | 11 ++
.../iotdb/confignode/persistence/AuthorInfo.java | 128 ++++++++++++++-----
.../thrift/ConfigNodeRPCServiceProcessor.java | 7 ++
.../thrift/ConfigNodeRPCServiceProcessorTest.java | 22 ++++
.../org/apache/iotdb/db/auth/AuthorityChecker.java | 138 ++++++++++++++++++++-
.../db/auth/authorizer/AuthorizerManager.java | 44 +++++++
.../db/auth/authorizer/ClusterAuthorizer.java | 61 ++++++++-
.../apache/iotdb/db/client/ConfigNodeClient.java | 16 +++
.../iotdb/db/mpp/sql/statement/Statement.java | 9 ++
.../statement/crud/AggregationQueryStatement.java | 2 +
.../mpp/sql/statement/crud/FillQueryStatement.java | 1 +
.../statement/crud/GroupByFillQueryStatement.java | 1 +
.../sql/statement/crud/GroupByQueryStatement.java | 2 +
.../sql/statement/crud/InsertBaseStatement.java | 8 ++
.../crud/InsertMultiTabletsStatement.java | 9 ++
.../mpp/sql/statement/crud/InsertRowStatement.java | 12 ++
.../crud/InsertRowsOfOneDeviceStatement.java | 11 ++
.../sql/statement/crud/InsertRowsStatement.java | 9 ++
.../db/mpp/sql/statement/crud/InsertStatement.java | 11 ++
.../sql/statement/crud/InsertTabletStatement.java | 11 ++
.../mpp/sql/statement/crud/LastQueryStatement.java | 2 +
.../db/mpp/sql/statement/crud/QueryStatement.java | 5 +
.../mpp/sql/statement/crud/UDAFQueryStatement.java | 1 +
.../mpp/sql/statement/crud/UDTFQueryStatement.java | 1 +
.../metadata/AlterTimeSeriesStatement.java | 7 ++
.../mpp/sql/statement/metadata/CountStatement.java | 8 ++
.../metadata/CreateAlignedTimeSeriesStatement.java | 20 +++
.../metadata/CreateTimeSeriesStatement.java | 7 ++
.../statement/metadata/SchemaFetchStatement.java | 8 ++
.../metadata/SetStorageGroupStatement.java | 10 ++
.../statement/metadata/ShowDevicesStatement.java | 8 ++
.../mpp/sql/statement/metadata/ShowStatement.java | 9 ++
.../metadata/ShowStorageGroupStatement.java | 8 ++
.../db/mpp/sql/statement/sys/AuthorStatement.java | 63 +++++++++-
.../thrift/impl/DataNodeTSIServiceImpl.java | 79 ++++++++----
.../java/org/apache/iotdb/rpc/TSStatusCode.java | 3 +
.../src/main/thrift/confignode.thrift | 8 ++
39 files changed, 721 insertions(+), 64 deletions(-)
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java b/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index c8b55e1bdc..580f5f49f1 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -43,7 +43,6 @@ import org.apache.iotdb.confignode.consensus.response.DataPartitionResp;
import org.apache.iotdb.confignode.consensus.response.PermissionInfoResp;
import org.apache.iotdb.confignode.consensus.response.SchemaPartitionResp;
import org.apache.iotdb.confignode.consensus.response.StorageGroupSchemaResp;
-import org.apache.iotdb.confignode.persistence.AuthorInfo;
import org.apache.iotdb.consensus.common.DataSet;
import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -361,7 +360,17 @@ public class ConfigManager implements Manager {
public TSStatus login(String username, String password) {
TSStatus status = confirmLeader();
if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- return AuthorInfo.getInstance().login(username, password);
+ return permissionManager.login(username, password);
+ } else {
+ return status;
+ }
+ }
+
+ @Override
+ public TSStatus checkUserPrivileges(String username, List<String> paths, int permission) {
+ TSStatus status = confirmLeader();
+ if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return permissionManager.checkUserPrivileges(username, paths, permission);
} else {
return status;
}
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/manager/Manager.java b/confignode/src/main/java/org/apache/iotdb/confignode/manager/Manager.java
index 1da702de25..4830af4a75 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/manager/Manager.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/manager/Manager.java
@@ -34,6 +34,8 @@ import org.apache.iotdb.confignode.consensus.request.write.SetTimePartitionInter
import org.apache.iotdb.consensus.common.DataSet;
import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
+import java.util.List;
+
/**
* a subset of services provided by {@ConfigManager}. For use internally only, passed to Managers,
* services.
@@ -170,4 +172,14 @@ public interface Manager {
* @return
*/
TSStatus login(String username, String password);
+
+ /**
+ * Check User Privileges
+ *
+ * @param username
+ * @param paths
+ * @param permission
+ * @return
+ */
+ TSStatus checkUserPrivileges(String username, List<String> paths, int permission);
}
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java b/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
index e17e9181b5..61ef6a614a 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
@@ -22,6 +22,9 @@ package org.apache.iotdb.confignode.manager;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.confignode.consensus.request.auth.AuthorReq;
import org.apache.iotdb.confignode.consensus.response.PermissionInfoResp;
+import org.apache.iotdb.confignode.persistence.AuthorInfo;
+
+import java.util.List;
/** manager permission query and operation */
public class PermissionManager {
@@ -55,4 +58,12 @@ public class PermissionManager {
private ConsensusManager getConsensusManager() {
return configManager.getConsensusManager();
}
+
+ public TSStatus login(String username, String password) {
+ return AuthorInfo.getInstance().login(username, password);
+ }
+
+ public TSStatus checkUserPrivileges(String username, List<String> paths, int permission) {
+ return AuthorInfo.getInstance().checkUserPrivileges(username, paths, permission);
+ }
}
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
index 4428434b44..f489f70449 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
@@ -31,6 +31,7 @@ import org.apache.iotdb.db.auth.entity.PrivilegeType;
import org.apache.iotdb.db.auth.entity.Role;
import org.apache.iotdb.db.auth.entity.User;
import org.apache.iotdb.db.utils.AuthUtils;
+import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
import org.slf4j.Logger;
@@ -77,7 +78,37 @@ public class AuthorInfo {
return tsStatus;
}
- public TSStatus authorNonQuery(AuthorReq authorReq) throws AuthException {
+ public TSStatus checkUserPrivileges(String username, List<String> paths, int permission) {
+ boolean status = true;
+ try {
+ for (String path : paths) {
+ if (!checkOnePath(username, path, permission)) {
+ status = false;
+ }
+ }
+ } catch (AuthException e) {
+ status = false;
+ }
+ if (status) {
+ return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+ } else {
+ return RpcUtils.getStatus(TSStatusCode.NO_PERMISSION_ERROR);
+ }
+ }
+
+ private boolean checkOnePath(String username, String path, int permission) throws AuthException {
+ try {
+ if (authorizer.checkUserPrivileges(username, path, permission)) {
+ return true;
+ }
+ } catch (AuthException e) {
+ logger.error("Error occurs when checking the seriesPath {} for user {}", path, username, e);
+ throw new AuthException(e);
+ }
+ return false;
+ }
+
+ public TSStatus authorNonQuery(AuthorReq authorReq) {
ConfigRequestType authorType = authorReq.getAuthorType();
String userName = authorReq.getUserName();
String roleName = authorReq.getRoleName();
@@ -129,39 +160,49 @@ public class AuthorInfo {
authorizer.revokeRoleFromUser(roleName, userName);
break;
default:
- throw new AuthException("execute " + authorReq + " failed");
+ throw new AuthException("unknown type: " + authorReq.getAuthorType());
}
} catch (AuthException e) {
- throw new AuthException("execute " + authorReq + " failed: ", e);
+ return RpcUtils.getStatus(TSStatusCode.EXECUTE_PERMISSION_EXCEPTION_ERROR, e.getMessage());
}
- return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+ return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
}
- public PermissionInfoResp executeListRole() throws AuthException {
+ public PermissionInfoResp executeListRole() {
PermissionInfoResp result = new PermissionInfoResp();
List<String> roleList = authorizer.listAllRoles();
Map<String, List<String>> permissionInfo = new HashMap<>();
permissionInfo.put(IoTDBConstant.COLUMN_ROLE, roleList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
}
- public PermissionInfoResp executeListUser() throws AuthException {
+ public PermissionInfoResp executeListUser() {
PermissionInfoResp result = new PermissionInfoResp();
List<String> userList = authorizer.listAllUsers();
Map<String, List<String>> permissionInfo = new HashMap<>();
permissionInfo.put(IoTDBConstant.COLUMN_USER, userList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
}
public PermissionInfoResp executeListRoleUsers(AuthorReq plan) throws AuthException {
PermissionInfoResp result = new PermissionInfoResp();
- Role role = authorizer.getRole(plan.getRoleName());
- if (role == null) {
- throw new AuthException("No such role : " + plan.getRoleName());
+ Map<String, List<String>> permissionInfo = new HashMap<>();
+ Role role;
+ try {
+ role = authorizer.getRole(plan.getRoleName());
+ if (role == null) {
+ result.setStatus(
+ RpcUtils.getStatus(
+ TSStatusCode.ROLE_NOT_EXIST_ERROR, "No such role : " + plan.getRoleName()));
+ result.setPermissionInfo(permissionInfo);
+ return result;
+ }
+ } catch (AuthException e) {
+ throw new AuthException(e);
}
List<String> roleUsersList = new ArrayList<>();
List<String> userList = authorizer.listAllUsers();
@@ -171,35 +212,54 @@ public class AuthorInfo {
roleUsersList.add(userN);
}
}
- Map<String, List<String>> permissionInfo = new HashMap<>();
permissionInfo.put(IoTDBConstant.COLUMN_USER, roleUsersList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
}
public PermissionInfoResp executeListUserRoles(AuthorReq plan) throws AuthException {
PermissionInfoResp result = new PermissionInfoResp();
- User user = authorizer.getUser(plan.getUserName());
- if (user == null) {
- throw new AuthException("No such user : " + plan.getUserName());
+ Map<String, List<String>> permissionInfo = new HashMap<>();
+ User user;
+ try {
+ user = authorizer.getUser(plan.getUserName());
+ if (user == null) {
+ result.setStatus(
+ RpcUtils.getStatus(
+ TSStatusCode.USER_NOT_EXIST_ERROR, "No such user : " + plan.getUserName()));
+ result.setPermissionInfo(permissionInfo);
+ return result;
+ }
+ } catch (AuthException e) {
+ throw new AuthException(e);
}
List<String> userRoleList = new ArrayList<>();
for (String roleN : user.getRoleList()) {
userRoleList.add(roleN);
}
- Map<String, List<String>> permissionInfo = new HashMap<>();
+
permissionInfo.put(IoTDBConstant.COLUMN_ROLE, userRoleList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
}
public PermissionInfoResp executeListRolePrivileges(AuthorReq plan) throws AuthException {
PermissionInfoResp result = new PermissionInfoResp();
- Role role = authorizer.getRole(plan.getRoleName());
- if (role == null) {
- throw new AuthException("No such role : " + plan.getRoleName());
+ Map<String, List<String>> permissionInfo = new HashMap<>();
+ Role role;
+ try {
+ role = authorizer.getRole(plan.getRoleName());
+ if (role == null) {
+ result.setStatus(
+ RpcUtils.getStatus(
+ TSStatusCode.ROLE_NOT_EXIST_ERROR, "No such role : " + plan.getRoleName()));
+ result.setPermissionInfo(permissionInfo);
+ return result;
+ }
+ } catch (AuthException e) {
+ throw new AuthException(e);
}
List<String> rolePrivilegesList = new ArrayList<>();
for (PathPrivilege pathPrivilege : role.getPrivilegeList()) {
@@ -208,27 +268,37 @@ public class AuthorInfo {
rolePrivilegesList.add(pathPrivilege.toString());
}
}
- Map<String, List<String>> permissionInfo = new HashMap<>();
+
permissionInfo.put(IoTDBConstant.COLUMN_PRIVILEGE, rolePrivilegesList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
}
public PermissionInfoResp executeListUserPrivileges(AuthorReq plan) throws AuthException {
PermissionInfoResp result = new PermissionInfoResp();
- User user = authorizer.getUser(plan.getUserName());
- if (user == null) {
- throw new AuthException("No such user : " + plan.getUserName());
+ Map<String, List<String>> permissionInfo = new HashMap<>();
+ User user;
+ try {
+ user = authorizer.getUser(plan.getUserName());
+ if (user == null) {
+ result.setStatus(
+ RpcUtils.getStatus(
+ TSStatusCode.USER_NOT_EXIST_ERROR, "No such user : " + plan.getUserName()));
+ result.setPermissionInfo(permissionInfo);
+ return result;
+ }
+ } catch (AuthException e) {
+ throw new AuthException(e);
}
List<String> userPrivilegesList = new ArrayList<>();
- Map<String, List<String>> permissionInfo = new HashMap<>();
+
if (IoTDBConstant.PATH_ROOT.equals(plan.getUserName())) {
for (PrivilegeType privilegeType : PrivilegeType.values()) {
userPrivilegesList.add(privilegeType.toString());
}
permissionInfo.put(IoTDBConstant.COLUMN_PRIVILEGE, userPrivilegesList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
} else {
@@ -255,7 +325,7 @@ public class AuthorInfo {
}
permissionInfo.put(IoTDBConstant.COLUMN_ROLE, rolePrivileges);
permissionInfo.put(IoTDBConstant.COLUMN_PRIVILEGE, userPrivilegesList);
- result.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ result.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS));
result.setPermissionInfo(permissionInfo);
return result;
}
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java b/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
index d942abf4d1..758a6369b3 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
@@ -44,6 +44,7 @@ import org.apache.iotdb.confignode.manager.ConfigManager;
import org.apache.iotdb.confignode.rpc.thrift.ConfigIService;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerResp;
+import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
import org.apache.iotdb.confignode.rpc.thrift.TCountStorageGroupResp;
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeLocationResp;
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRegisterReq;
@@ -300,6 +301,12 @@ public class ConfigNodeRPCServiceProcessor implements ConfigIService.Iface {
return configManager.login(req.getUserrname(), req.getPassword());
}
+ @Override
+ public TSStatus checkUserPrivileges(TCheckUserPrivilegesReq req) throws TException {
+ return configManager.checkUserPrivileges(
+ req.getUsername(), req.getPaths(), req.getPermission());
+ }
+
public void handleClientExit() {}
// TODO: Interfaces for data operations
diff --git a/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java b/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
index 7d60ec6671..39bd2a5b87 100644
--- a/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
+++ b/confignode/src/test/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessorTest.java
@@ -33,6 +33,7 @@ import org.apache.iotdb.confignode.persistence.DataNodeInfo;
import org.apache.iotdb.confignode.persistence.PartitionInfo;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerResp;
+import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
import org.apache.iotdb.confignode.rpc.thrift.TCountStorageGroupResp;
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeLocationResp;
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRegisterReq;
@@ -547,21 +548,30 @@ public class ConfigNodeRPCServiceProcessorTest {
userList.add("root");
userList.add("tempuser0");
userList.add("tempuser1");
+
List<String> roleList = new ArrayList<>();
roleList.add("temprole0");
roleList.add("temprole1");
+
TAuthorizerReq authorizerReq;
TAuthorizerResp authorizerResp;
+ TCheckUserPrivilegesReq checkUserPrivilegesReq;
+
Set<Integer> privilegeList = new HashSet<>();
privilegeList.add(PrivilegeType.DELETE_USER.ordinal());
privilegeList.add(PrivilegeType.CREATE_USER.ordinal());
+
Set<Integer> revokePrivilege = new HashSet<>();
revokePrivilege.add(PrivilegeType.DELETE_USER.ordinal());
+
Map<String, List<String>> permissionInfo;
List<String> privilege = new ArrayList<>();
privilege.add("root : CREATE_USER");
privilege.add("root : CREATE_USER");
+ List<String> paths = new ArrayList<>();
+ paths.add("root.ln");
+
cleanUserAndRole();
// create user
@@ -580,6 +590,12 @@ public class ConfigNodeRPCServiceProcessorTest {
status = processor.operatePermission(authorizerReq);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+ // check user privileges
+ checkUserPrivilegesReq =
+ new TCheckUserPrivilegesReq("tempuser0", paths, PrivilegeType.DELETE_USER.ordinal());
+ status = processor.checkUserPrivileges(checkUserPrivilegesReq);
+ Assert.assertEquals(TSStatusCode.NO_PERMISSION_ERROR.getStatusCode(), status.getCode());
+
// drop user
authorizerReq =
new TAuthorizerReq(
@@ -670,6 +686,12 @@ public class ConfigNodeRPCServiceProcessorTest {
status = processor.operatePermission(authorizerReq);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+ // check user privileges
+ checkUserPrivilegesReq =
+ new TCheckUserPrivilegesReq("tempuser0", paths, PrivilegeType.DELETE_USER.ordinal());
+ status = processor.checkUserPrivileges(checkUserPrivilegesReq);
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+
// grant role
authorizerReq =
new TAuthorizerReq(
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java b/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
index 3749e87d58..4d25e159ca 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/AuthorityChecker.java
@@ -18,17 +18,20 @@
*/
package org.apache.iotdb.db.auth;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.conf.IoTDBConstant;
-import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
-import org.apache.iotdb.db.auth.authorizer.IAuthorizer;
+import org.apache.iotdb.db.auth.authorizer.AuthorizerManager;
import org.apache.iotdb.db.auth.entity.PrivilegeType;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.metadata.path.PartialPath;
+import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.qp.logical.Operator;
+import org.apache.iotdb.rpc.TSStatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.List;
public class AuthorityChecker {
@@ -79,16 +82,58 @@ public class AuthorityChecker {
return true;
}
+ /**
+ * check permission(datanode to confignode).
+ *
+ * @param username username
+ * @param paths paths in List structure
+ * @param type Statement Type
+ * @param targetUser target user
+ * @return if permission-check is passed
+ */
+ public static boolean checkPermission(
+ String username, List<? extends PartialPath> paths, StatementType type, String targetUser) {
+ if (SUPER_USER.equals(username)) {
+ return true;
+ }
+
+ int permission = translateToPermissionId(type);
+ if (permission == -1) {
+ return false;
+ } else if (permission == PrivilegeType.MODIFY_PASSWORD.ordinal()
+ && username.equals(targetUser)) {
+ // a user can modify his own password
+ return true;
+ }
+
+ List<String> allPath = new ArrayList<>();
+ if (paths != null && !paths.isEmpty()) {
+ for (PartialPath path : paths) {
+ allPath.add(path == null ? IoTDBConstant.PATH_ROOT : path.getFullPath());
+ }
+ } else {
+ allPath.add(IoTDBConstant.PATH_ROOT);
+ }
+
+ TSStatus status = AuthorizerManager.getInstance().checkPath(username, allPath, permission);
+ if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
private static boolean checkOnePath(String username, PartialPath path, int permission)
throws AuthException {
- IAuthorizer authorizer = BasicAuthorizer.getInstance();
+ AuthorizerManager authorizerManager = AuthorizerManager.getInstance();
try {
String fullPath = path == null ? IoTDBConstant.PATH_ROOT : path.getFullPath();
- if (authorizer.checkUserPrivileges(username, fullPath, permission)) {
+ if (authorizerManager.checkUserPrivileges(username, fullPath, permission)) {
return true;
}
} catch (AuthException e) {
logger.error("Error occurs when checking the seriesPath {} for user {}", path, username, e);
+ throw new AuthException(e);
}
return false;
}
@@ -177,4 +222,89 @@ public class AuthorityChecker {
return -1;
}
}
+
+ private static int translateToPermissionId(StatementType type) {
+ switch (type) {
+ case GRANT_ROLE_PRIVILEGE:
+ return PrivilegeType.GRANT_ROLE_PRIVILEGE.ordinal();
+ case CREATE_ROLE:
+ return PrivilegeType.CREATE_ROLE.ordinal();
+ case CREATE_USER:
+ return PrivilegeType.CREATE_USER.ordinal();
+ case MODIFY_PASSWORD:
+ return PrivilegeType.MODIFY_PASSWORD.ordinal();
+ case GRANT_USER_PRIVILEGE:
+ return PrivilegeType.GRANT_USER_PRIVILEGE.ordinal();
+ case REVOKE_ROLE_PRIVILEGE:
+ return PrivilegeType.REVOKE_ROLE_PRIVILEGE.ordinal();
+ case REVOKE_USER_PRIVILEGE:
+ return PrivilegeType.REVOKE_USER_PRIVILEGE.ordinal();
+ case GRANT_USER_ROLE:
+ return PrivilegeType.GRANT_USER_ROLE.ordinal();
+ case DELETE_USER:
+ return PrivilegeType.DELETE_USER.ordinal();
+ case DELETE_ROLE:
+ return PrivilegeType.DELETE_ROLE.ordinal();
+ case REVOKE_USER_ROLE:
+ return PrivilegeType.REVOKE_USER_ROLE.ordinal();
+ case SET_STORAGE_GROUP:
+ return PrivilegeType.SET_STORAGE_GROUP.ordinal();
+ case DELETE_STORAGE_GROUP:
+ return PrivilegeType.DELETE_STORAGE_GROUP.ordinal();
+ case CREATE_TIMESERIES:
+ case CREATE_ALIGNED_TIMESERIES:
+ return PrivilegeType.CREATE_TIMESERIES.ordinal();
+ case DELETE_TIMESERIES:
+ case DELETE:
+ case DROP_INDEX:
+ return PrivilegeType.DELETE_TIMESERIES.ordinal();
+ case SHOW:
+ case QUERY:
+ case GROUP_BY_TIME:
+ case QUERY_INDEX:
+ case AGGREGATION:
+ case UDAF:
+ case UDTF:
+ case LAST:
+ case FILL:
+ case GROUP_BY_FILL:
+ case SELECT_INTO:
+ return PrivilegeType.READ_TIMESERIES.ordinal();
+ case INSERT:
+ case LOAD_DATA:
+ case CREATE_INDEX:
+ case BATCH_INSERT:
+ case BATCH_INSERT_ONE_DEVICE:
+ case BATCH_INSERT_ROWS:
+ case MULTI_BATCH_INSERT:
+ return PrivilegeType.INSERT_TIMESERIES.ordinal();
+ case LIST_ROLE:
+ case LIST_ROLE_USERS:
+ case LIST_ROLE_PRIVILEGE:
+ return PrivilegeType.LIST_ROLE.ordinal();
+ case LIST_USER:
+ case LIST_USER_ROLES:
+ case LIST_USER_PRIVILEGE:
+ return PrivilegeType.LIST_USER.ordinal();
+ case CREATE_FUNCTION:
+ return PrivilegeType.CREATE_FUNCTION.ordinal();
+ case DROP_FUNCTION:
+ return PrivilegeType.DROP_FUNCTION.ordinal();
+ case CREATE_TRIGGER:
+ return PrivilegeType.CREATE_TRIGGER.ordinal();
+ case DROP_TRIGGER:
+ return PrivilegeType.DROP_TRIGGER.ordinal();
+ case START_TRIGGER:
+ return PrivilegeType.START_TRIGGER.ordinal();
+ case STOP_TRIGGER:
+ return PrivilegeType.STOP_TRIGGER.ordinal();
+ case CREATE_CONTINUOUS_QUERY:
+ return PrivilegeType.CREATE_CONTINUOUS_QUERY.ordinal();
+ case DROP_CONTINUOUS_QUERY:
+ return PrivilegeType.DROP_CONTINUOUS_QUERY.ordinal();
+ default:
+ logger.error("Unrecognizable operator type ({}) for AuthorityChecker.", type);
+ return -1;
+ }
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/authorizer/AuthorizerManager.java b/server/src/main/java/org/apache/iotdb/db/auth/authorizer/AuthorizerManager.java
index 37fc1a5c2b..4a6a3f07ff 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/authorizer/AuthorizerManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/authorizer/AuthorizerManager.java
@@ -22,14 +22,20 @@ package org.apache.iotdb.db.auth.authorizer;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
+import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
import org.apache.iotdb.confignode.rpc.thrift.TLoginReq;
import org.apache.iotdb.db.auth.AuthException;
+import org.apache.iotdb.db.auth.AuthorityChecker;
import org.apache.iotdb.db.auth.entity.Role;
import org.apache.iotdb.db.auth.entity.User;
+import org.apache.iotdb.db.conf.OperationType;
import org.apache.iotdb.db.mpp.execution.config.ConfigTaskResult;
+import org.apache.iotdb.db.mpp.sql.statement.Statement;
+import org.apache.iotdb.db.mpp.sql.statement.sys.AuthorStatement;
import org.apache.iotdb.db.query.control.SessionManager;
import org.apache.iotdb.db.query.control.SessionTimeoutManager;
import org.apache.iotdb.db.service.basic.BasicOpenSessionResp;
+import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.iotdb.service.rpc.thrift.TSProtocolVersion;
@@ -42,6 +48,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.apache.iotdb.db.utils.ErrorHandlingUtils.onNPEOrUnexpectedException;
+
public class AuthorizerManager implements IAuthorizer {
private static final Logger logger = LoggerFactory.getLogger(AuthorizerManager.class);
@@ -254,4 +262,40 @@ public class AuthorizerManager implements IAuthorizer {
SessionTimeoutManager.getInstance().register(sessionId);
return openSessionResp.sessionId(sessionId);
}
+
+ /** Check whether specific Session has the authorization to given plan. */
+ public TSStatus checkAuthority(Statement statement, long sessionId) {
+ try {
+ if (!checkAuthorization(statement, sessionManager.getUsername(sessionId))) {
+ return RpcUtils.getStatus(
+ TSStatusCode.NO_PERMISSION_ERROR,
+ "No permissions for this operation " + statement.getType());
+ }
+ } catch (AuthException e) {
+ logger.warn("meet error while checking authorization.", e);
+ return RpcUtils.getStatus(TSStatusCode.UNINITIALIZED_AUTH_ERROR, e.getMessage());
+ } catch (Exception e) {
+ return onNPEOrUnexpectedException(
+ e, OperationType.CHECK_AUTHORITY, TSStatusCode.EXECUTE_STATEMENT_ERROR);
+ }
+ return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+ }
+
+ /** Check whether specific user has the authorization to given plan. */
+ public boolean checkAuthorization(Statement statement, String username) throws AuthException {
+ if (!statement.isAuthenticationRequired()) {
+ return true;
+ }
+ String targetUser = null;
+ if (statement instanceof AuthorStatement) {
+ targetUser = ((AuthorStatement) statement).getUserName();
+ }
+ return AuthorityChecker.checkPermission(
+ username, statement.getPaths(), statement.getType(), targetUser);
+ }
+
+ public TSStatus checkPath(String username, List<String> allPath, int permission) {
+ return clusterAuthorizer.checkUserPrivileges(
+ new TCheckUserPrivilegesReq(username, allPath, permission));
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/authorizer/ClusterAuthorizer.java b/server/src/main/java/org/apache/iotdb/db/auth/authorizer/ClusterAuthorizer.java
index 85ed49a992..183cc2f8d7 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/authorizer/ClusterAuthorizer.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/authorizer/ClusterAuthorizer.java
@@ -23,21 +23,29 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.exception.BadNodeUrlException;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerResp;
+import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
import org.apache.iotdb.confignode.rpc.thrift.TLoginReq;
import org.apache.iotdb.db.client.ConfigNodeClient;
+import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
+import org.apache.iotdb.db.mpp.common.header.DatasetHeader;
import org.apache.iotdb.db.mpp.execution.config.ConfigTaskResult;
import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
import org.apache.iotdb.rpc.ConfigNodeConnectionException;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.rpc.TSStatusCode;
-import org.apache.iotdb.tsfile.read.common.block.TsBlock;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
+import org.apache.iotdb.tsfile.utils.Binary;
import com.google.common.util.concurrent.SettableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
public class ClusterAuthorizer {
@@ -78,7 +86,6 @@ public class ClusterAuthorizer {
public SettableFuture<ConfigTaskResult> queryPermission(TAuthorizerReq authorizerReq) {
SettableFuture<ConfigTaskResult> future = SettableFuture.create();
ConfigNodeClient configNodeClient = null;
- TsBlock tsBlock = null;
TAuthorizerResp authorizerResp;
try {
configNodeClient = new ConfigNodeClient();
@@ -94,8 +101,34 @@ public class ClusterAuthorizer {
authorizerResp.getStatus());
future.setException(new StatementExecutionException(authorizerResp.getStatus()));
} else {
- // TODO: Construct result
- future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, tsBlock, null));
+ // build TSBlock
+ List<TSDataType> types = new ArrayList<>();
+ Map<String, List<String>> authorizerInfo = authorizerResp.getAuthorizerInfo();
+ for (int i = 0; i < authorizerInfo.size(); i++) {
+ types.add(TSDataType.TEXT);
+ }
+ TsBlockBuilder builder = new TsBlockBuilder(types);
+ List<ColumnHeader> headerList = new ArrayList<>();
+
+ for (String header : authorizerInfo.keySet()) {
+ headerList.add(new ColumnHeader(header, TSDataType.TEXT));
+ }
+ // The Time column will be ignored by the setting of ColumnHeader.
+ // So we can put a meaningless value here
+ for (String value : authorizerInfo.get(headerList.get(0).getColumnName())) {
+ builder.getTimeColumnBuilder().writeLong(0L);
+ builder.getColumnBuilder(0).writeBinary(new Binary(value));
+ builder.declarePosition();
+ }
+ for (int i = 1; i < headerList.size(); i++) {
+ for (String value : authorizerInfo.get(headerList.get(i).getColumnName())) {
+ builder.getColumnBuilder(i).writeBinary(new Binary(value));
+ }
+ }
+
+ DatasetHeader datasetHeader = new DatasetHeader(headerList, true);
+ future.set(
+ new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, builder.build(), datasetHeader));
}
} catch (IoTDBConnectionException | BadNodeUrlException e) {
LOGGER.error("Failed to connect to config node.");
@@ -129,4 +162,24 @@ public class ClusterAuthorizer {
}
return status;
}
+
+ public TSStatus checkUserPrivileges(TCheckUserPrivilegesReq req) {
+ ConfigNodeClient configNodeClient = null;
+ TSStatus status = null;
+ try {
+ configNodeClient = new ConfigNodeClient();
+ // Send request to some API server
+ status = configNodeClient.checkUserPrivileges(req);
+ } catch (IoTDBConnectionException | BadNodeUrlException e) {
+ throw new ConfigNodeConnectionException("Couldn't connect config node");
+ } finally {
+ if (configNodeClient != null) {
+ configNodeClient.close();
+ }
+ if (status == null) {
+ status = new TSStatus();
+ }
+ }
+ return status;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java b/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java
index 9069fe2d67..7464c0a48e 100644
--- a/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java
+++ b/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.commons.utils.CommonUtils;
import org.apache.iotdb.confignode.rpc.thrift.ConfigIService;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerResp;
+import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
import org.apache.iotdb.confignode.rpc.thrift.TCountStorageGroupResp;
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeLocationResp;
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRegisterReq;
@@ -365,4 +366,19 @@ public class ConfigNodeClient {
}
throw new IoTDBConnectionException(MSG_RECONNECTION_FAIL);
}
+
+ public TSStatus checkUserPrivileges(TCheckUserPrivilegesReq req) throws IoTDBConnectionException {
+ for (int i = 0; i < RETRY_NUM; i++) {
+ try {
+ TSStatus status = client.checkUserPrivileges(req);
+ if (!updateConfigNodeLeader(status)) {
+ return status;
+ }
+ } catch (TException e) {
+ configLeader = null;
+ }
+ reconnect();
+ }
+ throw new IoTDBConnectionException(MSG_RECONNECTION_FAIL);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/Statement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/Statement.java
index fe3ee2a077..262430ecde 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/Statement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/Statement.java
@@ -19,9 +19,12 @@
package org.apache.iotdb.db.mpp.sql.statement;
+import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.parser.ASTVisitor;
+import java.util.List;
+
/**
* This class is a superclass of all statements.
*
@@ -55,4 +58,10 @@ public abstract class Statement extends StatementNode {
public boolean isQuery() {
return statementType == StatementType.QUERY;
}
+
+ public boolean isAuthenticationRequired() {
+ return true;
+ }
+
+ public abstract List<? extends PartialPath> getPaths();
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java
index 0e9f408636..8d370d42ee 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/AggregationQueryStatement.java
@@ -80,6 +80,7 @@ public class AggregationQueryStatement extends QueryStatement {
return deviceNameToAggregationsMap;
}
+ @Override
public DatasetHeader constructDatasetHeader() {
List<ColumnHeader> columnHeaders = new ArrayList<>();
// TODO: consider Aggregation
@@ -121,6 +122,7 @@ public class AggregationQueryStatement extends QueryStatement {
}
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitAggregationQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/FillQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/FillQueryStatement.java
index da72b8e1d3..2662041ae9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/FillQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/FillQueryStatement.java
@@ -72,6 +72,7 @@ public class FillQueryStatement extends QueryStatement {
}
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitFillQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByFillQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByFillQueryStatement.java
index b3d87aa5dd..c7a3c703f9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByFillQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByFillQueryStatement.java
@@ -42,6 +42,7 @@ public class GroupByFillQueryStatement extends GroupByQueryStatement {
this.fillComponent = fillComponent;
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitGroupByFillQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByQueryStatement.java
index 5a3fbc937b..f7398a274a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/GroupByQueryStatement.java
@@ -47,12 +47,14 @@ public class GroupByQueryStatement extends AggregationQueryStatement {
this.groupByTimeComponent = groupByTimeComponent;
}
+ @Override
public DatasetHeader constructDatasetHeader() {
List<ColumnHeader> columnHeaders = new ArrayList<>();
// TODO: consider GROUP BY
return new DatasetHeader(columnHeaders, false);
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitGroupByQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertBaseStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertBaseStatement.java
index cd4e9ec890..38e4a05557 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertBaseStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertBaseStatement.java
@@ -22,6 +22,9 @@ import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import java.util.Collections;
+import java.util.List;
+
public abstract class InsertBaseStatement extends Statement {
/**
@@ -67,4 +70,9 @@ public abstract class InsertBaseStatement extends Statement {
public void setAligned(boolean aligned) {
isAligned = aligned;
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.emptyList();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertMultiTabletsStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertMultiTabletsStatement.java
index 5b7aa98e9f..cb12ed1c57 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertMultiTabletsStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertMultiTabletsStatement.java
@@ -74,4 +74,13 @@ public class InsertMultiTabletsStatement extends InsertBaseStatement {
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitInsertMultiTablets(this, context);
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> result = new ArrayList<>();
+ for (InsertTabletStatement insertTabletStatement : insertTabletStatementList) {
+ result.addAll(insertTabletStatement.getPaths());
+ }
+ return result;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowStatement.java
index 39f9a0ac56..ed06864b02 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowStatement.java
@@ -22,12 +22,14 @@ package org.apache.iotdb.db.mpp.sql.statement.crud;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.db.engine.StorageEngineV2;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -45,6 +47,16 @@ public class InsertRowStatement extends InsertBaseStatement {
statementType = StatementType.INSERT;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> ret = new ArrayList<>();
+ for (String m : measurements) {
+ PartialPath fullPath = devicePath.concatNode(m);
+ ret.add(fullPath);
+ }
+ return ret;
+ }
+
public long getTime() {
return time;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsOfOneDeviceStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsOfOneDeviceStatement.java
index 71eccaa20d..1d8d610729 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsOfOneDeviceStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsOfOneDeviceStatement.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.sql.statement.crud;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.db.engine.StorageEngineV2;
+import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -76,4 +77,14 @@ public class InsertRowsOfOneDeviceStatement extends InsertBaseStatement {
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitInsertRowsOfOneDevice(this, context);
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> ret = new ArrayList<>();
+ for (String m : measurements) {
+ PartialPath fullPath = devicePath.concatNode(m);
+ ret.add(fullPath);
+ }
+ return ret;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsStatement.java
index d740a2290f..da5452fa2c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertRowsStatement.java
@@ -74,4 +74,13 @@ public class InsertRowsStatement extends InsertBaseStatement {
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitInsertRows(this, context);
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> result = new ArrayList<>();
+ for (InsertRowStatement insertRowStatement : insertRowStatementList) {
+ result.addAll(insertRowStatement.getPaths());
+ }
+ return result;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertStatement.java
index a85ebb8a32..db662cc1ca 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertStatement.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
+import java.util.ArrayList;
import java.util.List;
/** this class extends {@code Statement} and process insert statement. */
@@ -43,6 +44,16 @@ public class InsertStatement extends Statement {
statementType = StatementType.INSERT;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> ret = new ArrayList<>();
+ for (String m : measurementList) {
+ PartialPath fullPath = device.concatNode(m);
+ ret.add(fullPath);
+ }
+ return ret;
+ }
+
public PartialPath getDevice() {
return device;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertTabletStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertTabletStatement.java
index 612d2f8463..a0d88e4d84 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertTabletStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/InsertTabletStatement.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.sql.statement.crud;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.StorageEngineV2;
+import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
import org.apache.iotdb.tsfile.utils.BitMap;
@@ -91,4 +92,14 @@ public class InsertTabletStatement extends InsertBaseStatement {
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitInsertTablet(this, context);
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> ret = new ArrayList<>();
+ for (String m : measurements) {
+ PartialPath fullPath = devicePath.concatNode(m);
+ ret.add(fullPath);
+ }
+ return ret;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java
index b62b8f296d..7829c9265d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/LastQueryStatement.java
@@ -40,6 +40,7 @@ public class LastQueryStatement extends QueryStatement {
super(queryStatement);
}
+ @Override
public DatasetHeader constructDatasetHeader() {
List<ColumnHeader> columnHeaders = new ArrayList<>();
// TODO: consider LAST
@@ -66,6 +67,7 @@ public class LastQueryStatement extends QueryStatement {
}
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitLastQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java
index b7626d1c07..3598218c5e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/QueryStatement.java
@@ -103,6 +103,11 @@ public class QueryStatement extends Statement {
this.statementType = StatementType.QUERY;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ return fromComponent.getPrefixPaths();
+ }
+
public QueryStatement(QueryStatement another) {
this.statementType = StatementType.QUERY;
this.selectComponent = another.getSelectComponent();
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java
index c8a31f588b..a9af777f96 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDAFQueryStatement.java
@@ -90,6 +90,7 @@ public class UDAFQueryStatement extends QueryStatement {
}
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitUDAFQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDTFQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDTFQueryStatement.java
index b2fb9166ce..1dd39badb3 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDTFQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/crud/UDTFQueryStatement.java
@@ -27,6 +27,7 @@ public class UDTFQueryStatement extends QueryStatement {
super(queryStatement);
}
+ @Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitUDTFQuery(this, context);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/AlterTimeSeriesStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/AlterTimeSeriesStatement.java
index 5a4386fe16..022fe48109 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/AlterTimeSeriesStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/AlterTimeSeriesStatement.java
@@ -24,6 +24,8 @@ import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
/**
@@ -56,6 +58,11 @@ public class AlterTimeSeriesStatement extends Statement {
statementType = StatementType.ALTER_TIMESERIES;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.singletonList(path);
+ }
+
public PartialPath getPath() {
return path;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CountStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CountStatement.java
index 888dbed5f4..7191516cfd 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CountStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CountStatement.java
@@ -22,6 +22,9 @@ package org.apache.iotdb.db.mpp.sql.statement.metadata;
import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.constant.StatementType;
+import java.util.Collections;
+import java.util.List;
+
/**
* COUNT statement.
*
@@ -44,4 +47,9 @@ public class CountStatement extends ShowStatement {
public void setPartialPath(PartialPath partialPath) {
this.partialPath = partialPath;
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.singletonList(partialPath);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateAlignedTimeSeriesStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateAlignedTimeSeriesStatement.java
index 2ec0f1f2b4..25d5973791 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateAlignedTimeSeriesStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateAlignedTimeSeriesStatement.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.mpp.sql.statement.metadata;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
@@ -27,6 +28,9 @@ import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -41,6 +45,9 @@ import java.util.Map;
*/
public class CreateAlignedTimeSeriesStatement extends Statement {
+ private static final Logger logger =
+ LoggerFactory.getLogger(CreateAlignedTimeSeriesStatement.class);
+
private PartialPath devicePath;
private List<String> measurements = new ArrayList<>();
private List<TSDataType> dataTypes = new ArrayList<>();
@@ -56,6 +63,19 @@ public class CreateAlignedTimeSeriesStatement extends Statement {
statementType = StatementType.CREATE_ALIGNED_TIMESERIES;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ List<PartialPath> paths = new ArrayList<>();
+ for (String measurement : measurements) {
+ try {
+ paths.add(new PartialPath(devicePath.getFullPath(), measurement));
+ } catch (IllegalPathException e) {
+ logger.error("Failed to get paths of CreateAlignedTimeSeriesStatement. ", e);
+ }
+ }
+ return paths;
+ }
+
public PartialPath getDevicePath() {
return devicePath;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateTimeSeriesStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateTimeSeriesStatement.java
index c875262e17..2305814acf 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateTimeSeriesStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/CreateTimeSeriesStatement.java
@@ -27,6 +27,8 @@ import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
/**
@@ -54,6 +56,11 @@ public class CreateTimeSeriesStatement extends Statement {
statementType = StatementType.CREATE_TIMESERIES;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.singletonList(path);
+ }
+
public PartialPath getPath() {
return path;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SchemaFetchStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SchemaFetchStatement.java
index dbe7ca53f3..71e5a2716a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SchemaFetchStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SchemaFetchStatement.java
@@ -20,11 +20,14 @@
package org.apache.iotdb.db.mpp.sql.statement.metadata;
import org.apache.iotdb.commons.partition.SchemaPartition;
+import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
+import java.util.List;
+
public class SchemaFetchStatement extends Statement {
private PathPatternTree patternTree;
@@ -53,4 +56,9 @@ public class SchemaFetchStatement extends Statement {
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitSchemaFetch(this, context);
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return patternTree.splitToPathList();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SetStorageGroupStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SetStorageGroupStatement.java
index f05d70b59c..c99e40b67a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SetStorageGroupStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/SetStorageGroupStatement.java
@@ -26,6 +26,9 @@ import org.apache.iotdb.db.mpp.sql.statement.IConfigStatement;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
+import java.util.Collections;
+import java.util.List;
+
public class SetStorageGroupStatement extends Statement implements IConfigStatement {
private PartialPath storageGroupPath;
@@ -51,4 +54,11 @@ public class SetStorageGroupStatement extends Statement implements IConfigStatem
public QueryType getQueryType() {
return QueryType.WRITE;
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return storageGroupPath != null
+ ? Collections.singletonList(storageGroupPath)
+ : Collections.emptyList();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowDevicesStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowDevicesStatement.java
index 74a861e36e..909458101f 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowDevicesStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowDevicesStatement.java
@@ -22,6 +22,9 @@ package org.apache.iotdb.db.mpp.sql.statement.metadata;
import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
+import java.util.Collections;
+import java.util.List;
+
/**
* SHOW DEVICES statement.
*
@@ -55,4 +58,9 @@ public class ShowDevicesStatement extends ShowStatement {
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitShowDevices(this, context);
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.singletonList(pathPattern);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStatement.java
index 6baad7ad00..71030bcbdb 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStatement.java
@@ -19,9 +19,13 @@
package org.apache.iotdb.db.mpp.sql.statement.metadata;
+import org.apache.iotdb.db.metadata.path.PartialPath;
import org.apache.iotdb.db.mpp.sql.constant.StatementType;
import org.apache.iotdb.db.mpp.sql.statement.Statement;
+import java.util.Collections;
+import java.util.List;
+
public class ShowStatement extends Statement {
int limit = 0;
@@ -34,6 +38,11 @@ public class ShowStatement extends Statement {
statementType = StatementType.SHOW;
}
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.emptyList();
+ }
+
public int getLimit() {
return limit;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java
index efb57c57a1..30df19639f 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java
@@ -24,6 +24,9 @@ import org.apache.iotdb.db.mpp.sql.analyze.QueryType;
import org.apache.iotdb.db.mpp.sql.statement.IConfigStatement;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
+import java.util.Collections;
+import java.util.List;
+
/**
* SHOW STORAGE GROUP statement
*
@@ -53,4 +56,9 @@ public class ShowStorageGroupStatement extends ShowStatement implements IConfigS
public QueryType getQueryType() {
return QueryType.READ;
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return Collections.singletonList(pathPattern);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/sys/AuthorStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/sys/AuthorStatement.java
index 671f36717c..7d000b6599 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/sys/AuthorStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/sys/AuthorStatement.java
@@ -26,6 +26,9 @@ import org.apache.iotdb.db.mpp.sql.statement.Statement;
import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
+import java.util.Collections;
+import java.util.List;
+
public class AuthorStatement extends Statement implements IConfigStatement {
private final AuthorOperator.AuthorType authorType;
@@ -44,7 +47,60 @@ public class AuthorStatement extends Statement implements IConfigStatement {
public AuthorStatement(AuthorOperator.AuthorType type) {
super();
authorType = type;
- statementType = StatementType.AUTHOR;
+ switch (authorType) {
+ case DROP_ROLE:
+ this.setType(StatementType.DELETE_ROLE);
+ break;
+ case DROP_USER:
+ this.setType(StatementType.DELETE_USER);
+ break;
+ case GRANT_ROLE:
+ this.setType(StatementType.GRANT_ROLE_PRIVILEGE);
+ break;
+ case GRANT_USER:
+ this.setType(StatementType.GRANT_USER_PRIVILEGE);
+ break;
+ case CREATE_ROLE:
+ this.setType(StatementType.CREATE_ROLE);
+ break;
+ case CREATE_USER:
+ this.setType(StatementType.CREATE_USER);
+ break;
+ case REVOKE_ROLE:
+ this.setType(StatementType.REVOKE_ROLE_PRIVILEGE);
+ break;
+ case REVOKE_USER:
+ this.setType(StatementType.REVOKE_USER_PRIVILEGE);
+ break;
+ case UPDATE_USER:
+ this.setType(StatementType.MODIFY_PASSWORD);
+ break;
+ case GRANT_ROLE_TO_USER:
+ this.setType(StatementType.GRANT_ROLE_PRIVILEGE);
+ break;
+ case REVOKE_ROLE_FROM_USER:
+ this.setType(StatementType.REVOKE_USER_ROLE);
+ break;
+ case LIST_USER_PRIVILEGE:
+ this.setType(StatementType.LIST_USER_PRIVILEGE);
+ break;
+ case LIST_ROLE_PRIVILEGE:
+ this.setType(StatementType.LIST_ROLE_PRIVILEGE);
+ break;
+ case LIST_USER_ROLES:
+ this.setType(StatementType.LIST_USER_ROLES);
+ break;
+ case LIST_ROLE_USERS:
+ this.setType(StatementType.LIST_ROLE_USERS);
+ break;
+ case LIST_USER:
+ this.setType(StatementType.LIST_USER);
+ break;
+ case LIST_ROLE:
+ this.setType(StatementType.LIST_ROLE);
+ break;
+ default:
+ }
}
/**
@@ -145,4 +201,9 @@ public class AuthorStatement extends Statement implements IConfigStatement {
}
return queryType;
}
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return nodeName != null ? Collections.singletonList(nodeName) : Collections.emptyList();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeTSIServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeTSIServiceImpl.java
index 47647e05cf..75a1eb67db 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeTSIServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeTSIServiceImpl.java
@@ -270,6 +270,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
StatementGenerator.createStatement(
statement, SESSION_MANAGER.getZoneId(req.getSessionId()));
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(s, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return RpcUtils.getTSExecuteStatementResp(status);
+ }
+
QUERY_FREQUENCY_RECORDER.incrementAndGet();
AUDIT_LOGGER.debug("Session {} execute Query: {}", req.sessionId, statement);
@@ -377,6 +383,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
// Step 1: TODO(INSERT) transfer from TSInsertTabletsReq to Statement
InsertRowsStatement statement = (InsertRowsStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -388,9 +400,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = serviceProvider.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -420,6 +429,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
InsertRowsOfOneDeviceStatement statement =
(InsertRowsOfOneDeviceStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -431,9 +446,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = serviceProvider.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -463,6 +475,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
InsertRowsOfOneDeviceStatement statement =
(InsertRowsOfOneDeviceStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -474,9 +492,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = serviceProvider.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -502,6 +517,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
InsertRowStatement statement = (InsertRowStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -513,9 +534,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = SESSION_MANAGER.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -536,6 +554,13 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
// Step 1: TODO(INSERT) transfer from TSInsertTabletsReq to Statement
InsertMultiTabletsStatement statement =
(InsertMultiTabletsStatement) StatementGenerator.createStatement(req);
+
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -547,9 +572,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = serviceProvider.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -571,6 +593,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
InsertTabletStatement statement =
(InsertTabletStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -582,9 +610,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = SESSION_MANAGER.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -612,6 +637,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
InsertRowsStatement statement = (InsertRowsStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
COORDINATOR.execute(
@@ -622,9 +653,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = serviceProvider.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
@@ -747,6 +775,12 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
InsertRowStatement statement = (InsertRowStatement) StatementGenerator.createStatement(req);
+ // permission check
+ TSStatus status = AuthorizerManager.getInstance().checkAuthority(statement, req.sessionId);
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+
// Step 2: call the coordinator
long queryId = SESSION_MANAGER.requestQueryId(false);
ExecutionResult result =
@@ -758,9 +792,6 @@ public class DataNodeTSIServiceImpl implements TSIEventHandler {
PARTITION_FETCHER,
SCHEMA_FETCHER);
- // TODO(INSERT) do this check in analyze
- // TSStatus status = serviceProvider.checkAuthority(insertTabletPlan,
- // req.getSessionId());
return result.status;
} catch (Exception e) {
return onNPEOrUnexpectedException(
diff --git a/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java b/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index 78791a74bc..2466ddfdb3 100644
--- a/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++ b/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -98,6 +98,9 @@ public enum TSStatusCode {
NOT_LOGIN_ERROR(601),
NO_PERMISSION_ERROR(602),
UNINITIALIZED_AUTH_ERROR(603),
+ EXECUTE_PERMISSION_EXCEPTION_ERROR(604),
+ USER_NOT_EXIST_ERROR(605),
+ ROLE_NOT_EXIST_ERROR(606),
// cluster-related errors
PARTITION_NOT_READY(700),
diff --git a/thrift-confignode/src/main/thrift/confignode.thrift b/thrift-confignode/src/main/thrift/confignode.thrift
index 72055f34df..6442efa245 100644
--- a/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/thrift-confignode/src/main/thrift/confignode.thrift
@@ -143,6 +143,12 @@ struct TLoginReq {
2: required string password
}
+struct TCheckUserPrivilegesReq{
+ 1: required string username;
+ 2: required list<string> paths
+ 3: required i32 permission
+}
+
service ConfigIService {
/* DataNode */
@@ -188,4 +194,6 @@ service ConfigIService {
TAuthorizerResp queryPermission(TAuthorizerReq req)
common.TSStatus login(TLoginReq req)
+
+ common.TSStatus checkUserPrivileges(TCheckUserPrivilegesReq req)
}
\ No newline at end of file