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(); } }
