This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch Authority
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 5fe096f3efb0eeae6ba76da8d99f9849ac3dfffa
Author: JackieTien97 <[email protected]>
AuthorDate: Mon Nov 14 17:43:41 2022 +0800

    [IOTDB-4922] Support auth in create & drop trigger
---
 .../Administration-Management/Administration.md    |   2 -
 .../Administration-Management/Administration.md    |   2 -
 .../db/it/trigger/IoTDBTriggerManagementIT.java    | 104 ++++++++++++++++++++-
 .../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, 126 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..d64282fd26 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,104 @@ 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 `zm` 'zm'");
+
+      try (Connection connection2 = EnvFactory.getEnv().getConnection("zm", 
"zm");
+          Statement statement2 = connection.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) {
+          System.out.println(e.getMessage());
+        }
+
+        statement.execute("GRANT USER `zm` 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) {
+          System.out.println(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 `zm` 'zm'");
+
+      try (Connection connection2 = EnvFactory.getEnv().getConnection("zm", 
"zm");
+          Statement statement2 = connection.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) {
+          System.out.println(e.getMessage());
+        }
+
+        statement.execute("GRANT USER `zm` PRIVILEGES CREATE_TRIGGER on 
root.test.stateless.b");
+
+        try {
+          statement2.execute("drop trigger " + 
STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "a");
+          fail();
+        } catch (Exception e) {
+          System.out.println(e.getMessage());
+        }
+
+        statement.execute("GRANT USER `zm` 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();
   }
 }

Reply via email to