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 d988ea4f30a fix auth upgrade.
d988ea4f30a is described below
commit d988ea4f30a80433b6d3162c236f27d9e07cad26
Author: Colin Li <[email protected]>
AuthorDate: Tue Nov 21 10:29:06 2023 +0800
fix auth upgrade.
---
.../org/apache/iotdb/db/it/auth/IoTDBAuthIT.java | 2 +-
.../iotdb/confignode/persistence/AuthorInfo.java | 174 ++++++++++++---------
.../confignode/persistence/AuthorInfoTest.java | 134 ++++++----------
.../db/storageengine/dataregion/DataRegion.java | 2 +
.../io/LocalTextModificationAccessor.java | 3 +
.../db/auth/role/LocalFileRoleAccessorTest.java | 55 ++-----
.../db/auth/role/LocalFileRoleManagerTest.java | 124 ++++++++++-----
.../db/auth/user/LocalFileUserAccessorTest.java | 74 +++------
.../db/auth/user/LocalFileUserManagerTest.java | 48 ------
.../commons/auth/authorizer/BasicAuthorizer.java | 4 +
.../commons/auth/entity/PriPrivilegeType.java | 52 +++---
.../iotdb/commons/auth/role/BasicRoleManager.java | 92 +++++------
.../iotdb/commons/auth/user/BasicUserManager.java | 86 +++++-----
.../org/apache/iotdb/commons/utils/AuthUtils.java | 48 +++++-
.../org/apache/iotdb/commons/utils/IOUtils.java | 28 +---
15 files changed, 438 insertions(+), 488 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 e50955bd049..dc96a20a5ac 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
@@ -1092,7 +1092,7 @@ public class IoTDBAuthIT {
sql = "GRANT %s on root.** to USER user2";
adminStmt.execute(String.format(sql, item));
}
- Connection user1Con = EnvFactory.getEnv().getConnection();
+ Connection user1Con = EnvFactory.getEnv().getConnection("user1",
"password");
Statement user1Stmt = user1Con.createStatement();
ResultSet resultSet;
String ans = "";
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
index 1f7d05897af..d5c6b0ab60a 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
@@ -26,7 +26,6 @@ import org.apache.iotdb.commons.auth.authorizer.IAuthorizer;
import org.apache.iotdb.commons.auth.authorizer.OpenIdAuthorizer;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
-import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.auth.entity.User;
import org.apache.iotdb.commons.conf.CommonConfig;
@@ -60,7 +59,6 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -77,9 +75,12 @@ public class AuthorInfo implements SnapshotProcessor {
private IAuthorizer authorizer;
+ private boolean hasPrePriv = true;
+
public AuthorInfo() {
try {
authorizer = BasicAuthorizer.getInstance();
+
} catch (AuthException e) {
LOGGER.error("get user or role permissionInfo failed because ", e);
}
@@ -184,31 +185,33 @@ public class AuthorInfo implements SnapshotProcessor {
Set<Integer> permissions = authorPlan.getPermissions();
boolean grantOpt = authorPlan.getGrantOpt();
List<PartialPath> nodeNameList = authorPlan.getNodeNameList();
- if (authorType.ordinal() >= ConfigPhysicalPlanType.GrantRoleDep.ordinal()
- && authorType.ordinal() <=
ConfigPhysicalPlanType.RevokeRoleFromUserDep.ordinal()) {
- HashSet<Integer> pricopy = new HashSet<>();
- // for all privilege. the nodeNameList will be root.**
- for (int permission : permissions) {
- PriPrivilegeType type = PriPrivilegeType.values()[permission];
- if (type.isAccept()) {
- for (PrivilegeType item : type.getSubPri()) {
- pricopy.add(item.ordinal());
- }
- }
+ // We will process the new version permissions after handling all the old
version permissions.
+ // We assume that:
+ // 1. the permission logs generated by new version will always come after
the old permissions.
+ // 2. two types of permission logs will not be mixed.
+ // When we begin to handle the new version's permissions, we need to check
whether the old
+ // permissions have
+ // been processed before. The encoding and meaning of these old
permissions have changed
+ // significantly.
+ if (authorType.ordinal() >= ConfigPhysicalPlanType.CreateUserDep.ordinal()
+ && authorType.ordinal() <=
ConfigPhysicalPlanType.UpdateUserDep.ordinal()) {
+ // if meet old version's permissions, we will set pre version tag.
+ authorizer.setUserForPreVersion(true);
+ authorizer.setRoleForPreVersion(true);
+ } else {
+ if (hasPrePriv) {
+ // when we refresh our preversion's information?
+ // 1. before raftlog redoing finish.(ALL author plans in raftlog are
pre version)
+ // 2. refresh during raftlog. (pre version mixed with new version)
+ authorizer.checkUserPathPrivilege();
+ hasPrePriv = false;
}
- permissions = pricopy;
}
-
try {
switch (authorType) {
case UpdateUserDep:
- authorizer.setUserForPreVersion(true);
case UpdateUser:
- try {
- authorizer.updateUserPassword(userName, newPassword);
- } finally {
- authorizer.setUserForPreVersion(false);
- }
+ authorizer.updateUserPassword(userName, newPassword);
break;
case CreateUserDep:
AuthUtils.validatePasswordPre(password);
@@ -235,37 +238,31 @@ public class AuthorInfo implements SnapshotProcessor {
authorizer.deleteRole(roleName);
break;
case GrantRoleDep:
- authorizer.setRoleForPreVersion(true);
+ grantPrivilegeForPreVersion(false, roleName, permissions,
nodeNameList);
+ break;
case GrantRole:
- try {
- for (int permission : permissions) {
- if (!isPathRelevant(permission)) {
- authorizer.grantPrivilegeToRole(roleName, null, permission,
grantOpt);
- continue;
- }
- for (PartialPath path : nodeNameList) {
- authorizer.grantPrivilegeToRole(roleName, path, permission,
grantOpt);
- }
+ for (int permission : permissions) {
+ if (!isPathRelevant(permission)) {
+ authorizer.grantPrivilegeToRole(roleName, null, permission,
grantOpt);
+ continue;
+ }
+ for (PartialPath path : nodeNameList) {
+ authorizer.grantPrivilegeToRole(roleName, path, permission,
grantOpt);
}
- } finally {
- authorizer.setRoleForPreVersion(false);
}
break;
case GrantUserDep:
- authorizer.setUserForPreVersion(true);
+ grantPrivilegeForPreVersion(true, userName, permissions,
nodeNameList);
+ break;
case GrantUser:
- try {
- for (int permission : permissions) {
- if (!isPathRelevant(permission)) {
- authorizer.grantPrivilegeToUser(userName, null, permission,
grantOpt);
- continue;
- }
- for (PartialPath path : nodeNameList) {
- authorizer.grantPrivilegeToUser(userName, path, permission,
grantOpt);
- }
+ for (int permission : permissions) {
+ if (!isPathRelevant(permission)) {
+ authorizer.grantPrivilegeToUser(userName, null, permission,
grantOpt);
+ continue;
+ }
+ for (PartialPath path : nodeNameList) {
+ authorizer.grantPrivilegeToUser(userName, path, permission,
grantOpt);
}
- } finally {
- authorizer.setUserForPreVersion(false);
}
break;
case GrantRoleToUserDep:
@@ -273,40 +270,32 @@ public class AuthorInfo implements SnapshotProcessor {
authorizer.grantRoleToUser(roleName, userName);
break;
case RevokeUserDep:
- authorizer.setUserForPreVersion(true);
+ revokePrivilegeForPreVersion(true, userName, permissions,
nodeNameList);
+ break;
case RevokeUser:
- try {
- for (int permission : permissions) {
- if (!isPathRelevant(permission)) {
- authorizer.revokePrivilegeFromUser(userName, null, permission);
- continue;
- }
- for (PartialPath path : nodeNameList) {
- authorizer.revokePrivilegeFromUser(userName, path, permission);
- }
+ for (int permission : permissions) {
+ if (!isPathRelevant(permission)) {
+ authorizer.revokePrivilegeFromUser(userName, null, permission);
+ continue;
+ }
+ for (PartialPath path : nodeNameList) {
+ authorizer.revokePrivilegeFromUser(userName, path, permission);
}
- } finally {
- authorizer.setUserForPreVersion(false);
}
-
break;
case RevokeRoleDep:
- authorizer.setRoleForPreVersion(false);
+ revokePrivilegeForPreVersion(false, roleName, permissions,
nodeNameList);
+ break;
case RevokeRole:
- try {
- for (int permission : permissions) {
- if (!isPathRelevant(permission)) {
- authorizer.revokePrivilegeFromRole(roleName, null, permission);
- continue;
- }
- for (PartialPath path : nodeNameList) {
- authorizer.revokePrivilegeFromRole(roleName, path, permission);
- }
+ for (int permission : permissions) {
+ if (!isPathRelevant(permission)) {
+ authorizer.revokePrivilegeFromRole(roleName, null, permission);
+ continue;
+ }
+ for (PartialPath path : nodeNameList) {
+ authorizer.revokePrivilegeFromRole(roleName, path, permission);
}
- } finally {
- authorizer.setRoleForPreVersion(false);
}
-
break;
case RevokeRoleFromUserDep:
case RevokeRoleFromUser:
@@ -319,6 +308,9 @@ public class AuthorInfo implements SnapshotProcessor {
}
} catch (AuthException e) {
return RpcUtils.getStatus(e.getCode(), e.getMessage());
+ } finally {
+ authorizer.setUserForPreVersion(false);
+ authorizer.setRoleForPreVersion(false);
}
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
}
@@ -629,4 +621,44 @@ public class AuthorInfo implements SnapshotProcessor {
public void checkUserPathPrivilege() {
authorizer.checkUserPathPrivilege();
}
+
+ private void grantPrivilegeForPreVersion(
+ boolean isUser, String name, Set<Integer> permissions, List<PartialPath>
nodeNameList)
+ throws AuthException {
+ for (int permission : permissions) {
+ PriPrivilegeType type = PriPrivilegeType.values()[permission];
+ if (type.isAccept()) {
+ if (isUser) {
+ for (PartialPath path : nodeNameList) {
+ authorizer.grantPrivilegeToUser(name, path, permission, false);
+ }
+ } else {
+ for (PartialPath path : nodeNameList) {
+ authorizer.grantPrivilegeToRole(name, path, permission, false);
+ }
+ }
+ }
+ }
+ }
+
+ private void revokePrivilegeForPreVersion(
+ boolean isUser, String name, Set<Integer> permissions, List<PartialPath>
nodeNameList)
+ throws AuthException {
+ for (int permission : permissions) {
+ PriPrivilegeType type = PriPrivilegeType.values()[permission];
+ if (type.isAccept()) {
+ if (!type.isAccept()) {
+ if (isUser) {
+ for (PartialPath path : nodeNameList) {
+ authorizer.revokePrivilegeFromUser(name, path, permission);
+ }
+ } else {
+ for (PartialPath path : nodeNameList) {
+ authorizer.revokePrivilegeFromRole(name, path, permission);
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
index 26bb15d7ab3..4c741d1c361 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.utils.AuthUtils;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
import org.apache.iotdb.confignode.consensus.request.auth.AuthorPlan;
import org.apache.iotdb.confignode.consensus.response.auth.PermissionInfoResp;
@@ -671,7 +672,6 @@ public class AuthorInfoTest {
AuthorPlan authorPlan;
TSStatus status;
cleanUserAndRole();
- // After authNonQuery, preVersion tag must be false;
/*--TEST FOR USER CREATE 、UPDATE AND DROP -*/
// this operation will success for pre version.
@@ -688,7 +688,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
// this operation will success for pre version. --length~(32,64)
authorPlan =
@@ -703,7 +702,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
// this operation will fail for pre version. --length > 64
authorPlan =
@@ -718,7 +716,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.ILLEGAL_PARAMETER.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
// this operation will fail for pre version. -- contain &%*@
authorPlan =
@@ -733,7 +730,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.ILLEGAL_PARAMETER.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
// root, user1, user1234567user1234567user1234567user1234567
Assert.assertEquals(
@@ -764,7 +760,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
Assert.assertEquals(
2,
@@ -795,7 +790,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.ILLEGAL_PARAMETER.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
/*--TEST FOR ROLE CREATE AND DROP -*/
authorPlan =
@@ -810,7 +804,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forRolePreVersion());
// name longer than 32, It's ok.
authorPlan =
@@ -825,7 +818,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forRolePreVersion());
// contain wrong character, error.
authorPlan =
@@ -840,7 +832,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.ILLEGAL_PARAMETER.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forRolePreVersion());
authorPlan =
new AuthorPlan(
@@ -854,7 +845,6 @@ public class AuthorInfoTest {
new ArrayList<>());
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertFalse(BasicAuthorizer.getInstance().forRolePreVersion());
Assert.assertEquals(
1,
@@ -887,14 +877,13 @@ public class AuthorInfoTest {
"",
Collections.singleton(item.ordinal()),
false,
- new ArrayList<>());
+ Collections.singletonList(new PartialPath("root.**")));
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getUser("user1").getPathPrivilegeList().size());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getUser("user1").getSysPrivilege().size());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
// for role to grant
authorPlan =
@@ -906,14 +895,13 @@ public class AuthorInfoTest {
"",
Collections.singleton(item.ordinal()),
false,
- new ArrayList<>());
+ Collections.singletonList(new PartialPath("root.**")));
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getRole("role1").getPathPrivilegeList().size());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getRole("role1").getSysPrivilege().size());
- Assert.assertFalse(BasicAuthorizer.getInstance().forRolePreVersion());
// for user to revoke
authorPlan =
@@ -925,14 +913,13 @@ public class AuthorInfoTest {
"",
Collections.singleton(item.ordinal()),
false,
- new ArrayList<>());
+ Collections.singletonList(new PartialPath("root.**")));
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getUser("user1").getPathPrivilegeList().size());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getUser("user1").getSysPrivilege().size());
- Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
// for role to revoke
authorPlan =
@@ -944,16 +931,19 @@ public class AuthorInfoTest {
"",
Collections.singleton(item.ordinal()),
false,
- new ArrayList<>());
+ Collections.singletonList(new PartialPath("root.**")));
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getRole("role1").getPathPrivilegeList().size());
Assert.assertEquals(
0,
BasicAuthorizer.getInstance().getRole("role1").getSysPrivilege().size());
- Assert.assertFalse(BasicAuthorizer.getInstance().forRolePreVersion());
+
} else {
- if (item.isPreIsPathRelevant()) {
+ if (item == PriPrivilegeType.ALL) {
+ continue;
+ }
+ if (item.isPrePathRelevant()) {
authorPlan =
new AuthorPlan(
ConfigPhysicalPlanType.GrantUserDep,
@@ -966,51 +956,28 @@ public class AuthorInfoTest {
Collections.singletonList(new PartialPath("root.t1.*.t2")));
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- if (item.isPathRelevant()) {
- Assert.assertEquals(
- 1,
- BasicAuthorizer.getInstance()
- .getUser("user1")
- .getPathPrivileges(new PartialPath("root.t1.*.t2"))
- .size());
- Assert.assertTrue(
- BasicAuthorizer.getInstance()
- .getUser("user1")
- .getPathPrivileges(new PartialPath("root.t1.*.t2"))
- .containsAll(item.getSubPriOrd()));
-
Assert.assertFalse(BasicAuthorizer.getInstance().getUser("user1").getServiceReady());
- } else {
- Assert.assertTrue(
- BasicAuthorizer.getInstance()
- .getUser("user1")
- .getSysPrivilege()
- .containsAll(item.getSubPriOrd()));
- }
-
Assert.assertFalse(BasicAuthorizer.getInstance().forUserPreVersion());
+ Assert.assertEquals(
+ 1,
+ BasicAuthorizer.getInstance()
+ .getUser("user1")
+ .getPathPrivileges(new PartialPath("root.t1.*.t2"))
+ .size());
authorInfo.checkUserPathPrivilege();
- // path will turn to root.t1.**
- authorPlan =
- new AuthorPlan(
- ConfigPhysicalPlanType.RevokeUserDep,
- "user1",
- "",
- "",
- "",
- Collections.singleton(item.ordinal()),
- false,
- Collections.singletonList(new PartialPath("root.t1.**")));
- status = authorInfo.authorNonQuery(authorPlan);
- Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- if (item.isPathRelevant()) {
- Assert.assertEquals(
- 0,
- BasicAuthorizer.getInstance()
- .getUser("user1")
- .getPathPrivileges(new PartialPath("root.t1.**"))
- .size());
- } else {
- Assert.assertEquals(
- 0,
BasicAuthorizer.getInstance().getUser("user1").getSysPrivilege().size());
+ PartialPath path1 = AuthUtils.convertPatternPath(new
PartialPath("root.t1.*.t2"));
+ for (PrivilegeType pri : item.getSubPri()) {
+ if (pri.isPathRelevant()) {
+ Assert.assertTrue(
+ BasicAuthorizer.getInstance()
+ .getUser("user1")
+ .checkPathPrivilege(path1, pri.ordinal()));
+ BasicAuthorizer.getInstance()
+ .getUser("user1")
+ .removePathPrivilege(path1, pri.ordinal());
+ } else {
+ Assert.assertTrue(
+
BasicAuthorizer.getInstance().getUser("user1").checkSysPrivilege(pri.ordinal()));
+
BasicAuthorizer.getInstance().getUser("user1").removeSysPrivilege(pri.ordinal());
+ }
}
} else {
authorPlan =
@@ -1022,32 +989,33 @@ public class AuthorInfoTest {
"",
Collections.singleton(item.ordinal()),
false,
- Collections.emptyList());
+ Collections.singletonList(new PartialPath("root.**")));
+
status = authorInfo.authorNonQuery(authorPlan);
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
+ authorInfo.checkUserPathPrivilege();
Assert.assertTrue(
BasicAuthorizer.getInstance()
.getUser("user1")
.getSysPrivilege()
.containsAll(item.getSubSysPriOrd()));
- authorPlan =
- new AuthorPlan(
- ConfigPhysicalPlanType.RevokeUserDep,
- "user1",
- "",
- "",
- "",
- Collections.singleton(item.ordinal()),
- false,
- Collections.emptyList());
- status = authorInfo.authorNonQuery(authorPlan);
- Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
- Assert.assertEquals(
- 0,
- BasicAuthorizer.getInstance()
- .getUser("user1")
- .getPathPrivileges(new PartialPath("root.t1.**"))
- .size());
+
+ for (PrivilegeType pri : item.getSubPri()) {
+ authorPlan =
+ new AuthorPlan(
+ ConfigPhysicalPlanType.RevokeUser,
+ "user1",
+ "",
+ "",
+ "",
+ Collections.singleton(pri.ordinal()),
+ false,
+ Collections.emptyList());
+ status = authorInfo.authorNonQuery(authorPlan);
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
+ Assert.assertEquals(
+ 0,
BasicAuthorizer.getInstance().getUser("user1").getSysPrivilege().size());
+ }
}
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
index 615b86ef3a5..0e825130f97 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
@@ -2014,6 +2014,8 @@ public class DataRegion implements IDataRegionForQuery {
// we have to set modification offset to MAX_VALUE, as the
offset of source chunk may
// change after compaction
deletion.setFileOffset(Long.MAX_VALUE);
+ // 如果这个时候正在执行清理,就写入到一个 compact 的文件里面
+ // 这里一次删除会写入到两个文件里面
// write deletion into compaction modification file
tsFileResource.getCompactionModFile().write(deletion);
// write deletion into modification file to enable read during
compaction
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/io/LocalTextModificationAccessor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/io/LocalTextModificationAccessor.java
index 75c32adf5e8..0bc12abf3d8 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/io/LocalTextModificationAccessor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/io/LocalTextModificationAccessor.java
@@ -63,6 +63,8 @@ public class LocalTextModificationAccessor
*
* @param filePath the path of the file that is used for storing
modifications.
*/
+
+ // 针对每个路径都有一个 accessor
public LocalTextModificationAccessor(String filePath) {
this.filePath = filePath;
}
@@ -246,6 +248,7 @@ public class LocalTextModificationAccessor
}
private static String encodeDeletion(Deletion del) {
+ // deletion, path , fileoffest,
return del.getType()
+ SEPARATOR
+ del.getPathString()
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleAccessorTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleAccessorTest.java
index f8aeec503f5..4153c3701bd 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleAccessorTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleAccessorTest.java
@@ -20,7 +20,6 @@ package org.apache.iotdb.db.auth.role;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
-import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.auth.role.LocalFileRoleAccessor;
import org.apache.iotdb.commons.exception.IllegalPathException;
@@ -115,7 +114,11 @@ public class LocalFileRoleAccessorTest {
PathPrivilege wroPathPriv = new PathPrivilege(new
PartialPath("root.c.*.d"));
PathPrivilege wroPathPriv2 = new PathPrivilege(new
PartialPath("root.c.*.**"));
for (PriPrivilegeType item : PriPrivilegeType.values()) {
- if (item.isPreIsPathRelevant()) {
+ // ALL will never appear in file.
+ if (item.ordinal() == PriPrivilegeType.ALL.ordinal()) {
+ continue;
+ }
+ if (item.isPrePathRelevant()) {
normalPathPriv.grantPrivilege(item.ordinal(), false);
wroPathPriv.grantPrivilege(item.ordinal(), false);
wroPathPriv2.grantPrivilege(item.ordinal(), false);
@@ -123,50 +126,24 @@ public class LocalFileRoleAccessorTest {
rootPathPriv.grantPrivilege(item.ordinal(), false);
}
- // In this case, we use four path to store some privileges.
- // path1: root.** will store all privileges
- // path2: root.b.c.** will store relevant privileges
- // path3: root.c.*.d will store relevant privileges but the path will be
transformed to
- // root.c.**
- // path4: root.c.*.** will store relevant privileges but the path will be
transformed like path3
-
- // 1. for path 1:
pathPriList.add(rootPathPriv);
+ pathPriList.add(normalPathPriv);
+ pathPriList.add(wroPathPriv);
+ pathPriList.add(wroPathPriv2);
role.setPrivilegeList(pathPriList);
role.setSysPriGrantOpt(new HashSet<>());
role.setSysPrivilegeSet(new HashSet<>());
accessor.saveRoleOldVer(role);
Role newRole = accessor.loadRole("root");
assertEquals("root", newRole.getName());
- assertTrue(newRole.getServiceReady());
- assertEquals(1, newRole.getPathPrivilegeList().size());
- assertEquals(
- PrivilegeType.getPathPriCount(),
- newRole.getPathPrivilegeList().get(0).getPrivileges().size());
- assertEquals(PrivilegeType.getSysPriCount(),
newRole.getSysPrivilege().size());
- accessor.deleteRole("root");
-
- // 2. for path2:
- pathPriList.clear();
- pathPriList.add(normalPathPriv);
- role.setPrivilegeList(pathPriList);
- accessor.saveRoleOldVer(role);
- newRole = accessor.loadRole("root");
- assertTrue(newRole.getServiceReady());
- assertEquals(3,
newRole.getPathPrivilegeList().get(0).getPrivileges().size());
- assertEquals(2, newRole.getSysPrivilege().size());
- accessor.deleteRole("root");
-
- // 3. for path3 and path4
- pathPriList.clear();
- pathPriList.add(wroPathPriv2);
- pathPriList.add(wroPathPriv);
- role.setPrivilegeList(pathPriList);
- accessor.saveRoleOldVer(role);
- newRole = accessor.loadRole("root");
assertFalse(newRole.getServiceReady());
- assertEquals(3,
newRole.getPathPrivilegeList().get(0).getPrivileges().size());
- assertEquals(3,
newRole.getPathPrivilegeList().get(1).getPrivileges().size());
- assertEquals(2, newRole.getSysPrivilege().size());
+ assertEquals(4, newRole.getPathPrivilegeList().size());
+ for (PathPrivilege path : newRole.getPathPrivilegeList()) {
+ if (!path.getPath().equals(new PartialPath("root.**"))) {
+ assertEquals(17, path.getPrivileges().size());
+ } else {
+ assertEquals(33, path.getPrivileges().size());
+ }
+ }
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleManagerTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleManagerTest.java
index d4dce992912..b838ae25a96 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleManagerTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/role/LocalFileRoleManagerTest.java
@@ -20,14 +20,17 @@ package org.apache.iotdb.db.auth.role;
import org.apache.iotdb.commons.auth.AuthException;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
+import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.auth.role.LocalFileRoleManager;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.utils.AuthUtils;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.db.utils.constant.TestConstant;
+import io.jsonwebtoken.lang.Assert;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
@@ -143,45 +146,88 @@ public class LocalFileRoleManagerTest {
public void testPathCheckForUpgrade() throws AuthException,
IllegalPathException {
manager.createRole("test");
manager.setPreVersion(true);
-
- // turn to root.d.a
- manager.grantPrivilegeToRole(
- "test", new PartialPath("root.d.a"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.**
- manager.grantPrivilegeToRole(
- "test", new PartialPath("root.d*.a"),
PrivilegeType.READ_DATA.ordinal(), false);
- // turn to root.**
- manager.grantPrivilegeToRole(
- "test", new PartialPath("root.d*.a"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.**
- manager.grantPrivilegeToRole(
- "test", new PartialPath("root.*.a.b"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.ds.a.**
- manager.grantPrivilegeToRole(
- "test", new PartialPath("root.ds.a.b*"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.ds.a.b
- manager.grantPrivilegeToRole(
- "test", new PartialPath("root.ds.a.b"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- assertFalse(manager.getRole("test").getServiceReady());
- // after this operation, the user has these privileges:
- // root.d.a : read_schema
- // root.** : read_data, read_schema
- // root.ds.a.** :read_schema
- // root.ds.a.b : read_schema
+ // In this case. We will grant role some preversion. And try to refresh
its privilege.
+ // the result:
+ // 1. all privileges will be turned to current privileges.
+ // 2. all illegal paths will be turned to legal path.
+
+ // for Pre version, all global system (including ALL) will have a default
path:root.**
+ for (PriPrivilegeType item : PriPrivilegeType.values()) {
+ if (item == PriPrivilegeType.ALL) {
+ continue;
+ }
+ if (item.isAccept()) {
+ if (item.isPrePathRelevant()) {
+ // turn to root.d.a -- legal path
+ manager.grantPrivilegeToRole("test", new PartialPath("root.d.a"),
item.ordinal(), false);
+ // turn to root.ds.a.** -- illegal path
+ manager.grantPrivilegeToRole(
+ "test", new PartialPath("root.ds.a.b*"), item.ordinal(), false);
+ // will be turned to path "root.ds.a.**" like previous
+ manager.grantPrivilegeToRole(
+ "test", new PartialPath("root.ds.a.c*"), item.ordinal(), false);
+ } else {
+ manager.grantPrivilegeToRole("test", new PartialPath("root.**"),
item.ordinal(), false);
+ }
+ }
+ }
+ Assert.isTrue(manager.getRole("test").getPathPrivilegeList().size() == 4);
+ Assert.isTrue(!manager.getRole("test").getServiceReady());
manager.checkAndRefreshPathPri();
- Role role = manager.getRole("test");
- assertTrue(role.getServiceReady());
- assertEquals(4, role.getPathPrivilegeList().size());
- manager.revokePrivilegeFromRole(
- "test", new PartialPath("root.**"),
PrivilegeType.READ_SCHEMA.ordinal());
- manager.revokePrivilegeFromRole(
- "test", new PartialPath("root.**"), PrivilegeType.READ_DATA.ordinal());
- assertEquals(3, role.getPathPrivilegeList().size());
- assertTrue(
- role.checkPathPrivilege(
- new PartialPath("root.ds.a.**"),
PrivilegeType.READ_SCHEMA.ordinal()));
- assertFalse(
- role.checkPathPrivilege(
- new PartialPath("root.ds.a.**"),
PrivilegeType.READ_DATA.ordinal()));
+
+ // after refresh. we will have three path:
+ // 1. root.d.a
+ // 2. root.ds.a.**
+ // 3. root.**
+
+ // only: write_data, write_schema, read_data
+ assertEquals(3, manager.getRole("test").getPathPrivileges(new
PartialPath("root.d.a")).size());
+ assertEquals(
+ 3, manager.getRole("test").getPathPrivileges(new
PartialPath("root.ds.a.**")).size());
+ // All system privileges in root.** will be turned into system privileges
set.
+ assertEquals(0, manager.getRole("test").getPathPrivileges(new
PartialPath("root.**")).size());
+ assertEquals(
+ PrivilegeType.getSysPriCount() - 3,
manager.getRole("test").getSysPrivilege().size());
+
+ manager.getRole("test").getPathPrivilegeList().clear();
+ manager.getRole("test").getSysPrivilege().clear();
+ }
+
+ @Test
+ public void testPrivRefreshSingle() throws AuthException,
IllegalPathException {
+ manager.createRole("test");
+ manager.setPreVersion(true);
+ for (PriPrivilegeType item : PriPrivilegeType.values()) {
+ if (item == PriPrivilegeType.ALL) {
+ continue;
+ }
+ if (item.isAccept()) {
+ if (item.isPrePathRelevant()) {
+ // turn to root.d.a -- legal path
+ manager.grantPrivilegeToRole("test", new PartialPath("root.d.a"),
item.ordinal(), false);
+ // turn to root.ds.a.** -- illegal path
+ manager.grantPrivilegeToRole(
+ "test", new PartialPath("root.ds.a.b*"), item.ordinal(), false);
+ } else {
+ manager.grantPrivilegeToRole("test", new PartialPath("root.**"),
item.ordinal(), false);
+ }
+ }
+ manager.checkAndRefreshPathPri();
+ PartialPath path1 = AuthUtils.convertPatternPath(new
PartialPath("root.ds.a.b*"));
+ PartialPath path2 = new PartialPath("root.d.a");
+ for (PrivilegeType pri : item.getSubPri()) {
+ if (pri.isPathRelevant()) {
+ Assert.isTrue(manager.getRole("test").checkPathPrivilege(path1,
pri.ordinal()));
+ Assert.isTrue(manager.getRole("test").checkPathPrivilege(path2,
pri.ordinal()));
+ manager.getRole("test").removePathPrivilege(path1, pri.ordinal());
+ manager.getRole("test").removePathPrivilege(path2, pri.ordinal());
+ } else {
+
Assert.isTrue(manager.getRole("test").checkSysPrivilege(pri.ordinal()));
+ manager.getRole("test").removeSysPrivilege(pri.ordinal());
+ }
+ }
+ Assert.isTrue(manager.getRole("test").getPathPrivilegeList().isEmpty());
+ Assert.isTrue(manager.getRole("test").getSysPrivilege().isEmpty());
+ }
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserAccessorTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserAccessorTest.java
index 2113ff9c4c7..f4a9d7dd195 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserAccessorTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserAccessorTest.java
@@ -20,8 +20,6 @@ package org.apache.iotdb.db.auth.user;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
-import org.apache.iotdb.commons.auth.entity.PrivilegeType;
-import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.auth.entity.User;
import org.apache.iotdb.commons.auth.user.LocalFileUserAccessor;
import org.apache.iotdb.commons.exception.IllegalPathException;
@@ -37,7 +35,6 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -122,18 +119,20 @@ public class LocalFileUserAccessorTest {
@Test
public void testLoadOldVersion() throws IOException, IllegalPathException {
- User user = new User();
- user.setName("root");
- user.setPassword("password1");
- user.setRoleList(Collections.emptyList());
-
+ // In this test, we will store role with old func and role might have
illegal path.
+ User role = new User();
+ role.setName("root");
List<PathPrivilege> pathPriList = new ArrayList<>();
PathPrivilege rootPathPriv = new PathPrivilege(new PartialPath("root.**"));
PathPrivilege normalPathPriv = new PathPrivilege(new
PartialPath("root.b.c.**"));
PathPrivilege wroPathPriv = new PathPrivilege(new
PartialPath("root.c.*.d"));
PathPrivilege wroPathPriv2 = new PathPrivilege(new
PartialPath("root.c.*.**"));
for (PriPrivilegeType item : PriPrivilegeType.values()) {
- if (item.isPreIsPathRelevant()) {
+ // ALL will never appear in file.
+ if (item.ordinal() == PriPrivilegeType.ALL.ordinal()) {
+ continue;
+ }
+ if (item.isPrePathRelevant()) {
normalPathPriv.grantPrivilege(item.ordinal(), false);
wroPathPriv.grantPrivilege(item.ordinal(), false);
wroPathPriv2.grantPrivilege(item.ordinal(), false);
@@ -141,50 +140,25 @@ public class LocalFileUserAccessorTest {
rootPathPriv.grantPrivilege(item.ordinal(), false);
}
- // In this case, we use four path to store some privileges.
- // path1: root.** will store all privileges
- // path2: root.b.c.** will store relevant privileges
- // path3: root.c.*.d will store relevant privileges but the path will be
transformed to
- // root.c.**
- // path4: root.c.*.** will store relevant privileges but the path will be
transformed like path3
-
- // 1. for path 1:
pathPriList.add(rootPathPriv);
- user.setPrivilegeList(pathPriList);
- user.setSysPriGrantOpt(new HashSet<>());
- user.setSysPrivilegeSet(new HashSet<>());
- accessor.saveUserOldVersion(user);
- Role newRole = accessor.loadUser("root");
- assertEquals("root", newRole.getName());
- assertTrue(newRole.getServiceReady());
- assertEquals(1, newRole.getPathPrivilegeList().size());
- assertEquals(
- PrivilegeType.getPathPriCount(),
- newRole.getPathPrivilegeList().get(0).getPrivileges().size());
- assertEquals(PrivilegeType.getSysPriCount(),
newRole.getSysPrivilege().size());
- accessor.deleteUser("root");
-
- // 2. for path2:
- pathPriList.clear();
pathPriList.add(normalPathPriv);
- user.setPrivilegeList(pathPriList);
- accessor.saveUserOldVersion(user);
- newRole = accessor.loadUser("root");
- assertTrue(newRole.getServiceReady());
- assertEquals(3,
newRole.getPathPrivilegeList().get(0).getPrivileges().size());
- assertEquals(2, newRole.getSysPrivilege().size());
- accessor.deleteUser("root");
-
- // 3. for path3 and path4
- pathPriList.clear();
- pathPriList.add(wroPathPriv2);
pathPriList.add(wroPathPriv);
- user.setPrivilegeList(pathPriList);
- accessor.saveUserOldVersion(user);
- newRole = accessor.loadUser("root");
+ pathPriList.add(wroPathPriv2);
+ role.setPrivilegeList(pathPriList);
+ role.setSysPriGrantOpt(new HashSet<>());
+ role.setSysPrivilegeSet(new HashSet<>());
+ role.setRoleList(new ArrayList<>());
+ accessor.saveUserOldVersion(role);
+ User newRole = accessor.loadUser("root");
+ assertEquals("root", newRole.getName());
assertFalse(newRole.getServiceReady());
- assertEquals(3,
newRole.getPathPrivilegeList().get(0).getPrivileges().size());
- assertEquals(3,
newRole.getPathPrivilegeList().get(1).getPrivileges().size());
- assertEquals(2, newRole.getSysPrivilege().size());
+ assertEquals(4, newRole.getPathPrivilegeList().size());
+ for (PathPrivilege path : newRole.getPathPrivilegeList()) {
+ if (!path.getPath().equals(new PartialPath("root.**"))) {
+ assertEquals(17, path.getPrivileges().size());
+ } else {
+ assertEquals(33, path.getPrivileges().size());
+ }
+ }
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserManagerTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserManagerTest.java
index 5c0e964d6e7..a837df4c654 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserManagerTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/user/LocalFileUserManagerTest.java
@@ -20,8 +20,6 @@ package org.apache.iotdb.db.auth.user;
import org.apache.iotdb.commons.auth.AuthException;
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.auth.entity.User;
import org.apache.iotdb.commons.auth.user.LocalFileUserManager;
import org.apache.iotdb.commons.conf.CommonDescriptor;
@@ -185,50 +183,4 @@ public class LocalFileUserManagerTest {
assertEquals(users[i].getName(), usernames.get(i + 1));
}
}
-
- @Test
- public void testPathCheckForUpgrade() throws AuthException,
IllegalPathException {
- manager.createUser("test", "pwssord", false);
- manager.setPreVersion(true);
-
- // turn to root.d.a
- manager.grantPrivilegeToUser(
- "test", new PartialPath("root.d.a"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.**
- manager.grantPrivilegeToUser(
- "test", new PartialPath("root.d*.a"),
PrivilegeType.READ_DATA.ordinal(), false);
- // turn to root.**
- manager.grantPrivilegeToUser(
- "test", new PartialPath("root.d*.a"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.**
- manager.grantPrivilegeToUser(
- "test", new PartialPath("root.*.a.b"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.ds.a.**
- manager.grantPrivilegeToUser(
- "test", new PartialPath("root.ds.a.b*"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- // turn to root.ds.a.b
- manager.grantPrivilegeToUser(
- "test", new PartialPath("root.ds.a.b"),
PrivilegeType.READ_SCHEMA.ordinal(), false);
- assertFalse(manager.getUser("test").getServiceReady());
- // after this operation, the user has these privileges:
- // root.d.a : read_schema
- // root.** : read_data, read_schema
- // root.ds.a.** :read_schema
- // root.ds.a.b : read_schema
- manager.checkAndRefreshPathPri();
- Role role = manager.getUser("test");
- assertTrue(role.getServiceReady());
- assertEquals(4, role.getPathPrivilegeList().size());
- manager.revokePrivilegeFromUser(
- "test", new PartialPath("root.**"),
PrivilegeType.READ_SCHEMA.ordinal());
- manager.revokePrivilegeFromUser(
- "test", new PartialPath("root.**"), PrivilegeType.READ_DATA.ordinal());
- assertEquals(3, role.getPathPrivilegeList().size());
- assertTrue(
- role.checkPathPrivilege(
- new PartialPath("root.ds.a.**"),
PrivilegeType.READ_SCHEMA.ordinal()));
- assertFalse(
- role.checkPathPrivilege(
- new PartialPath("root.ds.a.**"),
PrivilegeType.READ_DATA.ordinal()));
- }
}
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 ca840a888c2..9650b4fd0a7 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
@@ -58,9 +58,13 @@ public abstract class BasicAuthorizer implements
IAuthorizer, IService {
* directly.
*/
// FOR PRE VERSION BEGIN -----
+
+ @Override
public void checkUserPathPrivilege() {
userManager.checkAndRefreshPathPri();
roleManager.checkAndRefreshPathPri();
+ userManager.setPreVersion(false);
+ roleManager.setPreVersion(false);
}
// FOR PRE VERSION END -----
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PriPrivilegeType.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PriPrivilegeType.java
index 48dc5597d76..4dee3b57421 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PriPrivilegeType.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/entity/PriPrivilegeType.java
@@ -27,13 +27,22 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+// This file contains the relationship of privilege between old and new
version.
+// To handle online upgrade from old version to new version. We need to handle
information:
+// 1. Pre privilege store in user.profile
+// 2. Pre Privilege store in raftlog.
+// Upgrade action has these stage:
+// 1. load old version's profile from snapshot
+// 2. redo raft log.
+// 3. do new version's raftlog.
+
public enum PriPrivilegeType {
- CREATE_DATABASE(true, false, PrivilegeType.MANAGE_DATABASE),
- INSERT_TIMESERIES(true, true, PrivilegeType.WRITE_DATA),
- UPDATE_TIMESERIES(true, true, PrivilegeType.WRITE_DATA),
- READ_TIMESERIES(true, true, PrivilegeType.READ_DATA),
- CREATE_TIMESERIES(true, true, PrivilegeType.WRITE_SCHEMA),
- DELETE_TIMESERIES(true, true, PrivilegeType.WRITE_SCHEMA),
+ CREATE_DATABASE(true, PrivilegeType.MANAGE_DATABASE),
+ INSERT_TIMESERIES(true, PrivilegeType.WRITE_DATA),
+ UPDATE_TIMESERIES(true, PrivilegeType.WRITE_DATA),
+ READ_TIMESERIES(true, PrivilegeType.READ_DATA),
+ CREATE_TIMESERIES(true, PrivilegeType.WRITE_SCHEMA),
+ DELETE_TIMESERIES(true, PrivilegeType.WRITE_SCHEMA),
CREATE_USER(false, PrivilegeType.MANAGE_USER),
DELETE_USER(false, PrivilegeType.MANAGE_USER),
MODIFY_PASSWORD(false),
@@ -49,10 +58,10 @@ public enum PriPrivilegeType {
REVOKE_ROLE_PRIVILEGE(false),
CREATE_FUNCTION(false, PrivilegeType.USE_UDF),
DROP_FUNCTION(false, PrivilegeType.USE_UDF),
- CREATE_TRIGGER(true, false, PrivilegeType.USE_TRIGGER),
- DROP_TRIGGER(true, false, PrivilegeType.USE_TRIGGER),
- START_TRIGGER(true, false, PrivilegeType.USE_TRIGGER),
- STOP_TRIGGER(true, false, PrivilegeType.USE_TRIGGER),
+ CREATE_TRIGGER(true, PrivilegeType.USE_TRIGGER),
+ DROP_TRIGGER(true, PrivilegeType.USE_TRIGGER),
+ START_TRIGGER(true, PrivilegeType.USE_TRIGGER),
+ STOP_TRIGGER(true, PrivilegeType.USE_TRIGGER),
CREATE_CONTINUOUS_QUERY(false, PrivilegeType.USE_CQ),
DROP_CONTINUOUS_QUERY(false, PrivilegeType.USE_CQ),
ALL(
@@ -71,8 +80,8 @@ public enum PriPrivilegeType {
PrivilegeType.READ_DATA,
PrivilegeType.READ_SCHEMA,
PrivilegeType.MAINTAIN),
- DELETE_DATABASE(true, false, PrivilegeType.MANAGE_DATABASE),
- ALTER_TIMESERIES(true, true, PrivilegeType.WRITE_SCHEMA),
+ DELETE_DATABASE(true, PrivilegeType.MANAGE_DATABASE),
+ ALTER_TIMESERIES(true, PrivilegeType.WRITE_SCHEMA),
UPDATE_TEMPLATE(false),
READ_TEMPLATE(false),
APPLY_TEMPLATE(true, PrivilegeType.WRITE_SCHEMA),
@@ -93,28 +102,17 @@ public enum PriPrivilegeType {
;
boolean accept = false;
- private final boolean isPathRelevant;
private final boolean preIsPathRelevant;
private final List<PrivilegeType> refPri = new ArrayList<>();
PriPrivilegeType(boolean accept) {
this.accept = accept;
- this.isPathRelevant = false;
- this.preIsPathRelevant = false;
- }
-
- PriPrivilegeType(boolean isPathRelevant, PrivilegeType... privilegeTypes) {
- this.accept = true;
- this.isPathRelevant = isPathRelevant;
this.preIsPathRelevant = false;
- this.refPri.addAll(Arrays.asList(privilegeTypes));
}
- PriPrivilegeType(
- boolean preIsPathRelevant, boolean isPathRelevant, PrivilegeType...
privilegeTypes) {
+ PriPrivilegeType(boolean preIsPathRelevant, PrivilegeType... privilegeTypes)
{
this.accept = true;
this.preIsPathRelevant = preIsPathRelevant;
- this.isPathRelevant = isPathRelevant;
this.refPri.addAll(Arrays.asList(privilegeTypes));
}
@@ -122,12 +120,8 @@ public enum PriPrivilegeType {
return this.accept;
}
- public boolean isPathRelevant() {
- return this.isPathRelevant;
- }
-
@TestOnly
- public boolean isPreIsPathRelevant() {
+ public boolean isPrePathRelevant() {
return this.preIsPathRelevant;
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
index e43bba4f41f..f0994200c56 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
@@ -19,10 +19,9 @@
package org.apache.iotdb.commons.auth.role;
import org.apache.iotdb.commons.auth.AuthException;
-import org.apache.iotdb.commons.auth.entity.PathPrivilege;
+import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.concurrent.HashLock;
-import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.utils.AuthUtils;
import org.apache.iotdb.commons.utils.TestOnly;
@@ -46,7 +45,6 @@ public abstract class BasicRoleManager implements
IRoleManager {
protected Map<String, Role> roleMap;
protected IRoleAccessor accessor;
protected HashLock lock;
-
private boolean preVersion = false;
BasicRoleManager(LocalFileRoleAccessor accessor) {
@@ -97,19 +95,29 @@ public abstract class BasicRoleManager implements
IRoleManager {
throw new AuthException(
TSStatusCode.ROLE_NOT_EXIST, String.format("No such role %s",
rolename));
}
- if (path != null) {
- if (preVersion) {
- AuthUtils.validatePath(path);
- if (role.getServiceReady()) {
- try {
- AuthUtils.validatePatternPath(path);
- } catch (AuthException e) {
- role.setServiceReady(false);
- }
+
+ // Pre version's operation:
+ // all privileges are stored in path privileges.
+ // global privileges will come with root.**
+ // need to handle privileges ALL there.
+ if (preVersion) {
+ AuthUtils.validatePath(path);
+ if (privilegeId == PriPrivilegeType.ALL.ordinal()) {
+ for (PriPrivilegeType type : PriPrivilegeType.values()) {
+ role.addPathPrivilege(path, type.ordinal(), false);
}
} else {
- AuthUtils.validatePatternPath(path);
+ role.addPathPrivilege(path, privilegeId, false);
+ }
+ // mark that the user has pre Version's privilege.
+ if (role.getServiceReady()) {
+ role.setServiceReady(false);
}
+ return;
+ }
+
+ if (path != null) {
+ AuthUtils.validatePatternPath(path);
role.addPathPrivilege(path, privilegeId, grantOpt);
} else {
role.getSysPrivilege().add(privilegeId);
@@ -133,29 +141,22 @@ public abstract class BasicRoleManager implements
IRoleManager {
TSStatusCode.ROLE_NOT_EXIST, String.format("No such role %s",
rolename));
}
if (preVersion) {
- if (path != null) {
- if (!AuthUtils.hasPrivilege(path, privilegeId,
role.getPathPrivilegeList())) {
- return false;
- }
- AuthUtils.validatePath(path);
- AuthUtils.removePrivilegePre(path, privilegeId,
role.getPathPrivilegeList());
- } else {
- if (role.getSysPrivilege().contains(privilegeId)) {
- return false;
- }
- role.getSysPrivilege().remove(privilegeId);
- }
- } else {
- if (!role.hasPrivilegeToRevoke(path, privilegeId)) {
+ if (!AuthUtils.hasPrivilege(path, privilegeId,
role.getPathPrivilegeList())) {
return false;
}
- if (path != null) {
- AuthUtils.validatePatternPath(path);
- role.removePathPrivilege(path, privilegeId);
- } else {
- role.getSysPrivilege().remove(privilegeId);
- role.getSysPriGrantOpt().remove(privilegeId);
- }
+ AuthUtils.removePrivilegePre(path, privilegeId,
role.getPathPrivilegeList());
+ return true;
+ }
+
+ if (!role.hasPrivilegeToRevoke(path, privilegeId)) {
+ return false;
+ }
+ if (path != null) {
+ AuthUtils.validatePatternPath(path);
+ role.removePathPrivilege(path, privilegeId);
+ } else {
+ role.getSysPrivilege().remove(privilegeId);
+ role.getSysPriGrantOpt().remove(privilegeId);
}
return true;
} finally {
@@ -216,27 +217,8 @@ public abstract class BasicRoleManager implements
IRoleManager {
@Override
public void checkAndRefreshPathPri() {
roleMap.forEach(
- (rolename, role) -> {
- if (!role.getServiceReady()) {
- List<PathPrivilege> priCopy = new ArrayList<>();
- for (PathPrivilege pathPri : role.getPathPrivilegeList()) {
- try {
- AuthUtils.validatePatternPath(pathPri.getPath());
- priCopy.add(pathPri);
- } catch (AuthException e) {
- PartialPath path = pathPri.getPath();
- try {
- for (Integer pri : pathPri.getPrivileges()) {
- AuthUtils.addPrivilege(AuthUtils.convertPatternPath(path),
pri, priCopy, false);
- }
- } catch (IllegalPathException illegalE) {
- //
- }
- }
- }
- role.setPrivilegeList(priCopy);
- }
- role.setServiceReady(true);
+ (rolename, user) -> {
+ AuthUtils.checkAndRefreshPri(user);
});
}
}
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 473450cc49b..04edf749bd2 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
@@ -20,6 +20,7 @@ package org.apache.iotdb.commons.auth.user;
import org.apache.iotdb.commons.auth.AuthException;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
+import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.auth.entity.User;
import org.apache.iotdb.commons.concurrent.HashLock;
@@ -176,19 +177,27 @@ public abstract class BasicUserManager implements
IUserManager {
throw new AuthException(
TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR,
username));
}
- if (path != null) {
- if (preVersion) {
- AuthUtils.validatePath(path);
- if (user.getServiceReady()) {
- try {
- AuthUtils.validatePatternPath(path);
- } catch (AuthException e) {
- user.setServiceReady(false);
- }
+ // Pre version's operation:
+ // all privileges are stored in path privileges.
+ // global privileges will come with root.**
+ // need to handle privileges ALL there.
+ if (preVersion) {
+ AuthUtils.validatePath(path);
+ if (privilegeId == PriPrivilegeType.ALL.ordinal()) {
+ for (PriPrivilegeType type : PriPrivilegeType.values()) {
+ user.addPathPrivilege(path, type.ordinal(), false);
}
} else {
- AuthUtils.validatePatternPath(path);
+ user.addPathPrivilege(path, privilegeId, false);
+ }
+ // mark that the user has pre Version's privilege.
+ if (user.getServiceReady()) {
+ user.setServiceReady(false);
}
+ return true;
+ }
+ if (path != null) {
+ AuthUtils.validatePatternPath(path);
user.addPathPrivilege(path, privilegeId, grantOpt);
} else {
user.addSysPrivilege(privilegeId);
@@ -213,30 +222,24 @@ public abstract class BasicUserManager implements
IUserManager {
TSStatusCode.USER_NOT_EXIST, String.format(NO_SUCH_USER_ERROR,
username));
}
if (preVersion) {
- if (path != null) {
- if (!AuthUtils.hasPrivilege(path, privilegeId,
user.getPathPrivilegeList())) {
- return false;
- }
- AuthUtils.validatePath(path);
- AuthUtils.removePrivilegePre(path, privilegeId,
user.getPathPrivilegeList());
- } else {
- if (!user.getSysPrivilege().contains(privilegeId)) {
- return false;
- }
- user.getSysPrivilege().remove(privilegeId);
- }
- } else {
- if (!user.hasPrivilegeToRevoke(path, privilegeId)) {
+ if (!AuthUtils.hasPrivilege(path, privilegeId,
user.getPathPrivilegeList())) {
return false;
}
- if (path != null) {
- AuthUtils.validatePatternPath(path);
- user.removePathPrivilege(path, privilegeId);
- } else {
- user.getSysPrivilege().remove(privilegeId);
- user.getSysPriGrantOpt().remove(privilegeId);
- }
+ AuthUtils.removePrivilegePre(path, privilegeId,
user.getPathPrivilegeList());
+ return true;
+ }
+
+ if (!user.hasPrivilegeToRevoke(path, privilegeId)) {
+ return false;
}
+ if (path != null) {
+ AuthUtils.validatePatternPath(path);
+ user.removePathPrivilege(path, privilegeId);
+ } else {
+ user.getSysPrivilege().remove(privilegeId);
+ user.getSysPriGrantOpt().remove(privilegeId);
+ }
+
return true;
} finally {
lock.writeUnlock(username);
@@ -375,26 +378,7 @@ public abstract class BasicUserManager implements
IUserManager {
public void checkAndRefreshPathPri() {
userMap.forEach(
(rolename, user) -> {
- if (!user.getServiceReady()) {
- List<PathPrivilege> priCopy = new ArrayList<>();
- for (PathPrivilege pathPri : user.getPathPrivilegeList()) {
- try {
- AuthUtils.validatePatternPath(pathPri.getPath());
- priCopy.add(pathPri);
- } catch (AuthException e) {
- PartialPath path = pathPri.getPath();
- try {
- for (Integer pri : pathPri.getPrivileges()) {
- AuthUtils.addPrivilege(AuthUtils.convertPatternPath(path),
pri, priCopy, false);
- }
- } catch (IllegalPathException illegalE) {
- //
- }
- }
- }
- user.setPrivilegeList(priCopy);
- }
- user.setServiceReady(true);
+ AuthUtils.checkAndRefreshPri(user);
});
}
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
index ab862280e26..87e277ac76e 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
@@ -20,7 +20,9 @@ package org.apache.iotdb.commons.utils;
import org.apache.iotdb.commons.auth.AuthException;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
+import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.exception.IllegalPathException;
@@ -371,7 +373,12 @@ public class AuthUtils {
while (it.hasNext()) {
PathPrivilege pathPri = it.next();
if (pathPri.getPath().equals(path)) {
- pathPri.revokePrivilege(privilegeId);
+ if (privilegeId != PriPrivilegeType.ALL.ordinal()) {
+ pathPri.revokePrivilege(privilegeId);
+ } else {
+ it.remove();
+ return;
+ }
if (pathPri.getPrivileges().isEmpty()) {
it.remove();
}
@@ -444,4 +451,43 @@ public class AuthUtils {
}
return paths;
}
+
+ public static void checkAndRefreshPri(Role role) {
+ if (role.getServiceReady()) {
+ return;
+ }
+ Set<Integer> sysPriCopy = role.getSysPrivilege();
+ List<PathPrivilege> priCopy = role.getPathPrivilegeList();
+ role.setSysPrivilegeSet(new HashSet<>());
+ role.setPrivilegeList(new ArrayList<>());
+
+ // Pre version's privileges were stored in path list;
+ for (PathPrivilege pathPri : priCopy) {
+ PartialPath path = pathPri.getPath();
+ for (int prePri : pathPri.getPrivileges()) {
+ PriPrivilegeType type = PriPrivilegeType.values()[prePri];
+ if (type.isAccept()) {
+ for (PrivilegeType curType : type.getSubPri()) {
+ if (curType.isPathRelevant()) {
+ try {
+ AuthUtils.validatePatternPath(path);
+ } catch (AuthException e) {
+ try {
+ path = AuthUtils.convertPatternPath(path);
+ } catch (IllegalPathException illegalE) {
+ // will never get here
+ String[] str = {"root", "**"};
+ path = new PartialPath(str);
+ }
+ }
+ role.addPathPrivilege(path, curType.ordinal(), false);
+ } else {
+ role.addSysPrivilege(curType.ordinal());
+ }
+ }
+ }
+ }
+ }
+ role.setServiceReady(true);
+ }
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/IOUtils.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/IOUtils.java
index 093072f28b8..2cc51d15d15 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/IOUtils.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/IOUtils.java
@@ -18,10 +18,8 @@
*/
package org.apache.iotdb.commons.utils;
-import org.apache.iotdb.commons.auth.AuthException;
import org.apache.iotdb.commons.auth.entity.PathPrivilege;
import org.apache.iotdb.commons.auth.entity.PriPrivilegeType;
-import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.auth.entity.Role;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.path.PartialPath;
@@ -198,6 +196,10 @@ public class IOUtils {
}
}
+ // Because pre version's privilege will stored by path + privilege
+ // This func will turn the privilege info into role's path privileges.
+ // for the global privilege, they were stored by root + privilege.
+
public static void loadRolePrivilege(
Role role, DataInputStream inputStream, String encoding,
ThreadLocal<byte[]> strBufferLocal)
throws IOException, IllegalPathException {
@@ -207,34 +209,18 @@ public class IOUtils {
for (int i = 0; i < pathPriNum; i++) {
String path = IOUtils.readString(inputStream, encoding, strBufferLocal);
PartialPath ppath = new PartialPath(path);
- if (role.getServiceReady()) {
- try {
- AuthUtils.validatePatternPath(ppath);
- } catch (AuthException e) {
- role.setServiceReady(false);
- }
- }
PathPrivilege pathPriv = new PathPrivilege(ppath);
int priNum = inputStream.readInt();
- boolean isPathRelevant = false;
for (int j = 0; j < priNum; j++) {
PriPrivilegeType priType =
PriPrivilegeType.values()[inputStream.readInt()];
if (priType.isAccept()) {
- for (PrivilegeType item : priType.getSubPri()) {
- if (item.isPathRelevant()) {
- pathPriv.grantPrivilege(item.ordinal(), false);
- isPathRelevant = true;
- } else {
- role.getSysPrivilege().add(item.ordinal());
- }
- }
+ pathPriv.grantPrivilege(priType.ordinal(), false);
}
}
- if (isPathRelevant) {
- pathPrivilegeList.add(pathPriv);
- }
+ pathPrivilegeList.add(pathPriv);
}
role.setPrivilegeList(pathPrivilegeList);
+ role.setServiceReady(false);
}
/**