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 cb93f12ca0a fix.root privileges lost and grant role
cb93f12ca0a is described below
commit cb93f12ca0a5cf99e8e6ff1121764cb7d02820d9
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();