This is an automated email from the ASF dual-hosted git repository.
jackietien 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 5596e7ccf0 [IOTDB-4922] Support auth in create & drop trigger (#7980)
5596e7ccf0 is described below
commit 5596e7ccf0a2bc1d5ea059ec3e5c2daaef36986b
Author: Jackie Tien <[email protected]>
AuthorDate: Tue Nov 15 08:59:23 2022 +0800
[IOTDB-4922] Support auth in create & drop trigger (#7980)
---
.../Administration-Management/Administration.md | 2 -
.../Administration-Management/Administration.md | 2 -
.../db/it/trigger/IoTDBTriggerManagementIT.java | 112 ++++++++++++++++++++-
.../org/apache/iotdb/db/auth/AuthorityChecker.java | 14 +--
.../iotdb/db/mpp/plan/constant/StatementType.java | 2 -
.../statement/metadata/CreateTriggerStatement.java | 2 +-
.../statement/metadata/DropTriggerStatement.java | 22 +++-
7 files changed, 134 insertions(+), 22 deletions(-)
diff --git a/docs/UserGuide/Administration-Management/Administration.md
b/docs/UserGuide/Administration-Management/Administration.md
index aa7f201e7d..51e3937dc0 100644
--- a/docs/UserGuide/Administration-Management/Administration.md
+++ b/docs/UserGuide/Administration-Management/Administration.md
@@ -391,8 +391,6 @@ At the same time, changes to roles are immediately
reflected on all users who ow
|DROP_FUNCTION|deregister UDFs; path independent|Eg: `drop function example`|
|CREATE_TRIGGER|create triggers; path dependent|Eg1: `CREATE TRIGGER
<TRIGGER-NAME> BEFORE INSERT ON <FULL-PATH> AS <CLASSNAME>`<br />Eg2: `CREATE
TRIGGER <TRIGGER-NAME> AFTER INSERT ON <FULL-PATH> AS <CLASSNAME>`|
|DROP_TRIGGER|drop triggers; path dependent|Eg: `drop trigger
'alert-listener-sg1d1s1'`|
-|START_TRIGGER|start triggers; path dependent|Eg: `start trigger
lert-listener-sg1d1s1'`|
-|STOP_TRIGGER|stop triggers; path dependent|Eg: `stop trigger
'alert-listener-sg1d1s1'`|
|CREATE_CONTINUOUS_QUERY|create continuous queries; path independent|Eg:
`select s1, s1 into t1, t2 from root.sg.d1`|
|DROP_CONTINUOUS_QUERY|drop continuous queries; path independent|Eg1: `DROP
CONTINUOUS QUERY cq3`<br />Eg2: `DROP CQ cq3`|
|UPDATE_TEMPLATE|create, drop, append and prune schema template; path
independent|Eg1: `create schema template t1(s1 int32)`
diff --git a/docs/zh/UserGuide/Administration-Management/Administration.md
b/docs/zh/UserGuide/Administration-Management/Administration.md
index 2d952fe67c..9a761cccac 100644
--- a/docs/zh/UserGuide/Administration-Management/Administration.md
+++ b/docs/zh/UserGuide/Administration-Management/Administration.md
@@ -390,8 +390,6 @@ Eg: IoTDB > ALTER USER `tempuser` SET PASSWORD 'newpwd';
|DROP_FUNCTION|卸载 UDF。路径无关|Eg: `drop function example`|
|CREATE_TRIGGER|创建触发器。路径相关|Eg1: `CREATE TRIGGER <TRIGGER-NAME> BEFORE INSERT
ON <FULL-PATH> AS <CLASSNAME>`<br />Eg2: `CREATE TRIGGER <TRIGGER-NAME> AFTER
INSERT ON <FULL-PATH> AS <CLASSNAME>`|
|DROP_TRIGGER|卸载触发器。路径相关|Eg: `drop trigger 'alert-listener-sg1d1s1'`|
-|START_TRIGGER|启动触发器。路径相关|Eg: `start trigger lert-listener-sg1d1s1'`|
-|STOP_TRIGGER|停止触发器。路径相关|Eg: `stop trigger 'alert-listener-sg1d1s1'`|
|CREATE_CONTINUOUS_QUERY|创建连续查询。路径无关|Eg: `select s1, s1 into t1, t2 from
root.sg.d1`|
|DROP_CONTINUOUS_QUERY|卸载连续查询。路径无关|Eg1: `DROP CONTINUOUS QUERY cq3`<br />Eg2:
`DROP CQ cq3`|
|UPDATE_TEMPLATE|创建、删除、修改模板。路径无关。|Eg1: `create schema template t1(s1 int32)`
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
index 15a016a673..a9de3b02d4 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
@@ -23,6 +23,7 @@ import
org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant;
import org.apache.iotdb.it.env.EnvFactory;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
import org.junit.After;
import org.junit.Before;
@@ -44,8 +45,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
-// todo: add StandaloneIT.class when supporting trigger on Standalone
-@Category({ClusterIT.class})
+@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBTriggerManagementIT {
private static final String TRIGGER_COUNTER_PREFIX =
System.getProperty("user.dir")
@@ -486,4 +486,112 @@ public class IoTDBTriggerManagementIT {
assertTrue(e.getMessage().contains("has not been created"));
}
}
+
+ @Test
+ public void testCreateAuth() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ statement.execute("CREATE USER `zmty` 'zmty'");
+
+ try (Connection connection2 = EnvFactory.getEnv().getConnection("zmty",
"zmty");
+ Statement statement2 = connection2.createStatement()) {
+ try {
+ statement2.execute(
+ String.format(
+ "create stateless trigger %s before insert on
root.test.stateless.a as '%s' using URI '%s' with (\"name\"=\"%s\")",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a",
+ TRIGGER_FILE_TIMES_COUNTER,
+ TRIGGER_JAR_PREFIX + "TriggerFireTimesCounter.jar",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a"));
+ fail();
+ } catch (Exception e) {
+ assertEquals(
+ "602: No permissions for this operation, please add privilege
CREATE_TRIGGER",
+ e.getMessage());
+ }
+
+ statement.execute("GRANT USER `zmty` PRIVILEGES CREATE_TRIGGER on
root.test.stateless.a");
+
+ try {
+ statement2.execute(
+ String.format(
+ "create stateless trigger %s before insert on
root.test.stateless.a as '%s' using URI '%s' with (\"name\"=\"%s\")",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a",
+ TRIGGER_FILE_TIMES_COUNTER,
+ TRIGGER_JAR_PREFIX + "TriggerFireTimesCounter.jar",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a"));
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ try {
+ statement2.execute(
+ String.format(
+ "create stateless trigger %s before insert on
root.test.stateless.b as '%s' using URI '%s' with (\"name\"=\"%s\")",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "b",
+ TRIGGER_FILE_TIMES_COUNTER,
+ TRIGGER_JAR_PREFIX + "TriggerFireTimesCounter.jar",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "b"));
+ fail();
+ } catch (Exception e) {
+ assertEquals(
+ "602: No permissions for this operation, please add privilege
CREATE_TRIGGER",
+ e.getMessage());
+ }
+ }
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDropAuth() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ statement.execute("CREATE USER `zmty` 'zmty'");
+
+ try (Connection connection2 = EnvFactory.getEnv().getConnection("zmty",
"zmty");
+ Statement statement2 = connection2.createStatement()) {
+ try {
+ statement.execute(
+ String.format(
+ "create stateless trigger %s before insert on
root.test.stateless.a as '%s' using URI '%s' with (\"name\"=\"%s\")",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a",
+ TRIGGER_FILE_TIMES_COUNTER,
+ TRIGGER_JAR_PREFIX + "TriggerFireTimesCounter.jar",
+ STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a"));
+
+ statement2.execute("drop trigger " +
STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a");
+ fail();
+ } catch (Exception e) {
+ assertEquals(
+ "602: No permissions for this operation, please add privilege
DROP_TRIGGER",
+ e.getMessage());
+ }
+
+ statement.execute("GRANT USER `zmty` PRIVILEGES CREATE_TRIGGER on
root.test.stateless.b");
+
+ try {
+ statement2.execute("drop trigger " +
STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a");
+ fail();
+ } catch (Exception e) {
+ assertEquals(
+ "602: No permissions for this operation, please add privilege
DROP_TRIGGER",
+ e.getMessage());
+ }
+
+ statement.execute("GRANT USER `zmty` PRIVILEGES DROP_TRIGGER on
root.test.stateless.a");
+
+ try {
+ statement2.execute("drop trigger " +
STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a");
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
}
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 d78d18d122..f660c47615 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
@@ -29,7 +29,6 @@ import org.apache.iotdb.db.mpp.plan.constant.StatementType;
import org.apache.iotdb.db.mpp.plan.statement.Statement;
import org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
import org.apache.iotdb.db.qp.logical.Operator;
-import org.apache.iotdb.db.query.control.SessionManager;
import org.apache.iotdb.db.query.control.clientsession.IClientSession;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -48,8 +47,7 @@ public class AuthorityChecker {
CommonDescriptor.getInstance().getConfig().getAdminName();
private static final Logger logger =
LoggerFactory.getLogger(AuthorityChecker.class);
- private static AuthorizerManager authorizerManager =
AuthorizerManager.getInstance();
- private static SessionManager sessionManager = SessionManager.getInstance();
+ private static final AuthorizerManager authorizerManager =
AuthorizerManager.getInstance();
private AuthorityChecker() {}
@@ -128,11 +126,7 @@ public class AuthorityChecker {
}
TSStatus status = authorizerManager.checkPath(username, allPath,
permission);
- if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- return true;
- } else {
- return false;
- }
+ return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode();
}
private static boolean checkOnePath(String username, PartialPath path, int
permission)
@@ -348,10 +342,6 @@ public class AuthorityChecker {
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:
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
index 411fbc5bbd..7e88374da7 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
@@ -94,8 +94,6 @@ public enum StatementType {
CREATE_TRIGGER,
DROP_TRIGGER,
- START_TRIGGER,
- STOP_TRIGGER,
CREATE_TEMPLATE,
SET_TEMPLATE,
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateTriggerStatement.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateTriggerStatement.java
index 6351e1238a..200b547b1c 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateTriggerStatement.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateTriggerStatement.java
@@ -115,6 +115,6 @@ public class CreateTriggerStatement extends Statement
implements IConfigStatemen
@Override
public List<? extends PartialPath> getPaths() {
- return Collections.emptyList();
+ return Collections.singletonList(pathPattern);
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DropTriggerStatement.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DropTriggerStatement.java
index a48b9e973a..3927dfe7e6 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DropTriggerStatement.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DropTriggerStatement.java
@@ -20,11 +20,13 @@
package org.apache.iotdb.db.mpp.plan.statement.metadata;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.trigger.TriggerInformation;
import org.apache.iotdb.db.mpp.plan.analyze.QueryType;
import org.apache.iotdb.db.mpp.plan.constant.StatementType;
import org.apache.iotdb.db.mpp.plan.statement.IConfigStatement;
import org.apache.iotdb.db.mpp.plan.statement.Statement;
import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
+import org.apache.iotdb.db.trigger.service.TriggerManagementService;
import java.util.Collections;
import java.util.List;
@@ -32,6 +34,8 @@ import java.util.List;
public class DropTriggerStatement extends Statement implements
IConfigStatement {
private final String triggerName;
+ private PartialPath authPath;
+
public DropTriggerStatement(String triggerName) {
super();
statementType = StatementType.DROP_TRIGGER;
@@ -52,8 +56,24 @@ public class DropTriggerStatement extends Statement
implements IConfigStatement
return QueryType.WRITE;
}
+ @Override
+ public boolean isAuthenticationRequired() {
+ if (authPath == null) {
+ TriggerInformation information =
+
TriggerManagementService.getInstance().getTriggerInformation(triggerName);
+ if (information == null) {
+ return false;
+ } else {
+ authPath = information.getPathPattern();
+ }
+ }
+ return true;
+ }
+
@Override
public List<? extends PartialPath> getPaths() {
- return Collections.emptyList();
+ return isAuthenticationRequired()
+ ? Collections.singletonList(authPath)
+ : Collections.emptyList();
}
}