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

haonan pushed a commit to branch rc/1.3.1
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 3a6dcc64be755934284f38939b3719e4aa729123
Author: Colin Li <[email protected]>
AuthorDate: Wed Feb 28 08:37:54 2024 +0800

    fix.root privileges lost and grant role
---
 .../org/apache/iotdb/db/it/auth/IoTDBAuthIT.java   |  2 ++
 .../org/apache/iotdb/db/auth/entity/RoleTest.java  | 31 ++++++++++++++++------
 .../commons/auth/authorizer/BasicAuthorizer.java   | 10 +++++++
 .../org/apache/iotdb/commons/auth/entity/Role.java | 14 +++++++++-
 .../iotdb/commons/auth/user/BasicUserManager.java  | 15 ++++++++++-
 5 files changed, 62 insertions(+), 10 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java
index 95e3e6dcf1f..25e1b6833f9 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java
@@ -906,6 +906,8 @@ public class IoTDBAuthIT {
       adminStatement.execute("CREATE USER user02 'pass1234'");
       adminStatement.execute("CREATE ROLE manager");
       adminStatement.execute("GRANT MANAGE_ROLE on root.** TO USER user01");
+      Assert.assertThrows(
+          SQLException.class, () -> adminStatement.execute("GRANT role manager 
to `root`"));
     }
 
     try (Connection userCon = EnvFactory.getEnv().getConnection("user01", 
"pass1234");
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/entity/RoleTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/entity/RoleTest.java
index 114a84d1304..8b527eb235e 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/entity/RoleTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/entity/RoleTest.java
@@ -19,9 +19,10 @@
 package org.apache.iotdb.db.auth.entity;
 
 import org.apache.iotdb.commons.auth.entity.PathPrivilege;
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
 import org.apache.iotdb.commons.auth.entity.Role;
+import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.exception.IllegalPathException;
-import org.apache.iotdb.commons.exception.IllegalPrivilegeException;
 import org.apache.iotdb.commons.path.PartialPath;
 
 import org.junit.Assert;
@@ -48,13 +49,27 @@ public class RoleTest {
         "Role{name='role', pathPrivilegeList=[root.ln : "
             + "WRITE_DATA READ_SCHEMA_with_grant_option], 
systemPrivilegeSet=[]}",
         role1.toString());
-  }
 
-  @Test
-  public void TestRole_GrantAndRevoke() throws IllegalPrivilegeException, 
IllegalPathException {
-    Role role = new Role("role");
-    PathPrivilege pathPrivilege = new PathPrivilege(new 
PartialPath("root.ln"));
-    role.setPrivilegeList(Collections.singletonList(pathPrivilege));
-    //    role.
+    Role admin = new Role("root");
+    PartialPath rootPath = new PartialPath(IoTDBConstant.PATH_ROOT + ".**");
+    PathPrivilege pathPri = new PathPrivilege(rootPath);
+    for (PrivilegeType item : PrivilegeType.values()) {
+      if (!item.isPathRelevant()) {
+        admin.getSysPrivilege().add(item.ordinal());
+        admin.getSysPriGrantOpt().add(item.ordinal());
+      } else {
+        pathPri.grantPrivilege(item.ordinal(), true);
+      }
+    }
+    admin.getPathPrivilegeList().add(pathPri);
+    Assert.assertEquals(
+        "Role{name='root', pathPrivilegeList=[root.** : READ_DAT"
+            + "A_with_grant_option WRITE_DATA_with_grant_option 
READ_SCHEMA_with"
+            + "_grant_option WRITE_SCHEMA_with_grant_option], 
systemPrivilegeSet=[MANAGE_ROLE"
+            + "_with_grant_option , USE_UDF_with_grant_option , 
USE_CQ_with_grant_option , USE"
+            + "_PIPE_with_grant_option , USE_TRIGGER_with_grant_option , 
MANAGE_DATABASE_with_g"
+            + "rant_option , MANAGE_USER_with_grant_option , 
MAINTAIN_with_grant_option , EXTEND"
+            + "_TEMPLATE_with_grant_option , USE_MODEL_with_grant_option ]}",
+        admin.toString());
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
index e61982ff65b..7ccc17e33c6 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
@@ -230,6 +230,11 @@ public abstract class BasicAuthorizer implements 
IAuthorizer, IService {
 
   @Override
   public void grantRoleToUser(String roleName, String username) throws 
AuthException {
+    if (isAdmin(username)) {
+      throw new AuthException(
+          TSStatusCode.NO_PERMISSION, "Invalid operation, cannot grant role to 
administrator ");
+    }
+
     Role role = roleManager.getRole(roleName);
     if (role == null) {
       throw new AuthException(
@@ -252,6 +257,11 @@ public abstract class BasicAuthorizer implements 
IAuthorizer, IService {
 
   @Override
   public void revokeRoleFromUser(String roleName, String username) throws 
AuthException {
+    if (isAdmin(username)) {
+      throw new AuthException(
+          TSStatusCode.NO_PERMISSION, "Invalid operation, cannot revoke role 
from administrator ");
+    }
+
     Role role = roleManager.getRole(roleName);
     if (role == null) {
       throw new AuthException(
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/Role.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/Role.java
index b644ecc369c..2fbd4914af0 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/Role.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/Role.java
@@ -311,7 +311,19 @@ public class Role {
         + ", pathPrivilegeList="
         + pathPrivilegeList
         + ", systemPrivilegeSet="
-        + sysPrivilegeSet
+        + sysPriToString()
         + '}';
   }
+
+  private Set<String> sysPriToString() {
+    Set<String> priSet = new HashSet<>();
+    for (Integer pri : sysPrivilegeSet) {
+      StringBuilder str = new 
StringBuilder(String.valueOf(PrivilegeType.values()[pri].toString()));
+      if (sysPriGrantOpt.contains(pri)) {
+        str.append("_with_grant_option ");
+      }
+      priSet.add(str.toString());
+    }
+    return priSet;
+  }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
index b40417cb534..774cfe5a1e8 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
@@ -82,7 +82,7 @@ public abstract class BasicUserManager implements 
IUserManager {
     this.accessor = accessor;
     this.lock = new HashLock();
 
-    reset();
+    init();
   }
 
   /**
@@ -119,7 +119,9 @@ public abstract class BasicUserManager implements 
IUserManager {
           pathPri.grantPrivilege(item.ordinal(), true);
         }
       }
+      admin.getPathPrivilegeList().clear();
       admin.getPathPrivilegeList().add(pathPri);
+      admin.setServiceReady(true);
     } catch (IllegalPathException e) {
       // This error only leads to  a lack of permissions for list.
       LOGGER.warn("Got a wrong path for root to init");
@@ -311,6 +313,17 @@ public abstract class BasicUserManager implements 
IUserManager {
     }
   }
 
+  // If system.users is empty, it means we are init our system, so init an 
admin user.
+  // If system.user is not empty when we start system, it means we will boost 
our system with
+  // snapshot data,
+  // init admin when we load snapshot.
+  private void init() throws AuthException {
+    this.accessor.reset();
+    if (accessor.listAllUsers().isEmpty()) {
+      initAdmin();
+    }
+  }
+
   @Override
   public void reset() throws AuthException {
     accessor.reset();

Reply via email to