Skip to content

Commit e92c30e

Browse files
committed
Fix account unlock propagation for pipe password checks
1 parent 44d4f6d commit e92c30e

11 files changed

Lines changed: 113 additions & 25 deletions

File tree

integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipePermissionIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ public void testIllegalPassword() throws Exception {
595595

596596
try {
597597
statement.execute("alter pipe a2b modify source ('password'='fake')");
598+
fail();
598599
} catch (final SQLException e) {
599600
Assert.assertEquals("801: Failed to check password for pipe a2b.", e.getMessage());
600601
}

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlan.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ public static ConfigPhysicalPlan create(final ByteBuffer buffer) throws IOExcept
311311
case UpdateUserV2:
312312
case CreateUserWithRawPassword:
313313
case RenameUser:
314+
case AccountUnlock:
314315
plan = new AuthorTreePlan(configPhysicalPlanType);
315316
break;
316317
case RCreateUser:
@@ -343,6 +344,7 @@ public static ConfigPhysicalPlan create(final ByteBuffer buffer) throws IOExcept
343344
case RRevokeUserSysPri:
344345
case RRevokeRoleSysPri:
345346
case RRenameUser:
347+
case RAccountUnlock:
346348
plan = new AuthorRelationalPlan(configPhysicalPlanType);
347349
break;
348350
case ApplyConfigNode:

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ public enum ConfigPhysicalPlanType {
333333
RDropUserV2((short) 2103),
334334
RenameUser((short) 2104),
335335
RRenameUser((short) 2105),
336+
AccountUnlock((short) 2106),
336337

337338
EnableSeparationOfAdminPowers((short) 2200),
338339

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ public R process(final ConfigPhysicalPlan plan, final C context) {
104104
return visitGrantRoleToUser((AuthorTreePlan) plan, context);
105105
case RevokeRoleFromUser:
106106
return visitRevokeRoleFromUser((AuthorTreePlan) plan, context);
107+
case AccountUnlock:
108+
return visitAccountUnlock((AuthorTreePlan) plan, context);
107109
case RCreateUser:
108110
return visitRCreateUser((AuthorRelationalPlan) plan, context);
109111
case RCreateRole:
@@ -160,6 +162,8 @@ public R process(final ConfigPhysicalPlan plan, final C context) {
160162
return visitRRevokeUserSysPrivilege((AuthorRelationalPlan) plan, context);
161163
case RRevokeRoleSysPri:
162164
return visitRRevokeRoleSysPrivilege((AuthorRelationalPlan) plan, context);
165+
case RAccountUnlock:
166+
return visitRAccountUnlock((AuthorRelationalPlan) plan, context);
163167
case SetTTL:
164168
return visitTTL((SetTTLPlan) plan, context);
165169
case PipeCreateTableOrView:
@@ -310,6 +314,10 @@ public R visitRevokeRoleFromUser(final AuthorTreePlan revokeRoleFromUserPlan, fi
310314
return visitPlan(revokeRoleFromUserPlan, context);
311315
}
312316

317+
public R visitAccountUnlock(final AuthorTreePlan accountUnlockPlan, final C context) {
318+
return visitPlan(accountUnlockPlan, context);
319+
}
320+
313321
public R visitRCreateUser(final AuthorRelationalPlan rCreateUserPlan, final C context) {
314322
return visitPlan(rCreateUserPlan, context);
315323
}
@@ -426,6 +434,10 @@ public R visitRRevokeRoleSysPrivilege(
426434
return visitPlan(rRevokeRoleSysPrivilegePlan, context);
427435
}
428436

437+
public R visitRAccountUnlock(final AuthorRelationalPlan rAccountUnlockPlan, final C context) {
438+
return visitPlan(rAccountUnlockPlan, context);
439+
}
440+
429441
public R visitTTL(final SetTTLPlan setTTLPlan, final C context) {
430442
return visitPlan(setTTLPlan, context);
431443
}

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/auth/AuthorInfo.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ public static ConfigPhysicalPlanType getConfigPhysicalPlanTypeFromAuthorType(int
7474
throw new IndexOutOfBoundsException(ConfigNodeMessages.INVALID_AUTHOR_TYPE_ORDINAL);
7575
}
7676
ConfigPhysicalPlanType configPhysicalPlanType;
77-
if (authorType >= AuthorType.RENAME_USER.ordinal()) {
77+
if (authorType == AuthorType.ACCOUNT_UNLOCK.ordinal()) {
78+
return ConfigPhysicalPlanType.AccountUnlock;
79+
} else if (authorType >= AuthorType.RENAME_USER.ordinal()) {
7880
AuthorType type = AuthorType.values()[authorType];
7981
switch (type) {
8082
case RENAME_USER:
@@ -105,6 +107,8 @@ public static ConfigPhysicalPlanType getConfigPhysicalPlanTypeFromAuthorRType(in
105107
ConfigPhysicalPlanType configPhysicalPlanType;
106108
if (authorRType == AuthorRType.RENAME_USER.ordinal()) {
107109
configPhysicalPlanType = ConfigPhysicalPlanType.RRenameUser;
110+
} else if (authorRType == AuthorRType.ACCOUNT_UNLOCK.ordinal()) {
111+
configPhysicalPlanType = ConfigPhysicalPlanType.RAccountUnlock;
108112
} else {
109113
configPhysicalPlanType =
110114
ConfigPhysicalPlanType.values()[

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/auth/AuthorPlanExecutor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ public TSStatus executeAuthorNonQuery(AuthorTreePlan authorPlan) {
124124
case RenameUser:
125125
authorizer.renameUser(userName, newUsername);
126126
break;
127+
case AccountUnlock:
128+
authorizer.getUser(userName);
129+
break;
127130
case CreateUser:
128131
authorizer.createUser(userName, password);
129132
break;
@@ -241,6 +244,7 @@ public TSStatus executeRelationalAuthorNonQuery(AuthorRelationalPlan authorPlan)
241244
authorizer.renameUser(userName, newUsername);
242245
break;
243246
case RAccountUnlock:
247+
authorizer.getUser(userName);
244248
break;
245249
case RDropRole:
246250
authorizer.deleteRole(roleName);

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigPlanExecutor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ public TSStatus executeNonQueryPlan(ConfigPhysicalPlan physicalPlan)
488488
case RevokeRoleFromUserDep:
489489
case UpdateUserDep:
490490
case RenameUser:
491+
case AccountUnlock:
491492
case RCreateRole:
492493
case RCreateUser:
493494
case RDropUser:

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/sync/AuthOperationProcedure.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.iotdb.confignode.client.sync.CnToDnSyncRequestType;
2929
import org.apache.iotdb.confignode.client.sync.SyncDataNodeClientPool;
3030
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
31+
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
3132
import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
3233
import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeEnrichedPlan;
3334
import org.apache.iotdb.confignode.i18n.ProcedureMessages;
@@ -100,6 +101,11 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AuthOperationProcedu
100101
TSStatus status;
101102
req.setUsername(user);
102103
req.setRoleName(role);
104+
if (plan.getAuthorType() == ConfigPhysicalPlanType.AccountUnlock
105+
|| plan.getAuthorType() == ConfigPhysicalPlanType.RAccountUnlock) {
106+
// For account unlock, role carries the optional login address.
107+
req.setNeedDisconnect(true);
108+
}
103109
Iterator<Pair<TDataNodeConfiguration, Long>> it = dataNodesToInvalid.iterator();
104110
while (it.hasNext()) {
105111
Pair<TDataNodeConfiguration, Long> pair = it.next();

iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/sync/AuthOperationProcedureTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,34 @@ public void serializeDeserializeTest() throws IOException {
9898
fail();
9999
}
100100

101+
try {
102+
final AuthOperationProcedure proc =
103+
new AuthOperationProcedure(
104+
new AuthorTreePlan(
105+
ConfigPhysicalPlanType.AccountUnlock,
106+
"user1",
107+
"",
108+
"",
109+
"",
110+
Collections.emptySet(),
111+
false,
112+
Collections.emptyList()),
113+
datanodes,
114+
false);
115+
proc.serialize(outputStream);
116+
final ByteBuffer buffer =
117+
ByteBuffer.wrap(byteArrayOutputStream.getBuf(), 0, byteArrayOutputStream.size());
118+
119+
final AuthOperationProcedure proc2 =
120+
(AuthOperationProcedure) ProcedureFactory.getInstance().create(buffer);
121+
Assert.assertEquals(proc, proc2);
122+
buffer.clear();
123+
byteArrayOutputStream.reset();
124+
} catch (final Exception e) {
125+
e.printStackTrace();
126+
fail();
127+
}
128+
101129
try {
102130
final int begin = ConfigPhysicalPlanType.RCreateUser.ordinal();
103131
final int end = ConfigPhysicalPlanType.RRevokeRoleSysPri.ordinal();
@@ -129,5 +157,33 @@ public void serializeDeserializeTest() throws IOException {
129157
e.printStackTrace();
130158
fail();
131159
}
160+
161+
try {
162+
final AuthOperationProcedure proc =
163+
new AuthOperationProcedure(
164+
new AuthorRelationalPlan(
165+
ConfigPhysicalPlanType.RAccountUnlock,
166+
"user1",
167+
"127.0.0.1",
168+
"",
169+
"",
170+
Collections.emptySet(),
171+
false,
172+
""),
173+
datanodes,
174+
false);
175+
proc.serialize(outputStream);
176+
final ByteBuffer buffer =
177+
ByteBuffer.wrap(byteArrayOutputStream.getBuf(), 0, byteArrayOutputStream.size());
178+
179+
final AuthOperationProcedure proc2 =
180+
(AuthOperationProcedure) ProcedureFactory.getInstance().create(buffer);
181+
Assert.assertEquals(proc, proc2);
182+
buffer.clear();
183+
byteArrayOutputStream.reset();
184+
} catch (final Exception e) {
185+
e.printStackTrace();
186+
fail();
187+
}
132188
}
133189
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -424,44 +424,31 @@ private void onOperatePermissionSuccess(Object plan) {
424424

425425
@Override
426426
public SettableFuture<ConfigTaskResult> operatePermission(AuthorStatement authorStatement) {
427-
return handleAccountUnlock(
428-
authorStatement,
429-
authorStatement.getUserName(),
430-
false,
431-
() -> onOperatePermissionSuccess(authorStatement));
427+
return handleAccountUnlock(authorStatement, false);
432428
}
433429

434430
@Override
435431
public SettableFuture<ConfigTaskResult> operatePermission(
436432
RelationalAuthorStatement authorStatement) {
437-
return handleAccountUnlock(
438-
authorStatement,
439-
authorStatement.getUserName(),
440-
true,
441-
() -> onOperatePermissionSuccess(authorStatement));
433+
return handleAccountUnlock(authorStatement, true);
442434
}
443435

444436
private SettableFuture<ConfigTaskResult> handleAccountUnlock(
445-
Object authorStatement, String username, boolean isRelational, Runnable successCallback) {
437+
Object authorStatement, boolean isRelational) {
446438

447439
if (isUnlockStatement(authorStatement, isRelational)) {
448-
final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
449-
final User user;
450-
try {
451-
user = getUser(username, false);
452-
} catch (final IoTDBRuntimeException e) {
453-
future.setException(e);
454-
return future;
455-
}
456440
String loginAddr =
457441
isRelational
458442
? ((RelationalAuthorStatement) authorStatement).getLoginAddr()
459443
: ((AuthorStatement) authorStatement).getLoginAddr();
460444

461-
LoginLockManager.getInstance().unlock(user.getUserId(), loginAddr);
462-
successCallback.run();
463-
future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
464-
return future;
445+
// Reuse roleName to carry the optional login address for the internal unlock broadcast.
446+
if (isRelational) {
447+
((RelationalAuthorStatement) authorStatement).setRoleName(loginAddr);
448+
} else {
449+
((AuthorStatement) authorStatement).setRoleName(loginAddr);
450+
}
451+
return operatePermissionInternal(authorStatement, isRelational);
465452
}
466453
return operatePermissionInternal(authorStatement, isRelational);
467454
}
@@ -748,7 +735,7 @@ public Role cacheRole(String roleName, TPermissionInfoResp tPermissionInfoResp)
748735

749736
private TAuthorizerReq statementToAuthorizerReq(AuthorStatement authorStatement)
750737
throws AuthException {
751-
if (authorStatement.getAuthorType() == null) {
738+
if (authorStatement.getNodeNameList() == null) {
752739
authorStatement.setNodeNameList(new ArrayList<>());
753740
}
754741
return new TAuthorizerReq(

0 commit comments

Comments
 (0)