You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by zy...@apache.org on 2022/08/17 12:04:33 UTC
[iotdb] branch master updated: [IOTDB-4153]Grant ALL privileges to different paths return privilege exists (#7023)
This is an automated email from the ASF dual-hosted git repository.
zyk 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 16a5f7ab5b [IOTDB-4153]Grant ALL privileges to different paths return privilege exists (#7023)
16a5f7ab5b is described below
commit 16a5f7ab5bc0979ee1b8d5347a408813ec6e4e25
Author: Yifu Zhou <ef...@outlook.com>
AuthorDate: Wed Aug 17 20:04:27 2022 +0800
[IOTDB-4153]Grant ALL privileges to different paths return privilege exists (#7023)
[IOTDB-4153]Grant ALL privileges to different paths return privilege exists (#7023)
---
.../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 4 +-
.../Administration-Management/Administration.md | 20 ++--
.../Administration-Management/Administration.md | 22 +++--
.../iotdb/db/integration/IoTDBAuthorizationIT.java | 90 ++++++++++++++++++
.../iotdb/db/mpp/plan/parser/ASTVisitor.java | 96 ++++++++++++-------
.../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java | 103 +++++++++++++--------
6 files changed, 243 insertions(+), 92 deletions(-)
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 71f210c4c9..15a9239d00 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -537,7 +537,7 @@ grantUser
// Grant Role Privileges
grantRole
- : GRANT ROLE roleName=identifier PRIVILEGES privileges ON prefixPath (COMMA prefixPath)*
+ : GRANT ROLE roleName=identifier PRIVILEGES privileges (ON prefixPath (COMMA prefixPath)*)?
;
// Grant User Role
@@ -552,7 +552,7 @@ revokeUser
// Revoke Role Privileges
revokeRole
- : REVOKE ROLE roleName=identifier PRIVILEGES privileges ON prefixPath (COMMA prefixPath)*
+ : REVOKE ROLE roleName=identifier PRIVILEGES privileges (ON prefixPath (COMMA prefixPath)*)?
;
// Revoke Role From User
diff --git a/docs/UserGuide/Administration-Management/Administration.md b/docs/UserGuide/Administration-Management/Administration.md
index f918cfbd28..42fef4811b 100644
--- a/docs/UserGuide/Administration-Management/Administration.md
+++ b/docs/UserGuide/Administration-Management/Administration.md
@@ -184,13 +184,14 @@ Eg: IoTDB > DROP ROLE `admin`;
```
GRANT USER <userName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > GRANT USER `tempuser` PRIVILEGES INSERT_TIMESERIES, DELETE_TIMESERIES on root.ln.**, root.sgcc.**;
+Eg: IoTDB > GRANT USER `tempuser` PRIVILEGES CREATE_ROLE;
```
- Grant User All Privileges
```
-GRANT USER <userName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > grant user renyuhua privileges all on root.sgcc.**, root.**;
+GRANT USER <userName> PRIVILEGES ALL;
+Eg: IoTDB > GRANT USER `tempuser` PRIVILEGES ALL;
```
* Grant Role Privileges
@@ -198,13 +199,14 @@ Eg: IoTDB > grant user renyuhua privileges all on root.sgcc.**, root.**;
```
GRANT ROLE <roleName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES INSERT_TIMESERIES, DELETE_TIMESERIES ON root.sgcc.**, root.ln.**;
+Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES CREATE_ROLE;
```
- Grant Role All Privileges
```
GRANT ROLE <roleName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES ALL ON root.ln.**;
+Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES ALL;
```
* Grant User Role
@@ -219,13 +221,14 @@ Eg: IoTDB > GRANT `temprole` TO tempuser;
```
REVOKE USER <userName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES DELETE_TIMESERIES on root.ln.**;
+Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES CREATE_ROLE;
```
* Revoke User All Privileges
```
-REVOKE USER <userName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES ALL on root.ln.**;
+REVOKE USER <userName> PRIVILEGES ALL;
+Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES ALL;
```
* Revoke Role Privileges
@@ -233,13 +236,14 @@ Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES ALL on root.ln.**;
```
REVOKE ROLE <roleName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES DELETE_TIMESERIES ON root.ln.**;
+Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES CREATE_ROLE;
```
* Revoke All Role Privileges
```
-REVOKE ROLE <roleName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES ALL ON root.ln.**;
+REVOKE ROLE <roleName> PRIVILEGES ALL;
+Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES ALL;
```
* Revoke Role From User
@@ -396,6 +400,8 @@ At the same time, changes to roles are immediately reflected on all users who ow
|APPLY_TEMPLATE|set, unset and activate schema template; path dependent|Eg1: `set schema template t1 to root.sg.d`<br/>Eg2: `create timeseries of schema template on root.sg.d`
|READ_TEMPLATE_APPLICATION|show paths set and using schema template; path independent|Eg1: `show paths set schema template t1`<br/>Eg2: `show paths using schema template t1`
+Note that path dependent privileges can only be granted or revoked on root.**;
+
Note that the following SQL statements need to be granted multiple permissions before they can be used:
- Import data: Need to assign `READ_TIMESERIES`,`INSERT_TIMESERIES` two permissions.。
diff --git a/docs/zh/UserGuide/Administration-Management/Administration.md b/docs/zh/UserGuide/Administration-Management/Administration.md
index 700ca0820c..fdb92620d6 100644
--- a/docs/zh/UserGuide/Administration-Management/Administration.md
+++ b/docs/zh/UserGuide/Administration-Management/Administration.md
@@ -183,13 +183,14 @@ Eg: IoTDB > DROP ROLE `admin`;
```
GRANT USER <userName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > GRANT USER `tempuser` PRIVILEGES INSERT_TIMESERIES, DELETE_TIMESERIES on root.ln.**, root.sgcc.**;
+Eg: IoTDB > GRANT USER `tempuser` PRIVILEGES CREATE_ROLE;
```
- 赋予用户全部的权限
```
-GRANT USER <userName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > grant user renyuhua privileges all on root.sgcc.**, root.**;
+GRANT USER <userName> PRIVILEGES ALL;
+Eg: IoTDB > GRANT USER `tempuser` PRIVILEGES ALL;
```
* 赋予角色权限
@@ -197,13 +198,14 @@ Eg: IoTDB > grant user renyuhua privileges all on root.sgcc.**, root.**;
```
GRANT ROLE <roleName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES INSERT_TIMESERIES, DELETE_TIMESERIES ON root.sgcc.**, root.ln.**;
+Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES CREATE_ROLE;
```
- 赋予角色全部的权限
```
-GRANT ROLE <roleName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES ALL ON root.ln.**;
+GRANT ROLE <roleName> PRIVILEGES ALL;
+Eg: IoTDB > GRANT ROLE `temprole` PRIVILEGES ALL;
```
* 赋予用户角色
@@ -218,13 +220,14 @@ Eg: IoTDB > GRANT `temprole` TO tempuser;
```
REVOKE USER <userName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES DELETE_TIMESERIES on root.ln.**;
+Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES CREATE_ROLE;
```
- 移除用户所有权限
```
-REVOKE USER <userName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES ALL on root.ln.**;
+REVOKE USER <userName> PRIVILEGES ALL;
+Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES ALL;
```
* 撤销角色权限
@@ -232,13 +235,14 @@ Eg: IoTDB > REVOKE USER `tempuser` PRIVILEGES ALL on root.ln.**;
```
REVOKE ROLE <roleName> PRIVILEGES <privileges> ON <nodeNames>;
Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES DELETE_TIMESERIES ON root.ln.**;
+Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES CREATE_ROLE;
```
- 撤销角色全部的权限
```
-REVOKE ROLE <roleName> PRIVILEGES ALL ON <nodeNames>;
-Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES ALL ON root.ln.**;
+REVOKE ROLE <roleName> PRIVILEGES ALL;
+Eg: IoTDB > REVOKE ROLE `temprole` PRIVILEGES ALL;
```
* 撤销用户角色
@@ -395,6 +399,8 @@ Eg: IoTDB > ALTER USER `tempuser` SET PASSWORD 'newpwd';
|APPLY_TEMPLATE|挂载、卸载、激活模板。路径有关。|Eg1: `set schema template t1 to root.sg.d`<br/>Eg2: `create timeseries of schema template on root.sg.d`
|READ_TEMPLATE_APPLICATION|查看模板的挂载路径和激活路径。路径无关|Eg1: `show paths set schema template t1`<br/>Eg2: `show paths using schema template t1`
+注意: 路径无关的权限只能在路径root.**下赋予或撤销;
+
注意: 下述sql语句需要赋予多个权限才可以使用:
- 导入数据,需要赋予`READ_TIMESERIES`,`INSERT_TIMESERIES`两种权限。
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
index 183c7576c3..1e5196fc77 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBAuthorizationIT.java
@@ -1398,4 +1398,94 @@ public class IoTDBAuthorizationIT {
assertFalse(resultSet.next());
}
}
+
+ @Test
+ public void testCheckGrantRevokePrivileges() throws ClassNotFoundException, SQLException {
+ Class.forName(Config.JDBC_DRIVER_NAME);
+ try (Connection adminCon =
+ DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+ Statement adminStmt = adminCon.createStatement()) {
+ adminStmt.execute("CREATE USER tempuser 'temppw'");
+
+ adminStmt.execute("GRANT USER tempuser PRIVILEGES ALL on root.**");
+ adminStmt.execute("REVOKE USER tempuser PRIVILEGES ALL on root.**");
+ adminStmt.execute("GRANT USER tempuser PRIVILEGES ALL");
+ adminStmt.execute(
+ "GRANT USER tempuser PRIVILEGES INSERT_TIMESERIES, READ_TIMESERIES on root.ln.**");
+ adminStmt.execute(
+ "REVOKE USER tempuser PRIVILEGES INSERT_TIMESERIES, READ_TIMESERIES on root.ln.**");
+ boolean caught = false;
+ try {
+ adminStmt.execute("GRANT USER tempuser PRIVILEGES ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ caught = false;
+ try {
+ adminStmt.execute("REVOKE USER tempuser PRIVILEGES ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ caught = false;
+ try {
+ adminStmt.execute("GRANT USER tempuser PRIVILEGES INSERT_TIMESERIES, ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ caught = false;
+ try {
+ adminStmt.execute("REVOKE USER tempuser PRIVILEGES INSERT_TIMESERIES, ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ adminStmt.execute("CREATE ROLE temprole");
+ adminStmt.execute("GRANT ROLE temprole PRIVILEGES ALL on root.**");
+ adminStmt.execute("REVOKE ROLE temprole PRIVILEGES ALL on root.**");
+ adminStmt.execute("GRANT ROLE temprole PRIVILEGES ALL");
+ adminStmt.execute(
+ "GRANT ROLE temprole PRIVILEGES INSERT_TIMESERIES, READ_TIMESERIES on root.ln.**");
+ adminStmt.execute(
+ "REVOKE ROLE temprole PRIVILEGES INSERT_TIMESERIES, READ_TIMESERIES on root.ln.**");
+ caught = false;
+ try {
+ adminStmt.execute("GRANT ROLE temprole PRIVILEGES ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ caught = false;
+ try {
+ adminStmt.execute("REVOKE ROLE temprole PRIVILEGES ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ caught = false;
+ try {
+ adminStmt.execute("GRANT ROLE temprole PRIVILEGES INSERT_TIMESERIES, ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+
+ caught = false;
+ try {
+ adminStmt.execute("REVOKE ROLE temprole PRIVILEGES INSERT_TIMESERIES, ALL on root.ln.**");
+ } catch (Exception e) {
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index d306127944..760a403d14 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -162,6 +162,8 @@ import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import static org.apache.iotdb.db.metadata.MetadataConstant.ALL_RESULT_NODES;
+
/** Parse AST to Statement. */
public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
@@ -1622,22 +1624,17 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
@Override
public Statement visitGrantUser(IoTDBSqlParser.GrantUserContext ctx) {
+ String[] privileges = parsePrivilege(ctx.privileges());
+ List<PartialPath> nodeNameList =
+ ctx.prefixPath().stream()
+ .map(this::parsePrefixPath)
+ .distinct()
+ .collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
AuthorStatement authorStatement = new AuthorStatement(AuthorOperator.AuthorType.GRANT_USER);
authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
- authorStatement.setPrivilegeList(parsePrivilege(ctx.privileges()));
-
- String privilege = parsePrivilege(ctx.privileges())[0];
- List<PartialPath> nodeNameList;
- if (!PrivilegeType.valueOf(privilege.toUpperCase()).isPathRelevant()) {
- String[] path = {"root"};
- nodeNameList = Collections.singletonList(new PartialPath(path));
- } else {
- if (ctx.prefixPath() == null) {
- throw new SQLParserException("Invalid prefix path");
- }
- nodeNameList =
- ctx.prefixPath().stream().map(this::parsePrefixPath).collect(Collectors.toList());
- }
+ authorStatement.setPrivilegeList(privileges);
authorStatement.setNodeNameList(nodeNameList);
return authorStatement;
}
@@ -1646,11 +1643,17 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
@Override
public Statement visitGrantRole(IoTDBSqlParser.GrantRoleContext ctx) {
+ String[] privileges = parsePrivilege(ctx.privileges());
+ List<PartialPath> nodeNameList =
+ ctx.prefixPath().stream()
+ .map(this::parsePrefixPath)
+ .distinct()
+ .collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
AuthorStatement authorStatement = new AuthorStatement(AuthorOperator.AuthorType.GRANT_ROLE);
authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
- authorStatement.setPrivilegeList(parsePrivilege(ctx.privileges()));
- List<PartialPath> nodeNameList =
- ctx.prefixPath().stream().map(this::parsePrefixPath).collect(Collectors.toList());
+ authorStatement.setPrivilegeList(privileges);
authorStatement.setNodeNameList(nodeNameList);
return authorStatement;
}
@@ -1670,22 +1673,17 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
@Override
public Statement visitRevokeUser(IoTDBSqlParser.RevokeUserContext ctx) {
+ String[] privileges = parsePrivilege(ctx.privileges());
+ List<PartialPath> nodeNameList =
+ ctx.prefixPath().stream()
+ .map(this::parsePrefixPath)
+ .distinct()
+ .collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
AuthorStatement authorStatement = new AuthorStatement(AuthorOperator.AuthorType.REVOKE_USER);
authorStatement.setUserName(parseIdentifier(ctx.userName.getText()));
- authorStatement.setPrivilegeList(parsePrivilege(ctx.privileges()));
- String privilege = parsePrivilege(ctx.privileges())[0];
-
- List<PartialPath> nodeNameList;
- if (!PrivilegeType.valueOf(privilege.toUpperCase()).isPathRelevant()) {
- String[] path = {"root"};
- nodeNameList = Collections.singletonList(new PartialPath(path));
- } else {
- if (ctx.prefixPath() == null) {
- throw new SQLParserException("Invalid prefix path");
- }
- nodeNameList =
- ctx.prefixPath().stream().map(this::parsePrefixPath).collect(Collectors.toList());
- }
+ authorStatement.setPrivilegeList(privileges);
authorStatement.setNodeNameList(nodeNameList);
return authorStatement;
}
@@ -1694,15 +1692,45 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
@Override
public Statement visitRevokeRole(IoTDBSqlParser.RevokeRoleContext ctx) {
+ String[] privileges = parsePrivilege(ctx.privileges());
+ List<PartialPath> nodeNameList =
+ ctx.prefixPath().stream()
+ .map(this::parsePrefixPath)
+ .distinct()
+ .collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
AuthorStatement authorStatement = new AuthorStatement(AuthorOperator.AuthorType.REVOKE_ROLE);
authorStatement.setRoleName(parseIdentifier(ctx.roleName.getText()));
- authorStatement.setPrivilegeList(parsePrivilege(ctx.privileges()));
- List<PartialPath> nodeNameList =
- ctx.prefixPath().stream().map(this::parsePrefixPath).collect(Collectors.toList());
+ authorStatement.setPrivilegeList(privileges);
authorStatement.setNodeNameList(nodeNameList);
return authorStatement;
}
+ private void checkGrantRevokePrivileges(String[] privileges, List<PartialPath> nodeNameList) {
+ if (nodeNameList.isEmpty()) {
+ nodeNameList.addAll(Collections.singletonList(new PartialPath(ALL_RESULT_NODES)));
+ return;
+ }
+ boolean pathRelevant = true;
+ String errorPrivilegeName = "";
+ for (String privilege : privileges) {
+ if (!PrivilegeType.valueOf(privilege.toUpperCase()).isPathRelevant()) {
+ pathRelevant = false;
+ errorPrivilegeName = privilege.toUpperCase();
+ break;
+ }
+ }
+ if (!(pathRelevant
+ || (nodeNameList.size() == 1
+ && nodeNameList.contains(new PartialPath(ALL_RESULT_NODES))))) {
+ throw new SQLParserException(
+ String.format(
+ "path independent privilege: [%s] can only be set on path: root.**",
+ errorPrivilegeName));
+ }
+ }
+
// Revoke Role From User
@Override
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index fd3ce0b205..7be4b3058c 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -184,6 +184,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import static org.apache.iotdb.db.metadata.MetadataConstant.ALL_RESULT_NODES;
import static org.apache.iotdb.db.qp.constant.SQLConstant.TIME_PATH;
import static org.apache.iotdb.db.qp.constant.SQLConstant.TOK_KILL_QUERY;
@@ -1967,24 +1968,19 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
@Override
public Operator visitGrantUser(IoTDBSqlParser.GrantUserContext ctx) {
+ String[] privileges = parsePrivilege(ctx.privileges());
+ List<PartialPath> nodeNameList =
+ ctx.prefixPath().stream()
+ .map(this::parsePrefixPath)
+ .distinct()
+ .collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
AuthorOperator authorOperator =
new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, AuthorOperator.AuthorType.GRANT_USER);
authorOperator.setUserName(parseIdentifier(ctx.userName.getText()));
- authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
- String privilege = parsePrivilege(ctx.privileges())[0];
-
- List<PartialPath> prefixPath;
- if (!PrivilegeType.valueOf(privilege.toUpperCase()).isPathRelevant()) {
- String[] path = {"root"};
- prefixPath = Collections.singletonList(new PartialPath(path));
- } else {
- if (ctx.prefixPath() == null) {
- throw new SQLParserException("Invalid prefix path");
- }
- prefixPath =
- ctx.prefixPath().stream().map(path -> parsePrefixPath(path)).collect(Collectors.toList());
- }
- authorOperator.setNodeNameList(prefixPath);
+ authorOperator.setPrivilegeList(privileges);
+ authorOperator.setNodeNameList(nodeNameList);
return authorOperator;
}
@@ -1992,14 +1988,18 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
@Override
public Operator visitGrantRole(IoTDBSqlParser.GrantRoleContext ctx) {
- AuthorOperator authorOperator =
- new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, AuthorType.GRANT_ROLE);
- authorOperator.setRoleName(parseIdentifier(ctx.roleName.getText()));
- authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
+ String[] privileges = parsePrivilege(ctx.privileges());
List<PartialPath> nodeNameList =
ctx.prefixPath().stream()
- .map(prefixPath -> parsePrefixPath(prefixPath))
+ .map(this::parsePrefixPath)
+ .distinct()
.collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
+ AuthorOperator authorOperator =
+ new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, AuthorType.GRANT_ROLE);
+ authorOperator.setRoleName(parseIdentifier(ctx.roleName.getText()));
+ authorOperator.setPrivilegeList(privileges);
authorOperator.setNodeNameList(nodeNameList);
return authorOperator;
}
@@ -2020,25 +2020,18 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
@Override
public Operator visitRevokeUser(IoTDBSqlParser.RevokeUserContext ctx) {
+ String[] privileges = parsePrivilege(ctx.privileges());
+ List<PartialPath> nodeNameList =
+ ctx.prefixPath().stream()
+ .map(this::parsePrefixPath)
+ .distinct()
+ .collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
AuthorOperator authorOperator =
new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, AuthorType.REVOKE_USER);
authorOperator.setUserName(parseIdentifier(ctx.userName.getText()));
- authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
- String privilege = parsePrivilege(ctx.privileges())[0];
-
- List<PartialPath> nodeNameList;
- if (!PrivilegeType.valueOf(privilege.toUpperCase()).isPathRelevant()) {
- String[] path = {"root"};
- nodeNameList = Collections.singletonList(new PartialPath(path));
- } else {
- if (ctx.prefixPath() == null) {
- throw new SQLParserException("Invalid prefix path");
- }
- nodeNameList =
- ctx.prefixPath().stream()
- .map(prefixPath -> parsePrefixPath(prefixPath))
- .collect(Collectors.toList());
- }
+ authorOperator.setPrivilegeList(privileges);
authorOperator.setNodeNameList(nodeNameList);
return authorOperator;
}
@@ -2047,18 +2040,46 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
@Override
public Operator visitRevokeRole(IoTDBSqlParser.RevokeRoleContext ctx) {
- AuthorOperator authorOperator =
- new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, AuthorType.REVOKE_ROLE);
- authorOperator.setRoleName(parseIdentifier(ctx.roleName.getText()));
- authorOperator.setPrivilegeList(parsePrivilege(ctx.privileges()));
+ String[] privileges = parsePrivilege(ctx.privileges());
List<PartialPath> nodeNameList =
ctx.prefixPath().stream()
- .map(prefixPath -> parsePrefixPath(prefixPath))
+ .map(this::parsePrefixPath)
+ .distinct()
.collect(Collectors.toList());
+ checkGrantRevokePrivileges(privileges, nodeNameList);
+
+ AuthorOperator authorOperator =
+ new AuthorOperator(SQLConstant.TOK_AUTHOR_GRANT, AuthorType.REVOKE_ROLE);
+ authorOperator.setRoleName(parseIdentifier(ctx.roleName.getText()));
+ authorOperator.setPrivilegeList(privileges);
authorOperator.setNodeNameList(nodeNameList);
return authorOperator;
}
+ private void checkGrantRevokePrivileges(String[] privileges, List<PartialPath> nodeNameList) {
+ if (nodeNameList.isEmpty()) {
+ nodeNameList.addAll(Collections.singletonList(new PartialPath(ALL_RESULT_NODES)));
+ return;
+ }
+ boolean pathRelevant = true;
+ String errorPrivilegeName = "";
+ for (String privilege : privileges) {
+ if (!PrivilegeType.valueOf(privilege.toUpperCase()).isPathRelevant()) {
+ pathRelevant = false;
+ errorPrivilegeName = privilege.toUpperCase();
+ break;
+ }
+ }
+ if (!(pathRelevant
+ || (nodeNameList.size() == 1
+ && nodeNameList.contains(new PartialPath(ALL_RESULT_NODES))))) {
+ throw new SQLParserException(
+ String.format(
+ "path independent privilege: [%s] can only be set on path: root.**",
+ errorPrivilegeName));
+ }
+ }
+
// Revoke Role From User
@Override