Skip to content

Commit c89c44c

Browse files
author
Chen, Taiyue
committed
<feature>[ldap]: refactor LDAP login logic and add two-factor authentication support
1. Extract common method findAccountThirdPartyAccountSourceRefByName - Extract the logic of finding third-party account source reference from login method into a standalone method - Unify account lookup logic in both login and collectUserInfoIntoContext methods 2. Add two-factor authentication support - getRequiredAdditionalAuthFeature method now returns a list containing both basicLoginControl and twoFactor - Support two-factor authentication for LDAP login Resolves: ZSV-11833 Change-Id: I7578626465676e6569686a786271786b64667179
1 parent 1340bd2 commit c89c44c

4 files changed

Lines changed: 37 additions & 18 deletions

File tree

plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.zstack.core.Platform;
44
import org.zstack.header.errorcode.ErrorableValue;
5+
import org.zstack.identity.imports.entity.AccountThirdPartyAccountSourceRefVO;
56
import org.zstack.ldap.driver.LdapUtil;
67
import org.zstack.ldap.entity.LdapServerVO;
78

@@ -10,7 +11,7 @@
1011
*/
1112
public interface LdapManager {
1213
boolean isValid(String uid, String password);
13-
14+
ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword);
1415
ErrorableValue<String> findCurrentLdapServerUuid();
1516
ErrorableValue<LdapServerVO> findCurrentLdapServer();
1617

plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.zstack.header.core.ReturnValueCompletion;
1616
import org.zstack.header.errorcode.ErrorCode;
1717
import org.zstack.header.errorcode.ErrorableValue;
18+
import org.zstack.header.errorcode.OperationFailureException;
1819
import org.zstack.header.identity.*;
1920
import org.zstack.header.identity.login.*;
2021
import org.zstack.header.message.APIMessage;
@@ -407,22 +408,16 @@ public LoginType getLoginType() {
407408
return loginType;
408409
}
409410

410-
@Override
411-
public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionInfo> completion) {
411+
public ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword) {
412412
final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
413413
if (!currentLdapServer.isSuccess()) {
414-
logger.debug("failed to login by LDAP: failed to find current LdapServer: " + currentLdapServer.error.getDetails());
415-
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
416-
"Login validation failed in LDAP"));
417-
return;
414+
return ErrorableValue.ofErrorCode(currentLdapServer.error);
418415
}
419416
final LdapServerVO ldap = currentLdapServer.result;
420417

421-
String ldapLoginName = loginContext.getUsername();
422-
if (!isValid(ldapLoginName, loginContext.getPassword())) {
423-
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
418+
if (!isValid(ldapLoginName, ldapLoginPassword)) {
419+
return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
424420
"Login validation failed in LDAP"));
425-
return;
426421
}
427422

428423
String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), ldapLoginName);
@@ -432,19 +427,29 @@ public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionI
432427
.find();
433428

434429
if (vo == null) {
435-
completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
430+
return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
436431
"The ldapUid does not have a binding account."));
437-
return;
438432
}
433+
return ErrorableValue.of(vo);
434+
}
439435

436+
@Override
437+
public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionInfo> completion) {
438+
final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
439+
440+
if (!accountThirdPartyAccountSourceRef.isSuccess()) {
441+
completion.fail(accountThirdPartyAccountSourceRef.error);
442+
return;
443+
}
444+
String accountUuid = accountThirdPartyAccountSourceRef.result.getAccountUuid();
440445
final AccountState state = Q.New(AccountVO.class)
441-
.eq(AccountVO_.uuid, vo.getAccountUuid())
446+
.eq(AccountVO_.uuid, accountUuid)
442447
.select(AccountVO_.state)
443448
.findValue();
444449

445450
if (state == null || state == AccountState.Staled) {
446451
completion.fail(operr(
447-
"Account[uuid:%s] Not Found!!!", vo.getAccountUuid()));
452+
"Account[uuid:%s] Not Found!!!", accountUuid));
448453
return;
449454
}
450455
if (state == AccountState.Disabled) {
@@ -453,7 +458,7 @@ public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionI
453458
}
454459

455460
LoginSessionInfo info = new LoginSessionInfo();
456-
info.setAccountUuid(vo.getAccountUuid());
461+
info.setAccountUuid(accountUuid);
457462
completion.success(info);
458463
}
459464

@@ -478,11 +483,18 @@ public String getAccountIdByName(String username) {
478483

479484
@Override
480485
public void collectUserInfoIntoContext(LoginContext loginContext) {
481-
loginContext.setAccountUuid(getAccountIdByName(loginContext.getUsername()));
486+
ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
487+
if (!accountThirdPartyAccountSourceRef.isSuccess()) {
488+
throw new OperationFailureException(accountThirdPartyAccountSourceRef.error);
489+
}
490+
if (accountThirdPartyAccountSourceRef.result == null) {
491+
return;
492+
}
493+
loginContext.setAccountUuid(accountThirdPartyAccountSourceRef.result.getAccountUuid());
482494
}
483495

484496
@Override
485497
public List<AdditionalAuthFeature> getRequiredAdditionalAuthFeature() {
486-
return Collections.singletonList(LoginAuthConstant.basicLoginControl);
498+
return Arrays.asList(LoginAuthConstant.basicLoginControl, LoginAuthConstant.twoFactor);
487499
}
488500
}

sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public Result throwExceptionIfError() {
3737
@Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
3838
public java.lang.String verifyCode;
3939

40+
@Param(required = true, validValues = {"account","ldap"}, nonempty = true, nullElements = false, emptyString = true, noTrim = false)
41+
public java.lang.String type;
42+
4043
@Param(required = false)
4144
public java.util.List systemTags;
4245

sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public Result throwExceptionIfError() {
3737
@Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false)
3838
public java.lang.String verifyCode;
3939

40+
@Param(required = true, validValues = {"account","ldap"}, nonempty = true, nullElements = false, emptyString = true, noTrim = false)
41+
public java.lang.String type;
42+
4043
@Param(required = false)
4144
public java.util.List systemTags;
4245

0 commit comments

Comments
 (0)