Caideyipi commented on code in PR #13158:
URL: https://github.com/apache/iotdb/pull/13158#discussion_r1923532268
##########
iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/CNPhysicalPlanGenerator.java:
##########
@@ -236,9 +273,10 @@ private void generateUserRolePhysicalPlan(final boolean
isUser) {
private void generateGrantRolePhysicalPlan() {
try (final DataInputStream roleInputStream =
new DataInputStream(new BufferedInputStream((inputStream)))) {
- while (roleInputStream.available() != 0) {
+ int roleNum = roleInputStream.readInt();
Review Comment:
Will this cause compatibility problem...
##########
iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4:
##########
@@ -1350,6 +1470,12 @@ CONCAT: '||';
QUESTION_MARK: '?';
SEMICOLON: ';';
+MANAGE_USER: 'MANAGE_USER';
+MANAGE_ROLE: 'MANAGE_ROLE';
+MAINTAIN: 'MAINTAIN';
Review Comment:
Keep the dictionary order .....
##########
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/ITableAuthCheckerImpl.java:
##########
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.queryengine.plan.relational.security;
+
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.commons.exception.IoTDBException;
+import org.apache.iotdb.db.auth.AuthorityChecker;
+import
org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+public class ITableAuthCheckerImpl implements ITableAuthChecker {
+
+ @Override
+ public void checkDatabaseVisibility(String userName, String databaseName) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ if (!AuthorityChecker.checkDBVisible(userName, databaseName)) {
+ throw new RuntimeException(
+ new IoTDBException("NO PERMISSION",
TSStatusCode.NO_PERMISSION.getStatusCode()));
+ }
+ }
+
+ @Override
+ public void checkDatabasePrivilege(
+ String userName, String databaseName, TableModelPrivilege privilege) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ TSStatus result =
+ AuthorityChecker.getTSStatus(
+ AuthorityChecker.checkDBPermission(
+ userName, databaseName, privilege.getPrivilegeType()),
+ privilege.getPrivilegeType(),
+ databaseName);
+ if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ throw new RuntimeException(new IoTDBException(result.getMessage(),
result.getCode()));
+ }
+ }
+
+ @Override
+ public void checkDatabasePrivilegeGrantOption(
+ String userName, String databaseName, TableModelPrivilege privilege) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ TSStatus result =
+ AuthorityChecker.getGrantOptTSStatus(
+ AuthorityChecker.checkDBPermissionGrantOption(
+ userName, databaseName, privilege.getPrivilegeType()),
+ privilege.getPrivilegeType(),
+ databaseName);
+ if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ throw new RuntimeException(new IoTDBException(result.getMessage(),
result.getCode()));
+ }
+ }
+
+ @Override
+ public void checkTablePrivilege(
+ String userName, QualifiedObjectName tableName, TableModelPrivilege
privilege) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ TSStatus result =
+ AuthorityChecker.getTSStatus(
+ AuthorityChecker.checkTablePermission(
+ userName,
+ tableName.getDatabaseName(),
+ tableName.getObjectName(),
+ privilege.getPrivilegeType()),
+ privilege.getPrivilegeType(),
+ tableName.getDatabaseName(),
+ tableName.getObjectName());
+ if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ throw new RuntimeException(new IoTDBException(result.getMessage(),
result.getCode()));
+ }
+ }
+
+ @Override
+ public void checkTablePrivilegeGrantOption(
+ String userName, QualifiedObjectName tableName, TableModelPrivilege
privilege) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ TSStatus result =
+ AuthorityChecker.getGrantOptTSStatus(
+ AuthorityChecker.checkTablePermissionGrantOption(
+ userName,
+ tableName.getDatabaseName(),
+ tableName.getObjectName(),
+ privilege.getPrivilegeType()),
+ privilege.getPrivilegeType(),
+ tableName.getDatabaseName(),
+ tableName.getObjectName());
+ if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ throw new RuntimeException(new IoTDBException(result.getMessage(),
result.getCode()));
+ }
+ }
+
+ @Override
+ public void checkTableVisibility(String userName, QualifiedObjectName
tableName) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ if (!AuthorityChecker.checkTableVisible(
+ userName, tableName.getDatabaseName(), tableName.getObjectName())) {
+ throw new RuntimeException(
+ new IoTDBException("NO PERMISSION",
TSStatusCode.NO_PERMISSION.getStatusCode()));
+ }
+ }
+
+ @Override
+ public void checkGlobalPrivilege(String userName, TableModelPrivilege
privilege) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ TSStatus result =
+ AuthorityChecker.getTSStatus(
+ AuthorityChecker.checkSystemPermission(userName,
privilege.getPrivilegeType()),
+ privilege.getPrivilegeType());
+ if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ throw new RuntimeException(new IoTDBException(result.getMessage(),
result.getCode()));
+ }
+ }
+
+ @Override
+ public void checkGlobalPrivilegeGrantOption(String userName,
TableModelPrivilege privilege) {
+ if (AuthorityChecker.SUPER_USER.equals(userName)) {
+ return;
+ }
+ TSStatus result =
+ AuthorityChecker.getGrantOptTSStatus(
+ AuthorityChecker.checkSystemPermissionGrantOption(
+ userName, privilege.getPrivilegeType()),
+ privilege.getPrivilegeType());
+ if (result.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ throw new RuntimeException(new IoTDBException(result.getMessage(),
result.getCode()));
Review Comment:
Replace them all
##########
integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBRelationalAuthIT.java:
##########
@@ -0,0 +1,350 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it.auth;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.db.it.utils.TestUtils;
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.TableClusterIT;
+import org.apache.iotdb.itbase.category.TableLocalStandaloneIT;
+import org.apache.iotdb.itbase.env.BaseEnv;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({TableLocalStandaloneIT.class, TableClusterIT.class})
+public class IoTDBRelationalAuthIT {
+ @Before
+ public void setUp() throws Exception {
+ EnvFactory.getEnv().initClusterEnvironment();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ @Test
+ public void listUserPrivileges() throws SQLException {
+ try (Connection adminCon =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement adminStmt = adminCon.createStatement()) {
+
+ adminStmt.execute("create user testuser 'password'");
+ adminStmt.execute("create database testdb");
+ adminStmt.execute("GRANT MANAGE_USER to user testuser");
+ Assert.assertThrows(
+ SQLException.class,
+ () -> {
+ adminStmt.execute("GRANT MANAGE_DATABASE to user testuser");
+ });
+ Assert.assertThrows(
+ SQLException.class,
+ () -> {
+ adminStmt.execute("GRANT read_data on database db1 to user
testuser");
+ });
+
+ adminStmt.execute("GRANT MANAGE_ROLE TO USER testuser");
+ adminStmt.execute("GRANT SELECT ON ANY TO USER testuser");
+ adminStmt.execute("GRANT INSERT ON ANY TO USER testuser");
+ adminStmt.execute("GRANT DELETE ON ANY TO USER testuser");
+ Assert.assertThrows(
+ SQLException.class,
+ () -> {
+ adminStmt.execute("GRANT SELECT ON TABLE TB to user testuser");
+ });
+ adminStmt.execute("GRANT SELECT ON DATABASE TESTDB TO USER testuser");
+ adminStmt.execute("GRANT SELECT ON DATABASE TESTDB TO USER testuser WITH
GRANT OPTION");
+
+ adminStmt.execute("use testdb");
+ adminStmt.execute("GRANT SELECT ON TABLE TB to user testuser");
+ adminStmt.execute("GRANT INSERT ON TABLE TB to user testuser with grant
option");
+ adminStmt.execute("GRANT DROP ON testdb.tb to user testuser with grant
option");
+
+ ResultSet rs = adminStmt.executeQuery("LIST PRIVILEGES OF USER
testuser");
+ Set<String> ans =
+ new HashSet<>(
+ Arrays.asList(
+ ",,MANAGE_USER,false,",
+ ",,MANAGE_ROLE,false,",
+ ",*.*,SELECT,false,",
+ ",*.*,INSERT,false,",
+ ",*.*,DELETE,false,",
+ ",testdb.*,SELECT,true,",
+ ",testdb.tb,SELECT,false,",
+ ",testdb.tb,INSERT,true,",
+ ",testdb.tb,DROP,true,"));
+ TestUtils.assertResultSetEqual(rs, "Role,Scope,Privileges,GrantOption,",
ans);
+ }
+ }
+
+ @Test
+ public void checkAuthorStatementPrivilegeCheck() throws SQLException {
+ try (Connection adminCon =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement adminStmt = adminCon.createStatement()) {
+ adminStmt.execute("create user testuser 'password'");
+ adminStmt.execute("create user testuser2 'password'");
+ adminStmt.execute("create role testrole");
+ adminStmt.execute("create database testdb");
+
+ // cannot create admin user
+ Assert.assertThrows(
+ SQLException.class,
+ () -> {
+ adminStmt.execute("CREATE USER root 'password'");
+ });
+ // cannot create admin role
+ Assert.assertThrows(
+ SQLException.class,
+ () -> {
+ adminStmt.execute("CREATE role root");
+ });
+
+ // cannot grant role to admin user
+ Assert.assertThrows(
+ SQLException.class,
+ () -> {
+ adminStmt.execute("GRANT ROLE testrole to root");
+ });
+
+ // cannot grant privileg to admin user
Review Comment:
privilege
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]