Skip to content

<feature>[ldap]: refactor LDAP login logic and add two-factor authentication support#3725

Open
ZStack-Robot wants to merge 2 commits intozsv_5.0.0from
sync/zstackio/ZSV-11833@@2
Open

<feature>[ldap]: refactor LDAP login logic and add two-factor authentication support#3725
ZStack-Robot wants to merge 2 commits intozsv_5.0.0from
sync/zstackio/ZSV-11833@@2

Conversation

@ZStack-Robot
Copy link
Copy Markdown
Collaborator

  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

sync from gitlab !9594

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

新增 LDAP 辅助方法 findAccountThirdPartyAccountSourceRefByName;登录与用户信息采集流程改为基于该方法获取 AccountThirdPartyAccountSourceRefVOaccountUuid;为两项 SDK 两因素操作添加必需参数 type"account""ldap")。

Changes

Cohort / File(s) Summary
LDAP 管理器接口与实现
plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java, plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java
在接口中新增方法 findAccountThirdPartyAccountSourceRefByName(String,String);实现中新增该 helper 并调整 login(...)collectUserInfoIntoContext(...)getAccountIdByName(...) 使用返回的 accountUuid,并在 getRequiredAdditionalAuthFeature() 中加入 twoFactor
SDK 两因素认证操作
sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java, sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java
为两个 Action 添加必需字段 typeString),约束为 validValues={"account","ldap"} 且为非空。
测试驱动重命名
testlib/src/main/java/org/zstack/testlib/identity/ldap/LdapDriverSimulator.groovy, testlib/src/main/java/org/zstack/testlib/identity/ldap/LdapVirtualEndpointSpec.groovy
将测试驱动类由 LdapDriverForTest 重命名为 LdapDriverSimulator,并在测试替身中使用新类,回调字段保持不变。

Sequence Diagram(s)

sequenceDiagram
    participant 客户端 as Client
    participant LDAP管理 as LdapManagerImpl
    participant LDAP服 as LDAP
    participant 数据库 as DB

    客户端->>LDAP管理: 发起 login 或 collectUserInfo 请求(含凭据)
    LDAP管理->>LDAP管理: 解析当前 LDAP server UUID 并计算 full‑DN
    LDAP管理->>数据库: 查询 AccountThirdPartyAccountSourceRefVO(ldapUuid, DN)
    数据库-->>LDAP管理: 返回 AccountThirdPartyAccountSourceRefVO (含 accountUuid) 或 错误/空
    LDAP管理->>LDAP服: 使用提供凭据尝试绑定(验证凭据)
    LDAP服-->>LDAP管理: 绑定成功 / 失败
    LDAP管理->>客户端: 返回 LoginSessionInfo(含 accountUuid)或 返回错误
Loading

预估代码审查工作量

🎯 4 (Complex) | ⏱️ ~45 分钟

诗歌

🐰 我在代码林间跳跃,翻开新径寻 UUID,
LDAP 引路映全名,凭证一验便不疑,
type 分岔两条路,双因守护更稳妥,
小兔闻香轻一跃,改动落叶随风起 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main changes: refactoring LDAP login logic and adding two-factor authentication support, which aligns with the changeset.
Description check ✅ Passed The PR description clearly describes the key changes: extracting findAccountThirdPartyAccountSourceRefByName method and adding two-factor authentication support for LDAP login, which directly relates to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/zstackio/ZSV-11833@@2

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java`:
- Around line 12-15: 为接口方法添加 Javadoc 注释:为 LdapManager 接口中的 isValid,
findAccountThirdPartyAccountSourceRefByName 和 findCurrentLdapServerUuid
三个方法补充明确的
Javadoc,说明每个方法的行为语义(例如是否会进行认证)、参数含义(uid、password、ldapLoginName、ldapLoginPassword)、返回值含义(何时返回
true/false、ErrorableValue 中可能包含的 ErrorCode/错误情形)以及是否会抛出异常或返回
null/空值;同时移除任何多余的访问修饰符(接口方法不应显式声明 public)。确保注释使用标准 Javadoc
标签(@param、@return、@throws 如适用)并覆盖边界/失败场景以避免语义漂移。

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 485-493: Summary: collectUserInfoIntoContext() was changed to call
findAccountThirdPartyAccountSourceRefByName(...) which performs LDAP password
validation and can throw, turning this helper into a primary authentication step
and conflicting with actions like GetTwoFactorAuthenticationSecretAction that
rely on isSuppressCredentialCheck = true. Fix: revert
collectUserInfoIntoContext() to only resolve accountUuid by username (do not
validate credentials or throw on LDAP auth failure) — either call or add a
lookup method that only maps username → AccountThirdPartyAccountSourceRefVO
without checking the password, or add a flag parameter to
findAccountThirdPartyAccountSourceRefByName(...) to skip credential validation;
ensure only authenticate()/login() performs LDAP password checks and that
collectUserInfoIntoContext() returns quietly when the lookup cannot resolve an
account instead of throwing.
- Around line 411-420: The code fetches currentLdapServer once in
findAccountThirdPartyAccountSourceRefByName but then calls isValid(...) which
internally calls findCurrentLdapServer() again, risking using different LDAP
servers in one auth flow; change validation to use the same LdapServerVO
snapshot: update isValid to accept the LdapServerVO (e.g., add
isValid(LdapServerVO ldap, String ldapLoginName, String ldapLoginPassword) or an
overload) and call that from findAccountThirdPartyAccountSourceRefByName using
the local variable ldap so all checks (password validation and DN/bind lookup)
use the same ldap instance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4a343e3c-d552-4bf2-ad9b-a1f02c6f7dd0

📥 Commits

Reviewing files that changed from the base of the PR and between 1340bd2 and c89c44c.

📒 Files selected for processing (4)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

Comment on lines 12 to 15
public interface LdapManager {
boolean isValid(String uid, String password);

ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword);
ErrorableValue<String> findCurrentLdapServerUuid();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

给新接口方法补上 Javadoc。

这是对外契约,当前只看签名无法判断这里是否一定会做认证、失败时会返回哪些 ErrorCode,后续实现和调用方都容易出现语义漂移。

As per coding guidelines, “接口方法不应有多余的修饰符(例如 public),且必须配有有效的 Javadoc 注释。”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java` around lines 12 -
15, 为接口方法添加 Javadoc 注释:为 LdapManager 接口中的 isValid,
findAccountThirdPartyAccountSourceRefByName 和 findCurrentLdapServerUuid
三个方法补充明确的
Javadoc,说明每个方法的行为语义(例如是否会进行认证)、参数含义(uid、password、ldapLoginName、ldapLoginPassword)、返回值含义(何时返回
true/false、ErrorableValue 中可能包含的 ErrorCode/错误情形)以及是否会抛出异常或返回
null/空值;同时移除任何多余的访问修饰符(接口方法不应显式声明 public)。确保注释使用标准 Javadoc
标签(@param、@return、@throws 如适用)并覆盖边界/失败场景以避免语义漂移。

@zstack-robot-2
Copy link
Copy Markdown
Collaborator

Comment from yaohua.wu:

Review: MR !9594 — ZSV-11833

MR 概要:重构 LDAP 登录逻辑,提取公共方法 findAccountThirdPartyAccountSourceRefByName,并为 LDAP 登录添加双因子认证(2FA)支持。

Jira 背景:ZSV-11833 要求 AD/LDAP 账号支持双因子认证。用户流程为:启用 2FA → 添加 LDAP 服务器 → 调用 GetTwoFactorAuthenticationSecretAction 获取 secret → 导入认证器 APP → 登录时附加 TOTP 验证码。


🔴 Critical — collectUserInfoIntoContext() 不应执行凭据校验

文件plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java,约第 485–493 行

重构后 collectUserInfoIntoContext() 调用了 findAccountThirdPartyAccountSourceRefByName(),而该方法内部执行了 isValid() 进行 LDAP 密码校验,失败时直接 throw new OperationFailureException

问题collectUserInfoIntoContext() 的语义是「上下文信息收集」,用于在认证前填充 loginContext.accountUuid,不应该承担主认证职责。在双因子认证流程中,GetTwoFactorAuthenticationSecretAction 等操作依赖 isSuppressCredentialCheck = true 来跳过凭据校验。重构后,这些操作在上下文收集阶段就会因 LDAP 密码校验失败而抛错,违反了 suppress 语义。

建议:将「按用户名解析绑定账号」和「校验 LDAP 密码」拆开。新增一个仅做账号查找的方法(如 findAccountSourceRefByNameOnly),collectUserInfoIntoContext() 调用该方法仅解析 accountUuid,不做密码校验。主认证逻辑继续保留在 login() / findAccountThirdPartyAccountSourceRefByName() 中。

// 建议拆分为纯查找方法(无密码校验)
public ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountSourceRefByNameOnly(String ldapLoginName) {
    final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
    if (!currentLdapServer.isSuccess()) {
        return ErrorableValue.ofErrorCode(currentLdapServer.error);
    }
    final LdapServerVO ldap = currentLdapServer.result;
    String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), ldapLoginName);
    // 仅查找绑定关系,不做密码校验
    AccountThirdPartyAccountSourceRefVO vo = ...find by dn...;
    if (vo == null) {
        return ErrorableValue.ofErrorCode(...);
    }
    return ErrorableValue.of(vo);
}

🟡 Warning — 同一认证流程中两次获取 LDAP 服务器实例,存在不一致风险

文件plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java,约第 411–420 行

findAccountThirdPartyAccountSourceRefByName() 先通过 findCurrentLdapServer() 拿到当前 LDAP 服务器 ldap,随后调用 isValid(ldapLoginName, ldapLoginPassword)。如果 isValid() 内部又调用了 findCurrentLdapServer(),则在并发切换 LDAP 服务器的场景下,密码校验可能命中服务器 A,而 DN 查询却走服务器 B,导致认证结果与绑定账号不一致。

建议:为 isValid() 新增一个接受 LdapServerVO 参数的重载方法,或者将已获取的 ldap 实例传入,确保单次流程使用同一服务器快照。


🟡 Warning — SDK 新增 required=truetype 字段属于 Breaking Change

文件

  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java,约第 40 行
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java,约第 40 行

两个 Action 新增了 @Param(required = true, validValues = {"account","ldap"})type 字段。所有现有的 API 调用方如果未传入 type 参数,将直接报错。

建议

  1. 确认目标分支 zsv_5.0.0 是否允许 Breaking API Change(如属于大版本迭代,则可接受)。
  2. 若需向后兼容,可将 required 设为 false 并设置默认值 "account",保持老客户端行为不变。
  3. 无论哪种选择,应在 Release Notes 或升级文档中明确说明此 API 变更。

🟡 Warning — collectUserInfoIntoContext() 中存在不可达的 null 检查

文件plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java,约第 489–491 行

if (accountThirdPartyAccountSourceRef.result == null) {
    return;
}

findAccountThirdPartyAccountSourceRefByName() 方法中,vo == null 时已经返回 ErrorableValue.ofErrorCode(...)。因此当 isSuccess()true 时,result 不可能为 null,这段检查是死代码。虽然不影响正确性,但会误导阅读者以为存在 result 为 null 的正常分支。

建议:移除该 null 检查,或者如果确实需要防御性编程,添加注释说明意图。


🟢 Suggestion — 代码风格:if 后双空格

文件plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java,约第 439 行

if  (!accountThirdPartyAccountSourceRef.isSuccess()) {

if( 之间有两个空格,应为一个。


🟢 Suggestion — 接口新方法缺少 Javadoc

文件plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java,约第 13 行

findAccountThirdPartyAccountSourceRefByName 是对外契约,当前缺少 Javadoc。仅看方法签名无法判断:

  • 该方法是否一定会执行 LDAP 认证?
  • 失败时返回哪些 ErrorCode
  • 参数 ldapLoginPassword 如果为 null 会怎样?

建议补充标准 Javadoc(@param@return),明确方法语义,避免后续实现和调用方出现理解偏差。


总结

级别 数量 说明
🔴 Critical 1 collectUserInfoIntoContext 不应做密码校验,与 isSuppressCredentialCheck 语义冲突
🟡 Warning 3 LDAP 服务器双重获取风险;SDK Breaking Change;死代码
🟢 Suggestion 2 代码风格;接口 Javadoc

核心问题在于提取公共方法时,将「账号查找」与「密码校验」绑定在一起,导致所有调用方都被迫执行认证。建议将两者拆分,collectUserInfoIntoContext() 仅做纯查找,确保双因子认证获取 secret 的流程不受影响。


🤖 Robot Reviewer

@MatheMatrix MatheMatrix force-pushed the sync/zstackio/ZSV-11833@@2 branch from c89c44c to 893727d Compare April 11, 2026 08:42
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java (3)

441-441: 修复代码风格:双空格。

if 语句中有多余的空格。

♻️ 建议修改
-        if  (!accountThirdPartyAccountSourceRef.isSuccess()) {
+        if (!accountThirdPartyAccountSourceRef.isSuccess()) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` at line 441,
Remove the extra space between the if keyword and the opening parenthesis in the
conditional at LdapManagerImpl (the line using if 
(!accountThirdPartyAccountSourceRef.isSuccess())). Update it to use standard
Java style: if (!accountThirdPartyAccountSourceRef.isSuccess()) so the code
follows proper spacing conventions.

411-429: 参数 ldapLoginPassword 未被使用。

方法签名中的 ldapLoginPassword 参数在方法体内未被使用。如果是为了将来扩展或保持 API 一致性而保留,请添加注释说明;否则建议移除该参数以避免混淆。

♻️ 建议修改
-    public ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword) {
+    public ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName) {

相应地,调用处也需要同步更新。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
411 - 429, The parameter ldapLoginPassword in
findAccountThirdPartyAccountSourceRefByName is unused; either remove it from the
method signature and update all callers, or if it must remain for API
compatibility, document it explicitly and avoid warnings (e.g., add a comment or
annotate as unused) and, if appropriate, pass it into
createDriver().getFullUserDn or other auth logic in LdapManagerImpl to reflect
intended use; locate the method by name and update references (call sites) or
add the explanatory comment/unused annotation next to ldapLoginPassword to make
intent clear.

431-444: 同一认证流程中存在两次 LDAP 服务器查询。

isValid() (Line 433) 和 findAccountThirdPartyAccountSourceRefByName() (Line 439) 各自独立调用 findCurrentLdapServer()。虽然全局配置在请求期间变更的概率较低,但严格来说,如果两次调用之间配置发生变化,可能导致密码校验与账号绑定查询使用不同的 LDAP 服务器。

建议将 LdapServerVO 实例传递给 isValidfindAccountThirdPartyAccountSourceRefByName,确保同一请求中使用同一服务器快照。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
431 - 444, The login method currently calls findCurrentLdapServer() twice via
isValid(...) and findAccountThirdPartyAccountSourceRefByName(...), risking
inconsistent server snapshots; change login(LoginContext, ReturnValueCompletion)
to call findCurrentLdapServer() once (capture the LdapServerVO) and pass that
LdapServerVO into isValid(...) and
findAccountThirdPartyAccountSourceRefByName(...) (or add overloads that accept
an LdapServerVO) so both credential validation and account binding lookup use
the same server instance; update the signatures of isValid and/or
findAccountThirdPartyAccountSourceRefByName to accept LdapServerVO and use that
instead of calling findCurrentLdapServer() internally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 502-504: The null-check branch guarding
accountThirdPartyAccountSourceRef.result in LdapManagerImpl is dead because
findAccountThirdPartyAccountSourceRefByName() returns an ErrorableValue with an
error rather than a successful value containing null; remove the unreachable "if
(accountThirdPartyAccountSourceRef.result == null) return;" branch, or if you
prefer to keep it for defensive clarity, add a `@SuppressWarnings` annotation on
the enclosing method and a one-line comment referencing
findAccountThirdPartyAccountSourceRefByName()’s ErrorableValue behavior
explaining why the null-check is unnecessary.

---

Nitpick comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Line 441: Remove the extra space between the if keyword and the opening
parenthesis in the conditional at LdapManagerImpl (the line using if 
(!accountThirdPartyAccountSourceRef.isSuccess())). Update it to use standard
Java style: if (!accountThirdPartyAccountSourceRef.isSuccess()) so the code
follows proper spacing conventions.
- Around line 411-429: The parameter ldapLoginPassword in
findAccountThirdPartyAccountSourceRefByName is unused; either remove it from the
method signature and update all callers, or if it must remain for API
compatibility, document it explicitly and avoid warnings (e.g., add a comment or
annotate as unused) and, if appropriate, pass it into
createDriver().getFullUserDn or other auth logic in LdapManagerImpl to reflect
intended use; locate the method by name and update references (call sites) or
add the explanatory comment/unused annotation next to ldapLoginPassword to make
intent clear.
- Around line 431-444: The login method currently calls findCurrentLdapServer()
twice via isValid(...) and findAccountThirdPartyAccountSourceRefByName(...),
risking inconsistent server snapshots; change login(LoginContext,
ReturnValueCompletion) to call findCurrentLdapServer() once (capture the
LdapServerVO) and pass that LdapServerVO into isValid(...) and
findAccountThirdPartyAccountSourceRefByName(...) (or add overloads that accept
an LdapServerVO) so both credential validation and account binding lookup use
the same server instance; update the signatures of isValid and/or
findAccountThirdPartyAccountSourceRefByName to accept LdapServerVO and use that
instead of calling findCurrentLdapServer() internally.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e8e41b6c-2efa-45fa-a9ec-520d11324786

📥 Commits

Reviewing files that changed from the base of the PR and between c89c44c and 893727d.

⛔ Files ignored due to path filters (1)
  • test/src/test/resources/springConfigXml/license.xml is excluded by !**/*.xml
📒 Files selected for processing (4)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java
🚧 Files skipped from review as they are similar to previous changes (3)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

@MatheMatrix MatheMatrix force-pushed the sync/zstackio/ZSV-11833@@2 branch from 893727d to 2040660 Compare April 11, 2026 09:41
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java (1)

410-416: ⚠️ Potential issue | 🟠 Major

同一次登录流程里不要两次读取“当前 LDAP”。

这里先通过 isValid() 做一次密码校验,再在 findAccountThirdPartyAccountSourceRefByName() 里重新取一次当前 LDAP。若两次调用之间 CURRENT_LDAP_SERVER_UUID 被切换,密码校验和绑定账号解析就可能落到不同服务器,导致这次登录的认证结果与账号映射不一致。建议先取一次 LdapServerVO,并在本次登录流程里复用同一个实例。

🔧 建议修改
+    private ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(LdapServerVO ldap, String ldapLoginName) {
+        String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), ldapLoginName);
+        AccountThirdPartyAccountSourceRefVO vo = Q.New(AccountThirdPartyAccountSourceRefVO.class)
+                .eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
+                .eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
+                .find();
+        if (vo == null) {
+            return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
+                    "The ldapUid does not have a binding account."));
+        }
+        return ErrorableValue.of(vo);
+    }
+
     `@Override`
     public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionInfo> completion) {
-        if (!isValid(loginContext.getUsername(), loginContext.getPassword())) {
+        final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
+        if (!currentLdapServer.isSuccess()) {
+            completion.fail(currentLdapServer.error);
+            return;
+        }
+        final LdapServerVO ldap = currentLdapServer.result;
+
+        if (!createDriver().isValid(loginContext.getUsername(), loginContext.getPassword(), ldap)) {
             completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
                     "Login validation failed in LDAP"));
             return;
         }
 
-        final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
+        final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef =
+                findAccountThirdPartyAccountSourceRefByName(ldap, loginContext.getUsername());

Also applies to: 432-438

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
410 - 416, 当前登录流程中出现两次读取“当前 LDAP”的问题:在调用 isValid() 做密码校验后又在
findAccountThirdPartyAccountSourceRefByName() 内重新调用
findCurrentLdapServer(),可能导致两次获取到不同的 LdapServerVO(CURRENT_LDAP_SERVER_UUID
被切换),从而使校验与账号映射不一致。修复方法是只在登录流程开始时获取一次 LdapServerVO(result 的
LdapServerVO),并在后续复用该实例;为此修改 findAccountThirdPartyAccountSourceRefByName(...)
的签名或调用方以接受一个 LdapServerVO 参数(或传入该实例作为额外参数),并在
isValid(...)、findAccountThirdPartyAccountSourceRefByName(...) 等使用到当前 LDAP
的地方都使用同一个 LdapServerVO 实例(注意同时修复在同文件的另一处 432-438 区域同样的重复读取问题)。
🧹 Nitpick comments (1)
plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java (1)

410-428: 把“用户名→绑定账号”解析抽成无密码 helper,避免继续复制查询逻辑。

findAccountThirdPartyAccountSourceRefByName() 现在已经不做 LDAP 密码校验了,但签名仍然要求 ldapLoginPassword。这会误导调用方,也让 getAccountIdByName() 只能再复制一遍 DN 和绑定账号查询逻辑。更稳妥的是抽一个只依赖 LdapServerVO + username 的 lookup 方法,login() 前面单独做密码校验即可。

♻️ 建议修改
+    private ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountRefByUsername(LdapServerVO ldap, String username) {
+        String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), username);
+        AccountThirdPartyAccountSourceRefVO vo = Q.New(AccountThirdPartyAccountSourceRefVO.class)
+                .eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
+                .eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
+                .find();
+        if (vo == null) {
+            return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
+                    "The ldapUid does not have a binding account."));
+        }
+        return ErrorableValue.of(vo);
+    }
+
     public ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(String ldapLoginName, String ldapLoginPassword) {
         final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
         if (!currentLdapServer.isSuccess()) {
             return ErrorableValue.ofErrorCode(currentLdapServer.error);
         }
-        final LdapServerVO ldap = currentLdapServer.result;
-
-        String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), ldapLoginName);
-        AccountThirdPartyAccountSourceRefVO vo = Q.New(AccountThirdPartyAccountSourceRefVO.class)
-                .eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
-                .eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
-                .find();
-
-        if (vo == null) {
-            return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
-                    "The ldapUid does not have a binding account."));
-        }
-        return ErrorableValue.of(vo);
+        return findAccountRefByUsername(currentLdapServer.result, ldapLoginName);
     }
 
     `@Override`
     public String getAccountIdByName(String username) {
         final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
@@
-        String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), username);
-        if (dn == null || dn.isEmpty()) {
-            return null;
-        }
-
-        String accountUuid = Q.New(AccountThirdPartyAccountSourceRefVO.class)
-                .select(AccountThirdPartyAccountSourceRefVO_.accountUuid)
-                .eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
-                .eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
-                .findValue();
-        return accountUuid;
+        ErrorableValue<AccountThirdPartyAccountSourceRefVO> ref = findAccountRefByUsername(ldap, username);
+        return ref.isSuccess() ? ref.result.getAccountUuid() : null;
     }

As per coding guidelines, “命名应尽量用完整的单词组合表达意图,并在名称中体现数据类型或用途。”

Also applies to: 475-492

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
410 - 428, The method findAccountThirdPartyAccountSourceRefByName currently
takes ldapLoginPassword but does not use it and forces callers (like
getAccountIdByName) to duplicate DN lookup/query logic; refactor by introducing
a password-less helper such as
findAccountThirdPartyAccountSourceRefByUsername(LdapServerVO ldap, String
username) or lookupAccountThirdPartyRefByUsername(LdapServerVO, String) that
uses createDriver().getFullUserDn(...) and queries
AccountThirdPartyAccountSourceRefVO, update
findAccountThirdPartyAccountSourceRefByName to obtain the LdapServerVO via
findCurrentLdapServer() and delegate to the new helper (removing the unused
ldapLoginPassword parameter), and change callers (getAccountIdByName and login)
to call the helper and perform password validation separately using
createDriver().validatePassword(...) or equivalent; ensure error returns remain
identical.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 410-416: 当前登录流程中出现两次读取“当前 LDAP”的问题:在调用 isValid() 做密码校验后又在
findAccountThirdPartyAccountSourceRefByName() 内重新调用
findCurrentLdapServer(),可能导致两次获取到不同的 LdapServerVO(CURRENT_LDAP_SERVER_UUID
被切换),从而使校验与账号映射不一致。修复方法是只在登录流程开始时获取一次 LdapServerVO(result 的
LdapServerVO),并在后续复用该实例;为此修改 findAccountThirdPartyAccountSourceRefByName(...)
的签名或调用方以接受一个 LdapServerVO 参数(或传入该实例作为额外参数),并在
isValid(...)、findAccountThirdPartyAccountSourceRefByName(...) 等使用到当前 LDAP
的地方都使用同一个 LdapServerVO 实例(注意同时修复在同文件的另一处 432-438 区域同样的重复读取问题)。

---

Nitpick comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 410-428: The method findAccountThirdPartyAccountSourceRefByName
currently takes ldapLoginPassword but does not use it and forces callers (like
getAccountIdByName) to duplicate DN lookup/query logic; refactor by introducing
a password-less helper such as
findAccountThirdPartyAccountSourceRefByUsername(LdapServerVO ldap, String
username) or lookupAccountThirdPartyRefByUsername(LdapServerVO, String) that
uses createDriver().getFullUserDn(...) and queries
AccountThirdPartyAccountSourceRefVO, update
findAccountThirdPartyAccountSourceRefByName to obtain the LdapServerVO via
findCurrentLdapServer() and delegate to the new helper (removing the unused
ldapLoginPassword parameter), and change callers (getAccountIdByName and login)
to call the helper and perform password validation separately using
createDriver().validatePassword(...) or equivalent; ensure error returns remain
identical.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 78648d1b-4e97-4fb2-8fe6-19d4f43dde46

📥 Commits

Reviewing files that changed from the base of the PR and between 893727d and 2040660.

⛔ Files ignored due to path filters (1)
  • test/src/test/resources/springConfigXml/license.xml is excluded by !**/*.xml
📒 Files selected for processing (4)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java
🚧 Files skipped from review as they are similar to previous changes (3)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

@MatheMatrix MatheMatrix force-pushed the sync/zstackio/ZSV-11833@@2 branch from 2040660 to b43b4d5 Compare April 11, 2026 10:59
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java (1)

431-443: ⚠️ Potential issue | 🟠 Major

同一次登录链路里仍然会读取两次“当前 LDAP”。

Line 432 先通过 findAccountThirdPartyAccountSourceRefByName(...) 解析了一次当前 LDAP,Line 439 又通过 isValid(...) 再取一次。如果这两步之间全局当前 LDAP 被切换,绑定查询和口令校验就可能落到不同服务器上,最终把 A 服务器的账号映射和 B 服务器的认证结果拼在一起。这里最好在 login() 开头只解析一次 LdapServerVO,后续查绑定和 isValid 都复用同一个快照。

🔧 建议修改
+    private ErrorableValue<AccountThirdPartyAccountSourceRefVO> findAccountThirdPartyAccountSourceRefByName(LdapServerVO ldap, String ldapLoginName) {
+        String dn = createDriver().getFullUserDn(ldap, ldap.getUsernameProperty(), ldapLoginName);
+        AccountThirdPartyAccountSourceRefVO vo = Q.New(AccountThirdPartyAccountSourceRefVO.class)
+                .eq(AccountThirdPartyAccountSourceRefVO_.credentials, dn)
+                .eq(AccountThirdPartyAccountSourceRefVO_.accountSourceUuid, ldap.getUuid())
+                .find();
+        if (vo == null) {
+            return ErrorableValue.ofErrorCode(err(IdentityErrors.AUTHENTICATION_ERROR,
+                    "The ldapUid does not have a binding account."));
+        }
+        return ErrorableValue.of(vo);
+    }
+
     `@Override`
     public void login(LoginContext loginContext, ReturnValueCompletion<LoginSessionInfo> completion) {
-        final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
+        final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
+        if (!currentLdapServer.isSuccess()) {
+            completion.fail(currentLdapServer.error);
+            return;
+        }
+
+        final LdapServerVO ldap = currentLdapServer.result;
+        final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef =
+                findAccountThirdPartyAccountSourceRefByName(ldap, loginContext.getUsername());
 
-        if  (!accountThirdPartyAccountSourceRef.isSuccess()) {
+        if (!accountThirdPartyAccountSourceRef.isSuccess()) {
             completion.fail(accountThirdPartyAccountSourceRef.error);
             return;
         }
 
-        if (!isValid(loginContext.getUsername(), loginContext.getPassword())) {
+        if (!createDriver().isValid(loginContext.getUsername(), loginContext.getPassword(), ldap)) {
             completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
                     "Login validation failed in LDAP"));
             return;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
431 - 443, The login method currently resolves the current LDAP twice (via
findAccountThirdPartyAccountSourceRefByName(...) and again inside isValid(...)),
which can race if the global "current LDAP" flips between calls; change
login(LoginContext, ReturnValueCompletion) to resolve the LdapServerVO once at
the start (use the result from findAccountThirdPartyAccountSourceRefByName(...)
/ accountThirdPartyAccountSourceRef), store that snapshot, and pass it into
subsequent operations (binding lookup and password validation) so both the
binding lookup and isValid use the same LdapServerVO instance; if needed add an
overload or helper that accepts the resolved LdapServerVO to avoid re-reading
the global current server.
🧹 Nitpick comments (1)
plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java (1)

410-428: 这个辅助方法的签名现在有误导性。

ldapLoginPassword 在这里没有任何用途,但这个 public 方法的签名会让调用方误以为它顺带做了 LDAP 凭证校验。既然它现在只负责“登录名 → 绑定账号”的解析,建议去掉这个参数,或者至少补一个不带密码参数的 lookup-only 重载,并把校验责任明确留在 login()/authenticate()。 As per coding guidelines, "命名应尽量用完整的单词组合表达意图" 且 "代码应尽量做到自解释"。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
410 - 428, The method findAccountThirdPartyAccountSourceRefByName currently
accepts ldapLoginPassword but never uses it; update the API to avoid misleading
callers by either removing the unused ldapLoginPassword parameter from
findAccountThirdPartyAccountSourceRefByName or add an overload
findAccountThirdPartyAccountSourceRefByName(String ldapLoginName) that is
explicitly lookup-only; then update all callers to use the no-password variant
and ensure any credential validation remains in the login()/authenticate() flow
(keep createDriver().getFullUserDn(…) and the Q.New(...) lookup logic
unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 431-443: The login method currently resolves the current LDAP
twice (via findAccountThirdPartyAccountSourceRefByName(...) and again inside
isValid(...)), which can race if the global "current LDAP" flips between calls;
change login(LoginContext, ReturnValueCompletion) to resolve the LdapServerVO
once at the start (use the result from
findAccountThirdPartyAccountSourceRefByName(...) /
accountThirdPartyAccountSourceRef), store that snapshot, and pass it into
subsequent operations (binding lookup and password validation) so both the
binding lookup and isValid use the same LdapServerVO instance; if needed add an
overload or helper that accepts the resolved LdapServerVO to avoid re-reading
the global current server.

---

Nitpick comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 410-428: The method findAccountThirdPartyAccountSourceRefByName
currently accepts ldapLoginPassword but never uses it; update the API to avoid
misleading callers by either removing the unused ldapLoginPassword parameter
from findAccountThirdPartyAccountSourceRefByName or add an overload
findAccountThirdPartyAccountSourceRefByName(String ldapLoginName) that is
explicitly lookup-only; then update all callers to use the no-password variant
and ensure any credential validation remains in the login()/authenticate() flow
(keep createDriver().getFullUserDn(…) and the Q.New(...) lookup logic
unchanged).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 94e1878e-e75c-4585-beb2-17115182bcee

📥 Commits

Reviewing files that changed from the base of the PR and between 2040660 and b43b4d5.

⛔ Files ignored due to path filters (1)
  • test/src/test/resources/springConfigXml/license.xml is excluded by !**/*.xml
📒 Files selected for processing (4)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java
🚧 Files skipped from review as they are similar to previous changes (3)
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

…ication 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
@MatheMatrix MatheMatrix force-pushed the sync/zstackio/ZSV-11833@@2 branch from b43b4d5 to 82bc126 Compare April 11, 2026 15:06
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java (1)

410-427: ⚠️ Potential issue | 🟠 Major

同一次登录流程里仍然可能跨两个 LDAP 服务器快照。

这里先在 findAccountThirdPartyAccountSourceRefByName() 里取一次当前 LDAP 并完成 DN/绑定查询,随后 Line 439 又通过 isValid() 再取一次当前 LDAP。若这两步之间“当前 LDAP”被切换,绑定账号和密码校验就可能落到不同服务器,认证结果会不一致。建议把同一个 LdapServerVO 快照贯穿整个登录流程。

🔧 建议方向
-        final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef = findAccountThirdPartyAccountSourceRefByName(loginContext.getUsername(), loginContext.getPassword());
+        final ErrorableValue<LdapServerVO> currentLdapServer = findCurrentLdapServer();
+        if (!currentLdapServer.isSuccess()) {
+            completion.fail(currentLdapServer.error);
+            return;
+        }
+        final LdapServerVO ldap = currentLdapServer.result;
+
+        final ErrorableValue<AccountThirdPartyAccountSourceRefVO> accountThirdPartyAccountSourceRef =
+                findAccountThirdPartyAccountSourceRefByName(ldap, loginContext.getUsername());

         if (!accountThirdPartyAccountSourceRef.isSuccess()) {
             completion.fail(accountThirdPartyAccountSourceRef.error);
             return;
         }

-        if (!isValid(loginContext.getUsername(), loginContext.getPassword())) {
+        if (!createDriver().isValid(loginContext.getUsername(), loginContext.getPassword(), ldap)) {
             completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR,
                     "Login validation failed in LDAP"));
             return;
         }

Also applies to: 431-443

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java` around lines
410 - 427, The current login flow can observe two different LdapServerVO
snapshots because findAccountThirdPartyAccountSourceRefByName() calls
findCurrentLdapServer() and later other code calls isValid() which re-reads the
current LDAP; to fix, capture and pass a single LdapServerVO snapshot through
the entire authentication flow instead of re-fetching: modify
findAccountThirdPartyAccountSourceRefByName() (and callers) to accept an
LdapServerVO parameter (or return both the VO and any needed values) so
subsequent calls to isValid(), createDriver(), and credential checks use the
same LdapServerVO instance; ensure methods like findCurrentLdapServer(),
createDriver(), isValid(), and any call sites that currently re-read the server
are updated to use the provided LdapServerVO to keep a consistent snapshot
during one login attempt.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java`:
- Around line 410-427: The current login flow can observe two different
LdapServerVO snapshots because findAccountThirdPartyAccountSourceRefByName()
calls findCurrentLdapServer() and later other code calls isValid() which
re-reads the current LDAP; to fix, capture and pass a single LdapServerVO
snapshot through the entire authentication flow instead of re-fetching: modify
findAccountThirdPartyAccountSourceRefByName() (and callers) to accept an
LdapServerVO parameter (or return both the VO and any needed values) so
subsequent calls to isValid(), createDriver(), and credential checks use the
same LdapServerVO instance; ensure methods like findCurrentLdapServer(),
createDriver(), isValid(), and any call sites that currently re-read the server
are updated to use the provided LdapServerVO to keep a consistent snapshot
during one login attempt.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a4905365-2197-4896-8a9e-c6b5b18d5fd3

📥 Commits

Reviewing files that changed from the base of the PR and between b43b4d5 and 82bc126.

⛔ Files ignored due to path filters (1)
  • test/src/test/resources/springConfigXml/license.xml is excluded by !**/*.xml
📒 Files selected for processing (6)
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java
  • testlib/src/main/java/org/zstack/testlib/identity/ldap/LdapDriverSimulator.groovy
  • testlib/src/main/java/org/zstack/testlib/identity/ldap/LdapVirtualEndpointSpec.groovy
🚧 Files skipped from review as they are similar to previous changes (3)
  • sdk/src/main/java/org/zstack/sdk/GetTwoFactorAuthenticationSecretAction.java
  • plugin/ldap/src/main/java/org/zstack/ldap/LdapManager.java
  • sdk/src/main/java/org/zstack/sdk/ResetTwoFactorAuthenticationSecretAction.java

Resolves: ZSV-11833

Change-Id: I696c6e746965616478786e6f6e6263636d766868
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants